2 Unix SMB/CIFS implementation.
3 Samba Web Administration Tool
5 Copyright (C) Andrew Tridgell 1997-2002
6 Copyright (C) John H Terpstra 2002
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 * @defgroup swat SWAT - Samba Web Administration Tool
28 * @brief Samba Web Administration Tool.
32 #include "../web/swat_proto.h"
34 static BOOL demo_mode
= False
;
35 static BOOL have_write_access
= False
;
36 static BOOL have_read_access
= False
;
37 static int iNumNonAutoPrintServices
= 0;
40 * Password Management Globals
42 #define SWAT_USER "username"
43 #define OLD_PSWD "old_passwd"
44 #define NEW_PSWD "new_passwd"
45 #define NEW2_PSWD "new2_passwd"
46 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
47 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
48 #define ADD_USER_FLAG "add_user_flag"
49 #define DELETE_USER_FLAG "delete_user_flag"
50 #define DISABLE_USER_FLAG "disable_user_flag"
51 #define ENABLE_USER_FLAG "enable_user_flag"
52 #define RHOST "remote_host"
54 /****************************************************************************
55 ****************************************************************************/
56 static int enum_index(int value
, const struct enum_list
*enumlist
)
59 for (i
=0;enumlist
[i
].name
;i
++)
60 if (value
== enumlist
[i
].value
) break;
64 static char *fix_backslash(const char *str
)
66 static char newstring
[1024];
70 if (*str
== '\\') {*p
++ = '\\';*p
++ = '\\';}
78 static char *stripspaceupper(const char *str
)
80 static char newstring
[1024];
84 if (*str
!= ' ') *p
++ = toupper(*str
);
91 static char *make_parm_name(const char *label
)
93 static char parmname
[1024];
97 if (*label
== ' ') *p
++ = '_';
105 /****************************************************************************
106 include a lump of html in a page
107 ****************************************************************************/
108 static int include_html(const char *fname
)
114 fd
= web_open(fname
, O_RDONLY
, 0);
117 d_printf(_("ERROR: Can't open %s"), fname
);
122 while ((ret
= read(fd
, buf
, sizeof(buf
))) > 0) {
130 /****************************************************************************
131 start the page with standard stuff
132 ****************************************************************************/
133 static void print_header(void)
135 if (!cgi_waspost()) {
136 d_printf("Expires: 0\r\n");
138 d_printf("Content-type: text/html\r\n\r\n");
140 if (!include_html("include/header.html")) {
141 d_printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
142 d_printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
146 /* *******************************************************************
147 show parameter label with translated name in the following form
148 because showing original and translated label in one line looks
149 too long, and showing translated label only is unusable for
151 -------------------------------
152 HELP security [combo box][button]
154 -------------------------------
155 (capital words are translated by gettext.)
156 if no translation is available, then same form as original is
158 "i18n_translated_parm" class is used to change the color of the
159 translated parameter with CSS.
160 **************************************************************** */
161 static const char* get_parm_translated(
162 const char* pAnchor
, const char* pHelp
, const char* pLabel
)
164 const char* pTranslated
= _(pLabel
);
165 static pstring output
;
166 if(strcmp(pLabel
, pTranslated
) != 0)
169 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
170 pAnchor
, pHelp
, pLabel
, pTranslated
);
174 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
175 pAnchor
, pHelp
, pLabel
);
178 /****************************************************************************
180 ****************************************************************************/
181 static void print_footer(void)
183 if (!include_html("include/footer.html")) {
184 d_printf("\n</BODY>\n</HTML>\n");
188 /****************************************************************************
189 display one editable parameter in a form
190 ****************************************************************************/
191 static void show_parameter(int snum
, struct parm_struct
*parm
)
194 void *ptr
= parm
->ptr
;
196 if (parm
->class == P_LOCAL
&& snum
>= 0) {
197 ptr
= lp_local_ptr(snum
, ptr
);
200 d_printf("<tr><td>%s</td><td>", get_parm_translated(stripspaceupper(parm
->label
), _("Help"), parm
->label
));
201 switch (parm
->type
) {
203 d_printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
204 make_parm_name(parm
->label
), *(char *)ptr
);
205 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
206 _("Set Default"), make_parm_name(parm
->label
),(char)(parm
->def
.cvalue
));
210 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"",
211 make_parm_name(parm
->label
));
212 if ((char ***)ptr
&& *(char ***)ptr
&& **(char ***)ptr
) {
213 char **list
= *(char ***)ptr
;
214 for (;*list
;list
++) {
215 /* enclose in quotes if the string contains a space */
216 if ( strchr_m(*list
, ' ') )
217 d_printf("\'%s\'%s", *list
, ((*(list
+1))?", ":""));
219 d_printf("%s%s", *list
, ((*(list
+1))?", ":""));
223 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
224 _("Set Default"), make_parm_name(parm
->label
));
225 if (parm
->def
.lvalue
) {
226 char **list
= (char **)(parm
->def
.lvalue
);
227 for (; *list
; list
++) {
228 /* enclose in quotes if the string contains a space */
229 if ( strchr_m(*list
, ' ') )
230 d_printf("\'%s\'%s", *list
, ((*(list
+1))?", ":""));
232 d_printf("%s%s", *list
, ((*(list
+1))?", ":""));
240 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
241 make_parm_name(parm
->label
), *(char **)ptr
);
242 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
243 _("Set Default"), make_parm_name(parm
->label
),fix_backslash((char *)(parm
->def
.svalue
)));
248 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
249 make_parm_name(parm
->label
), (char *)ptr
);
250 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
251 _("Set Default"), make_parm_name(parm
->label
),fix_backslash((char *)(parm
->def
.svalue
)));
255 d_printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
256 d_printf("<option %s>Yes", (*(BOOL
*)ptr
)?"selected":"");
257 d_printf("<option %s>No", (*(BOOL
*)ptr
)?"":"selected");
258 d_printf("</select>");
259 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
260 _("Set Default"), make_parm_name(parm
->label
),(BOOL
)(parm
->def
.bvalue
)?0:1);
264 d_printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
265 d_printf("<option %s>Yes", (*(BOOL
*)ptr
)?"":"selected");
266 d_printf("<option %s>No", (*(BOOL
*)ptr
)?"selected":"");
267 d_printf("</select>");
268 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
269 _("Set Default"), make_parm_name(parm
->label
),(BOOL
)(parm
->def
.bvalue
)?1:0);
273 d_printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm
->label
), *(int *)ptr
);
274 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
275 _("Set Default"), make_parm_name(parm
->label
),(int)(parm
->def
.ivalue
));
279 d_printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm
->label
), octal_string(*(int *)ptr
));
280 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
281 _("Set Default"), make_parm_name(parm
->label
),
282 octal_string((int)(parm
->def
.ivalue
)));
286 d_printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
287 for (i
=0;parm
->enum_list
[i
].name
;i
++) {
288 if (i
== 0 || parm
->enum_list
[i
].value
!= parm
->enum_list
[i
-1].value
) {
289 d_printf("<option %s>%s",(*(int *)ptr
)==parm
->enum_list
[i
].value
?"selected":"",parm
->enum_list
[i
].name
);
292 d_printf("</select>");
293 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
294 _("Set Default"), make_parm_name(parm
->label
),enum_index((int)(parm
->def
.ivalue
),parm
->enum_list
));
299 d_printf("</td></tr>\n");
302 /****************************************************************************
303 display a set of parameters for a service
304 ****************************************************************************/
305 static void show_parameters(int snum
, int allparameters
, unsigned int parm_filter
, int printers
)
308 struct parm_struct
*parm
;
309 const char *heading
= NULL
;
310 const char *last_heading
= NULL
;
312 while ((parm
= lp_next_parameter(snum
, &i
, allparameters
))) {
313 if (snum
< 0 && parm
->class == P_LOCAL
&& !(parm
->flags
& FLAG_GLOBAL
))
315 if (parm
->class == P_SEPARATOR
) {
316 heading
= parm
->label
;
319 if (parm
->flags
& FLAG_HIDE
) continue;
321 if (printers
& !(parm
->flags
& FLAG_PRINT
)) continue;
322 if (!printers
& !(parm
->flags
& FLAG_SHARE
)) continue;
325 if (!( parm_filter
& FLAG_ADVANCED
)) {
326 if (!(parm
->flags
& FLAG_BASIC
)) {
327 void *ptr
= parm
->ptr
;
329 if (parm
->class == P_LOCAL
&& snum
>= 0) {
330 ptr
= lp_local_ptr(snum
, ptr
);
333 switch (parm
->type
) {
335 if (*(char *)ptr
== (char)(parm
->def
.cvalue
)) continue;
339 if (!str_list_compare(*(char ***)ptr
, (char **)(parm
->def
.lvalue
))) continue;
344 if (!strcmp(*(char **)ptr
,(char *)(parm
->def
.svalue
))) continue;
349 if (!strcmp((char *)ptr
,(char *)(parm
->def
.svalue
))) continue;
354 if (*(BOOL
*)ptr
== (BOOL
)(parm
->def
.bvalue
)) continue;
359 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
364 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
370 if (printers
&& !(parm
->flags
& FLAG_PRINT
)) continue;
373 if ((parm_filter
& FLAG_WIZARD
) && !(parm
->flags
& FLAG_WIZARD
)) continue;
375 if ((parm_filter
& FLAG_ADVANCED
) && !(parm
->flags
& FLAG_ADVANCED
)) continue;
377 if (heading
&& heading
!= last_heading
) {
378 d_printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading
));
379 last_heading
= heading
;
381 show_parameter(snum
, parm
);
385 /****************************************************************************
386 load the smb.conf file into loadparm.
387 ****************************************************************************/
388 static BOOL
load_config(BOOL save_def
)
390 lp_resetnumservices();
391 return lp_load(dyn_CONFIGFILE
,False
,save_def
,False
);
394 /****************************************************************************
396 ****************************************************************************/
397 static void write_config(FILE *f
, BOOL show_defaults
)
399 fprintf(f
, "# Samba config file created using SWAT\n");
400 fprintf(f
, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
401 fprintf(f
, "# Date: %s\n\n", timestring(False
));
403 lp_dump(f
, show_defaults
, iNumNonAutoPrintServices
);
406 /****************************************************************************
407 save and reload the smb.conf config file
408 ****************************************************************************/
409 static int save_reload(int snum
)
414 f
= sys_fopen(dyn_CONFIGFILE
,"w");
416 d_printf(_("failed to open %s for writing"), dyn_CONFIGFILE
);
421 /* just in case they have used the buggy xinetd to create the file */
422 if (fstat(fileno(f
), &st
) == 0 &&
423 (st
.st_mode
& S_IWOTH
)) {
424 #if defined HAVE_FCHMOD
425 fchmod(fileno(f
), S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
427 chmod(dyn_CONFIGFILE
, S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
431 write_config(f
, False
);
433 lp_dump_one(f
, False
, snum
);
438 if (!load_config(False
)) {
439 d_printf(_("Can't reload %s"), dyn_CONFIGFILE
);
443 iNumNonAutoPrintServices
= lp_numservices();
449 /****************************************************************************
451 ****************************************************************************/
452 static void commit_parameter(int snum
, struct parm_struct
*parm
, const char *v
)
457 if (snum
< 0 && parm
->class == P_LOCAL
) {
458 /* this handles the case where we are changing a local
459 variable globally. We need to change the parameter in
460 all shares where it is currently set to the default */
461 for (i
=0;i
<lp_numservices();i
++) {
462 s
= lp_servicename(i
);
463 if (s
&& (*s
) && lp_is_default(i
, parm
)) {
464 lp_do_parameter(i
, parm
->label
, v
);
469 lp_do_parameter(snum
, parm
->label
, v
);
472 /****************************************************************************
473 commit a set of parameters for a service
474 ****************************************************************************/
475 static void commit_parameters(int snum
)
478 struct parm_struct
*parm
;
482 while ((parm
= lp_next_parameter(snum
, &i
, 1))) {
483 slprintf(label
, sizeof(label
)-1, "parm_%s", make_parm_name(parm
->label
));
484 if ((v
= cgi_variable(label
))) {
485 if (parm
->flags
& FLAG_HIDE
) continue;
486 commit_parameter(snum
, parm
, v
);
491 /****************************************************************************
492 spit out the html for a link with an image
493 ****************************************************************************/
494 static void image_link(const char *name
, const char *hlink
, const char *src
)
496 d_printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
497 cgi_baseurl(), hlink
, src
, name
);
500 /****************************************************************************
501 display the main navigation controls at the top of each page along
503 ****************************************************************************/
504 static void show_main_buttons(void)
508 if ((p
= cgi_user_name()) && strcmp(p
, "root")) {
509 d_printf(_("Logged in as <b>%s</b>"), p
);
513 image_link(_("Home"), "", "images/home.gif");
514 if (have_write_access
) {
515 image_link(_("Globals"), "globals", "images/globals.gif");
516 image_link(_("Shares"), "shares", "images/shares.gif");
517 image_link(_("Printers"), "printers", "images/printers.gif");
518 image_link(_("Wizard"), "wizard", "images/wizard.gif");
520 if (have_read_access
) {
521 image_link(_("Status"), "status", "images/status.gif");
522 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
524 image_link(_("Password Management"), "passwd", "images/passwd.gif");
529 /****************************************************************************
530 * Handle Display/Edit Mode CGI
531 ****************************************************************************/
532 static void ViewModeBoxes(int mode
)
534 d_printf("<p>%s: \n", _("Current View Is"));
535 d_printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode
== 0) ? "checked" : ""), _("Basic"));
536 d_printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode
== 1) ? "checked" : ""), _("Advanced"));
537 d_printf("<br>%s: \n", _("Change View To"));
538 d_printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
539 d_printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
540 d_printf("</p><br>\n");
543 /****************************************************************************
544 display a welcome page
545 ****************************************************************************/
546 static void welcome_page(void)
548 include_html("help/welcome.html");
551 /****************************************************************************
552 display the current smb.conf
553 ****************************************************************************/
554 static void viewconfig_page(void)
558 if (cgi_variable("full_view")) {
562 d_printf("<H2>%s</H2>\n", _("Current Config"));
563 d_printf("<form method=post>\n");
566 d_printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
568 d_printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
571 d_printf("<p><pre>");
572 write_config(stdout
, full_view
);
574 d_printf("</form>\n");
577 /****************************************************************************
578 second screen of the wizard ... Fetch Configuration Parameters
579 ****************************************************************************/
580 static void wizard_params_page(void)
582 unsigned int parm_filter
= FLAG_WIZARD
;
584 /* Here we first set and commit all the parameters that were selected
585 in the previous screen. */
587 d_printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
589 if (cgi_variable("Commit")) {
590 commit_parameters(GLOBAL_SECTION_SNUM
);
594 d_printf("<form name=\"swatform\" method=post action=wizard_params>\n");
596 if (have_write_access
) {
597 d_printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
600 d_printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
603 d_printf("<table>\n");
604 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
605 d_printf("</table>\n");
606 d_printf("</form>\n");
609 /****************************************************************************
610 Utility to just rewrite the smb.conf file - effectively just cleans it up
611 ****************************************************************************/
612 static void rewritecfg_file(void)
614 commit_parameters(GLOBAL_SECTION_SNUM
);
616 d_printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
619 /****************************************************************************
620 wizard to create/modify the smb.conf file
621 ****************************************************************************/
622 static void wizard_page(void)
624 /* Set some variables to collect data from smb.conf */
631 if (cgi_variable("Rewrite")) {
632 (void) rewritecfg_file();
636 if (cgi_variable("GetWizardParams")){
637 (void) wizard_params_page();
641 if (cgi_variable("Commit")){
642 SerType
= atoi(cgi_variable("ServerType"));
643 winstype
= atoi(cgi_variable("WINSType"));
644 have_home
= lp_servicenumber(HOMES_NAME
);
645 HomeExpo
= atoi(cgi_variable("HomeExpo"));
647 /* Plain text passwords are too badly broken - use encrypted passwords only */
648 lp_do_parameter( GLOBAL_SECTION_SNUM
, "encrypt passwords", "Yes");
652 /* Stand-alone Server */
653 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
654 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
658 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "DOMAIN" );
659 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
662 /* Domain Controller */
663 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
664 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "Yes" );
667 switch ( winstype
) {
669 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
670 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
673 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "Yes" );
674 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
677 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
678 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", cgi_variable("WINSAddr"));
682 /* Have to create Homes share? */
683 if ((HomeExpo
== 1) && (have_home
== -1)) {
686 pstrcpy(unix_share
,HOMES_NAME
);
688 lp_copy_service(GLOBAL_SECTION_SNUM
, unix_share
);
689 iNumNonAutoPrintServices
= lp_numservices();
690 have_home
= lp_servicenumber(HOMES_NAME
);
691 lp_do_parameter( have_home
, "read only", "No");
692 lp_do_parameter( have_home
, "valid users", "%S");
693 lp_do_parameter( have_home
, "browseable", "No");
694 commit_parameters(have_home
);
697 /* Need to Delete Homes share? */
698 if ((HomeExpo
== 0) && (have_home
!= -1)) {
699 lp_remove_service(have_home
);
703 commit_parameters(GLOBAL_SECTION_SNUM
);
708 /* Now determine smb.conf WINS settings */
709 if (lp_wins_support())
711 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
715 /* Do we have a homes share? */
716 have_home
= lp_servicenumber(HOMES_NAME
);
718 if ((winstype
== 2) && lp_wins_support())
721 role
= lp_server_role();
724 d_printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
725 d_printf("<form method=post action=wizard>\n");
727 if (have_write_access
) {
728 d_printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
729 d_printf("%s", _("The same will happen if you press the commit button."));
730 d_printf("<br><br>\n");
731 d_printf("<center>");
732 d_printf("<input type=submit name=\"Rewrite\" value=\"%s\"> ",_("Rewrite smb.conf file"));
733 d_printf("<input type=submit name=\"Commit\" value=\"%s\"> ",_("Commit"));
734 d_printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
735 d_printf("</center>\n");
739 d_printf("<center><table border=0>");
740 d_printf("<tr><td><b>%s: </b></td>\n", _("Server Type"));
741 d_printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s </td>", ((role
== ROLE_STANDALONE
) ? "checked" : ""), _("Stand Alone"));
742 d_printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s </td>", ((role
== ROLE_DOMAIN_MEMBER
) ? "checked" : ""), _("Domain Member"));
743 d_printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s </td>", ((role
== ROLE_DOMAIN_PDC
) ? "checked" : ""), _("Domain Controller"));
745 if (role
== ROLE_DOMAIN_BDC
) {
746 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
748 d_printf("<tr><td><b>%s: </b></td>\n", _("Configure WINS As"));
749 d_printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s </td>", ((winstype
== 0) ? "checked" : ""), _("Not Used"));
750 d_printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s </td>", ((winstype
== 1) ? "checked" : ""), _("Server for client use"));
751 d_printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s </td>", ((winstype
== 2) ? "checked" : ""), _("Client of another WINS server"));
753 d_printf("<tr><td></td><td></td><td></td><td>%s <input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
755 /* Print out the list of wins servers */
756 if(lp_wins_server_list()) {
758 const char **wins_servers
= lp_wins_server_list();
759 for(i
= 0; wins_servers
[i
]; i
++) d_printf("%s ", wins_servers
[i
]);
762 d_printf("\"></td></tr>\n");
764 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Error: WINS Server Mode and WINS Support both set in smb.conf"));
765 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
767 d_printf("<tr><td><b>%s: </b></td>\n", _("Expose Home Directories"));
768 d_printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home
== -1) ? "" : "checked ");
769 d_printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home
== -1 ) ? "checked" : "");
770 d_printf("<td></td></tr>\n");
772 /* Enable this when we are ready ....
773 * d_printf("<tr><td><b>%s: </b></td>\n", _("Is Print Server"));
774 * d_printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
775 * d_printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
776 * d_printf("<td></td></tr>\n");
779 d_printf("</table></center>");
782 d_printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
783 d_printf("</form>\n");
787 /****************************************************************************
788 display a globals editing page
789 ****************************************************************************/
790 static void globals_page(void)
792 unsigned int parm_filter
= FLAG_BASIC
;
795 d_printf("<H2>%s</H2>\n", _("Global Parameters"));
797 if (cgi_variable("Commit")) {
798 commit_parameters(GLOBAL_SECTION_SNUM
);
802 if ( cgi_variable("ViewMode") )
803 mode
= atoi(cgi_variable("ViewMode"));
804 if ( cgi_variable("BasicMode"))
806 if ( cgi_variable("AdvMode"))
809 d_printf("<form name=\"swatform\" method=post action=globals>\n");
811 ViewModeBoxes( mode
);
814 parm_filter
= FLAG_BASIC
;
817 parm_filter
= FLAG_ADVANCED
;
821 if (have_write_access
) {
822 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
823 _("Commit Changes"));
826 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
830 d_printf("<table>\n");
831 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
832 d_printf("</table>\n");
833 d_printf("</form>\n");
836 /****************************************************************************
837 display a shares editing page. share is in unix codepage, and must be in
838 dos codepage. FIXME !!! JRA.
839 ****************************************************************************/
840 static void shares_page(void)
842 const char *share
= cgi_variable("share");
847 unsigned int parm_filter
= FLAG_BASIC
;
850 snum
= lp_servicenumber(share
);
852 d_printf("<H2>%s</H2>\n", _("Share Parameters"));
854 if (cgi_variable("Commit") && snum
>= 0) {
855 commit_parameters(snum
);
859 if (cgi_variable("Delete") && snum
>= 0) {
860 lp_remove_service(snum
);
866 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
868 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
869 iNumNonAutoPrintServices
= lp_numservices();
871 snum
= lp_servicenumber(share
);
874 d_printf("<FORM name=\"swatform\" method=post>\n");
876 d_printf("<table>\n");
878 if ( cgi_variable("ViewMode") )
879 mode
= atoi(cgi_variable("ViewMode"));
880 if ( cgi_variable("BasicMode"))
882 if ( cgi_variable("AdvMode"))
885 ViewModeBoxes( mode
);
888 parm_filter
= FLAG_BASIC
;
891 parm_filter
= FLAG_ADVANCED
;
894 d_printf("<br><tr>\n");
895 d_printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
896 d_printf("<td><select name=share>\n");
898 d_printf("<option value=\" \"> \n");
899 for (i
=0;i
<lp_numservices();i
++) {
900 s
= lp_servicename(i
);
901 if (s
&& (*s
) && strcmp(s
,"IPC$") && !lp_print_ok(i
)) {
902 d_printf("<option %s value=\"%s\">%s\n",
903 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
907 d_printf("</select></td>\n");
908 if (have_write_access
) {
909 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
912 d_printf("</table>");
914 if (have_write_access
) {
916 d_printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
917 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
919 d_printf("</table>");
923 if (have_write_access
) {
924 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
927 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
932 d_printf("<table>\n");
933 show_parameters(snum
, 1, parm_filter
, 0);
934 d_printf("</table>\n");
937 d_printf("</FORM>\n");
940 /*************************************************************
941 change a password either locally or remotely
942 *************************************************************/
943 static BOOL
change_password(const char *remote_machine
, const char *user_name
,
944 const char *old_passwd
, const char *new_passwd
,
952 d_printf("%s\n<p>", _("password change in demo mode rejected"));
956 if (remote_machine
!= NULL
) {
957 ret
= remote_password_change(remote_machine
, user_name
, old_passwd
,
958 new_passwd
, err_str
, sizeof(err_str
));
960 d_printf("%s\n<p>", err_str
);
964 if(!initialize_password_db(True
)) {
965 d_printf("%s\n<p>", _("Can't setup password database vectors."));
969 ret
= local_password_change(user_name
, local_flags
, new_passwd
, err_str
, sizeof(err_str
),
970 msg_str
, sizeof(msg_str
));
973 d_printf("%s\n<p>", msg_str
);
975 d_printf("%s\n<p>", err_str
);
980 /****************************************************************************
981 do the stuff required to add or change a password
982 ****************************************************************************/
983 static void chg_passwd(void)
989 /* Make sure users name has been specified */
990 if (strlen(cgi_variable(SWAT_USER
)) == 0) {
991 d_printf("<p>%s\n", _(" Must specify \"User Name\" "));
996 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
997 * so if that's what we're doing, skip the rest of the checks
999 if (!cgi_variable(DISABLE_USER_FLAG
) && !cgi_variable(ENABLE_USER_FLAG
) && !cgi_variable(DELETE_USER_FLAG
)) {
1002 * If current user is not root, make sure old password has been specified
1003 * If REMOTE change, even root must provide old password
1005 if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD
)) <= 0)) ||
1006 ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable(OLD_PSWD
)) <= 0))) {
1007 d_printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1011 /* If changing a users password on a remote hosts we have to know what host */
1012 if ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable(RHOST
)) <= 0)) {
1013 d_printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1017 /* Make sure new passwords have been specified */
1018 if ((strlen( cgi_variable(NEW_PSWD
)) <= 0) ||
1019 (strlen( cgi_variable(NEW2_PSWD
)) <= 0)) {
1020 d_printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1024 /* Make sure new passwords was typed correctly twice */
1025 if (strcmp(cgi_variable(NEW_PSWD
), cgi_variable(NEW2_PSWD
)) != 0) {
1026 d_printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1031 if (cgi_variable(CHG_R_PASSWD_FLAG
)) {
1032 host
= cgi_variable(RHOST
);
1033 } else if (am_root()) {
1040 * Set up the local flags.
1043 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_ADD_USER
: 0);
1044 local_flags
|= (cgi_variable(DELETE_USER_FLAG
) ? LOCAL_DELETE_USER
: 0);
1045 local_flags
|= (cgi_variable(ENABLE_USER_FLAG
) ? LOCAL_ENABLE_USER
: 0);
1046 local_flags
|= (cgi_variable(DISABLE_USER_FLAG
) ? LOCAL_DISABLE_USER
: 0);
1048 rslt
= change_password(host
,
1049 cgi_variable(SWAT_USER
),
1050 cgi_variable(OLD_PSWD
), cgi_variable(NEW_PSWD
),
1053 if(local_flags
== 0) {
1056 d_printf(_(" The passwd for '%s' has been changed."), cgi_variable(SWAT_USER
));
1059 d_printf(_(" The passwd for '%s' has NOT been changed."), cgi_variable(SWAT_USER
));
1067 /****************************************************************************
1068 display a password editing page
1069 ****************************************************************************/
1070 static void passwd_page(void)
1072 const char *new_name
= cgi_user_name();
1075 * After the first time through here be nice. If the user
1076 * changed the User box text to another users name, remember it.
1078 if (cgi_variable(SWAT_USER
)) {
1079 new_name
= cgi_variable(SWAT_USER
);
1082 if (!new_name
) new_name
= "";
1084 d_printf("<H2>%s</H2>\n", _("Server Password Management"));
1086 d_printf("<FORM name=\"swatform\" method=post>\n");
1088 d_printf("<table>\n");
1091 * Create all the dialog boxes for data collection
1093 d_printf("<tr><td> %s : </td>\n", _("User Name"));
1094 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER
, new_name
);
1096 d_printf("<tr><td> %s : </td>\n", _("Old Password"));
1097 d_printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD
);
1099 d_printf("<tr><td> %s : </td>\n", _("New Password"));
1100 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1101 d_printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1102 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1103 d_printf("</table>\n");
1106 * Create all the control buttons for requesting action
1108 d_printf("<input type=submit name=%s value=\"%s\">\n",
1109 CHG_S_PASSWD_FLAG
, _("Change Password"));
1110 if (demo_mode
|| am_root()) {
1111 d_printf("<input type=submit name=%s value=\"%s\">\n",
1112 ADD_USER_FLAG
, _("Add New User"));
1113 d_printf("<input type=submit name=%s value=\"%s\">\n",
1114 DELETE_USER_FLAG
, _("Delete User"));
1115 d_printf("<input type=submit name=%s value=\"%s\">\n",
1116 DISABLE_USER_FLAG
, _("Disable User"));
1117 d_printf("<input type=submit name=%s value=\"%s\">\n",
1118 ENABLE_USER_FLAG
, _("Enable User"));
1120 d_printf("<p></FORM>\n");
1123 * Do some work if change, add, disable or enable was
1124 * requested. It could be this is the first time through this
1125 * code, so there isn't anything to do. */
1126 if ((cgi_variable(CHG_S_PASSWD_FLAG
)) || (cgi_variable(ADD_USER_FLAG
)) || (cgi_variable(DELETE_USER_FLAG
)) ||
1127 (cgi_variable(DISABLE_USER_FLAG
)) || (cgi_variable(ENABLE_USER_FLAG
))) {
1131 d_printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1133 d_printf("<FORM name=\"swatform\" method=post>\n");
1135 d_printf("<table>\n");
1138 * Create all the dialog boxes for data collection
1140 d_printf("<tr><td> %s : </td>\n", _("User Name"));
1141 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER
, new_name
);
1142 d_printf("<tr><td> %s : </td>\n", _("Old Password"));
1143 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD
);
1144 d_printf("<tr><td> %s : </td>\n", _("New Password"));
1145 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1146 d_printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1147 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1148 d_printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1149 d_printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST
);
1151 d_printf("</table>");
1154 * Create all the control buttons for requesting action
1156 d_printf("<input type=submit name=%s value=\"%s\">",
1157 CHG_R_PASSWD_FLAG
, _("Change Password"));
1159 d_printf("<p></FORM>\n");
1162 * Do some work if a request has been made to change the
1163 * password somewhere other than the server. It could be this
1164 * is the first time through this code, so there isn't
1165 * anything to do. */
1166 if (cgi_variable(CHG_R_PASSWD_FLAG
)) {
1172 /****************************************************************************
1173 display a printers editing page
1174 ****************************************************************************/
1175 static void printers_page(void)
1177 const char *share
= cgi_variable("share");
1182 unsigned int parm_filter
= FLAG_BASIC
;
1185 snum
= lp_servicenumber(share
);
1187 d_printf("<H2>%s</H2>\n", _("Printer Parameters"));
1189 d_printf("<H3>%s</H3>\n", _("Important Note:"));
1190 d_printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
1191 d_printf(_("are autoloaded printers from "));
1192 d_printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1193 d_printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1195 if (cgi_variable("Commit") && snum
>= 0) {
1196 commit_parameters(snum
);
1197 if (snum
>= iNumNonAutoPrintServices
)
1203 if (cgi_variable("Delete") && snum
>= 0) {
1204 lp_remove_service(snum
);
1210 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
1212 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
1213 iNumNonAutoPrintServices
= lp_numservices();
1214 snum
= lp_servicenumber(share
);
1215 lp_do_parameter(snum
, "print ok", "Yes");
1217 snum
= lp_servicenumber(share
);
1220 d_printf("<FORM name=\"swatform\" method=post>\n");
1222 if ( cgi_variable("ViewMode") )
1223 mode
= atoi(cgi_variable("ViewMode"));
1224 if ( cgi_variable("BasicMode"))
1226 if ( cgi_variable("AdvMode"))
1229 ViewModeBoxes( mode
);
1232 parm_filter
= FLAG_BASIC
;
1235 parm_filter
= FLAG_ADVANCED
;
1238 d_printf("<table>\n");
1239 d_printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1240 d_printf("<td><select name=\"share\">\n");
1241 if (snum
< 0 || !lp_print_ok(snum
))
1242 d_printf("<option value=\" \"> \n");
1243 for (i
=0;i
<lp_numservices();i
++) {
1244 s
= lp_servicename(i
);
1245 if (s
&& (*s
) && strcmp(s
,"IPC$") && lp_print_ok(i
)) {
1246 if (i
>= iNumNonAutoPrintServices
)
1247 d_printf("<option %s value=\"%s\">[*]%s\n",
1248 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1251 d_printf("<option %s value=\"%s\">%s\n",
1252 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1256 d_printf("</select></td>");
1257 if (have_write_access
) {
1258 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1261 d_printf("</table>\n");
1263 if (have_write_access
) {
1264 d_printf("<table>\n");
1265 d_printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1266 d_printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1267 d_printf("</table>");
1272 if (have_write_access
) {
1273 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1275 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1280 d_printf("<table>\n");
1281 show_parameters(snum
, 1, parm_filter
, 1);
1282 d_printf("</table>\n");
1284 d_printf("</FORM>\n");
1289 * main function for SWAT.
1291 int main(int argc
, char *argv
[])
1296 struct poptOption long_options
[] = {
1298 { "disable-authentication", 'a', POPT_ARG_VAL
, &demo_mode
, True
, "Disable authentication (demo mode)" },
1304 umask(S_IWGRP
| S_IWOTH
);
1306 #if defined(HAVE_SET_AUTH_PARAMETERS)
1307 set_auth_parameters(argc
, argv
);
1308 #endif /* HAVE_SET_AUTH_PARAMETERS */
1310 /* just in case it goes wild ... */
1315 /* we don't want any SIGPIPE messages */
1316 BlockSignals(True
,SIGPIPE
);
1318 dbf
= x_fopen("/dev/null", O_WRONLY
, 0);
1319 if (!dbf
) dbf
= x_stderr
;
1321 /* we don't want stderr screwing us up */
1323 open("/dev/null", O_WRONLY
);
1325 pc
= poptGetContext("swat", argc
, (const char **) argv
, long_options
, 0);
1327 /* Parse command line options */
1329 while((opt
= poptGetNextOpt(pc
)) != -1) { }
1331 poptFreeContext(pc
);
1333 setup_logging(argv
[0],False
);
1335 iNumNonAutoPrintServices
= lp_numservices();
1338 cgi_setup(dyn_SWATDIR
, !demo_mode
);
1342 cgi_load_variables();
1344 if (!file_exist(dyn_CONFIGFILE
, NULL
)) {
1345 have_read_access
= True
;
1346 have_write_access
= True
;
1348 /* check if the authenticated user has write access - if not then
1349 don't show write options */
1350 have_write_access
= (access(dyn_CONFIGFILE
,W_OK
) == 0);
1352 /* if the user doesn't have read access to smb.conf then
1353 don't let them view it */
1354 have_read_access
= (access(dyn_CONFIGFILE
,R_OK
) == 0);
1357 show_main_buttons();
1359 page
= cgi_pathinfo();
1361 /* Root gets full functionality */
1362 if (have_read_access
&& strcmp(page
, "globals")==0) {
1364 } else if (have_read_access
&& strcmp(page
,"shares")==0) {
1366 } else if (have_read_access
&& strcmp(page
,"printers")==0) {
1368 } else if (have_read_access
&& strcmp(page
,"status")==0) {
1370 } else if (have_read_access
&& strcmp(page
,"viewconfig")==0) {
1372 } else if (strcmp(page
,"passwd")==0) {
1374 } else if (have_read_access
&& strcmp(page
,"wizard")==0) {
1376 } else if (have_read_access
&& strcmp(page
,"wizard_params")==0) {
1377 wizard_params_page();
1378 } else if (have_read_access
&& strcmp(page
,"rewritecfg")==0) {