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\n", fname
);
121 while ((ret
= read(fd
, buf
, sizeof(buf
))) > 0) {
129 /****************************************************************************
130 start the page with standard stuff
131 ****************************************************************************/
132 static void print_header(void)
134 if (!cgi_waspost()) {
135 d_printf("Expires: 0\r\n");
137 d_printf("Content-type: text/html\r\n\r\n");
139 if (!include_html("include/header.html")) {
140 d_printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
141 d_printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
145 /* *******************************************************************
146 show parameter label with translated name in the following form
147 because showing original and translated label in one line looks
148 too long, and showing translated label only is unusable for
150 -------------------------------
151 HELP security [combo box][button]
153 -------------------------------
154 (capital words are translated by gettext.)
155 if no translation is available, then same form as original is
157 "i18n_translated_parm" class is used to change the color of the
158 translated parameter with CSS.
159 **************************************************************** */
160 static const char* get_parm_translated(
161 const char* pAnchor
, const char* pHelp
, const char* pLabel
)
163 const char* pTranslated
= _(pLabel
);
164 static pstring output
;
165 if(strcmp(pLabel
, pTranslated
) != 0)
168 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
169 pAnchor
, pHelp
, pLabel
, pTranslated
);
173 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
174 pAnchor
, pHelp
, pLabel
);
177 /****************************************************************************
179 ****************************************************************************/
180 static void print_footer(void)
182 if (!include_html("include/footer.html")) {
183 d_printf("\n</BODY>\n</HTML>\n");
187 /****************************************************************************
188 display one editable parameter in a form
189 ****************************************************************************/
190 static void show_parameter(int snum
, struct parm_struct
*parm
)
193 void *ptr
= parm
->ptr
;
195 if (parm
->class == P_LOCAL
&& snum
>= 0) {
196 ptr
= lp_local_ptr(snum
, ptr
);
199 printf("<tr><td>%s</td><td>", get_parm_translated(stripspaceupper(parm
->label
), _("Help"), parm
->label
));
200 switch (parm
->type
) {
202 d_printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
203 make_parm_name(parm
->label
), *(char *)ptr
);
204 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
205 _("Set Default"), make_parm_name(parm
->label
),(char)(parm
->def
.cvalue
));
209 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"",
210 make_parm_name(parm
->label
));
211 if ((char ***)ptr
&& *(char ***)ptr
&& **(char ***)ptr
) {
212 char **list
= *(char ***)ptr
;
213 for (;*list
;list
++) {
214 d_printf("%s%s", *list
, ((*(list
+1))?" ":""));
218 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
219 _("Set Default"), make_parm_name(parm
->label
));
220 if (parm
->def
.lvalue
) {
221 char **list
= (char **)(parm
->def
.lvalue
);
222 for (; *list
; list
++) {
223 d_printf("%s%s", *list
, ((*(list
+1))?" ":""));
231 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
232 make_parm_name(parm
->label
), *(char **)ptr
);
233 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
234 _("Set Default"), make_parm_name(parm
->label
),fix_backslash((char *)(parm
->def
.svalue
)));
239 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
240 make_parm_name(parm
->label
), (char *)ptr
);
241 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
242 _("Set Default"), make_parm_name(parm
->label
),fix_backslash((char *)(parm
->def
.svalue
)));
246 d_printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
247 d_printf("<option %s>Yes", (*(BOOL
*)ptr
)?"selected":"");
248 d_printf("<option %s>No", (*(BOOL
*)ptr
)?"":"selected");
249 d_printf("</select>");
250 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
251 _("Set Default"), make_parm_name(parm
->label
),(BOOL
)(parm
->def
.bvalue
)?0:1);
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
)?1:0);
264 d_printf("<input type=text size=8 name=\"parm_%s\" value=%d>", make_parm_name(parm
->label
), *(int *)ptr
);
265 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
266 _("Set Default"), make_parm_name(parm
->label
),(int)(parm
->def
.ivalue
));
270 d_printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm
->label
), octal_string(*(int *)ptr
));
271 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
272 _("Set Default"), make_parm_name(parm
->label
),
273 octal_string((int)(parm
->def
.ivalue
)));
277 d_printf("<select name=\"parm_%s\">",make_parm_name(parm
->label
));
278 for (i
=0;parm
->enum_list
[i
].name
;i
++) {
279 if (i
== 0 || parm
->enum_list
[i
].value
!= parm
->enum_list
[i
-1].value
) {
280 d_printf("<option %s>%s",(*(int *)ptr
)==parm
->enum_list
[i
].value
?"selected":"",parm
->enum_list
[i
].name
);
283 d_printf("</select>");
284 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
285 _("Set Default"), make_parm_name(parm
->label
),enum_index((int)(parm
->def
.ivalue
),parm
->enum_list
));
290 d_printf("</td></tr>\n");
293 /****************************************************************************
294 display a set of parameters for a service
295 ****************************************************************************/
296 static void show_parameters(int snum
, int allparameters
, unsigned int parm_filter
, int printers
)
299 struct parm_struct
*parm
;
300 const char *heading
= NULL
;
301 const char *last_heading
= NULL
;
303 while ((parm
= lp_next_parameter(snum
, &i
, allparameters
))) {
304 if (snum
< 0 && parm
->class == P_LOCAL
&& !(parm
->flags
& FLAG_GLOBAL
))
306 if (parm
->class == P_SEPARATOR
) {
307 heading
= parm
->label
;
310 if (parm
->flags
& FLAG_HIDE
) continue;
312 if (printers
& !(parm
->flags
& FLAG_PRINT
)) continue;
313 if (!printers
& !(parm
->flags
& FLAG_SHARE
)) continue;
316 if (!( parm_filter
& FLAG_ADVANCED
)) {
317 if (!(parm
->flags
& FLAG_BASIC
)) {
318 void *ptr
= parm
->ptr
;
320 if (parm
->class == P_LOCAL
&& snum
>= 0) {
321 ptr
= lp_local_ptr(snum
, ptr
);
324 switch (parm
->type
) {
326 if (*(char *)ptr
== (char)(parm
->def
.cvalue
)) continue;
330 if (!str_list_compare(*(char ***)ptr
, (char **)(parm
->def
.lvalue
))) continue;
335 if (!strcmp(*(char **)ptr
,(char *)(parm
->def
.svalue
))) continue;
340 if (!strcmp((char *)ptr
,(char *)(parm
->def
.svalue
))) continue;
345 if (*(BOOL
*)ptr
== (BOOL
)(parm
->def
.bvalue
)) continue;
350 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
355 if (*(int *)ptr
== (int)(parm
->def
.ivalue
)) continue;
361 if (printers
&& !(parm
->flags
& FLAG_PRINT
)) continue;
364 if ((parm_filter
& FLAG_WIZARD
) && !(parm
->flags
& FLAG_WIZARD
)) continue;
366 if ((parm_filter
& FLAG_ADVANCED
) && !(parm
->flags
& FLAG_ADVANCED
)) continue;
368 if (heading
&& heading
!= last_heading
) {
369 d_printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading
));
370 last_heading
= heading
;
372 show_parameter(snum
, parm
);
376 /****************************************************************************
377 load the smb.conf file into loadparm.
378 ****************************************************************************/
379 static BOOL
load_config(BOOL save_def
)
381 lp_resetnumservices();
382 return lp_load(dyn_CONFIGFILE
,False
,save_def
,False
);
385 /****************************************************************************
387 ****************************************************************************/
388 static void write_config(FILE *f
, BOOL show_defaults
)
390 fprintf(f
, "# Samba config file created using SWAT\n");
391 fprintf(f
, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
392 fprintf(f
, "# Date: %s\n\n", timestring(False
));
394 lp_dump(f
, show_defaults
, iNumNonAutoPrintServices
);
397 /****************************************************************************
398 save and reload the smb.conf config file
399 ****************************************************************************/
400 static int save_reload(int snum
)
405 f
= sys_fopen(dyn_CONFIGFILE
,"w");
407 d_printf("failed to open %s for writing\n", dyn_CONFIGFILE
);
411 /* just in case they have used the buggy xinetd to create the file */
412 if (fstat(fileno(f
), &st
) == 0 &&
413 (st
.st_mode
& S_IWOTH
)) {
414 #if defined HAVE_FCHMOD
415 fchmod(fileno(f
), S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
417 chmod(dyn_CONFIGFILE
, S_IWUSR
| S_IRUSR
| S_IRGRP
| S_IROTH
);
421 write_config(f
, False
);
423 lp_dump_one(f
, False
, snum
);
428 if (!load_config(False
)) {
429 d_printf("Can't reload %s\n", dyn_CONFIGFILE
);
432 iNumNonAutoPrintServices
= lp_numservices();
438 /****************************************************************************
440 ****************************************************************************/
441 static void commit_parameter(int snum
, struct parm_struct
*parm
, const char *v
)
446 if (snum
< 0 && parm
->class == P_LOCAL
) {
447 /* this handles the case where we are changing a local
448 variable globally. We need to change the parameter in
449 all shares where it is currently set to the default */
450 for (i
=0;i
<lp_numservices();i
++) {
451 s
= lp_servicename(i
);
452 if (s
&& (*s
) && lp_is_default(i
, parm
)) {
453 lp_do_parameter(i
, parm
->label
, v
);
458 lp_do_parameter(snum
, parm
->label
, v
);
461 /****************************************************************************
462 commit a set of parameters for a service
463 ****************************************************************************/
464 static void commit_parameters(int snum
)
467 struct parm_struct
*parm
;
471 while ((parm
= lp_next_parameter(snum
, &i
, 1))) {
472 slprintf(label
, sizeof(label
)-1, "parm_%s", make_parm_name(parm
->label
));
473 if ((v
= cgi_variable(label
))) {
474 if (parm
->flags
& FLAG_HIDE
) continue;
475 commit_parameter(snum
, parm
, v
);
480 /****************************************************************************
481 spit out the html for a link with an image
482 ****************************************************************************/
483 static void image_link(const char *name
, const char *hlink
, const char *src
)
485 d_printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
486 cgi_baseurl(), hlink
, src
, name
);
489 /****************************************************************************
490 display the main navigation controls at the top of each page along
492 ****************************************************************************/
493 static void show_main_buttons(void)
497 if ((p
= cgi_user_name()) && strcmp(p
, "root")) {
498 d_printf(_("Logged in as <b>%s</b><p>\n"), p
);
501 image_link(_("Home"), "", "images/home.gif");
502 if (have_write_access
) {
503 image_link(_("Globals"), "globals", "images/globals.gif");
504 image_link(_("Shares"), "shares", "images/shares.gif");
505 image_link(_("Printers"), "printers", "images/printers.gif");
506 image_link(_("Wizard"), "wizard", "images/wizard.gif");
508 if (have_read_access
) {
509 image_link(_("Status"), "status", "images/status.gif");
510 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
512 image_link(_("Password Management"), "passwd", "images/passwd.gif");
517 /****************************************************************************
518 * Handle Display/Edit Mode CGI
519 ****************************************************************************/
520 static void ViewModeBoxes(int mode
)
522 d_printf("<p>%s\n", _("Current View Is:  \n"));
523 d_printf("<input type=radio name=\"ViewMode\" value=0 %s>Basic\n", (mode
== 0) ? "checked" : "");
524 d_printf("<input type=radio name=\"ViewMode\" value=1 %s>Advanced\n", (mode
== 1) ? "checked" : "");
525 d_printf("<br>%s\n", _("Change View To: "));
526 d_printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
527 d_printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
528 d_printf("</p><br>\n");
531 /****************************************************************************
532 display a welcome page
533 ****************************************************************************/
534 static void welcome_page(void)
536 include_html("help/welcome.html");
539 /****************************************************************************
540 display the current smb.conf
541 ****************************************************************************/
542 static void viewconfig_page(void)
546 if (cgi_variable("full_view")) {
550 d_printf("<H2>%s</H2>\n", _("Current Config"));
551 d_printf("<form method=post>\n");
554 d_printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
556 d_printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
559 d_printf("<p><pre>");
560 write_config(stdout
, full_view
);
562 d_printf("</form>\n");
565 /****************************************************************************
566 second screen of the wizard ... Fetch Configuration Parameters
567 ****************************************************************************/
568 static void wizard_params_page(void)
570 unsigned int parm_filter
= FLAG_WIZARD
;
572 /* Here we first set and commit all the parameters that were selected
573 in the previous screen. */
575 d_printf("<H2>Wizard Parameter Edit Page</H2>\n");
577 if (cgi_variable("Commit")) {
578 commit_parameters(GLOBAL_SECTION_SNUM
);
582 d_printf("<form name=\"swatform\" method=post action=wizard_params>\n");
584 if (have_write_access
) {
585 d_printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
588 d_printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
591 d_printf("<table>\n");
592 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
593 d_printf("</table>\n");
594 d_printf("</form>\n");
597 /****************************************************************************
598 Utility to just rewrite the smb.conf file - effectively just cleans it up
599 ****************************************************************************/
600 static void rewritecfg_file(void)
602 commit_parameters(GLOBAL_SECTION_SNUM
);
604 d_printf("<H2>Note: smb.conf %s</H2>\n", _("file has been read and rewritten"));
607 /****************************************************************************
608 wizard to create/modify the smb.conf file
609 ****************************************************************************/
610 static void wizard_page(void)
612 /* Set some variables to collect data from smb.conf */
619 if (cgi_variable("Rewrite")) {
620 (void) rewritecfg_file();
624 if (cgi_variable("GetWizardParams")){
625 (void) wizard_params_page();
629 if (cgi_variable("Commit")){
630 SerType
= atoi(cgi_variable("ServerType"));
631 winstype
= atoi(cgi_variable("WINSType"));
632 have_home
= lp_servicenumber(HOMES_NAME
);
633 HomeExpo
= atoi(cgi_variable("HomeExpo"));
635 /* Plain text passwords are too badly broken - use encrypted passwords only */
636 lp_do_parameter( GLOBAL_SECTION_SNUM
, "encrypt passwords", "Yes");
640 /* Stand-alone Server */
641 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
642 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
646 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "DOMAIN" );
647 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "No" );
650 /* Domain Controller */
651 lp_do_parameter( GLOBAL_SECTION_SNUM
, "security", "USER" );
652 lp_do_parameter( GLOBAL_SECTION_SNUM
, "domain logons", "Yes" );
655 switch ( winstype
) {
657 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
658 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
661 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "Yes" );
662 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", "" );
665 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins support", "No" );
666 lp_do_parameter( GLOBAL_SECTION_SNUM
, "wins server", cgi_variable("WINSAddr"));
670 /* Have to create Homes share? */
671 if ((HomeExpo
== 1) && (have_home
== -1)) {
674 pstrcpy(unix_share
,HOMES_NAME
);
676 lp_copy_service(GLOBAL_SECTION_SNUM
, unix_share
);
677 iNumNonAutoPrintServices
= lp_numservices();
678 have_home
= lp_servicenumber(HOMES_NAME
);
679 lp_do_parameter( have_home
, "read only", "No");
680 lp_do_parameter( have_home
, "valid users", "%S");
681 lp_do_parameter( have_home
, "browseable", "No");
682 commit_parameters(have_home
);
685 /* Need to Delete Homes share? */
686 if ((HomeExpo
== 0) && (have_home
!= -1)) {
687 lp_remove_service(have_home
);
691 commit_parameters(GLOBAL_SECTION_SNUM
);
696 /* Now determine smb.conf WINS settings */
697 if (lp_wins_support())
699 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
703 /* Do we have a homes share? */
704 have_home
= lp_servicenumber(HOMES_NAME
);
706 if ((winstype
== 2) && lp_wins_support())
709 role
= lp_server_role();
712 d_printf("<H2>Samba Configuration Wizard</H2>\n");
713 d_printf("<form method=post action=wizard>\n");
715 if (have_write_access
) {
716 d_printf(_("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments.\n"));
717 d_printf(_("The same will happen if you press the commit button."));
718 d_printf("<br><br>");
719 d_printf("<center>");
720 d_printf("<input type=submit name=\"Rewrite\" value=%s> ",_("Rewrite smb.conf file"));
721 d_printf("<input type=submit name=\"Commit\" value=%s> ",_("Commit"));
722 d_printf("<input type=submit name=\"GetWizardParams\" value=%s>", _("Edit Parameter Values"));
723 d_printf("</center>");
727 d_printf("<center><table border=0>");
728 d_printf("<tr><td><b>%s</b></td>\n", "Server Type: ");
729 d_printf("<td><input type=radio name=\"ServerType\" value=0 %s> Stand Alone </td>", (role
== ROLE_STANDALONE
) ? "checked" : "");
730 d_printf("<td><input type=radio name=\"ServerType\" value=1 %s> Domain Member </td>", (role
== ROLE_DOMAIN_MEMBER
) ? "checked" : "");
731 d_printf("<td><input type=radio name=\"ServerType\" value=2 %s> Domain Controller </td>", (role
== ROLE_DOMAIN_PDC
) ? "checked" : "");
733 if (role
== ROLE_DOMAIN_BDC
) {
734 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Unusual Type in smb.conf - Please Select New Mode</font></td></tr>");
736 d_printf("<tr><td><b>%s</b></td>\n", "Configure WINS As: ");
737 d_printf("<td><input type=radio name=\"WINSType\" value=0 %s> Not Used </td>", (winstype
== 0) ? "checked" : "");
738 d_printf("<td><input type=radio name=\"WINSType\" value=1 %s> Server for client use </td>", (winstype
== 1) ? "checked" : "");
739 d_printf("<td><input type=radio name=\"WINSType\" value=2 %s> Client of another WINS server </td>", (winstype
== 2) ? "checked" : "");
740 d_printf("<tr><td></td><td></td><td></td><td>Remote WINS Server <input type=text size=\"16\" name=\"WINSAddr\" value=\"");
742 /* Print out the list of wins servers */
743 if(lp_wins_server_list()) {
745 const char **wins_servers
= lp_wins_server_list();
746 for(i
= 0; wins_servers
[i
]; i
++) d_printf("%s ", wins_servers
[i
]);
749 d_printf("\"></td></tr>");
751 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Error: WINS Server Mode and WINS Support both set in smb.conf</font></td></tr>");
752 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Please Select desired WINS mode above.</font></td></tr>");
755 d_printf("<tr><td><b>%s</b></td>\n","Expose Home Directories: ");
756 d_printf("<td><input type=radio name=\"HomeExpo\" value=1 %s> Yes</td>", (have_home
== -1) ? "" : "checked ");
757 d_printf("<td><input type=radio name=\"HomeExpo\" value=0 %s> No</td>", (have_home
== -1 ) ? "checked" : "");
758 d_printf("<td></td></tr>");
760 /* Enable this when we are ready ....
761 * d_printf("<tr><td><b>%s</b></td>\n","Is Print Server: ");
762 * d_printf("<td><input type=radio name=\"PtrSvr\" value=1 %s> Yes</td>");
763 * d_printf("<td><input type=radio name=\"PtrSvr\" value=0 %s> No</td>");
764 * d_printf("<td></td></tr>");
767 d_printf("</table></center>");
770 d_printf(_("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment.\n"));
771 d_printf("</form>\n");
775 /****************************************************************************
776 display a globals editing page
777 ****************************************************************************/
778 static void globals_page(void)
780 unsigned int parm_filter
= FLAG_BASIC
;
783 d_printf("<H2>%s</H2>\n", _("Global Variables"));
785 if (cgi_variable("Commit")) {
786 commit_parameters(GLOBAL_SECTION_SNUM
);
790 if ( cgi_variable("ViewMode") )
791 mode
= atoi(cgi_variable("ViewMode"));
792 if ( cgi_variable("BasicMode"))
794 if ( cgi_variable("AdvMode"))
797 d_printf("<form name=\"swatform\" method=post action=globals>\n");
799 ViewModeBoxes( mode
);
802 parm_filter
= FLAG_BASIC
;
805 parm_filter
= FLAG_ADVANCED
;
809 if (have_write_access
) {
810 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
811 _("Commit Changes"));
814 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
818 d_printf("<table>\n");
819 show_parameters(GLOBAL_SECTION_SNUM
, 1, parm_filter
, 0);
820 d_printf("</table>\n");
821 d_printf("</form>\n");
824 /****************************************************************************
825 display a shares editing page. share is in unix codepage, and must be in
826 dos codepage. FIXME !!! JRA.
827 ****************************************************************************/
828 static void shares_page(void)
830 const char *share
= cgi_variable("share");
835 unsigned int parm_filter
= FLAG_BASIC
;
838 snum
= lp_servicenumber(share
);
840 d_printf("<H2>%s</H2>\n", _("Share Parameters"));
842 if (cgi_variable("Commit") && snum
>= 0) {
843 commit_parameters(snum
);
847 if (cgi_variable("Delete") && snum
>= 0) {
848 lp_remove_service(snum
);
854 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
856 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
857 iNumNonAutoPrintServices
= lp_numservices();
859 snum
= lp_servicenumber(share
);
862 d_printf("<FORM name=\"swatform\" method=post>\n");
864 d_printf("<table>\n");
866 if ( cgi_variable("ViewMode") )
867 mode
= atoi(cgi_variable("ViewMode"));
868 if ( cgi_variable("BasicMode"))
870 if ( cgi_variable("AdvMode"))
873 ViewModeBoxes( mode
);
876 parm_filter
= FLAG_BASIC
;
879 parm_filter
= FLAG_ADVANCED
;
882 d_printf("<br><tr>\n");
883 d_printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
884 d_printf("<td><select name=share>\n");
886 d_printf("<option value=\" \"> \n");
887 for (i
=0;i
<lp_numservices();i
++) {
888 s
= lp_servicename(i
);
889 if (s
&& (*s
) && strcmp(s
,"IPC$") && !lp_print_ok(i
)) {
890 d_printf("<option %s value=\"%s\">%s\n",
891 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
895 d_printf("</select></td>\n");
896 if (have_write_access
) {
897 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
900 d_printf("</table>");
902 if (have_write_access
) {
904 d_printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
905 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
907 d_printf("</table>");
911 if (have_write_access
) {
912 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
915 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
920 d_printf("<table>\n");
921 show_parameters(snum
, 1, parm_filter
, 0);
922 d_printf("</table>\n");
925 d_printf("</FORM>\n");
928 /*************************************************************
929 change a password either locally or remotely
930 *************************************************************/
931 static BOOL
change_password(const char *remote_machine
, const char *user_name
,
932 const char *old_passwd
, const char *new_passwd
,
940 d_printf("%s<p>", _("password change in demo mode rejected\n"));
944 if (remote_machine
!= NULL
) {
945 ret
= remote_password_change(remote_machine
, user_name
, old_passwd
,
946 new_passwd
, err_str
, sizeof(err_str
));
948 d_printf("%s\n<p>", err_str
);
952 if(!initialize_password_db(True
)) {
953 d_printf("Can't setup password database vectors.\n<p>");
957 ret
= local_password_change(user_name
, local_flags
, new_passwd
, err_str
, sizeof(err_str
),
958 msg_str
, sizeof(msg_str
));
961 d_printf("%s\n<p>", msg_str
);
963 d_printf("%s\n<p>", err_str
);
968 /****************************************************************************
969 do the stuff required to add or change a password
970 ****************************************************************************/
971 static void chg_passwd(void)
977 /* Make sure users name has been specified */
978 if (strlen(cgi_variable(SWAT_USER
)) == 0) {
979 d_printf("<p>%s", _(" Must specify \"User Name\" \n"));
984 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
985 * so if that's what we're doing, skip the rest of the checks
987 if (!cgi_variable(DISABLE_USER_FLAG
) && !cgi_variable(ENABLE_USER_FLAG
) && !cgi_variable(DELETE_USER_FLAG
)) {
990 * If current user is not root, make sure old password has been specified
991 * If REMOTE change, even root must provide old password
993 if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD
)) <= 0)) ||
994 ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable(OLD_PSWD
)) <= 0))) {
995 d_printf("<p>%s", _(" Must specify \"Old Password\" \n"));
999 /* If changing a users password on a remote hosts we have to know what host */
1000 if ((cgi_variable(CHG_R_PASSWD_FLAG
)) && (strlen( cgi_variable(RHOST
)) <= 0)) {
1001 d_printf("<p>%s", _(" Must specify \"Remote Machine\" \n"));
1005 /* Make sure new passwords have been specified */
1006 if ((strlen( cgi_variable(NEW_PSWD
)) <= 0) ||
1007 (strlen( cgi_variable(NEW2_PSWD
)) <= 0)) {
1008 d_printf("<p>%s", _(" Must specify \"New, and Re-typed Passwords\" \n"));
1012 /* Make sure new passwords was typed correctly twice */
1013 if (strcmp(cgi_variable(NEW_PSWD
), cgi_variable(NEW2_PSWD
)) != 0) {
1014 d_printf("<p>%s", _(" Re-typed password didn't match new password\n"));
1019 if (cgi_variable(CHG_R_PASSWD_FLAG
)) {
1020 host
= cgi_variable(RHOST
);
1021 } else if (am_root()) {
1028 * Set up the local flags.
1031 local_flags
|= (cgi_variable(ADD_USER_FLAG
) ? LOCAL_ADD_USER
: 0);
1032 local_flags
|= (cgi_variable(DELETE_USER_FLAG
) ? LOCAL_DELETE_USER
: 0);
1033 local_flags
|= (cgi_variable(ENABLE_USER_FLAG
) ? LOCAL_ENABLE_USER
: 0);
1034 local_flags
|= (cgi_variable(DISABLE_USER_FLAG
) ? LOCAL_DISABLE_USER
: 0);
1036 rslt
= change_password(host
,
1037 cgi_variable(SWAT_USER
),
1038 cgi_variable(OLD_PSWD
), cgi_variable(NEW_PSWD
),
1041 if(local_flags
== 0) {
1044 d_printf(_(" The passwd for '%s' has been changed. \n"), cgi_variable(SWAT_USER
));
1046 d_printf(_(" The passwd for '%s' has NOT been changed. \n"), cgi_variable(SWAT_USER
));
1053 /****************************************************************************
1054 display a password editing page
1055 ****************************************************************************/
1056 static void passwd_page(void)
1058 const char *new_name
= cgi_user_name();
1061 * After the first time through here be nice. If the user
1062 * changed the User box text to another users name, remember it.
1064 if (cgi_variable(SWAT_USER
)) {
1065 new_name
= cgi_variable(SWAT_USER
);
1068 if (!new_name
) new_name
= "";
1070 d_printf("<H2>%s</H2>\n", _("Server Password Management"));
1072 d_printf("<FORM name=\"swatform\" method=post>\n");
1074 d_printf("<table>\n");
1077 * Create all the dialog boxes for data collection
1079 d_printf("<tr><td>%s</td>\n", _(" User Name : "));
1080 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER
, new_name
);
1082 d_printf("<tr><td>%s</td>\n", _(" Old Password : "));
1083 d_printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD
);
1085 d_printf("<tr><td>%s</td>\n", _(" New Password : "));
1086 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1087 d_printf("<tr><td>%s</td>\n", _(" Re-type New Password : "));
1088 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1089 d_printf("</table>\n");
1092 * Create all the control buttons for requesting action
1094 d_printf("<input type=submit name=%s value=\"%s\">\n",
1095 CHG_S_PASSWD_FLAG
, _("Change Password"));
1096 if (demo_mode
|| am_root()) {
1097 d_printf("<input type=submit name=%s value=\"%s\">\n",
1098 ADD_USER_FLAG
, _("Add New User"));
1099 d_printf("<input type=submit name=%s value=\"%s\">\n",
1100 DELETE_USER_FLAG
, _("Delete User"));
1101 d_printf("<input type=submit name=%s value=\"%s\">\n",
1102 DISABLE_USER_FLAG
, _("Disable User"));
1103 d_printf("<input type=submit name=%s value=\"%s\">\n",
1104 ENABLE_USER_FLAG
, _("Enable User"));
1106 d_printf("<p></FORM>\n");
1109 * Do some work if change, add, disable or enable was
1110 * requested. It could be this is the first time through this
1111 * code, so there isn't anything to do. */
1112 if ((cgi_variable(CHG_S_PASSWD_FLAG
)) || (cgi_variable(ADD_USER_FLAG
)) || (cgi_variable(DELETE_USER_FLAG
)) ||
1113 (cgi_variable(DISABLE_USER_FLAG
)) || (cgi_variable(ENABLE_USER_FLAG
))) {
1117 d_printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1119 d_printf("<FORM name=\"swatform\" method=post>\n");
1121 d_printf("<table>\n");
1124 * Create all the dialog boxes for data collection
1126 d_printf("<tr><td>%s</td>\n", _(" User Name : "));
1127 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER
, new_name
);
1128 d_printf("<tr><td>%s</td>\n", _(" Old Password : "));
1129 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD
);
1130 d_printf("<tr><td>%s</td>\n", _(" New Password : "));
1131 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD
);
1132 d_printf("<tr><td>%s</td>\n", _(" Re-type New Password : "));
1133 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD
);
1134 d_printf("<tr><td>%s</td>\n", _(" Remote Machine : "));
1135 d_printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST
);
1137 d_printf("</table>");
1140 * Create all the control buttons for requesting action
1142 d_printf("<input type=submit name=%s value=\"%s\">",
1143 CHG_R_PASSWD_FLAG
, _("Change Password"));
1145 d_printf("<p></FORM>\n");
1148 * Do some work if a request has been made to change the
1149 * password somewhere other than the server. It could be this
1150 * is the first time through this code, so there isn't
1151 * anything to do. */
1152 if (cgi_variable(CHG_R_PASSWD_FLAG
)) {
1158 /****************************************************************************
1159 display a printers editing page
1160 ****************************************************************************/
1161 static void printers_page(void)
1163 const char *share
= cgi_variable("share");
1168 unsigned int parm_filter
= FLAG_BASIC
;
1171 snum
= lp_servicenumber(share
);
1173 d_printf("<H2>%s</H2>\n", _("Printer Parameters"));
1175 d_printf("<H3>%s</H3>\n", _("Important Note:"));
1176 d_printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
1177 d_printf(_("are autoloaded printers from "));
1178 d_printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1179 d_printf(_("Attempting to delete these printers from SWAT will have no effect.\n"));
1181 if (cgi_variable("Commit") && snum
>= 0) {
1182 commit_parameters(snum
);
1183 if (snum
>= iNumNonAutoPrintServices
)
1189 if (cgi_variable("Delete") && snum
>= 0) {
1190 lp_remove_service(snum
);
1196 if (cgi_variable("createshare") && (share
=cgi_variable("newshare"))) {
1198 lp_copy_service(GLOBAL_SECTION_SNUM
, share
);
1199 iNumNonAutoPrintServices
= lp_numservices();
1200 snum
= lp_servicenumber(share
);
1201 lp_do_parameter(snum
, "print ok", "Yes");
1203 snum
= lp_servicenumber(share
);
1206 d_printf("<FORM name=\"swatform\" method=post>\n");
1208 if ( cgi_variable("ViewMode") )
1209 mode
= atoi(cgi_variable("ViewMode"));
1210 if ( cgi_variable("BasicMode"))
1212 if ( cgi_variable("AdvMode"))
1215 ViewModeBoxes( mode
);
1218 parm_filter
= FLAG_BASIC
;
1221 parm_filter
= FLAG_ADVANCED
;
1224 d_printf("<table>\n");
1225 d_printf("<tr><td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Printer"));
1226 d_printf("<td><select name=share>\n");
1227 if (snum
< 0 || !lp_print_ok(snum
))
1228 d_printf("<option value=\" \"> \n");
1229 for (i
=0;i
<lp_numservices();i
++) {
1230 s
= lp_servicename(i
);
1231 if (s
&& (*s
) && strcmp(s
,"IPC$") && lp_print_ok(i
)) {
1232 if (i
>= iNumNonAutoPrintServices
)
1233 d_printf("<option %s value=\"%s\">[*]%s\n",
1234 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1237 d_printf("<option %s value=\"%s\">%s\n",
1238 (share
&& strcmp(share
,s
)==0)?"SELECTED":"",
1242 d_printf("</select></td>");
1243 if (have_write_access
) {
1244 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1247 d_printf("</table>\n");
1249 if (have_write_access
) {
1250 d_printf("<table>\n");
1251 d_printf("<tr><td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Printer"));
1252 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1253 d_printf("</table>");
1258 if (have_write_access
) {
1259 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1261 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1266 d_printf("<table>\n");
1267 show_parameters(snum
, 1, parm_filter
, 1);
1268 d_printf("</table>\n");
1270 d_printf("</FORM>\n");
1275 * main function for SWAT.
1277 int main(int argc
, char *argv
[])
1282 struct poptOption long_options
[] = {
1284 { "disable-authentication", 'a', POPT_ARG_VAL
, &demo_mode
, True
, "Disable authentication (demo mode)" },
1290 umask(S_IWGRP
| S_IWOTH
);
1292 #if defined(HAVE_SET_AUTH_PARAMETERS)
1293 set_auth_parameters(argc
, argv
);
1294 #endif /* HAVE_SET_AUTH_PARAMETERS */
1296 /* just in case it goes wild ... */
1301 /* we don't want any SIGPIPE messages */
1302 BlockSignals(True
,SIGPIPE
);
1304 dbf
= x_fopen("/dev/null", O_WRONLY
, 0);
1305 if (!dbf
) dbf
= x_stderr
;
1307 /* we don't want stderr screwing us up */
1309 open("/dev/null", O_WRONLY
);
1311 pc
= poptGetContext("swat", argc
, (const char **) argv
, long_options
, 0);
1313 /* Parse command line options */
1315 while((opt
= poptGetNextOpt(pc
)) != -1) { }
1317 poptFreeContext(pc
);
1319 setup_logging(argv
[0],False
);
1321 iNumNonAutoPrintServices
= lp_numservices();
1324 cgi_setup(dyn_SWATDIR
, !demo_mode
);
1328 cgi_load_variables();
1330 if (!file_exist(dyn_CONFIGFILE
, NULL
)) {
1331 have_read_access
= True
;
1332 have_write_access
= True
;
1334 /* check if the authenticated user has write access - if not then
1335 don't show write options */
1336 have_write_access
= (access(dyn_CONFIGFILE
,W_OK
) == 0);
1338 /* if the user doesn't have read access to smb.conf then
1339 don't let them view it */
1340 have_read_access
= (access(dyn_CONFIGFILE
,R_OK
) == 0);
1343 show_main_buttons();
1345 page
= cgi_pathinfo();
1347 /* Root gets full functionality */
1348 if (have_read_access
&& strcmp(page
, "globals")==0) {
1350 } else if (have_read_access
&& strcmp(page
,"shares")==0) {
1352 } else if (have_read_access
&& strcmp(page
,"printers")==0) {
1354 } else if (have_read_access
&& strcmp(page
,"status")==0) {
1356 } else if (have_read_access
&& strcmp(page
,"viewconfig")==0) {
1358 } else if (strcmp(page
,"passwd")==0) {
1360 } else if (have_read_access
&& strcmp(page
,"wizard")==0) {
1362 } else if (have_read_access
&& strcmp(page
,"wizard_params")==0) {
1363 wizard_params_page();
1364 } else if (have_read_access
&& strcmp(page
,"rewritecfg")==0) {