Replace the eight (!) copies of dummy become/unbecome root with a single one.
[samba.git] / source3 / web / swat.c
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
7    
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.
12    
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.
17    
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.
21 */
22
23 /**
24  * @defgroup swat SWAT - Samba Web Administration Tool
25  * @{ 
26  * @file swat.c
27  *
28  * @brief Samba Web Administration Tool.
29  **/
30
31 #include "includes.h"
32 #include "../web/swat_proto.h"
33
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;
38
39 /*
40  * Password Management Globals
41  */
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"
53
54 /****************************************************************************
55 ****************************************************************************/
56 static int enum_index(int value, const struct enum_list *enumlist)
57 {
58         int i;
59         for (i=0;enumlist[i].name;i++)
60                 if (value == enumlist[i].value) break;
61         return(i);
62 }
63
64 static char *fix_backslash(const char *str)
65 {
66         static char newstring[1024];
67         char *p = newstring;
68
69         while (*str) {
70                 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
71                 else *p++ = *str;
72                 ++str;
73         }
74         *p = '\0';
75         return newstring;
76 }
77
78 static char *stripspaceupper(const char *str)
79 {
80         static char newstring[1024];
81         char *p = newstring;
82
83         while (*str) {
84                 if (*str != ' ') *p++ = toupper(*str);
85                 ++str;
86         }
87         *p = '\0';
88         return newstring;
89 }
90
91 static char *make_parm_name(const char *label)
92 {
93         static char parmname[1024];
94         char *p = parmname;
95
96         while (*label) {
97                 if (*label == ' ') *p++ = '_';
98                 else *p++ = *label;
99                 ++label;
100         }
101         *p = '\0';
102         return parmname;
103 }
104
105 /****************************************************************************
106   include a lump of html in a page 
107 ****************************************************************************/
108 static int include_html(const char *fname)
109 {
110         int fd;
111         char buf[1024];
112         int ret;
113
114         fd = web_open(fname, O_RDONLY, 0);
115
116         if (fd == -1) {
117                 d_printf("ERROR: Can't open %s\n", fname);
118                 return 0;
119         }
120
121         while ((ret = read(fd, buf, sizeof(buf))) > 0) {
122                 write(1, buf, ret);
123         }
124
125         close(fd);
126         return 1;
127 }
128
129 /****************************************************************************
130   start the page with standard stuff 
131 ****************************************************************************/
132 static void print_header(void)
133 {
134         if (!cgi_waspost()) {
135                 d_printf("Expires: 0\r\n");
136         }
137         d_printf("Content-type: text/html\r\n\r\n");
138
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");
142         }
143 }
144
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)
162 {
163         const char* pTranslated = _(pLabel);
164         static pstring output;
165         if(strcmp(pLabel, pTranslated) != 0)
166         {
167                 snprintf(output, sizeof(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;
171         }
172         snprintf(output, sizeof(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;
176 }
177 /****************************************************************************
178  finish off the page 
179 ****************************************************************************/
180 static void print_footer(void)
181 {
182         if (!include_html("include/footer.html")) {
183                 d_printf("\n</BODY>\n</HTML>\n");
184         }
185 }
186
187 /****************************************************************************
188   display one editable parameter in a form 
189 ****************************************************************************/
190 static void show_parameter(int snum, struct parm_struct *parm)
191 {
192         int i;
193         void *ptr = parm->ptr;
194
195         if (parm->class == P_LOCAL && snum >= 0) {
196                 ptr = lp_local_ptr(snum, ptr);
197         }
198
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;
207
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))?" ":""));
215                         }
216                 }
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))?" ":""));
224                         }
225                 }
226                 d_printf("\'\">");
227                 break;
228
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;
236
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;
244
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;
253
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;
262
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;
268
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;
275
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);
281                         }
282                 }
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;
289         }
290         d_printf("</td></tr>\n");
291 }
292
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)
297 {
298         int i = 0;
299         struct parm_struct *parm;
300         const char *heading = NULL;
301         const char *last_heading = NULL;
302
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;
309                 }
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;
314                 }
315                 if (parm_filter == FLAG_BASIC) {
316                         if (!(parm->flags & FLAG_BASIC)) {
317                                 void *ptr = parm->ptr;
318
319                                 if (parm->class == P_LOCAL && snum >= 0) {
320                                         ptr = lp_local_ptr(snum, ptr);
321                                 }
322
323                                 switch (parm->type) {
324                                 case P_CHAR:
325                                         if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
326                                         break;
327
328                                 case P_LIST:
329                                         if (!str_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
330                                         break;
331
332                                 case P_STRING:
333                                 case P_USTRING:
334                                         if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
335                                         break;
336
337                                 case P_GSTRING:
338                                 case P_UGSTRING:
339                                         if (!strcmp((char *)ptr,(char *)(parm->def.svalue))) continue;
340                                         break;
341
342                                 case P_BOOL:
343                                 case P_BOOLREV:
344                                         if (*(BOOL *)ptr == (BOOL)(parm->def.bvalue)) continue;
345                                         break;
346
347                                 case P_INTEGER:
348                                 case P_OCTAL:
349                                         if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
350                                         break;
351
352
353                                 case P_ENUM:
354                                         if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
355                                         break;
356                                 case P_SEP:
357                                         continue;
358                                 }
359                         }
360                         if (printers && !(parm->flags & FLAG_PRINT)) continue;
361                 }
362                 if (parm_filter == FLAG_WIZARD) {
363                         if (!((parm->flags & FLAG_WIZARD))) continue;
364                 }
365                 if (parm_filter == FLAG_ADVANCED) {
366                         if (!((parm->flags & FLAG_ADVANCED))) continue;
367                 }
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;
371                 }
372                 show_parameter(snum, parm);
373         }
374 }
375
376 /****************************************************************************
377   load the smb.conf file into loadparm.
378 ****************************************************************************/
379 static BOOL load_config(BOOL save_def)
380 {
381         lp_resetnumservices();
382         return lp_load(dyn_CONFIGFILE,False,save_def,False);
383 }
384
385 /****************************************************************************
386   write a config file 
387 ****************************************************************************/
388 static void write_config(FILE *f, BOOL show_defaults)
389 {
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));
393         
394         lp_dump(f, show_defaults, iNumNonAutoPrintServices);
395 }
396
397 /****************************************************************************
398   save and reload the smb.conf config file 
399 ****************************************************************************/
400 static int save_reload(int snum)
401 {
402         FILE *f;
403         struct stat st;
404
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;
409         }
410
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
419         }
420
421         write_config(f, False);
422         if (snum)
423                 lp_dump_one(f, False, snum);
424         fclose(f);
425
426         lp_killunused(NULL);
427
428         if (!load_config(False)) {
429                 d_printf("Can't reload %s\n", dyn_CONFIGFILE);
430                 return 0;
431         }
432         iNumNonAutoPrintServices = lp_numservices();
433         load_printers();
434
435         return 1;
436 }
437
438 /****************************************************************************
439   commit one parameter 
440 ****************************************************************************/
441 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
442 {
443         int i;
444         char *s;
445
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);
454                         }
455                 }
456         }
457
458         lp_do_parameter(snum, parm->label, v);
459 }
460
461 /****************************************************************************
462   commit a set of parameters for a service 
463 ****************************************************************************/
464 static void commit_parameters(int snum)
465 {
466         int i = 0;
467         struct parm_struct *parm;
468         pstring label;
469         const char *v;
470
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); 
476                 }
477         }
478 }
479
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)
484 {
485         d_printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n", 
486                cgi_baseurl(), hlink, src, name);
487 }
488
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)
494 {
495         char *p;
496         
497         if ((p = cgi_user_name()) && strcmp(p, "root")) {
498                 d_printf(_("Logged in as <b>%s</b><p>\n"), p);
499         }
500
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");
507         }
508         if (have_read_access) {
509                 image_link(_("Status"), "status", "images/status.gif");
510                 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
511         }
512         image_link(_("Password Management"), "passwd", "images/passwd.gif");
513
514         d_printf("<HR>\n");
515 }
516
517 /****************************************************************************
518  * Handle Display/Edit Mode CGI
519  ****************************************************************************/
520 static void ViewModeBoxes(int mode)
521 {
522         d_printf("<p>%s\n", _("Configuration View:&nbsp"));
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("<input type=radio name=\"ViewMode\" value=2 %s>Developer\n", (mode == 2) ? "checked" : "");
526         d_printf("</p><br>\n");
527 }
528
529 /****************************************************************************
530   display a welcome page  
531 ****************************************************************************/
532 static void welcome_page(void)
533 {
534         include_html("help/welcome.html");
535 }
536
537 /****************************************************************************
538   display the current smb.conf  
539 ****************************************************************************/
540 static void viewconfig_page(void)
541 {
542         int full_view=0;
543
544         if (cgi_variable("full_view")) {
545                 full_view = 1;
546         }
547
548         d_printf("<H2>%s</H2>\n", _("Current Config"));
549         d_printf("<form method=post>\n");
550
551         if (full_view) {
552                 d_printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
553         } else {
554                 d_printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
555         }
556
557         d_printf("<p><pre>");
558         write_config(stdout, full_view);
559         d_printf("</pre>");
560         d_printf("</form>\n");
561 }
562
563 /****************************************************************************
564   second screen of the wizard ... Fetch Configuration Parameters
565 ****************************************************************************/
566 static void wizard_params_page(void)
567 {
568         unsigned int parm_filter = FLAG_WIZARD;
569
570         /* Here we first set and commit all the parameters that were selected
571            in the previous screen. */
572
573         d_printf("<H2>Wizard Parameter Edit Page</H2>\n");
574
575         if (cgi_variable("Commit")) {
576                 commit_parameters(GLOBAL_SECTION_SNUM);
577                 save_reload(0);
578         }
579
580         d_printf("<form name=\"swatform\" method=post action=wizard_params>\n");
581
582         if (have_write_access) {
583                 d_printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
584         }
585
586         d_printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
587         d_printf("<p>\n");
588         
589         d_printf("<table>\n");
590         show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
591         d_printf("</table>\n");
592         d_printf("</form>\n");
593 }
594
595 /****************************************************************************
596   Utility to just rewrite the smb.conf file - effectively just cleans it up
597 ****************************************************************************/
598 static void rewritecfg_file(void)
599 {
600         commit_parameters(GLOBAL_SECTION_SNUM);
601         save_reload(0);
602         d_printf("<H2>Note: smb.conf %s</H2>\n", _("file has been read and rewritten"));
603 }
604
605 /****************************************************************************
606   wizard to create/modify the smb.conf file
607 ****************************************************************************/
608 static void wizard_page(void)
609 {
610         /* Set some variables to collect data from smb.conf */
611         int role = 0;
612         int winstype = 0;
613         int have_home = -1;
614         int HomeExpo = 0;
615         int SerType = 0;
616
617         if (cgi_variable("Rewrite")) {
618                 (void) rewritecfg_file();
619                 return;
620         }
621
622         if (cgi_variable("GetWizardParams")){
623                 (void) wizard_params_page();
624                 return;
625         }
626
627         if (cgi_variable("Commit")){
628                 SerType = atoi(cgi_variable("ServerType"));
629                 winstype = atoi(cgi_variable("WINSType"));
630                 have_home = lp_servicenumber(HOMES_NAME);
631                 HomeExpo = atoi(cgi_variable("HomeExpo"));
632
633                 /* Plain text passwords are too badly broken - use encrypted passwords only */
634                 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
635                 
636                 switch ( SerType ){
637                         case 0:
638                                 /* Stand-alone Server */
639                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
640                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
641                                 break;
642                         case 1:
643                                 /* Domain Member */
644                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
645                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
646                                 break;
647                         case 2:
648                                 /* Domain Controller */
649                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
650                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
651                                 break;
652                 }
653                 switch ( winstype ) {
654                         case 0:
655                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
656                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
657                                 break;
658                         case 1:
659                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
660                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
661                                 break;
662                         case 2:
663                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
664                                 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable("WINSAddr"));
665                                 break;
666                 }
667
668                 /* Have to create Homes share? */
669                 if ((HomeExpo == 1) && (have_home == -1)) {
670                         pstring unix_share;
671                         
672                         pstrcpy(unix_share,HOMES_NAME);
673                         load_config(False);
674                         lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
675                         iNumNonAutoPrintServices = lp_numservices();
676                         have_home = lp_servicenumber(HOMES_NAME);
677                         lp_do_parameter( have_home, "read only", "No");
678                         lp_do_parameter( have_home, "valid users", "%S");
679                         lp_do_parameter( have_home, "browseable", "No");
680                         commit_parameters(have_home);
681                 }
682
683                 /* Need to Delete Homes share? */
684                 if ((HomeExpo == 0) && (have_home != -1)) {
685                         lp_remove_service(have_home);
686                         have_home = -1;
687                 }
688
689                 commit_parameters(GLOBAL_SECTION_SNUM);
690                 save_reload(0);
691         }
692         else
693         {
694                 /* Now determine smb.conf WINS settings */
695                 if (lp_wins_support())
696                         winstype = 1;
697                 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
698                         winstype = 2;
699                 
700
701                 /* Do we have a homes share? */
702                 have_home = lp_servicenumber(HOMES_NAME);
703         }
704         if ((winstype == 2) && lp_wins_support())
705                 winstype = 3;
706
707         role = lp_server_role();
708         
709         /* Here we go ... */
710         d_printf("<H2>Samba Configuration Wizard</H2>\n");
711         d_printf("<form method=post action=wizard>\n");
712
713         if (have_write_access) {
714                 d_printf(_("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments.\n"));
715                 d_printf(_("The same will happen if you press the commit button."));
716                 d_printf("<br><br>");
717                 d_printf("<center>");
718                 d_printf("<input type=submit name=\"Rewrite\" value=%s> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
719                 d_printf("<input type=submit name=\"Commit\" value=%s> &nbsp;&nbsp;",_("Commit"));
720                 d_printf("<input type=submit name=\"GetWizardParams\" value=%s>", _("Edit Parameter Values"));
721                 d_printf("</center>");
722         }
723
724         d_printf("<hr>");
725         d_printf("<center><table border=0>");
726         d_printf("<tr><td><b>%s</b></td>\n", "Server Type:&nbsp;");
727         d_printf("<td><input type=radio name=\"ServerType\" value=0 %s> Stand Alone&nbsp;</td>", (role == ROLE_STANDALONE) ? "checked" : "");
728         d_printf("<td><input type=radio name=\"ServerType\" value=1 %s> Domain Member&nbsp;</td>", (role == ROLE_DOMAIN_MEMBER) ? "checked" : ""); 
729         d_printf("<td><input type=radio name=\"ServerType\" value=2 %s> Domain Controller&nbsp;</td>", (role == ROLE_DOMAIN_PDC) ? "checked" : "");
730         d_printf("</tr>");
731         if (role == ROLE_DOMAIN_BDC) {
732                 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Unusual Type in smb.conf - Please Select New Mode</font></td></tr>");
733         }
734         d_printf("<tr><td><b>%s</b></td>\n", "Configure WINS As:&nbsp;");
735         d_printf("<td><input type=radio name=\"WINSType\" value=0 %s> Not Used&nbsp;</td>", (winstype == 0) ? "checked" : "");
736         d_printf("<td><input type=radio name=\"WINSType\" value=1 %s> Server for client use&nbsp;</td>", (winstype == 1) ? "checked" : "");
737         d_printf("<td><input type=radio name=\"WINSType\" value=2 %s> Client of another WINS server&nbsp;</td>", (winstype == 2) ? "checked" : "");
738         d_printf("<tr><td></td><td></td><td></td><td>Remote WINS Server&nbsp;<input type=text size=\"16\" name=\"WINSAddr\" value=\"%s\"></td></tr>",lp_wins_server_list());
739         if (winstype == 3) {
740                 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>");
741                 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Please Select desired WINS mode above.</font></td></tr>");
742         }
743         d_printf("</tr>");
744         d_printf("<tr><td><b>%s</b></td>\n","Expose Home Directories:&nbsp;");
745         d_printf("<td><input type=radio name=\"HomeExpo\" value=1 %s> Yes</td>", (have_home == -1) ? "" : "checked ");
746         d_printf("<td><input type=radio name=\"HomeExpo\" value=0 %s> No</td>", (have_home == -1 ) ? "checked" : "");
747         d_printf("<td></td></tr>");
748         
749         /* Enable this when we are ready ....
750          * d_printf("<tr><td><b>%s</b></td>\n","Is Print Server:&nbsp;");
751          * d_printf("<td><input type=radio name=\"PtrSvr\" value=1 %s> Yes</td>");
752          * d_printf("<td><input type=radio name=\"PtrSvr\" value=0 %s> No</td>");
753          * d_printf("<td></td></tr>");
754          */
755         
756         d_printf("</table></center>");
757         d_printf("<hr>");
758
759         d_printf(_("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment.\n"));
760         d_printf("</form>\n");
761 }
762
763
764 /****************************************************************************
765   display a globals editing page  
766 ****************************************************************************/
767 static void globals_page(void)
768 {
769         unsigned int parm_filter = FLAG_BASIC;
770         int mode = 0;
771
772         d_printf("<H2>%s</H2>\n", _("Global Variables"));
773
774         if (cgi_variable("Commit")) {
775                 commit_parameters(GLOBAL_SECTION_SNUM);
776                 save_reload(0);
777         }
778
779         if ( cgi_variable("ViewMode") )
780                 mode = atoi(cgi_variable("ViewMode"));
781
782         d_printf("<form name=\"swatform\" method=post action=globals>\n");
783
784         ViewModeBoxes( mode );
785         switch ( mode ) {
786                 case 0:
787                         parm_filter = FLAG_BASIC;
788                         break;
789                 case 1:
790                         parm_filter = FLAG_ADVANCED;
791                         break;
792                 case 2:
793                         parm_filter = FLAG_DEVELOPER;
794                         break;
795         }
796         d_printf("<br>\n");
797         if (have_write_access) {
798                 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
799                         _("Commit Changes"));
800         }
801
802         d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", 
803                  _("Reset Values"));
804
805         d_printf("<p>\n");
806         d_printf("<table>\n");
807         show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
808         d_printf("</table>\n");
809         d_printf("</form>\n");
810 }
811
812 /****************************************************************************
813   display a shares editing page. share is in unix codepage, and must be in
814   dos codepage. FIXME !!! JRA.
815 ****************************************************************************/
816 static void shares_page(void)
817 {
818         const char *share = cgi_variable("share");
819         char *s;
820         int snum = -1;
821         int i;
822         int mode = 0;
823         unsigned int parm_filter = FLAG_BASIC;
824
825         if (share)
826                 snum = lp_servicenumber(share);
827
828         d_printf("<H2>%s</H2>\n", _("Share Parameters"));
829
830         if (cgi_variable("Commit") && snum >= 0) {
831                 commit_parameters(snum);
832                 save_reload(0);
833         }
834
835         if (cgi_variable("Delete") && snum >= 0) {
836                 lp_remove_service(snum);
837                 save_reload(0);
838                 share = NULL;
839                 snum = -1;
840         }
841
842         if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
843                 load_config(False);
844                 lp_copy_service(GLOBAL_SECTION_SNUM, share);
845                 iNumNonAutoPrintServices = lp_numservices();
846                 save_reload(0);
847                 snum = lp_servicenumber(share);
848         }
849
850         d_printf("<FORM name=\"swatform\" method=post>\n");
851
852         d_printf("<table>\n");
853         if ( cgi_variable("ViewMode") )
854                 mode = atoi(cgi_variable("ViewMode"));
855         ViewModeBoxes( mode );
856         switch ( mode ) {
857                 case 0:
858                         parm_filter = FLAG_BASIC;
859                         break;
860                 case 1:
861                         parm_filter = FLAG_ADVANCED;
862                         break;
863                 case 2:
864                         parm_filter = FLAG_DEVELOPER;
865                         break;
866         }
867         d_printf("<br><tr>\n");
868         d_printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
869         d_printf("<td><select name=share>\n");
870         if (snum < 0)
871                 d_printf("<option value=\" \"> \n");
872         for (i=0;i<lp_numservices();i++) {
873                 s = lp_servicename(i);
874                 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
875                         d_printf("<option %s value=\"%s\">%s\n", 
876                                (share && strcmp(share,s)==0)?"SELECTED":"",
877                                s, s);
878                 }
879         }
880         d_printf("</select></td>\n");
881         if (have_write_access) {
882                 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
883         }
884         d_printf("</tr>\n");
885         d_printf("</table>");
886         d_printf("<table>");
887         if (have_write_access) {
888                 d_printf("<tr>\n");
889                 d_printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
890                 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
891         }
892         d_printf("</table>");
893
894
895         if (snum >= 0) {
896                 if (have_write_access) {
897                         d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
898                 }
899
900                 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
901                 d_printf("<p>\n");
902         }
903
904         if (snum >= 0) {
905                 d_printf("<table>\n");
906                 show_parameters(snum, 1, parm_filter, 0);
907                 d_printf("</table>\n");
908         }
909
910         d_printf("</FORM>\n");
911 }
912
913 /*************************************************************
914 change a password either locally or remotely
915 *************************************************************/
916 static BOOL change_password(const char *remote_machine, const char *user_name, 
917                             const char *old_passwd, const char *new_passwd, 
918                                 int local_flags)
919 {
920         BOOL ret = False;
921         pstring err_str;
922         pstring msg_str;
923
924         if (demo_mode) {
925                 d_printf("%s<p>", _("password change in demo mode rejected\n"));
926                 return False;
927         }
928         
929         if (remote_machine != NULL) {
930                 ret = remote_password_change(remote_machine, user_name, old_passwd, 
931                                                                          new_passwd, err_str, sizeof(err_str));
932                 if(*err_str)
933                         d_printf("%s\n<p>", err_str);
934                 return ret;
935         }
936
937         if(!initialize_password_db(True)) {
938                 d_printf("Can't setup password database vectors.\n<p>");
939                 return False;
940         }
941         
942         ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
943                                          msg_str, sizeof(msg_str));
944
945         if(*msg_str)
946                 d_printf("%s\n<p>", msg_str);
947         if(*err_str)
948                 d_printf("%s\n<p>", err_str);
949
950         return ret;
951 }
952
953 /****************************************************************************
954   do the stuff required to add or change a password 
955 ****************************************************************************/
956 static void chg_passwd(void)
957 {
958         const char *host;
959         BOOL rslt;
960         int local_flags = 0;
961
962         /* Make sure users name has been specified */
963         if (strlen(cgi_variable(SWAT_USER)) == 0) {
964                 d_printf("<p>%s", _(" Must specify \"User Name\" \n"));
965                 return;
966         }
967
968         /*
969          * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
970          * so if that's what we're doing, skip the rest of the checks
971          */
972         if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
973
974                 /*
975                  * If current user is not root, make sure old password has been specified 
976                  * If REMOTE change, even root must provide old password 
977                  */
978                 if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
979                     ((cgi_variable(CHG_R_PASSWD_FLAG)) &&  (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
980                         d_printf("<p>%s", _(" Must specify \"Old Password\" \n"));
981                         return;
982                 }
983
984                 /* If changing a users password on a remote hosts we have to know what host */
985                 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
986                         d_printf("<p>%s", _(" Must specify \"Remote Machine\" \n"));
987                         return;
988                 }
989
990                 /* Make sure new passwords have been specified */
991                 if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
992                     (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
993                         d_printf("<p>%s", _(" Must specify \"New, and Re-typed Passwords\" \n"));
994                         return;
995                 }
996
997                 /* Make sure new passwords was typed correctly twice */
998                 if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
999                         d_printf("<p>%s", _(" Re-typed password didn't match new password\n"));
1000                         return;
1001                 }
1002         }
1003
1004         if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1005                 host = cgi_variable(RHOST);
1006         } else if (am_root()) {
1007                 host = NULL;
1008         } else {
1009                 host = "127.0.0.1";
1010         }
1011
1012         /*
1013          * Set up the local flags.
1014          */
1015
1016         local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1017         local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1018         local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1019         local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1020
1021         rslt = change_password(host,
1022                                cgi_variable(SWAT_USER),
1023                                cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
1024                                    local_flags);
1025
1026         if(local_flags == 0) {
1027                 d_printf("<p>");
1028                 if (rslt == True) {
1029                         d_printf(_(" The passwd for '%s' has been changed. \n"), cgi_variable(SWAT_USER));
1030                 } else {
1031                         d_printf(_(" The passwd for '%s' has NOT been changed. \n"), cgi_variable(SWAT_USER));
1032                 }
1033         }
1034         
1035         return;
1036 }
1037
1038 /****************************************************************************
1039   display a password editing page  
1040 ****************************************************************************/
1041 static void passwd_page(void)
1042 {
1043         const char *new_name = cgi_user_name();
1044
1045         /* 
1046          * After the first time through here be nice. If the user
1047          * changed the User box text to another users name, remember it.
1048          */
1049         if (cgi_variable(SWAT_USER)) {
1050                 new_name = cgi_variable(SWAT_USER);
1051         } 
1052
1053         if (!new_name) new_name = "";
1054
1055         d_printf("<H2>%s</H2>\n", _("Server Password Management"));
1056
1057         d_printf("<FORM name=\"swatform\" method=post>\n");
1058
1059         d_printf("<table>\n");
1060
1061         /* 
1062          * Create all the dialog boxes for data collection
1063          */
1064         d_printf("<tr><td>%s</td>\n", _(" User Name : "));
1065         d_printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1066         if (!am_root()) {
1067                 d_printf("<tr><td>%s</td>\n", _(" Old Password : "));
1068                 d_printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1069         }
1070         d_printf("<tr><td>%s</td>\n", _(" New Password : "));
1071         d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1072         d_printf("<tr><td>%s</td>\n", _(" Re-type New Password : "));
1073         d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1074         d_printf("</table>\n");
1075
1076         /*
1077          * Create all the control buttons for requesting action
1078          */
1079         d_printf("<input type=submit name=%s value=\"%s\">\n", 
1080                CHG_S_PASSWD_FLAG, _("Change Password"));
1081         if (demo_mode || am_root()) {
1082                 d_printf("<input type=submit name=%s value=\"%s\">\n",
1083                        ADD_USER_FLAG, _("Add New User"));
1084                 d_printf("<input type=submit name=%s value=\"%s\">\n",
1085                        DELETE_USER_FLAG, _("Delete User"));
1086                 d_printf("<input type=submit name=%s value=\"%s\">\n", 
1087                        DISABLE_USER_FLAG, _("Disable User"));
1088                 d_printf("<input type=submit name=%s value=\"%s\">\n", 
1089                        ENABLE_USER_FLAG, _("Enable User"));
1090         }
1091         d_printf("<p></FORM>\n");
1092
1093         /*
1094          * Do some work if change, add, disable or enable was
1095          * requested. It could be this is the first time through this
1096          * code, so there isn't anything to do.  */
1097         if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1098             (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1099                 chg_passwd();           
1100         }
1101
1102         d_printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1103
1104         d_printf("<FORM name=\"swatform\" method=post>\n");
1105
1106         d_printf("<table>\n");
1107
1108         /* 
1109          * Create all the dialog boxes for data collection
1110          */
1111         d_printf("<tr><td>%s</td>\n", _(" User Name : "));
1112         d_printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1113         d_printf("<tr><td>%s</td>\n", _(" Old Password : "));
1114         d_printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1115         d_printf("<tr><td>%s</td>\n", _(" New Password : "));
1116         d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1117         d_printf("<tr><td>%s</td>\n", _(" Re-type New Password : "));
1118         d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1119         d_printf("<tr><td>%s</td>\n", _(" Remote Machine : "));
1120         d_printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1121
1122         d_printf("</table>");
1123
1124         /*
1125          * Create all the control buttons for requesting action
1126          */
1127         d_printf("<input type=submit name=%s value=\"%s\">", 
1128                CHG_R_PASSWD_FLAG, _("Change Password"));
1129
1130         d_printf("<p></FORM>\n");
1131
1132         /*
1133          * Do some work if a request has been made to change the
1134          * password somewhere other than the server. It could be this
1135          * is the first time through this code, so there isn't
1136          * anything to do.  */
1137         if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1138                 chg_passwd();           
1139         }
1140
1141 }
1142
1143 /****************************************************************************
1144   display a printers editing page  
1145 ****************************************************************************/
1146 static void printers_page(void)
1147 {
1148         const char *share = cgi_variable("share");
1149         char *s;
1150         int snum=-1;
1151         int i;
1152         int mode = 0;
1153         unsigned int parm_filter = FLAG_BASIC;
1154
1155         if (share)
1156                 snum = lp_servicenumber(share);
1157
1158         d_printf("<H2>%s</H2>\n", _("Printer Parameters"));
1159  
1160         d_printf("<H3>%s</H3>\n", _("Important Note:"));
1161         d_printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
1162         d_printf(_("are autoloaded printers from "));
1163         d_printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1164         d_printf(_("Attempting to delete these printers from SWAT will have no effect.\n"));
1165
1166         if (cgi_variable("Commit") && snum >= 0) {
1167                 commit_parameters(snum);
1168                 if (snum >= iNumNonAutoPrintServices)
1169                     save_reload(snum);
1170                 else
1171                     save_reload(0);
1172         }
1173
1174         if (cgi_variable("Delete") && snum >= 0) {
1175                 lp_remove_service(snum);
1176                 save_reload(0);
1177                 share = NULL;
1178                 snum = -1;
1179         }
1180
1181         if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1182                 load_config(False);
1183                 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1184                 iNumNonAutoPrintServices = lp_numservices();
1185                 snum = lp_servicenumber(share);
1186                 lp_do_parameter(snum, "print ok", "Yes");
1187                 save_reload(0);
1188                 snum = lp_servicenumber(share);
1189         }
1190
1191         d_printf("<FORM name=\"swatform\" method=post>\n");
1192
1193         if ( cgi_variable("ViewMode") )
1194                 mode = atoi(cgi_variable("ViewMode"));
1195         ViewModeBoxes( mode );
1196         switch ( mode ) {
1197                 case 0:
1198                         parm_filter = FLAG_BASIC;
1199                         break;
1200                 case 1:
1201                         parm_filter = FLAG_ADVANCED;
1202                         break;
1203                 case 2:
1204                         parm_filter = FLAG_DEVELOPER;
1205                         break;
1206         }
1207         d_printf("<table>\n");
1208         d_printf("<tr><td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Printer"));
1209         d_printf("<td><select name=share>\n");
1210         if (snum < 0 || !lp_print_ok(snum))
1211                 d_printf("<option value=\" \"> \n");
1212         for (i=0;i<lp_numservices();i++) {
1213                 s = lp_servicename(i);
1214                 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1215                     if (i >= iNumNonAutoPrintServices)
1216                         d_printf("<option %s value=\"%s\">[*]%s\n",
1217                                (share && strcmp(share,s)==0)?"SELECTED":"",
1218                                s, s);
1219                     else
1220                         d_printf("<option %s value=\"%s\">%s\n", 
1221                                (share && strcmp(share,s)==0)?"SELECTED":"",
1222                                s, s);
1223                 }
1224         }
1225         d_printf("</select></td>");
1226         if (have_write_access) {
1227                 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1228         }
1229         d_printf("</tr>");
1230         d_printf("</table>\n");
1231
1232         if (have_write_access) {
1233                 d_printf("<table>\n");
1234                 d_printf("<tr><td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Printer"));
1235                 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1236                 d_printf("</table>");
1237         }
1238
1239
1240         if (snum >= 0) {
1241                 if (have_write_access) {
1242                         d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1243                 }
1244                 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1245                 d_printf("<p>\n");
1246         }
1247
1248         if (snum >= 0) {
1249                 d_printf("<table>\n");
1250                 show_parameters(snum, 1, parm_filter, 1);
1251                 d_printf("</table>\n");
1252         }
1253         d_printf("</FORM>\n");
1254 }
1255
1256
1257 /**
1258  * main function for SWAT.
1259  **/
1260  int main(int argc, char *argv[])
1261 {
1262         int opt;
1263         const char *page;
1264         poptContext pc;
1265         struct poptOption long_options[] = {
1266                 POPT_AUTOHELP
1267                 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1268                 POPT_COMMON_SAMBA
1269                 POPT_TABLEEND
1270         };
1271
1272         fault_setup(NULL);
1273         umask(S_IWGRP | S_IWOTH);
1274
1275 #if defined(HAVE_SET_AUTH_PARAMETERS)
1276         set_auth_parameters(argc, argv);
1277 #endif /* HAVE_SET_AUTH_PARAMETERS */
1278
1279         /* just in case it goes wild ... */
1280         alarm(300);
1281
1282         setlinebuf(stdout);
1283
1284         /* we don't want any SIGPIPE messages */
1285         BlockSignals(True,SIGPIPE);
1286
1287         dbf = x_fopen("/dev/null", O_WRONLY, 0);
1288         if (!dbf) dbf = x_stderr;
1289
1290         /* we don't want stderr screwing us up */
1291         close(2);
1292         open("/dev/null", O_WRONLY);
1293
1294         pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1295
1296         /* Parse command line options */
1297
1298         while((opt = poptGetNextOpt(pc)) != -1) { }
1299
1300         poptFreeContext(pc);
1301
1302         setup_logging(argv[0],False);
1303         load_config(True);
1304         iNumNonAutoPrintServices = lp_numservices();
1305         load_printers();
1306
1307         cgi_setup(dyn_SWATDIR, !demo_mode);
1308
1309         print_header();
1310
1311         cgi_load_variables();
1312
1313         if (!file_exist(dyn_CONFIGFILE, NULL)) {
1314                 have_read_access = True;
1315                 have_write_access = True;
1316         } else {
1317                 /* check if the authenticated user has write access - if not then
1318                    don't show write options */
1319                 have_write_access = (access(dyn_CONFIGFILE,W_OK) == 0);
1320
1321                 /* if the user doesn't have read access to smb.conf then
1322                    don't let them view it */
1323                 have_read_access = (access(dyn_CONFIGFILE,R_OK) == 0);
1324         }
1325
1326         show_main_buttons();
1327
1328         page = cgi_pathinfo();
1329
1330         /* Root gets full functionality */
1331         if (have_read_access && strcmp(page, "globals")==0) {
1332                 globals_page();
1333         } else if (have_read_access && strcmp(page,"shares")==0) {
1334                 shares_page();
1335         } else if (have_read_access && strcmp(page,"printers")==0) {
1336                 printers_page();
1337         } else if (have_read_access && strcmp(page,"status")==0) {
1338                 status_page();
1339         } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1340                 viewconfig_page();
1341         } else if (strcmp(page,"passwd")==0) {
1342                 passwd_page();
1343         } else if (have_read_access && strcmp(page,"wizard")==0) {
1344                 wizard_page();
1345         } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1346                 wizard_params_page();
1347         } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1348                 rewritecfg_file();
1349         } else {
1350                 welcome_page();
1351         }
1352
1353         print_footer();
1354         return 0;
1355 }
1356
1357 /** @} **/