fix from Brad Langhorst to correctly check if the primaryGroupID has been set
[Samba/gebeck_regimport.git] / source / web / swat.c
blob1c892559dd97f5b4971de3796d53985f91f1aa8d
1 /*
2 Unix SMB/CIFS implementation.
3 Samba Web Administration Tool
4 Version 3.0.0
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.
23 /**
24 * @defgroup swat SWAT - Samba Web Administration Tool
25 * @{
26 * @file swat.c
28 * @brief Samba Web Administration Tool.
29 **/
31 #include "includes.h"
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)
58 int i;
59 for (i=0;enumlist[i].name;i++)
60 if (value == enumlist[i].value) break;
61 return(i);
64 static char *fix_backslash(const char *str)
66 static char newstring[1024];
67 char *p = newstring;
69 while (*str) {
70 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
71 else *p++ = *str;
72 ++str;
74 *p = '\0';
75 return newstring;
78 static char *stripspaceupper(const char *str)
80 static char newstring[1024];
81 char *p = newstring;
83 while (*str) {
84 if (*str != ' ') *p++ = toupper(*str);
85 ++str;
87 *p = '\0';
88 return newstring;
91 static char *make_parm_name(const char *label)
93 static char parmname[1024];
94 char *p = parmname;
96 while (*label) {
97 if (*label == ' ') *p++ = '_';
98 else *p++ = *label;
99 ++label;
101 *p = '\0';
102 return parmname;
105 /****************************************************************************
106 include a lump of html in a page
107 ****************************************************************************/
108 static int include_html(const char *fname)
110 int fd;
111 char buf[1024];
112 int ret;
114 fd = web_open(fname, O_RDONLY, 0);
116 if (fd == -1) {
117 d_printf("ERROR: Can't open %s\n", fname);
118 return 0;
121 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
122 write(1, buf, ret);
125 close(fd);
126 return 1;
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
149 heavy users.
150 -------------------------------
151 HELP security [combo box][button]
152 SECURITY
153 -------------------------------
154 (capital words are translated by gettext.)
155 if no translation is available, then same form as original is
156 used.
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)
167 pstr_sprintf(output,
168 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s <br><span class=\"i18n_translated_parm\">%s</span>",
169 pAnchor, pHelp, pLabel, pTranslated);
170 return output;
172 pstr_sprintf(output,
173 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
174 pAnchor, pHelp, pLabel);
175 return output;
177 /****************************************************************************
178 finish off the page
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)
192 int i;
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) {
201 case P_CHAR:
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));
206 break;
208 case P_LIST:
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))?" ":""));
217 d_printf("\">");
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))?" ":""));
226 d_printf("\'\">");
227 break;
229 case P_STRING:
230 case P_USTRING:
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)));
235 break;
237 case P_GSTRING:
238 case P_UGSTRING:
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)));
243 break;
245 case P_BOOL:
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);
252 break;
254 case P_BOOLREV:
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);
261 break;
263 case P_INTEGER:
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));
267 break;
269 case P_OCTAL:
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)));
274 break;
276 case P_ENUM:
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));
286 break;
287 case P_SEP:
288 break;
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)
298 int i = 0;
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))
305 continue;
306 if (parm->class == P_SEPARATOR) {
307 heading = parm->label;
308 continue;
310 if (parm->flags & FLAG_HIDE) continue;
311 if (snum >= 0) {
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) {
325 case P_CHAR:
326 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
327 break;
329 case P_LIST:
330 if (!str_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
331 break;
333 case P_STRING:
334 case P_USTRING:
335 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
336 break;
338 case P_GSTRING:
339 case P_UGSTRING:
340 if (!strcmp((char *)ptr,(char *)(parm->def.svalue))) continue;
341 break;
343 case P_BOOL:
344 case P_BOOLREV:
345 if (*(BOOL *)ptr == (BOOL)(parm->def.bvalue)) continue;
346 break;
348 case P_INTEGER:
349 case P_OCTAL:
350 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
351 break;
354 case P_ENUM:
355 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
356 break;
357 case P_SEP:
358 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 /****************************************************************************
386 write a config file
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)
402 FILE *f;
403 struct stat st;
405 f = sys_fopen(dyn_CONFIGFILE,"w");
406 if (!f) {
407 d_printf("failed to open %s for writing\n", dyn_CONFIGFILE);
408 return 0;
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);
416 #else
417 chmod(dyn_CONFIGFILE, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
418 #endif
421 write_config(f, False);
422 if (snum)
423 lp_dump_one(f, False, snum);
424 fclose(f);
426 lp_killunused(NULL);
428 if (!load_config(False)) {
429 d_printf("Can't reload %s\n", dyn_CONFIGFILE);
430 return 0;
432 iNumNonAutoPrintServices = lp_numservices();
433 load_printers();
435 return 1;
438 /****************************************************************************
439 commit one parameter
440 ****************************************************************************/
441 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
443 int i;
444 char *s;
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)
466 int i = 0;
467 struct parm_struct *parm;
468 pstring label;
469 const char *v;
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
491 with a title
492 ****************************************************************************/
493 static void show_main_buttons(void)
495 char *p;
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");
514 d_printf("<HR>\n");
517 /****************************************************************************
518 * Handle Display/Edit Mode CGI
519 ****************************************************************************/
520 static void ViewModeBoxes(int mode)
522 d_printf("<p>%s\n", _("Current View Is:&nbsp \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:&nbsp"));
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)
544 int full_view=0;
546 if (cgi_variable("full_view")) {
547 full_view = 1;
550 d_printf("<H2>%s</H2>\n", _("Current Config"));
551 d_printf("<form method=post>\n");
553 if (full_view) {
554 d_printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
555 } else {
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);
561 d_printf("</pre>");
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);
579 save_reload(0);
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");
589 d_printf("<p>\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);
603 save_reload(0);
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 */
613 int role = 0;
614 int winstype = 0;
615 int have_home = -1;
616 int HomeExpo = 0;
617 int SerType = 0;
619 if (cgi_variable("Rewrite")) {
620 (void) rewritecfg_file();
621 return;
624 if (cgi_variable("GetWizardParams")){
625 (void) wizard_params_page();
626 return;
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");
638 switch ( SerType ){
639 case 0:
640 /* Stand-alone Server */
641 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
642 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
643 break;
644 case 1:
645 /* Domain Member */
646 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
647 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
648 break;
649 case 2:
650 /* Domain Controller */
651 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
652 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
653 break;
655 switch ( winstype ) {
656 case 0:
657 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
658 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
659 break;
660 case 1:
661 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
662 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
663 break;
664 case 2:
665 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
666 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable("WINSAddr"));
667 break;
670 /* Have to create Homes share? */
671 if ((HomeExpo == 1) && (have_home == -1)) {
672 pstring unix_share;
674 pstrcpy(unix_share,HOMES_NAME);
675 load_config(False);
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);
688 have_home = -1;
691 commit_parameters(GLOBAL_SECTION_SNUM);
692 save_reload(0);
694 else
696 /* Now determine smb.conf WINS settings */
697 if (lp_wins_support())
698 winstype = 1;
699 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
700 winstype = 2;
703 /* Do we have a homes share? */
704 have_home = lp_servicenumber(HOMES_NAME);
706 if ((winstype == 2) && lp_wins_support())
707 winstype = 3;
709 role = lp_server_role();
711 /* Here we go ... */
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> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
721 d_printf("<input type=submit name=\"Commit\" value=%s> &nbsp;&nbsp;",_("Commit"));
722 d_printf("<input type=submit name=\"GetWizardParams\" value=%s>", _("Edit Parameter Values"));
723 d_printf("</center>");
726 d_printf("<hr>");
727 d_printf("<center><table border=0>");
728 d_printf("<tr><td><b>%s</b></td>\n", "Server Type:&nbsp;");
729 d_printf("<td><input type=radio name=\"ServerType\" value=0 %s> Stand Alone&nbsp;</td>", (role == ROLE_STANDALONE) ? "checked" : "");
730 d_printf("<td><input type=radio name=\"ServerType\" value=1 %s> Domain Member&nbsp;</td>", (role == ROLE_DOMAIN_MEMBER) ? "checked" : "");
731 d_printf("<td><input type=radio name=\"ServerType\" value=2 %s> Domain Controller&nbsp;</td>", (role == ROLE_DOMAIN_PDC) ? "checked" : "");
732 d_printf("</tr>");
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:&nbsp;");
737 d_printf("<td><input type=radio name=\"WINSType\" value=0 %s> Not Used&nbsp;</td>", (winstype == 0) ? "checked" : "");
738 d_printf("<td><input type=radio name=\"WINSType\" value=1 %s> Server for client use&nbsp;</td>", (winstype == 1) ? "checked" : "");
739 d_printf("<td><input type=radio name=\"WINSType\" value=2 %s> Client of another WINS server&nbsp;</td>", (winstype == 2) ? "checked" : "");
740 d_printf("<tr><td></td><td></td><td></td><td>Remote WINS Server&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"");
742 /* Print out the list of wins servers */
743 if(lp_wins_server_list()) {
744 int i;
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>");
750 if (winstype == 3) {
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>");
754 d_printf("</tr>");
755 d_printf("<tr><td><b>%s</b></td>\n","Expose Home Directories:&nbsp;");
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:&nbsp;");
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>");
768 d_printf("<hr>");
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;
781 int mode = 0;
783 d_printf("<H2>%s</H2>\n", _("Global Variables"));
785 if (cgi_variable("Commit")) {
786 commit_parameters(GLOBAL_SECTION_SNUM);
787 save_reload(0);
790 if ( cgi_variable("ViewMode") )
791 mode = atoi(cgi_variable("ViewMode"));
792 if ( cgi_variable("BasicMode"))
793 mode = 0;
794 if ( cgi_variable("AdvMode"))
795 mode = 1;
797 d_printf("<form name=\"swatform\" method=post action=globals>\n");
799 ViewModeBoxes( mode );
800 switch ( mode ) {
801 case 0:
802 parm_filter = FLAG_BASIC;
803 break;
804 case 1:
805 parm_filter = FLAG_ADVANCED;
806 break;
808 d_printf("<br>\n");
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",
815 _("Reset Values"));
817 d_printf("<p>\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");
831 char *s;
832 int snum = -1;
833 int i;
834 int mode = 0;
835 unsigned int parm_filter = FLAG_BASIC;
837 if (share)
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);
844 save_reload(0);
847 if (cgi_variable("Delete") && snum >= 0) {
848 lp_remove_service(snum);
849 save_reload(0);
850 share = NULL;
851 snum = -1;
854 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
855 load_config(False);
856 lp_copy_service(GLOBAL_SECTION_SNUM, share);
857 iNumNonAutoPrintServices = lp_numservices();
858 save_reload(0);
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"))
869 mode = 0;
870 if ( cgi_variable("AdvMode"))
871 mode = 1;
873 ViewModeBoxes( mode );
874 switch ( mode ) {
875 case 0:
876 parm_filter = FLAG_BASIC;
877 break;
878 case 1:
879 parm_filter = FLAG_ADVANCED;
880 break;
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");
885 if (snum < 0)
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":"",
892 s, s);
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"));
899 d_printf("</tr>\n");
900 d_printf("</table>");
901 d_printf("<table>");
902 if (have_write_access) {
903 d_printf("<tr>\n");
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>");
910 if (snum >= 0) {
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"));
916 d_printf("<p>\n");
919 if (snum >= 0) {
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,
933 int local_flags)
935 BOOL ret = False;
936 pstring err_str;
937 pstring msg_str;
939 if (demo_mode) {
940 d_printf("%s<p>", _("password change in demo mode rejected\n"));
941 return False;
944 if (remote_machine != NULL) {
945 ret = remote_password_change(remote_machine, user_name, old_passwd,
946 new_passwd, err_str, sizeof(err_str));
947 if(*err_str)
948 d_printf("%s\n<p>", err_str);
949 return ret;
952 if(!initialize_password_db(True)) {
953 d_printf("Can't setup password database vectors.\n<p>");
954 return False;
957 ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
958 msg_str, sizeof(msg_str));
960 if(*msg_str)
961 d_printf("%s\n<p>", msg_str);
962 if(*err_str)
963 d_printf("%s\n<p>", err_str);
965 return ret;
968 /****************************************************************************
969 do the stuff required to add or change a password
970 ****************************************************************************/
971 static void chg_passwd(void)
973 const char *host;
974 BOOL rslt;
975 int local_flags = 0;
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"));
980 return;
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"));
996 return;
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"));
1002 return;
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"));
1009 return;
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"));
1015 return;
1019 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1020 host = cgi_variable(RHOST);
1021 } else if (am_root()) {
1022 host = NULL;
1023 } else {
1024 host = "127.0.0.1";
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),
1039 local_flags);
1041 if(local_flags == 0) {
1042 d_printf("<p>");
1043 if (rslt == True) {
1044 d_printf(_(" The passwd for '%s' has been changed. \n"), cgi_variable(SWAT_USER));
1045 } else {
1046 d_printf(_(" The passwd for '%s' has NOT been changed. \n"), cgi_variable(SWAT_USER));
1050 return;
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);
1081 if (!am_root()) {
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))) {
1114 chg_passwd();
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)) {
1153 chg_passwd();
1158 /****************************************************************************
1159 display a printers editing page
1160 ****************************************************************************/
1161 static void printers_page(void)
1163 const char *share = cgi_variable("share");
1164 char *s;
1165 int snum=-1;
1166 int i;
1167 int mode = 0;
1168 unsigned int parm_filter = FLAG_BASIC;
1170 if (share)
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)
1184 save_reload(snum);
1185 else
1186 save_reload(0);
1189 if (cgi_variable("Delete") && snum >= 0) {
1190 lp_remove_service(snum);
1191 save_reload(0);
1192 share = NULL;
1193 snum = -1;
1196 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1197 load_config(False);
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");
1202 save_reload(0);
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"))
1211 mode = 0;
1212 if ( cgi_variable("AdvMode"))
1213 mode = 1;
1215 ViewModeBoxes( mode );
1216 switch ( mode ) {
1217 case 0:
1218 parm_filter = FLAG_BASIC;
1219 break;
1220 case 1:
1221 parm_filter = FLAG_ADVANCED;
1222 break;
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":"",
1235 s, s);
1236 else
1237 d_printf("<option %s value=\"%s\">%s\n",
1238 (share && strcmp(share,s)==0)?"SELECTED":"",
1239 s, s);
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"));
1246 d_printf("</tr>");
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>");
1257 if (snum >= 0) {
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"));
1262 d_printf("<p>\n");
1265 if (snum >= 0) {
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[])
1279 int opt;
1280 const char *page;
1281 poptContext pc;
1282 struct poptOption long_options[] = {
1283 POPT_AUTOHELP
1284 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1285 POPT_COMMON_SAMBA
1286 POPT_TABLEEND
1289 fault_setup(NULL);
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 ... */
1297 alarm(300);
1299 setlinebuf(stdout);
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 */
1308 close(2);
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);
1320 load_config(True);
1321 iNumNonAutoPrintServices = lp_numservices();
1322 load_printers();
1324 cgi_setup(dyn_SWATDIR, !demo_mode);
1326 print_header();
1328 cgi_load_variables();
1330 if (!file_exist(dyn_CONFIGFILE, NULL)) {
1331 have_read_access = True;
1332 have_write_access = True;
1333 } else {
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) {
1349 globals_page();
1350 } else if (have_read_access && strcmp(page,"shares")==0) {
1351 shares_page();
1352 } else if (have_read_access && strcmp(page,"printers")==0) {
1353 printers_page();
1354 } else if (have_read_access && strcmp(page,"status")==0) {
1355 status_page();
1356 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1357 viewconfig_page();
1358 } else if (strcmp(page,"passwd")==0) {
1359 passwd_page();
1360 } else if (have_read_access && strcmp(page,"wizard")==0) {
1361 wizard_page();
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) {
1365 rewritecfg_file();
1366 } else {
1367 welcome_page();
1370 print_footer();
1371 return 0;
1374 /** @} **/