sync 3.0 into HEAD for the last time
[metze/samba/wip.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                 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;
171         }
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;
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
316                 if (!( parm_filter & FLAG_ADVANCED )) {
317                         if (!(parm->flags & FLAG_BASIC)) {
318                                         void *ptr = parm->ptr;
319
320                                 if (parm->class == P_LOCAL && snum >= 0) {
321                                         ptr = lp_local_ptr(snum, ptr);
322                                 }
323
324                                 switch (parm->type) {
325                                 case P_CHAR:
326                                         if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
327                                         break;
328
329                                 case P_LIST:
330                                         if (!str_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
331                                         break;
332
333                                 case P_STRING:
334                                 case P_USTRING:
335                                         if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
336                                         break;
337
338                                 case P_GSTRING:
339                                 case P_UGSTRING:
340                                         if (!strcmp((char *)ptr,(char *)(parm->def.svalue))) continue;
341                                         break;
342
343                                 case P_BOOL:
344                                 case P_BOOLREV:
345                                         if (*(BOOL *)ptr == (BOOL)(parm->def.bvalue)) continue;
346                                         break;
347
348                                 case P_INTEGER:
349                                 case P_OCTAL:
350                                         if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
351                                         break;
352
353
354                                 case P_ENUM:
355                                         if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
356                                         break;
357                                 case P_SEP:
358                                         continue;
359                                         }
360                         }
361                         if (printers && !(parm->flags & FLAG_PRINT)) continue;
362                 }
363
364                 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
365                 
366                 if ((parm_filter & FLAG_ADVANCED) && !(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", _("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");
529 }
530
531 /****************************************************************************
532   display a welcome page  
533 ****************************************************************************/
534 static void welcome_page(void)
535 {
536         include_html("help/welcome.html");
537 }
538
539 /****************************************************************************
540   display the current smb.conf  
541 ****************************************************************************/
542 static void viewconfig_page(void)
543 {
544         int full_view=0;
545
546         if (cgi_variable("full_view")) {
547                 full_view = 1;
548         }
549
550         d_printf("<H2>%s</H2>\n", _("Current Config"));
551         d_printf("<form method=post>\n");
552
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"));
557         }
558
559         d_printf("<p><pre>");
560         write_config(stdout, full_view);
561         d_printf("</pre>");
562         d_printf("</form>\n");
563 }
564
565 /****************************************************************************
566   second screen of the wizard ... Fetch Configuration Parameters
567 ****************************************************************************/
568 static void wizard_params_page(void)
569 {
570         unsigned int parm_filter = FLAG_WIZARD;
571
572         /* Here we first set and commit all the parameters that were selected
573            in the previous screen. */
574
575         d_printf("<H2>Wizard Parameter Edit Page</H2>\n");
576
577         if (cgi_variable("Commit")) {
578                 commit_parameters(GLOBAL_SECTION_SNUM);
579                 save_reload(0);
580         }
581
582         d_printf("<form name=\"swatform\" method=post action=wizard_params>\n");
583
584         if (have_write_access) {
585                 d_printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
586         }
587
588         d_printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
589         d_printf("<p>\n");
590         
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");
595 }
596
597 /****************************************************************************
598   Utility to just rewrite the smb.conf file - effectively just cleans it up
599 ****************************************************************************/
600 static void rewritecfg_file(void)
601 {
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"));
605 }
606
607 /****************************************************************************
608   wizard to create/modify the smb.conf file
609 ****************************************************************************/
610 static void wizard_page(void)
611 {
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;
618
619         if (cgi_variable("Rewrite")) {
620                 (void) rewritecfg_file();
621                 return;
622         }
623
624         if (cgi_variable("GetWizardParams")){
625                 (void) wizard_params_page();
626                 return;
627         }
628
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"));
634
635                 /* Plain text passwords are too badly broken - use encrypted passwords only */
636                 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
637                 
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;
654                 }
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;
668                 }
669
670                 /* Have to create Homes share? */
671                 if ((HomeExpo == 1) && (have_home == -1)) {
672                         pstring unix_share;
673                         
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);
683                 }
684
685                 /* Need to Delete Homes share? */
686                 if ((HomeExpo == 0) && (have_home != -1)) {
687                         lp_remove_service(have_home);
688                         have_home = -1;
689                 }
690
691                 commit_parameters(GLOBAL_SECTION_SNUM);
692                 save_reload(0);
693         }
694         else
695         {
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;
701                 
702
703                 /* Do we have a homes share? */
704                 have_home = lp_servicenumber(HOMES_NAME);
705         }
706         if ((winstype == 2) && lp_wins_support())
707                 winstype = 3;
708
709         role = lp_server_role();
710         
711         /* Here we go ... */
712         d_printf("<H2>Samba Configuration Wizard</H2>\n");
713         d_printf("<form method=post action=wizard>\n");
714
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>");
724         }
725
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>");
735         }
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=\"");
741         
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]);
747         }
748         
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>");
753         }
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>");
759         
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>");
765          */
766         
767         d_printf("</table></center>");
768         d_printf("<hr>");
769
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");
772 }
773
774
775 /****************************************************************************
776   display a globals editing page  
777 ****************************************************************************/
778 static void globals_page(void)
779 {
780         unsigned int parm_filter = FLAG_BASIC;
781         int mode = 0;
782
783         d_printf("<H2>%s</H2>\n", _("Global Variables"));
784
785         if (cgi_variable("Commit")) {
786                 commit_parameters(GLOBAL_SECTION_SNUM);
787                 save_reload(0);
788         }
789
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;
796
797         d_printf("<form name=\"swatform\" method=post action=globals>\n");
798
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;
807         }
808         d_printf("<br>\n");
809         if (have_write_access) {
810                 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
811                         _("Commit Changes"));
812         }
813
814         d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", 
815                  _("Reset Values"));
816
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");
822 }
823
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)
829 {
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;
836
837         if (share)
838                 snum = lp_servicenumber(share);
839
840         d_printf("<H2>%s</H2>\n", _("Share Parameters"));
841
842         if (cgi_variable("Commit") && snum >= 0) {
843                 commit_parameters(snum);
844                 save_reload(0);
845         }
846
847         if (cgi_variable("Delete") && snum >= 0) {
848                 lp_remove_service(snum);
849                 save_reload(0);
850                 share = NULL;
851                 snum = -1;
852         }
853
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);
860         }
861
862         d_printf("<FORM name=\"swatform\" method=post>\n");
863
864         d_printf("<table>\n");
865
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;
872
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;
881         }
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);
893                 }
894         }
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"));
898         }
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");
906         }
907         d_printf("</table>");
908
909
910         if (snum >= 0) {
911                 if (have_write_access) {
912                         d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
913                 }
914
915                 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
916                 d_printf("<p>\n");
917         }
918
919         if (snum >= 0) {
920                 d_printf("<table>\n");
921                 show_parameters(snum, 1, parm_filter, 0);
922                 d_printf("</table>\n");
923         }
924
925         d_printf("</FORM>\n");
926 }
927
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)
934 {
935         BOOL ret = False;
936         pstring err_str;
937         pstring msg_str;
938
939         if (demo_mode) {
940                 d_printf("%s<p>", _("password change in demo mode rejected\n"));
941                 return False;
942         }
943         
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;
950         }
951
952         if(!initialize_password_db(True)) {
953                 d_printf("Can't setup password database vectors.\n<p>");
954                 return False;
955         }
956         
957         ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
958                                          msg_str, sizeof(msg_str));
959
960         if(*msg_str)
961                 d_printf("%s\n<p>", msg_str);
962         if(*err_str)
963                 d_printf("%s\n<p>", err_str);
964
965         return ret;
966 }
967
968 /****************************************************************************
969   do the stuff required to add or change a password 
970 ****************************************************************************/
971 static void chg_passwd(void)
972 {
973         const char *host;
974         BOOL rslt;
975         int local_flags = 0;
976
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;
981         }
982
983         /*
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
986          */
987         if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
988
989                 /*
990                  * If current user is not root, make sure old password has been specified 
991                  * If REMOTE change, even root must provide old password 
992                  */
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;
997                 }
998
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;
1003                 }
1004
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;
1010                 }
1011
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;
1016                 }
1017         }
1018
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";
1025         }
1026
1027         /*
1028          * Set up the local flags.
1029          */
1030
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);
1035
1036         rslt = change_password(host,
1037                                cgi_variable(SWAT_USER),
1038                                cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
1039                                    local_flags);
1040
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));
1047                 }
1048         }
1049         
1050         return;
1051 }
1052
1053 /****************************************************************************
1054   display a password editing page  
1055 ****************************************************************************/
1056 static void passwd_page(void)
1057 {
1058         const char *new_name = cgi_user_name();
1059
1060         /* 
1061          * After the first time through here be nice. If the user
1062          * changed the User box text to another users name, remember it.
1063          */
1064         if (cgi_variable(SWAT_USER)) {
1065                 new_name = cgi_variable(SWAT_USER);
1066         } 
1067
1068         if (!new_name) new_name = "";
1069
1070         d_printf("<H2>%s</H2>\n", _("Server Password Management"));
1071
1072         d_printf("<FORM name=\"swatform\" method=post>\n");
1073
1074         d_printf("<table>\n");
1075
1076         /* 
1077          * Create all the dialog boxes for data collection
1078          */
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);
1084         }
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");
1090
1091         /*
1092          * Create all the control buttons for requesting action
1093          */
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"));
1105         }
1106         d_printf("<p></FORM>\n");
1107
1108         /*
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();           
1115         }
1116
1117         d_printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1118
1119         d_printf("<FORM name=\"swatform\" method=post>\n");
1120
1121         d_printf("<table>\n");
1122
1123         /* 
1124          * Create all the dialog boxes for data collection
1125          */
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);
1136
1137         d_printf("</table>");
1138
1139         /*
1140          * Create all the control buttons for requesting action
1141          */
1142         d_printf("<input type=submit name=%s value=\"%s\">", 
1143                CHG_R_PASSWD_FLAG, _("Change Password"));
1144
1145         d_printf("<p></FORM>\n");
1146
1147         /*
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();           
1154         }
1155
1156 }
1157
1158 /****************************************************************************
1159   display a printers editing page  
1160 ****************************************************************************/
1161 static void printers_page(void)
1162 {
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;
1169
1170         if (share)
1171                 snum = lp_servicenumber(share);
1172
1173         d_printf("<H2>%s</H2>\n", _("Printer Parameters"));
1174  
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"));
1180
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);
1187         }
1188
1189         if (cgi_variable("Delete") && snum >= 0) {
1190                 lp_remove_service(snum);
1191                 save_reload(0);
1192                 share = NULL;
1193                 snum = -1;
1194         }
1195
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);
1204         }
1205
1206         d_printf("<FORM name=\"swatform\" method=post>\n");
1207
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;
1214
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;
1223         }
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);
1240                 }
1241         }
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"));
1245         }
1246         d_printf("</tr>");
1247         d_printf("</table>\n");
1248
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>");
1254         }
1255
1256
1257         if (snum >= 0) {
1258                 if (have_write_access) {
1259                         d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1260                 }
1261                 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1262                 d_printf("<p>\n");
1263         }
1264
1265         if (snum >= 0) {
1266                 d_printf("<table>\n");
1267                 show_parameters(snum, 1, parm_filter, 1);
1268                 d_printf("</table>\n");
1269         }
1270         d_printf("</FORM>\n");
1271 }
1272
1273
1274 /**
1275  * main function for SWAT.
1276  **/
1277  int main(int argc, char *argv[])
1278 {
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
1287         };
1288
1289         fault_setup(NULL);
1290         umask(S_IWGRP | S_IWOTH);
1291
1292 #if defined(HAVE_SET_AUTH_PARAMETERS)
1293         set_auth_parameters(argc, argv);
1294 #endif /* HAVE_SET_AUTH_PARAMETERS */
1295
1296         /* just in case it goes wild ... */
1297         alarm(300);
1298
1299         setlinebuf(stdout);
1300
1301         /* we don't want any SIGPIPE messages */
1302         BlockSignals(True,SIGPIPE);
1303
1304         dbf = x_fopen("/dev/null", O_WRONLY, 0);
1305         if (!dbf) dbf = x_stderr;
1306
1307         /* we don't want stderr screwing us up */
1308         close(2);
1309         open("/dev/null", O_WRONLY);
1310
1311         pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1312
1313         /* Parse command line options */
1314
1315         while((opt = poptGetNextOpt(pc)) != -1) { }
1316
1317         poptFreeContext(pc);
1318
1319         setup_logging(argv[0],False);
1320         load_config(True);
1321         iNumNonAutoPrintServices = lp_numservices();
1322         load_printers();
1323
1324         cgi_setup(dyn_SWATDIR, !demo_mode);
1325
1326         print_header();
1327
1328         cgi_load_variables();
1329
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);
1337
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);
1341         }
1342
1343         show_main_buttons();
1344
1345         page = cgi_pathinfo();
1346
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();
1368         }
1369
1370         print_footer();
1371         return 0;
1372 }
1373
1374 /** @} **/