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"
55 /****************************************************************************
56 ****************************************************************************/
57 static int enum_index(int value
, const struct enum_list
*enumlist
)
60 for (i
=0;enumlist
[i
].name
;i
++)
61 if (value
== enumlist
[i
].value
) break;
65 static char *fix_backslash(const char *str
)
67 static char newstring
[1024];
71 if (*str
== '\\') {*p
++ = '\\';*p
++ = '\\';}
79 static char *stripspaceupper(const char *str
)
81 static char newstring
[1024];
85 if (*str
!= ' ') *p
++ = toupper(*str
);
92 static char *make_parm_name(const char *label
)
94 static char parmname
[1024];
98 if (*label
== ' ') *p
++ = '_';
106 /****************************************************************************
107 include a lump of html in a page
108 ****************************************************************************/
109 static int include_html(const char *fname
)
115 fd
= web_open(fname
, O_RDONLY
, 0);
118 d_printf(_("ERROR: Can't open %s"), fname
);
123 while ((ret
= read(fd
, buf
, sizeof(buf
))) > 0) {
131 /****************************************************************************
132 start the page with standard stuff
133 ****************************************************************************/
134 static void print_header(void)
136 if (!cgi_waspost()) {
137 d_printf("Expires: 0\r\n");
139 d_printf("Content-type: text/html\r\n\r\n");
141 if (!include_html("include/header.html")) {
142 d_printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
143 d_printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
147 /* *******************************************************************
148 show parameter label with translated name in the following form
149 because showing original and translated label in one line looks
150 too long, and showing translated label only is unusable for
152 -------------------------------
153 HELP security [combo box][button]
155 -------------------------------
156 (capital words are translated by gettext.)
157 if no translation is available, then same form as original is
159 "i18n_translated_parm" class is used to change the color of the
160 translated parameter with CSS.
161 **************************************************************** */
162 static const char* get_parm_translated(
163 const char* pAnchor
, const char* pHelp
, const char* pLabel
)
165 const char* pTranslated
= _(pLabel
);
166 static pstring output
;
167 if(strcmp(pLabel
, pTranslated
) != 0)
170 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
171 pAnchor
, pHelp
, pLabel
, pTranslated
);
175 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
176 pAnchor
, pHelp
, pLabel
);
179 /****************************************************************************
181 ****************************************************************************/
182 static void print_footer(void)
184 if (!include_html("include/footer.html")) {
185 d_printf("\n</BODY>\n</HTML>\n");
189 /****************************************************************************
190 display one editable parameter in a form
191 ****************************************************************************/
192 static void show_parameter(int snum
, struct parm_struct
*parm
)
195 void *ptr
= parm
->ptr
;
197 if (parm
->class == P_LOCAL
&& snum
>= 0) {
198 ptr
= lp_local_ptr(snum
, ptr
);
201 d_printf("<tr><td>%s</td><td>", get_parm_translated(stripspaceupper(parm
->label
), _("Help"), parm
->label
));
202 switch (parm
->type
) {
204 d_printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
205 make_parm_name(parm
->label
), *(char *)ptr
);
206 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
207 _("Set Default"), make_parm_name(parm
->label
),(char)(parm
->def
.cvalue
));
211 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"",
212 make_parm_name(parm
->label
));
213 if ((char ***)ptr
&& *(char ***)ptr
&& **(char ***)ptr
) {
214 char **list
= *(char ***)ptr
;
215 for (;*list
;list
++) {
216 /* enclose in quotes if the string contains a space */
217 if ( strchr_m(*list
, ' ') )
218 d_printf("\'%s\'%s", *list
, ((*(list
+1))?", ":""));
220 d_printf("%s%s", *list
, ((*(list
+1))?", ":""));
224 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
225 _("Set Default"), make_parm_name(parm
->label
));
226 if (parm
->def
.lvalue
) {
227 char **list
= (char **)(parm
->def
.lvalue
);
228 for (; *list
; list
++) {
229 /* enclose in quotes if the string contains a space */
230 if ( strchr_m(*list
, ' ') )
231 d_printf("\'%s\'%s", *list
, ((*(list
+1))?", ":""));
233 d_printf("%s%s", *list
, ((*(list
+1))?", ":""));
241 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
242 make_parm_name(parm
->label
), *(char **)ptr
);
243 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
244 _("Set Default"), make_parm_name(parm
->label
),fix_backslash((char *)(parm
->def
.svalue
)));
249 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
250 make_parm_name(parm
->label
), (char *)ptr
);
251 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
252 _("Set Default"), make_parm_name(parm
->label
),fix_backslash((char *)(parm
->def
.svalue
)));
256 d_printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
257 d_printf("<option %s>Yes", (*(BOOL
*)ptr
)?"selected":"");
258 d_printf("<option %s>No", (*(BOOL
*)ptr
)?"":"selected");
259 d_printf("</select>");
260 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
261 _("Set Default"), make_parm_name(parm
->label
),(BOOL
)(parm
->def
.bvalue
)?0:1);
265 d_printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
266 d_printf("<option %s>Yes", (*(BOOL
*)ptr
)?"":"selected");
267 d_printf("<option %s>No", (*(BOOL
*)ptr
)?"selected":"");
268 d_printf("</select>");
269 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
270 _("Set Default"), make_parm_name(parm
->label
),(BOOL
)(parm
->def
.bvalue
)?1:0);
274 d_printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm
->label
), *(int *)ptr
);
275 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
276 _("Set Default"), make_parm_name(parm
->label
),(int)(parm
->def
.ivalue
));
280 d_printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm
->label
), octal_string(*(int *)ptr
));
281 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
282 _("Set Default"), make_parm_name(parm
->label
),
283 octal_string((int)(parm
->def
.ivalue
)));
287 d_printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
288 for (i
=0;parm
->enum_list
[i
].name
;i
++) {
289 if (i
== 0 || parm
->enum_list
[i
].value
!= parm
->enum_list
[i
-1].value
) {
290 d_printf("<option %s>%s",(*(int *)ptr
)==parm
->enum_list
[i
].value
?"selected":"",parm
->enum_list
[i
].name
);
293 d_printf("</select>");
294 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
295 _("Set Default"), make_parm_name(parm
->label
),enum_index((int)(parm
->def
.ivalue
),parm
->enum_list
));
300 d_printf("</td></tr>\n");
303 /****************************************************************************
304 display a set of parameters for a service
305 ****************************************************************************/
306 static void show_parameters(int snum
, int allparameters
, unsigned int parm_filter
, int printers
)
309 struct parm_struct
*parm
;
310 const char *heading
= NULL
;
311 const char *last_heading
= NULL
;
313 while ((parm
= lp_next_parameter(snum
, &i
, allparameters
))) {
314 if (snum
< 0 && parm
->class == P_LOCAL
&& !(parm
->flags
& FLAG_GLOBAL
))
316 if (parm
->class == P_SEPARATOR
) {
317 heading
= parm
->label
;
320 if (parm
->flags
& FLAG_HIDE
) continue;
322 if (printers
& !(parm
->flags
& FLAG_PRINT
)) continue;
323 if (!printers
& !(parm
->flags
& FLAG_SHARE
)) continue;
326 if (!( parm_filter
& FLAG_ADVANCED
)) {
327 if (!(parm
->flags
& FLAG_BASIC
)) {
328 void *ptr
= parm
->ptr
;
330 if (parm
->class == P_LOCAL
&& snum
>= 0) {
331 ptr
= lp_local_ptr(snum
, ptr
);
334 switch (parm
->type
) {
336 if (*(char *)ptr
== (char)(parm
->def
.cvalue
)) continue;
340 if (!str_list_compare(*(char ***)ptr
, (char **)(parm
->def
.lvalue
))) continue;
345 if (!strcmp(*(char **)ptr
,(char *)(parm
->def
.svalue
))) continue;
350 if (!strcmp((char *)ptr
,(char *)(parm
->def
.svalue
))) continue;
355 if (*(BOOL
*)ptr
== (BOOL
)(parm
->def
.bvalue
)) continue;
360 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
365 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
371 if (printers
&& !(parm
->flags
& FLAG_PRINT
)) continue;
374 if ((parm_filter
& FLAG_WIZARD
) && !(parm
->flags
& FLAG_WIZARD
)) continue;
376 if ((parm_filter
& FLAG_ADVANCED
) && !(parm
->flags
& FLAG_ADVANCED
)) continue;
378 if (heading
&& heading
!= last_heading
) {
379 d_printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading
));
380 last_heading
= heading
;
382 show_parameter(snum
, parm
);
386 /****************************************************************************
387 load the smb.conf file into loadparm.
388 ****************************************************************************/
389 static BOOL
load_config(BOOL save_def
)
391 lp_resetnumservices();
392 return lp_load(dyn_CONFIGFILE
,False
,save_def
,False
);
395 /****************************************************************************
397 ****************************************************************************/
398 static void write_config(FILE *f
, BOOL show_defaults
)
400 fprintf(f
, "# Samba config file created using SWAT\n");
401 fprintf(f
, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
402 fprintf(f
, "# Date: %s\n\n", timestring(False
));
404 lp_dump(f
, show_defaults
, iNumNonAutoPrintServices
);
407 /****************************************************************************
408 save and reload the smb.conf config file
409 ****************************************************************************/
410 static int save_reload(int snum
)
415 f
= sys_fopen(dyn_CONFIGFILE
,"w");
417 d_printf(_("failed to open %s for writing"), dyn_CONFIGFILE
);
422 /* just in case they have used the buggy xinetd to create the file */
423 if (fstat(fileno(f
), &st
) == 0 &&
424 (st
.st_mode
& S_IWOTH
)) {
425 #if defined HAVE_FCHMOD
426 fchmod(fileno(f
), S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
428 chmod(dyn_CONFIGFILE
, S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
432 write_config(f
, False
);
434 lp_dump_one(f
, False
, snum
);
439 if (!load_config(False
)) {
440 d_printf(_("Can't reload %s"), dyn_CONFIGFILE
);
444 iNumNonAutoPrintServices
= lp_numservices();
450 /****************************************************************************
452 ****************************************************************************/
453 static void commit_parameter(int snum
, struct parm_struct
*parm
, const char *v
)
458 if (snum
< 0 && parm
->class == P_LOCAL
) {
459 /* this handles the case where we are changing a local
460 variable globally. We need to change the parameter in
461 all shares where it is currently set to the default */
462 for (i
=0;i
<lp_numservices();i
++) {
463 s
= lp_servicename(i
);
464 if (s
&& (*s
) && lp_is_default(i
, parm
)) {
465 lp_do_parameter(i
, parm
->label
, v
);
470 lp_do_parameter(snum
, parm
->label
, v
);
473 /****************************************************************************
474 commit a set of parameters for a service
475 ****************************************************************************/
476 static void commit_parameters(int snum
)
479 struct parm_struct
*parm
;
483 while ((parm
= lp_next_parameter(snum
, &i
, 1))) {
484 slprintf(label
, sizeof(label
)-1, "parm_%s", make_parm_name(parm
->label
));
485 if ((v
= cgi_variable(label
))) {
486 if (parm
->flags
& FLAG_HIDE
) continue;
487 commit_parameter(snum
, parm
, v
);
492 /****************************************************************************
493 spit out the html for a link with an image
494 ****************************************************************************/
495 static void image_link(const char *name
, const char *hlink
, const char *src
)
497 d_printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
498 cgi_baseurl(), hlink
, src
, name
);
501 /****************************************************************************
502 display the main navigation controls at the top of each page along
504 ****************************************************************************/
505 static void show_main_buttons(void)
509 if ((p
= cgi_user_name()) && strcmp(p
, "root")) {
510 d_printf(_("Logged in as <b>%s</b>"), p
);
514 image_link(_("Home"), "", "images/home.gif");
515 if (have_write_access
) {
516 image_link(_("Globals"), "globals", "images/globals.gif");
517 image_link(_("Shares"), "shares", "images/shares.gif");
518 image_link(_("Printers"), "printers", "images/printers.gif");
519 image_link(_("Wizard"), "wizard", "images/wizard.gif");
521 if (have_read_access
) {
522 image_link(_("Status"), "status", "images/status.gif");
523 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
525 image_link(_("Password Management"), "passwd", "images/passwd.gif");
530 /****************************************************************************
531 * Handle Display/Edit Mode CGI
532 ****************************************************************************/
533 static void ViewModeBoxes(int mode
)
535 d_printf("<p>%s: \n", _("Current View Is"));
536 d_printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode
== 0) ? "checked" : ""), _("Basic"));
537 d_printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode
== 1) ? "checked" : ""), _("Advanced"));
538 d_printf("<br>%s: \n", _("Change View To"));
539 d_printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
540 d_printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
541 d_printf("</p><br>\n");
544 /****************************************************************************
545 display a welcome page
546 ****************************************************************************/
547 static void welcome_page(void)
549 include_html("help/welcome.html");
552 /****************************************************************************
553 display the current smb.conf
554 ****************************************************************************/
555 static void viewconfig_page(void)
559 if (cgi_variable("full_view")) {
563 d_printf("<H2>%s</H2>\n", _("Current Config"));
564 d_printf("<form method=post>\n");
567 d_printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
569 d_printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
572 d_printf("<p><pre>");
573 write_config(stdout
, full_view
);
575 d_printf("</form>\n");
578 /****************************************************************************
579 second screen of the wizard ... Fetch Configuration Parameters
580 ****************************************************************************/
581 static void wizard_params_page(void)
583 unsigned int parm_filter
= FLAG_WIZARD
;
585 /* Here we first set and commit all the parameters that were selected
586 in the previous screen. */
588 d_printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
590 if (cgi_variable("Commit")) {
591 commit_parameters(GLOBAL_SECTION_SNUM
);
595 d_printf("<form name=\"swatform\" method=post action=wizard_params>\n");
597 if (have_write_access
) {
598 d_printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
601 d_printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
604 d_printf("<table>\n");
605 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
606 d_printf("</table>\n");
607 d_printf("</form>\n");
610 /****************************************************************************
611 Utility to just rewrite the smb.conf file - effectively just cleans it up
612 ****************************************************************************/
613 static void rewritecfg_file(void)
615 commit_parameters(GLOBAL_SECTION_SNUM
);
617 d_printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
620 /****************************************************************************
621 wizard to create/modify the smb.conf file
622 ****************************************************************************/
623 static void wizard_page(void)
625 /* Set some variables to collect data from smb.conf */
632 if (cgi_variable("Rewrite")) {
633 (void) rewritecfg_file();
637 if (cgi_variable("GetWizardParams")){
638 (void) wizard_params_page();
642 if (cgi_variable("Commit")){
643 SerType
= atoi(cgi_variable("ServerType"));
644 winstype
= atoi(cgi_variable("WINSType"));
645 have_home
= lp_servicenumber(HOMES_NAME
);
646 HomeExpo
= atoi(cgi_variable("HomeExpo"));
648 /* Plain text passwords are too badly broken - use encrypted passwords only */
649 lp_do_parameter( GLOBAL_SECTION_SNUM
, "encrypt passwords", "Yes");
653 /* Stand-alone Server */
654 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
655 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
659 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "DOMAIN" );
660 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
663 /* Domain Controller */
664 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
665 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "Yes" );
668 switch ( winstype
) {
670 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
671 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
674 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "Yes" );
675 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
678 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
679 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", cgi_variable("WINSAddr"));
683 /* Have to create Homes share? */
684 if ((HomeExpo
== 1) && (have_home
== -1)) {
687 pstrcpy(unix_share
,HOMES_NAME
);
689 lp_copy_service(GLOBAL_SECTION_SNUM
, unix_share
);
690 iNumNonAutoPrintServices
= lp_numservices();
691 have_home
= lp_servicenumber(HOMES_NAME
);
692 lp_do_parameter( have_home
, "read only", "No");
693 lp_do_parameter( have_home
, "valid users", "%S");
694 lp_do_parameter( have_home
, "browseable", "No");
695 commit_parameters(have_home
);
698 /* Need to Delete Homes share? */
699 if ((HomeExpo
== 0) && (have_home
!= -1)) {
700 lp_remove_service(have_home
);
704 commit_parameters(GLOBAL_SECTION_SNUM
);
709 /* Now determine smb.conf WINS settings */
710 if (lp_wins_support())
712 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
716 /* Do we have a homes share? */
717 have_home
= lp_servicenumber(HOMES_NAME
);
719 if ((winstype
== 2) && lp_wins_support())
722 role
= lp_server_role();
725 d_printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
726 d_printf("<form method=post action=wizard>\n");
728 if (have_write_access
) {
729 d_printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
730 d_printf("%s", _("The same will happen if you press the commit button."));
731 d_printf("<br><br>\n");
732 d_printf("<center>");
733 d_printf("<input type=submit name=\"Rewrite\" value=\"%s\"> ",_("Rewrite smb.conf file"));
734 d_printf("<input type=submit name=\"Commit\" value=\"%s\"> ",_("Commit"));
735 d_printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
736 d_printf("</center>\n");
740 d_printf("<center><table border=0>");
741 d_printf("<tr><td><b>%s: </b></td>\n", _("Server Type"));
742 d_printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s </td>", ((role
== ROLE_STANDALONE
) ? "checked" : ""), _("Stand Alone"));
743 d_printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s </td>", ((role
== ROLE_DOMAIN_MEMBER
) ? "checked" : ""), _("Domain Member"));
744 d_printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s </td>", ((role
== ROLE_DOMAIN_PDC
) ? "checked" : ""), _("Domain Controller"));
746 if (role
== ROLE_DOMAIN_BDC
) {
747 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"));
749 d_printf("<tr><td><b>%s: </b></td>\n", _("Configure WINS As"));
750 d_printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s </td>", ((winstype
== 0) ? "checked" : ""), _("Not Used"));
751 d_printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s </td>", ((winstype
== 1) ? "checked" : ""), _("Server for client use"));
752 d_printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s </td>", ((winstype
== 2) ? "checked" : ""), _("Client of another WINS server"));
754 d_printf("<tr><td></td><td></td><td></td><td>%s <input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
756 /* Print out the list of wins servers */
757 if(lp_wins_server_list()) {
759 const char **wins_servers
= lp_wins_server_list();
760 for(i
= 0; wins_servers
[i
]; i
++) d_printf("%s ", wins_servers
[i
]);
763 d_printf("\"></td></tr>\n");
765 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"));
766 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
768 d_printf("<tr><td><b>%s: </b></td>\n", _("Expose Home Directories"));
769 d_printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home
== -1) ? "" : "checked ");
770 d_printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home
== -1 ) ? "checked" : "");
771 d_printf("<td></td></tr>\n");
773 /* Enable this when we are ready ....
774 * d_printf("<tr><td><b>%s: </b></td>\n", _("Is Print Server"));
775 * d_printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
776 * d_printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
777 * d_printf("<td></td></tr>\n");
780 d_printf("</table></center>");
783 d_printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
784 d_printf("</form>\n");
788 /****************************************************************************
789 display a globals editing page
790 ****************************************************************************/
791 static void globals_page(void)
793 unsigned int parm_filter
= FLAG_BASIC
;
796 d_printf("<H2>%s</H2>\n", _("Global Parameters"));
798 if (cgi_variable("Commit")) {
799 commit_parameters(GLOBAL_SECTION_SNUM
);
803 if ( cgi_variable("ViewMode") )
804 mode
= atoi(cgi_variable("ViewMode"));
805 if ( cgi_variable("BasicMode"))
807 if ( cgi_variable("AdvMode"))
810 d_printf("<form name=\"swatform\" method=post action=globals>\n");
812 ViewModeBoxes( mode
);
815 parm_filter
= FLAG_BASIC
;
818 parm_filter
= FLAG_ADVANCED
;
822 if (have_write_access
) {
823 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
824 _("Commit Changes"));
827 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
831 d_printf("<table>\n");
832 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
833 d_printf("</table>\n");
834 d_printf("</form>\n");
837 /****************************************************************************
838 display a shares editing page. share is in unix codepage, and must be in
839 dos codepage. FIXME !!! JRA.
840 ****************************************************************************/
841 static void shares_page(void)
843 const char *share
= cgi_variable("share");
848 unsigned int parm_filter
= FLAG_BASIC
;
851 snum
= lp_servicenumber(share
);
853 d_printf("<H2>%s</H2>\n", _("Share Parameters"));
855 if (cgi_variable("Commit") && snum
>= 0) {
856 commit_parameters(snum
);
860 if (cgi_variable("Delete") && snum
>= 0) {
861 lp_remove_service(snum
);
867 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
869 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
870 iNumNonAutoPrintServices
= lp_numservices();
872 snum
= lp_servicenumber(share
);
875 d_printf("<FORM name=\"swatform\" method=post>\n");
877 d_printf("<table>\n");
879 if ( cgi_variable("ViewMode") )
880 mode
= atoi(cgi_variable("ViewMode"));
881 if ( cgi_variable("BasicMode"))
883 if ( cgi_variable("AdvMode"))
886 ViewModeBoxes( mode
);
889 parm_filter
= FLAG_BASIC
;
892 parm_filter
= FLAG_ADVANCED
;
895 d_printf("<br><tr>\n");
896 d_printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
897 d_printf("<td><select name=share>\n");
899 d_printf("<option value=\" \"> \n");
900 for (i
=0;i
<lp_numservices();i
++) {
901 s
= lp_servicename(i
);
902 if (s
&& (*s
) && strcmp(s
,"IPC$") && !lp_print_ok(i
)) {
903 d_printf("<option %s value=\"%s\">%s\n",
904 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
908 d_printf("</select></td>\n");
909 if (have_write_access
) {
910 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
913 d_printf("</table>");
915 if (have_write_access
) {
917 d_printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
918 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
920 d_printf("</table>");
924 if (have_write_access
) {
925 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
928 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
933 d_printf("<table>\n");
934 show_parameters(snum
, 1, parm_filter
, 0);
935 d_printf("</table>\n");
938 d_printf("</FORM>\n");
941 /*************************************************************
942 change a password either locally or remotely
943 *************************************************************/
944 static BOOL
change_password(const char *remote_machine
, const char *user_name
,
945 const char *old_passwd
, const char *new_passwd
,
953 d_printf("%s\n<p>", _("password change in demo mode rejected"));
957 if (remote_machine
!= NULL
) {
958 ret
= remote_password_change(remote_machine
, user_name
, old_passwd
,
959 new_passwd
, err_str
, sizeof(err_str
));
961 d_printf("%s\n<p>", err_str
);
965 if(!initialize_password_db(True
)) {
966 d_printf("%s\n<p>", _("Can't setup password database vectors."));
970 ret
= local_password_change(user_name
, local_flags
, new_passwd
, err_str
, sizeof(err_str
),
971 msg_str
, sizeof(msg_str
));
974 d_printf("%s\n<p>", msg_str
);
976 d_printf("%s\n<p>", err_str
);
981 /****************************************************************************
982 do the stuff required to add or change a password
983 ****************************************************************************/
984 static void chg_passwd(void)
990 /* Make sure users name has been specified */
991 if (strlen(cgi_variable(SWAT_USER
)) == 0) {
992 d_printf("<p>%s\n", _(" Must specify \"User Name\" "));
997 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
998 * so if that's what we're doing, skip the rest of the checks
1000 if (!cgi_variable(DISABLE_USER_FLAG
) && !cgi_variable(ENABLE_USER_FLAG
) && !cgi_variable(DELETE_USER_FLAG
)) {
1003 * If current user is not root, make sure old password has been specified
1004 * If REMOTE change, even root must provide old password
1006 if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD
)) <= 0)) ||
1007 ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable(OLD_PSWD
)) <= 0))) {
1008 d_printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1012 /* If changing a users password on a remote hosts we have to know what host */
1013 if ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable(RHOST
)) <= 0)) {
1014 d_printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1018 /* Make sure new passwords have been specified */
1019 if ((strlen( cgi_variable(NEW_PSWD
)) <= 0) ||
1020 (strlen( cgi_variable(NEW2_PSWD
)) <= 0)) {
1021 d_printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1025 /* Make sure new passwords was typed correctly twice */
1026 if (strcmp(cgi_variable(NEW_PSWD
), cgi_variable(NEW2_PSWD
)) != 0) {
1027 d_printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1032 if (cgi_variable(CHG_R_PASSWD_FLAG
)) {
1033 host
= cgi_variable(RHOST
);
1034 } else if (am_root()) {
1041 * Set up the local flags.
1044 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_ADD_USER
: 0);
1045 local_flags
|= (cgi_variable(DELETE_USER_FLAG
) ? LOCAL_DELETE_USER
: 0);
1046 local_flags
|= (cgi_variable(ENABLE_USER_FLAG
) ? LOCAL_ENABLE_USER
: 0);
1047 local_flags
|= (cgi_variable(DISABLE_USER_FLAG
) ? LOCAL_DISABLE_USER
: 0);
1049 rslt
= change_password(host
,
1050 cgi_variable(SWAT_USER
),
1051 cgi_variable(OLD_PSWD
), cgi_variable(NEW_PSWD
),
1054 if(local_flags
== 0) {
1057 d_printf(_(" The passwd for '%s' has been changed."), cgi_variable(SWAT_USER
));
1060 d_printf(_(" The passwd for '%s' has NOT been changed."), cgi_variable(SWAT_USER
));
1068 /****************************************************************************
1069 display a password editing page
1070 ****************************************************************************/
1071 static void passwd_page(void)
1073 const char *new_name
= cgi_user_name();
1076 * After the first time through here be nice. If the user
1077 * changed the User box text to another users name, remember it.
1079 if (cgi_variable(SWAT_USER
)) {
1080 new_name
= cgi_variable(SWAT_USER
);
1083 if (!new_name
) new_name
= "";
1085 d_printf("<H2>%s</H2>\n", _("Server Password Management"));
1087 d_printf("<FORM name=\"swatform\" method=post>\n");
1089 d_printf("<table>\n");
1092 * Create all the dialog boxes for data collection
1094 d_printf("<tr><td> %s : </td>\n", _("User Name"));
1095 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER
, new_name
);
1097 d_printf("<tr><td> %s : </td>\n", _("Old Password"));
1098 d_printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD
);
1100 d_printf("<tr><td> %s : </td>\n", _("New Password"));
1101 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1102 d_printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1103 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1104 d_printf("</table>\n");
1107 * Create all the control buttons for requesting action
1109 d_printf("<input type=submit name=%s value=\"%s\">\n",
1110 CHG_S_PASSWD_FLAG
, _("Change Password"));
1111 if (demo_mode
|| am_root()) {
1112 d_printf("<input type=submit name=%s value=\"%s\">\n",
1113 ADD_USER_FLAG
, _("Add New User"));
1114 d_printf("<input type=submit name=%s value=\"%s\">\n",
1115 DELETE_USER_FLAG
, _("Delete User"));
1116 d_printf("<input type=submit name=%s value=\"%s\">\n",
1117 DISABLE_USER_FLAG
, _("Disable User"));
1118 d_printf("<input type=submit name=%s value=\"%s\">\n",
1119 ENABLE_USER_FLAG
, _("Enable User"));
1121 d_printf("<p></FORM>\n");
1124 * Do some work if change, add, disable or enable was
1125 * requested. It could be this is the first time through this
1126 * code, so there isn't anything to do. */
1127 if ((cgi_variable(CHG_S_PASSWD_FLAG
)) || (cgi_variable(ADD_USER_FLAG
)) || (cgi_variable(DELETE_USER_FLAG
)) ||
1128 (cgi_variable(DISABLE_USER_FLAG
)) || (cgi_variable(ENABLE_USER_FLAG
))) {
1132 d_printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1134 d_printf("<FORM name=\"swatform\" method=post>\n");
1136 d_printf("<table>\n");
1139 * Create all the dialog boxes for data collection
1141 d_printf("<tr><td> %s : </td>\n", _("User Name"));
1142 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER
, new_name
);
1143 d_printf("<tr><td> %s : </td>\n", _("Old Password"));
1144 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD
);
1145 d_printf("<tr><td> %s : </td>\n", _("New Password"));
1146 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1147 d_printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1148 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1149 d_printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1150 d_printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST
);
1152 d_printf("</table>");
1155 * Create all the control buttons for requesting action
1157 d_printf("<input type=submit name=%s value=\"%s\">",
1158 CHG_R_PASSWD_FLAG
, _("Change Password"));
1160 d_printf("<p></FORM>\n");
1163 * Do some work if a request has been made to change the
1164 * password somewhere other than the server. It could be this
1165 * is the first time through this code, so there isn't
1166 * anything to do. */
1167 if (cgi_variable(CHG_R_PASSWD_FLAG
)) {
1173 /****************************************************************************
1174 display a printers editing page
1175 ****************************************************************************/
1176 static void printers_page(void)
1178 const char *share
= cgi_variable("share");
1183 unsigned int parm_filter
= FLAG_BASIC
;
1186 snum
= lp_servicenumber(share
);
1188 d_printf("<H2>%s</H2>\n", _("Printer Parameters"));
1190 d_printf("<H3>%s</H3>\n", _("Important Note:"));
1191 d_printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
1192 d_printf(_("are autoloaded printers from "));
1193 d_printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1194 d_printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1196 if (cgi_variable("Commit") && snum
>= 0) {
1197 commit_parameters(snum
);
1198 if (snum
>= iNumNonAutoPrintServices
)
1204 if (cgi_variable("Delete") && snum
>= 0) {
1205 lp_remove_service(snum
);
1211 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
1213 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
1214 iNumNonAutoPrintServices
= lp_numservices();
1215 snum
= lp_servicenumber(share
);
1216 lp_do_parameter(snum
, "print ok", "Yes");
1218 snum
= lp_servicenumber(share
);
1221 d_printf("<FORM name=\"swatform\" method=post>\n");
1223 if ( cgi_variable("ViewMode") )
1224 mode
= atoi(cgi_variable("ViewMode"));
1225 if ( cgi_variable("BasicMode"))
1227 if ( cgi_variable("AdvMode"))
1230 ViewModeBoxes( mode
);
1233 parm_filter
= FLAG_BASIC
;
1236 parm_filter
= FLAG_ADVANCED
;
1239 d_printf("<table>\n");
1240 d_printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1241 d_printf("<td><select name=\"share\">\n");
1242 if (snum
< 0 || !lp_print_ok(snum
))
1243 d_printf("<option value=\" \"> \n");
1244 for (i
=0;i
<lp_numservices();i
++) {
1245 s
= lp_servicename(i
);
1246 if (s
&& (*s
) && strcmp(s
,"IPC$") && lp_print_ok(i
)) {
1247 if (i
>= iNumNonAutoPrintServices
)
1248 d_printf("<option %s value=\"%s\">[*]%s\n",
1249 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1252 d_printf("<option %s value=\"%s\">%s\n",
1253 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1257 d_printf("</select></td>");
1258 if (have_write_access
) {
1259 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1262 d_printf("</table>\n");
1264 if (have_write_access
) {
1265 d_printf("<table>\n");
1266 d_printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1267 d_printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1268 d_printf("</table>");
1273 if (have_write_access
) {
1274 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1276 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1281 d_printf("<table>\n");
1282 show_parameters(snum
, 1, parm_filter
, 1);
1283 d_printf("</table>\n");
1285 d_printf("</FORM>\n");
1290 * main function for SWAT.
1292 int main(int argc
, char *argv
[])
1297 struct poptOption long_options
[] = {
1299 { "disable-authentication", 'a', POPT_ARG_VAL
, &demo_mode
, True
, "Disable authentication (demo mode)" },
1305 umask(S_IWGRP
| S_IWOTH
);
1307 #if defined(HAVE_SET_AUTH_PARAMETERS)
1308 set_auth_parameters(argc
, argv
);
1309 #endif /* HAVE_SET_AUTH_PARAMETERS */
1311 /* just in case it goes wild ... */
1316 /* we don't want any SIGPIPE messages */
1317 BlockSignals(True
,SIGPIPE
);
1319 dbf
= x_fopen("/dev/null", O_WRONLY
, 0);
1320 if (!dbf
) dbf
= x_stderr
;
1322 /* we don't want stderr screwing us up */
1324 open("/dev/null", O_WRONLY
);
1326 pc
= poptGetContext("swat", argc
, (const char **) argv
, long_options
, 0);
1328 /* Parse command line options */
1330 while((opt
= poptGetNextOpt(pc
)) != -1) { }
1332 poptFreeContext(pc
);
1334 setup_logging(argv
[0],False
);
1336 iNumNonAutoPrintServices
= lp_numservices();
1339 cgi_setup(dyn_SWATDIR
, !demo_mode
);
1343 cgi_load_variables();
1345 if (!file_exist(dyn_CONFIGFILE
, NULL
)) {
1346 have_read_access
= True
;
1347 have_write_access
= True
;
1349 /* check if the authenticated user has write access - if not then
1350 don't show write options */
1351 have_write_access
= (access(dyn_CONFIGFILE
,W_OK
) == 0);
1353 /* if the user doesn't have read access to smb.conf then
1354 don't let them view it */
1355 have_read_access
= (access(dyn_CONFIGFILE
,R_OK
) == 0);
1358 show_main_buttons();
1360 page
= cgi_pathinfo();
1362 /* Root gets full functionality */
1363 if (have_read_access
&& strcmp(page
, "globals")==0) {
1365 } else if (have_read_access
&& strcmp(page
,"shares")==0) {
1367 } else if (have_read_access
&& strcmp(page
,"printers")==0) {
1369 } else if (have_read_access
&& strcmp(page
,"status")==0) {
1371 } else if (have_read_access
&& strcmp(page
,"viewconfig")==0) {
1373 } else if (strcmp(page
,"passwd")==0) {
1375 } else if (have_read_access
&& strcmp(page
,"wizard")==0) {
1377 } else if (have_read_access
&& strcmp(page
,"wizard_params")==0) {
1378 wizard_params_page();
1379 } else if (have_read_access
&& strcmp(page
,"rewritecfg")==0) {