Make swat use popt
[ira/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 #define GLOBALS_SNUM -1
35
36 static BOOL demo_mode = False;
37 static BOOL have_write_access = False;
38 static BOOL have_read_access = False;
39 static int iNumNonAutoPrintServices = 0;
40
41 /*
42  * Password Management Globals
43  */
44 #define SWAT_USER "username"
45 #define OLD_PSWD "old_passwd"
46 #define NEW_PSWD "new_passwd"
47 #define NEW2_PSWD "new2_passwd"
48 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
49 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
50 #define ADD_USER_FLAG "add_user_flag"
51 #define DELETE_USER_FLAG "delete_user_flag"
52 #define DISABLE_USER_FLAG "disable_user_flag"
53 #define ENABLE_USER_FLAG "enable_user_flag"
54 #define RHOST "remote_host"
55
56 /* we need these because we link to locking*.o */
57  void become_root(void) {}
58  void unbecome_root(void) {}
59
60 /****************************************************************************
61 ****************************************************************************/
62 static int enum_index(int value, const struct enum_list *enumlist)
63 {
64         int i;
65         for (i=0;enumlist[i].name;i++)
66                 if (value == enumlist[i].value) break;
67         return(i);
68 }
69
70 static char *fix_backslash(const char *str)
71 {
72         static char newstring[1024];
73         char *p = newstring;
74
75         while (*str) {
76                 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
77                 else *p++ = *str;
78                 ++str;
79         }
80         *p = '\0';
81         return newstring;
82 }
83
84 static char *stripspaceupper(const char *str)
85 {
86         static char newstring[1024];
87         char *p = newstring;
88
89         while (*str) {
90                 if (*str != ' ') *p++ = toupper(*str);
91                 ++str;
92         }
93         *p = '\0';
94         return newstring;
95 }
96
97 static char *make_parm_name(const char *label)
98 {
99         static char parmname[1024];
100         char *p = parmname;
101
102         while (*label) {
103                 if (*label == ' ') *p++ = '_';
104                 else *p++ = *label;
105                 ++label;
106         }
107         *p = '\0';
108         return parmname;
109 }
110
111 /****************************************************************************
112   include a lump of html in a page 
113 ****************************************************************************/
114 static int include_html(const char *fname)
115 {
116         int fd;
117         char buf[1024];
118         int ret;
119
120         fd = web_open(fname, O_RDONLY, 0);
121
122         if (fd == -1) {
123                 d_printf("ERROR: Can't open %s\n", fname);
124                 return 0;
125         }
126
127         while ((ret = read(fd, buf, sizeof(buf))) > 0) {
128                 write(1, buf, ret);
129         }
130
131         close(fd);
132         return 1;
133 }
134
135 /****************************************************************************
136   start the page with standard stuff 
137 ****************************************************************************/
138 static void print_header(void)
139 {
140         if (!cgi_waspost()) {
141                 d_printf("Expires: 0\r\n");
142         }
143         d_printf("Content-type: text/html\r\n\r\n");
144
145         if (!include_html("include/header.html")) {
146                 d_printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
147                 d_printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
148         }
149 }
150
151 /* *******************************************************************
152    show parameter label with translated name in the following form
153    because showing original and translated label in one line looks
154    too long, and showing translated label only is unusable for
155    heavy users.
156    -------------------------------
157    HELP       security   [combo box][button]
158    SECURITY
159    -------------------------------
160    (capital words are translated by gettext.)
161    if no translation is available, then same form as original is
162    used.
163    "i18n_translated_parm" class is used to change the color of the
164    translated parameter with CSS.
165    **************************************************************** */
166 static const char* get_parm_translated(
167         const char* pAnchor, const char* pHelp, const char* pLabel)
168 {
169         const char* pTranslated = _(pLabel);
170         static pstring output;
171         if(strcmp(pLabel, pTranslated) != 0)
172         {
173                 snprintf(output, sizeof(output),
174                   "<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>",
175                    pAnchor, pHelp, pLabel, pTranslated);
176                 return output;
177         }
178         snprintf(output, sizeof(output), 
179           "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
180           pAnchor, pHelp, pLabel);
181         return output;
182 }
183 /****************************************************************************
184  finish off the page 
185 ****************************************************************************/
186 static void print_footer(void)
187 {
188         if (!include_html("include/footer.html")) {
189                 d_printf("\n</BODY>\n</HTML>\n");
190         }
191 }
192
193 /****************************************************************************
194   display one editable parameter in a form 
195 ****************************************************************************/
196 static void show_parameter(int snum, struct parm_struct *parm)
197 {
198         int i;
199         void *ptr = parm->ptr;
200
201         if (parm->class == P_LOCAL && snum >= 0) {
202                 ptr = lp_local_ptr(snum, ptr);
203         }
204
205         printf("<tr><td>%s</td><td>", get_parm_translated(stripspaceupper(parm->label), _("Help"), parm->label));
206         switch (parm->type) {
207         case P_CHAR:
208                 d_printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
209                        make_parm_name(parm->label), *(char *)ptr);
210                 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
211                         _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
212                 break;
213
214         case P_LIST:
215                 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"",
216                         make_parm_name(parm->label));
217                 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
218                         char **list = *(char ***)ptr;
219                         for (;*list;list++) {
220                                 d_printf("%s%s", *list, ((*(list+1))?" ":""));
221                         }
222                 }
223                 d_printf("\">");
224                 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
225                         _("Set Default"), make_parm_name(parm->label));
226                 if (parm->def.lvalue) {
227                         char **list = (char **)(parm->def.lvalue);
228                         for (; *list; list++) {
229                                 d_printf("%s%s", *list, ((*(list+1))?" ":""));
230                         }
231                 }
232                 d_printf("\'\">");
233                 break;
234
235         case P_STRING:
236         case P_USTRING:
237                 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
238                        make_parm_name(parm->label), *(char **)ptr);
239                 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
240                         _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
241                 break;
242
243         case P_GSTRING:
244         case P_UGSTRING:
245                 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
246                        make_parm_name(parm->label), (char *)ptr);
247                 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
248                         _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
249                 break;
250
251         case P_BOOL:
252                 d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label)); 
253                 d_printf("<option %s>Yes", (*(BOOL *)ptr)?"selected":"");
254                 d_printf("<option %s>No", (*(BOOL *)ptr)?"":"selected");
255                 d_printf("</select>");
256                 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
257                         _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?0:1);
258                 break;
259
260         case P_BOOLREV:
261                 d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label)); 
262                 d_printf("<option %s>Yes", (*(BOOL *)ptr)?"":"selected");
263                 d_printf("<option %s>No", (*(BOOL *)ptr)?"selected":"");
264                 d_printf("</select>");
265                 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
266                         _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?1:0);
267                 break;
268
269         case P_INTEGER:
270                 d_printf("<input type=text size=8 name=\"parm_%s\" value=%d>", make_parm_name(parm->label), *(int *)ptr);
271                 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
272                         _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
273                 break;
274
275         case P_OCTAL:
276                 d_printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm->label), octal_string(*(int *)ptr));
277                 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
278                        _("Set Default"), make_parm_name(parm->label),
279                        octal_string((int)(parm->def.ivalue)));
280                 break;
281
282         case P_ENUM:
283                 d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label)); 
284                 for (i=0;parm->enum_list[i].name;i++) {
285                         if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
286                                 d_printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
287                         }
288                 }
289                 d_printf("</select>");
290                 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
291                         _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
292                 break;
293         case P_SEP:
294                 break;
295         }
296         d_printf("</td></tr>\n");
297 }
298
299 /****************************************************************************
300   display a set of parameters for a service 
301 ****************************************************************************/
302 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
303 {
304         int i = 0;
305         struct parm_struct *parm;
306         const char *heading = NULL;
307         const char *last_heading = NULL;
308
309         while ((parm = lp_next_parameter(snum, &i, allparameters))) {
310                 if (snum < 0 && parm->class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
311                         continue;
312                 if (parm->class == P_SEPARATOR) {
313                         heading = parm->label;
314                         continue;
315                 }
316                 if (parm->flags & FLAG_HIDE) continue;
317                 if (snum >= 0) {
318                         if (printers & !(parm->flags & FLAG_PRINT)) continue;
319                         if (!printers & !(parm->flags & FLAG_SHARE)) continue;
320                 }
321                 if (parm_filter == FLAG_BASIC) {
322                         if (!(parm->flags & FLAG_BASIC)) {
323                                 void *ptr = parm->ptr;
324
325                                 if (parm->class == P_LOCAL && snum >= 0) {
326                                         ptr = lp_local_ptr(snum, ptr);
327                                 }
328
329                                 switch (parm->type) {
330                                 case P_CHAR:
331                                         if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
332                                         break;
333
334                                 case P_LIST:
335                                         if (!str_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
336                                         break;
337
338                                 case P_STRING:
339                                 case P_USTRING:
340                                         if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
341                                         break;
342
343                                 case P_GSTRING:
344                                 case P_UGSTRING:
345                                         if (!strcmp((char *)ptr,(char *)(parm->def.svalue))) continue;
346                                         break;
347
348                                 case P_BOOL:
349                                 case P_BOOLREV:
350                                         if (*(BOOL *)ptr == (BOOL)(parm->def.bvalue)) continue;
351                                         break;
352
353                                 case P_INTEGER:
354                                 case P_OCTAL:
355                                         if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
356                                         break;
357
358
359                                 case P_ENUM:
360                                         if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
361                                         break;
362                                 case P_SEP:
363                                         continue;
364                                 }
365                         }
366                         if (printers && !(parm->flags & FLAG_PRINT)) continue;
367                 }
368                 if (parm_filter == FLAG_WIZARD) {
369                         if (!((parm->flags & FLAG_WIZARD))) continue;
370                 }
371                 if (parm_filter == FLAG_ADVANCED) {
372                         if (!((parm->flags & FLAG_ADVANCED))) continue;
373                 }
374                 if (heading && heading != last_heading) {
375                         d_printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
376                         last_heading = heading;
377                 }
378                 show_parameter(snum, parm);
379         }
380 }
381
382 /****************************************************************************
383   load the smb.conf file into loadparm.
384 ****************************************************************************/
385 static BOOL load_config(BOOL save_def)
386 {
387         lp_resetnumservices();
388         return lp_load(dyn_CONFIGFILE,False,save_def,False);
389 }
390
391 /****************************************************************************
392   write a config file 
393 ****************************************************************************/
394 static void write_config(FILE *f, BOOL show_defaults)
395 {
396         fprintf(f, "# Samba config file created using SWAT\n");
397         fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
398         fprintf(f, "# Date: %s\n\n", timestring(False));
399         
400         lp_dump(f, show_defaults, iNumNonAutoPrintServices);
401 }
402
403 /****************************************************************************
404   save and reload the smb.conf config file 
405 ****************************************************************************/
406 static int save_reload(int snum)
407 {
408         FILE *f;
409         struct stat st;
410
411         f = sys_fopen(dyn_CONFIGFILE,"w");
412         if (!f) {
413                 d_printf("failed to open %s for writing\n", dyn_CONFIGFILE);
414                 return 0;
415         }
416
417         /* just in case they have used the buggy xinetd to create the file */
418         if (fstat(fileno(f), &st) == 0 &&
419             (st.st_mode & S_IWOTH)) {
420                 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
421         }
422
423         write_config(f, False);
424         if (snum)
425                 lp_dump_one(f, False, snum);
426         fclose(f);
427
428         lp_killunused(NULL);
429
430         if (!load_config(False)) {
431                 d_printf("Can't reload %s\n", dyn_CONFIGFILE);
432                 return 0;
433         }
434         iNumNonAutoPrintServices = lp_numservices();
435         load_printers();
436
437         return 1;
438 }
439
440 /****************************************************************************
441   commit one parameter 
442 ****************************************************************************/
443 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
444 {
445         int i;
446         char *s;
447
448         if (snum < 0 && parm->class == P_LOCAL) {
449                 /* this handles the case where we are changing a local
450                    variable globally. We need to change the parameter in 
451                    all shares where it is currently set to the default */
452                 for (i=0;i<lp_numservices();i++) {
453                         s = lp_servicename(i);
454                         if (s && (*s) && lp_is_default(i, parm)) {
455                                 lp_do_parameter(i, parm->label, v);
456                         }
457                 }
458         }
459
460         lp_do_parameter(snum, parm->label, v);
461 }
462
463 /****************************************************************************
464   commit a set of parameters for a service 
465 ****************************************************************************/
466 static void commit_parameters(int snum)
467 {
468         int i = 0;
469         struct parm_struct *parm;
470         pstring label;
471         const char *v;
472
473         while ((parm = lp_next_parameter(snum, &i, 1))) {
474                 slprintf(label, sizeof(label)-1, "parm_%s", make_parm_name(parm->label));
475                 if ((v = cgi_variable(label))) {
476                         if (parm->flags & FLAG_HIDE) continue;
477                         commit_parameter(snum, parm, v); 
478                 }
479         }
480 }
481
482 /****************************************************************************
483   spit out the html for a link with an image 
484 ****************************************************************************/
485 static void image_link(const char *name, const char *hlink, const char *src)
486 {
487         d_printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n", 
488                cgi_baseurl(), hlink, src, name);
489 }
490
491 /****************************************************************************
492   display the main navigation controls at the top of each page along
493   with a title 
494 ****************************************************************************/
495 static void show_main_buttons(void)
496 {
497         char *p;
498         
499         if ((p = cgi_user_name()) && strcmp(p, "root")) {
500                 d_printf(_("Logged in as <b>%s</b><p>\n"), p);
501         }
502
503         image_link(_("Home"), "", "images/home.gif");
504         if (have_write_access) {
505                 image_link(_("Globals"), "globals", "images/globals.gif");
506                 image_link(_("Shares"), "shares", "images/shares.gif");
507                 image_link(_("Printers"), "printers", "images/printers.gif");
508                 image_link(_("Wizard"), "wizard", "images/wizard.gif");
509         }
510         if (have_read_access) {
511                 image_link(_("Status"), "status", "images/status.gif");
512                 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
513         }
514         image_link(_("Password Management"), "passwd", "images/passwd.gif");
515
516         d_printf("<HR>\n");
517 }
518
519 /****************************************************************************
520  * Handle Display/Edit Mode CGI
521  ****************************************************************************/
522 static void ViewModeBoxes(int mode)
523 {
524         d_printf("<p>%s\n", _("Configuration View:&nbsp"));
525         d_printf("<input type=radio name=\"ViewMode\" value=0 %s>Basic\n", (mode == 0) ? "checked" : "");
526         d_printf("<input type=radio name=\"ViewMode\" value=1 %s>Advanced\n", (mode == 1) ? "checked" : "");
527         d_printf("<input type=radio name=\"ViewMode\" value=2 %s>Developer\n", (mode == 2) ? "checked" : "");
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(GLOBALS_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(GLOBALS_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(GLOBALS_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( GLOBALS_SNUM, "encrypt passwords", "Yes");
637                 
638                 switch ( SerType ){
639                         case 0:
640                                 /* Stand-alone Server */
641                                 lp_do_parameter( GLOBALS_SNUM, "security", "USER" );
642                                 lp_do_parameter( GLOBALS_SNUM, "domain logons", "No" );
643                                 break;
644                         case 1:
645                                 /* Domain Member */
646                                 lp_do_parameter( GLOBALS_SNUM, "security", "DOMAIN" );
647                                 lp_do_parameter( GLOBALS_SNUM, "domain logons", "No" );
648                                 break;
649                         case 2:
650                                 /* Domain Controller */
651                                 lp_do_parameter( GLOBALS_SNUM, "security", "USER" );
652                                 lp_do_parameter( GLOBALS_SNUM, "domain logons", "Yes" );
653                                 break;
654                 }
655                 switch ( winstype ) {
656                         case 0:
657                                 lp_do_parameter( GLOBALS_SNUM, "wins support", "No" );
658                                 lp_do_parameter( GLOBALS_SNUM, "wins server", "" );
659                                 break;
660                         case 1:
661                                 lp_do_parameter( GLOBALS_SNUM, "wins support", "Yes" );
662                                 lp_do_parameter( GLOBALS_SNUM, "wins server", "" );
663                                 break;
664                         case 2:
665                                 lp_do_parameter( GLOBALS_SNUM, "wins support", "No" );
666                                 lp_do_parameter( GLOBALS_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(GLOBALS_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(GLOBALS_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=\"%s\"></td></tr>",lp_wins_server_list());
741         if (winstype == 3) {
742                 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>");
743                 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Please Select desired WINS mode above.</font></td></tr>");
744         }
745         d_printf("</tr>");
746         d_printf("<tr><td><b>%s</b></td>\n","Expose Home Directories:&nbsp;");
747         d_printf("<td><input type=radio name=\"HomeExpo\" value=1 %s> Yes</td>", (have_home == -1) ? "" : "checked ");
748         d_printf("<td><input type=radio name=\"HomeExpo\" value=0 %s> No</td>", (have_home == -1 ) ? "checked" : "");
749         d_printf("<td></td></tr>");
750         
751         /* Enable this when we are ready ....
752          * d_printf("<tr><td><b>%s</b></td>\n","Is Print Server:&nbsp;");
753          * d_printf("<td><input type=radio name=\"PtrSvr\" value=1 %s> Yes</td>");
754          * d_printf("<td><input type=radio name=\"PtrSvr\" value=0 %s> No</td>");
755          * d_printf("<td></td></tr>");
756          */
757         
758         d_printf("</table></center>");
759         d_printf("<hr>");
760
761         d_printf(_("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment.\n"));
762         d_printf("</form>\n");
763 }
764
765
766 /****************************************************************************
767   display a globals editing page  
768 ****************************************************************************/
769 static void globals_page(void)
770 {
771         unsigned int parm_filter = FLAG_BASIC;
772         int mode = 0;
773
774         d_printf("<H2>%s</H2>\n", _("Global Variables"));
775
776         if (cgi_variable("Commit")) {
777                 commit_parameters(GLOBALS_SNUM);
778                 save_reload(0);
779         }
780
781         if ( cgi_variable("ViewMode") )
782                 mode = atoi(cgi_variable("ViewMode"));
783
784         d_printf("<form name=\"swatform\" method=post action=globals>\n");
785
786         ViewModeBoxes( mode );
787         switch ( mode ) {
788                 case 0:
789                         parm_filter = FLAG_BASIC;
790                         break;
791                 case 1:
792                         parm_filter = FLAG_ADVANCED;
793                         break;
794                 case 2:
795                         parm_filter = FLAG_DEVELOPER;
796                         break;
797         }
798         d_printf("<br>\n");
799         if (have_write_access) {
800                 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
801                         _("Commit Changes"));
802         }
803
804         d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", 
805                  _("Reset Values"));
806
807         d_printf("<p>\n");
808         d_printf("<table>\n");
809         show_parameters(GLOBALS_SNUM, 1, parm_filter, 0);
810         d_printf("</table>\n");
811         d_printf("</form>\n");
812 }
813
814 /****************************************************************************
815   display a shares editing page. share is in unix codepage, and must be in
816   dos codepage. FIXME !!! JRA.
817 ****************************************************************************/
818 static void shares_page(void)
819 {
820         const char *share = cgi_variable("share");
821         char *s;
822         int snum = -1;
823         int i;
824         int mode = 0;
825         unsigned int parm_filter = FLAG_BASIC;
826
827         if (share)
828                 snum = lp_servicenumber(share);
829
830         d_printf("<H2>%s</H2>\n", _("Share Parameters"));
831
832         if (cgi_variable("Commit") && snum >= 0) {
833                 commit_parameters(snum);
834                 save_reload(0);
835         }
836
837         if (cgi_variable("Delete") && snum >= 0) {
838                 lp_remove_service(snum);
839                 save_reload(0);
840                 share = NULL;
841                 snum = -1;
842         }
843
844         if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
845                 load_config(False);
846                 lp_copy_service(GLOBALS_SNUM, share);
847                 iNumNonAutoPrintServices = lp_numservices();
848                 save_reload(0);
849                 snum = lp_servicenumber(share);
850         }
851
852         d_printf("<FORM name=\"swatform\" method=post>\n");
853
854         d_printf("<table>\n");
855         if ( cgi_variable("ViewMode") )
856                 mode = atoi(cgi_variable("ViewMode"));
857         ViewModeBoxes( mode );
858         switch ( mode ) {
859                 case 0:
860                         parm_filter = FLAG_BASIC;
861                         break;
862                 case 1:
863                         parm_filter = FLAG_ADVANCED;
864                         break;
865                 case 2:
866                         parm_filter = FLAG_DEVELOPER;
867                         break;
868         }
869         d_printf("<br><tr>\n");
870         d_printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
871         d_printf("<td><select name=share>\n");
872         if (snum < 0)
873                 d_printf("<option value=\" \"> \n");
874         for (i=0;i<lp_numservices();i++) {
875                 s = lp_servicename(i);
876                 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
877                         d_printf("<option %s value=\"%s\">%s\n", 
878                                (share && strcmp(share,s)==0)?"SELECTED":"",
879                                s, s);
880                 }
881         }
882         d_printf("</select></td>\n");
883         if (have_write_access) {
884                 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
885         }
886         d_printf("</tr>\n");
887         d_printf("</table>");
888         d_printf("<table>");
889         if (have_write_access) {
890                 d_printf("<tr>\n");
891                 d_printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
892                 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
893         }
894         d_printf("</table>");
895
896
897         if (snum >= 0) {
898                 if (have_write_access) {
899                         d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
900                 }
901
902                 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
903                 d_printf("<p>\n");
904         }
905
906         if (snum >= 0) {
907                 d_printf("<table>\n");
908                 show_parameters(snum, 1, parm_filter, 0);
909                 d_printf("</table>\n");
910         }
911
912         d_printf("</FORM>\n");
913 }
914
915 /*************************************************************
916 change a password either locally or remotely
917 *************************************************************/
918 static BOOL change_password(const char *remote_machine, const char *user_name, 
919                             const char *old_passwd, const char *new_passwd, 
920                                 int local_flags)
921 {
922         BOOL ret = False;
923         pstring err_str;
924         pstring msg_str;
925
926         if (demo_mode) {
927                 d_printf("%s<p>", _("password change in demo mode rejected\n"));
928                 return False;
929         }
930         
931         if (remote_machine != NULL) {
932                 ret = remote_password_change(remote_machine, user_name, old_passwd, 
933                                                                          new_passwd, err_str, sizeof(err_str));
934                 if(*err_str)
935                         d_printf("%s\n<p>", err_str);
936                 return ret;
937         }
938
939         if(!initialize_password_db(True)) {
940                 d_printf("Can't setup password database vectors.\n<p>");
941                 return False;
942         }
943         
944         ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
945                                          msg_str, sizeof(msg_str));
946
947         if(*msg_str)
948                 d_printf("%s\n<p>", msg_str);
949         if(*err_str)
950                 d_printf("%s\n<p>", err_str);
951
952         return ret;
953 }
954
955 /****************************************************************************
956   do the stuff required to add or change a password 
957 ****************************************************************************/
958 static void chg_passwd(void)
959 {
960         const char *host;
961         BOOL rslt;
962         int local_flags = 0;
963
964         /* Make sure users name has been specified */
965         if (strlen(cgi_variable(SWAT_USER)) == 0) {
966                 d_printf("<p>%s", _(" Must specify \"User Name\" \n"));
967                 return;
968         }
969
970         /*
971          * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
972          * so if that's what we're doing, skip the rest of the checks
973          */
974         if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
975
976                 /*
977                  * If current user is not root, make sure old password has been specified 
978                  * If REMOTE change, even root must provide old password 
979                  */
980                 if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
981                     ((cgi_variable(CHG_R_PASSWD_FLAG)) &&  (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
982                         d_printf("<p>%s", _(" Must specify \"Old Password\" \n"));
983                         return;
984                 }
985
986                 /* If changing a users password on a remote hosts we have to know what host */
987                 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
988                         d_printf("<p>%s", _(" Must specify \"Remote Machine\" \n"));
989                         return;
990                 }
991
992                 /* Make sure new passwords have been specified */
993                 if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
994                     (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
995                         d_printf("<p>%s", _(" Must specify \"New, and Re-typed Passwords\" \n"));
996                         return;
997                 }
998
999                 /* Make sure new passwords was typed correctly twice */
1000                 if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
1001                         d_printf("<p>%s", _(" Re-typed password didn't match new password\n"));
1002                         return;
1003                 }
1004         }
1005
1006         if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1007                 host = cgi_variable(RHOST);
1008         } else if (am_root()) {
1009                 host = NULL;
1010         } else {
1011                 host = "127.0.0.1";
1012         }
1013
1014         /*
1015          * Set up the local flags.
1016          */
1017
1018         local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1019         local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1020         local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1021         local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1022
1023         rslt = change_password(host,
1024                                cgi_variable(SWAT_USER),
1025                                cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
1026                                    local_flags);
1027
1028         if(local_flags == 0) {
1029                 d_printf("<p>");
1030                 if (rslt == True) {
1031                         d_printf(_(" The passwd for '%s' has been changed. \n"), cgi_variable(SWAT_USER));
1032                 } else {
1033                         d_printf(_(" The passwd for '%s' has NOT been changed. \n"), cgi_variable(SWAT_USER));
1034                 }
1035         }
1036         
1037         return;
1038 }
1039
1040 /****************************************************************************
1041   display a password editing page  
1042 ****************************************************************************/
1043 static void passwd_page(void)
1044 {
1045         const char *new_name = cgi_user_name();
1046
1047         /* 
1048          * After the first time through here be nice. If the user
1049          * changed the User box text to another users name, remember it.
1050          */
1051         if (cgi_variable(SWAT_USER)) {
1052                 new_name = cgi_variable(SWAT_USER);
1053         } 
1054
1055         if (!new_name) new_name = "";
1056
1057         d_printf("<H2>%s</H2>\n", _("Server Password Management"));
1058
1059         d_printf("<FORM name=\"swatform\" method=post>\n");
1060
1061         d_printf("<table>\n");
1062
1063         /* 
1064          * Create all the dialog boxes for data collection
1065          */
1066         d_printf("<tr><td>%s</td>\n", _(" User Name : "));
1067         d_printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1068         if (!am_root()) {
1069                 d_printf("<tr><td>%s</td>\n", _(" Old Password : "));
1070                 d_printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1071         }
1072         d_printf("<tr><td>%s</td>\n", _(" New Password : "));
1073         d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1074         d_printf("<tr><td>%s</td>\n", _(" Re-type New Password : "));
1075         d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1076         d_printf("</table>\n");
1077
1078         /*
1079          * Create all the control buttons for requesting action
1080          */
1081         d_printf("<input type=submit name=%s value=\"%s\">\n", 
1082                CHG_S_PASSWD_FLAG, _("Change Password"));
1083         if (demo_mode || am_root()) {
1084                 d_printf("<input type=submit name=%s value=\"%s\">\n",
1085                        ADD_USER_FLAG, _("Add New User"));
1086                 d_printf("<input type=submit name=%s value=\"%s\">\n",
1087                        DELETE_USER_FLAG, _("Delete User"));
1088                 d_printf("<input type=submit name=%s value=\"%s\">\n", 
1089                        DISABLE_USER_FLAG, _("Disable User"));
1090                 d_printf("<input type=submit name=%s value=\"%s\">\n", 
1091                        ENABLE_USER_FLAG, _("Enable User"));
1092         }
1093         d_printf("<p></FORM>\n");
1094
1095         /*
1096          * Do some work if change, add, disable or enable was
1097          * requested. It could be this is the first time through this
1098          * code, so there isn't anything to do.  */
1099         if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1100             (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1101                 chg_passwd();           
1102         }
1103
1104         d_printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1105
1106         d_printf("<FORM name=\"swatform\" method=post>\n");
1107
1108         d_printf("<table>\n");
1109
1110         /* 
1111          * Create all the dialog boxes for data collection
1112          */
1113         d_printf("<tr><td>%s</td>\n", _(" User Name : "));
1114         d_printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1115         d_printf("<tr><td>%s</td>\n", _(" Old Password : "));
1116         d_printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1117         d_printf("<tr><td>%s</td>\n", _(" New Password : "));
1118         d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1119         d_printf("<tr><td>%s</td>\n", _(" Re-type New Password : "));
1120         d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1121         d_printf("<tr><td>%s</td>\n", _(" Remote Machine : "));
1122         d_printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1123
1124         d_printf("</table>");
1125
1126         /*
1127          * Create all the control buttons for requesting action
1128          */
1129         d_printf("<input type=submit name=%s value=\"%s\">", 
1130                CHG_R_PASSWD_FLAG, _("Change Password"));
1131
1132         d_printf("<p></FORM>\n");
1133
1134         /*
1135          * Do some work if a request has been made to change the
1136          * password somewhere other than the server. It could be this
1137          * is the first time through this code, so there isn't
1138          * anything to do.  */
1139         if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1140                 chg_passwd();           
1141         }
1142
1143 }
1144
1145 /****************************************************************************
1146   display a printers editing page  
1147 ****************************************************************************/
1148 static void printers_page(void)
1149 {
1150         const char *share = cgi_variable("share");
1151         char *s;
1152         int snum=-1;
1153         int i;
1154         int mode = 0;
1155         unsigned int parm_filter = FLAG_BASIC;
1156
1157         if (share)
1158                 snum = lp_servicenumber(share);
1159
1160         d_printf("<H2>%s</H2>\n", _("Printer Parameters"));
1161  
1162         d_printf("<H3>%s</H3>\n", _("Important Note:"));
1163         d_printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
1164         d_printf(_("are autoloaded printers from "));
1165         d_printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1166         d_printf(_("Attempting to delete these printers from SWAT will have no effect.\n"));
1167
1168         if (cgi_variable("Commit") && snum >= 0) {
1169                 commit_parameters(snum);
1170                 if (snum >= iNumNonAutoPrintServices)
1171                     save_reload(snum);
1172                 else
1173                     save_reload(0);
1174         }
1175
1176         if (cgi_variable("Delete") && snum >= 0) {
1177                 lp_remove_service(snum);
1178                 save_reload(0);
1179                 share = NULL;
1180                 snum = -1;
1181         }
1182
1183         if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1184                 load_config(False);
1185                 lp_copy_service(GLOBALS_SNUM, share);
1186                 iNumNonAutoPrintServices = lp_numservices();
1187                 snum = lp_servicenumber(share);
1188                 lp_do_parameter(snum, "print ok", "Yes");
1189                 save_reload(0);
1190                 snum = lp_servicenumber(share);
1191         }
1192
1193         d_printf("<FORM name=\"swatform\" method=post>\n");
1194
1195         if ( cgi_variable("ViewMode") )
1196                 mode = atoi(cgi_variable("ViewMode"));
1197         ViewModeBoxes( mode );
1198         switch ( mode ) {
1199                 case 0:
1200                         parm_filter = FLAG_BASIC;
1201                         break;
1202                 case 1:
1203                         parm_filter = FLAG_ADVANCED;
1204                         break;
1205                 case 2:
1206                         parm_filter = FLAG_DEVELOPER;
1207                         break;
1208         }
1209         d_printf("<table>\n");
1210         d_printf("<tr><td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Printer"));
1211         d_printf("<td><select name=share>\n");
1212         if (snum < 0 || !lp_print_ok(snum))
1213                 d_printf("<option value=\" \"> \n");
1214         for (i=0;i<lp_numservices();i++) {
1215                 s = lp_servicename(i);
1216                 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1217                     if (i >= iNumNonAutoPrintServices)
1218                         d_printf("<option %s value=\"%s\">[*]%s\n",
1219                                (share && strcmp(share,s)==0)?"SELECTED":"",
1220                                s, s);
1221                     else
1222                         d_printf("<option %s value=\"%s\">%s\n", 
1223                                (share && strcmp(share,s)==0)?"SELECTED":"",
1224                                s, s);
1225                 }
1226         }
1227         d_printf("</select></td>");
1228         if (have_write_access) {
1229                 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1230         }
1231         d_printf("</tr>");
1232         d_printf("</table>\n");
1233
1234         if (have_write_access) {
1235                 d_printf("<table>\n");
1236                 d_printf("<tr><td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Printer"));
1237                 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1238                 d_printf("</table>");
1239         }
1240
1241
1242         if (snum >= 0) {
1243                 if (have_write_access) {
1244                         d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1245                 }
1246                 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1247                 d_printf("<p>\n");
1248         }
1249
1250         if (snum >= 0) {
1251                 d_printf("<table>\n");
1252                 show_parameters(snum, 1, parm_filter, 1);
1253                 d_printf("</table>\n");
1254         }
1255         d_printf("</FORM>\n");
1256 }
1257
1258
1259 /**
1260  * main function for SWAT.
1261  **/
1262  int main(int argc, char *argv[])
1263 {
1264         int opt;
1265         char *page;
1266         poptContext pc;
1267         struct poptOption long_options[] = {
1268                 POPT_AUTOHELP
1269                 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, TRUE, "Disable authentication (demo mode)" },
1270                 { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_version},
1271                 { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_configfile},
1272                 { 0, 0, 0, 0 }
1273         };
1274
1275         fault_setup(NULL);
1276         umask(S_IWGRP | S_IWOTH);
1277
1278 #if defined(HAVE_SET_AUTH_PARAMETERS)
1279         set_auth_parameters(argc, argv);
1280 #endif /* HAVE_SET_AUTH_PARAMETERS */
1281
1282         /* just in case it goes wild ... */
1283         alarm(300);
1284
1285         setlinebuf(stdout);
1286
1287         /* we don't want any SIGPIPE messages */
1288         BlockSignals(True,SIGPIPE);
1289
1290         dbf = x_fopen("/dev/null", O_WRONLY, 0);
1291         if (!dbf) dbf = x_stderr;
1292
1293         /* we don't want stderr screwing us up */
1294         close(2);
1295         open("/dev/null", O_WRONLY);
1296
1297         pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1298
1299         /* Parse command line options */
1300
1301         while((opt = poptGetNextOpt(pc)) != -1) { }
1302
1303         poptFreeContext(pc);
1304
1305         setup_logging(argv[0],False);
1306         load_config(True);
1307         iNumNonAutoPrintServices = lp_numservices();
1308         load_printers();
1309
1310         cgi_setup(dyn_SWATDIR, !demo_mode);
1311
1312         print_header();
1313
1314         cgi_load_variables();
1315
1316         if (!file_exist(dyn_CONFIGFILE, NULL)) {
1317                 have_read_access = True;
1318                 have_write_access = True;
1319         } else {
1320                 /* check if the authenticated user has write access - if not then
1321                    don't show write options */
1322                 have_write_access = (access(dyn_CONFIGFILE,W_OK) == 0);
1323
1324                 /* if the user doesn't have read access to smb.conf then
1325                    don't let them view it */
1326                 have_read_access = (access(dyn_CONFIGFILE,R_OK) == 0);
1327         }
1328
1329         show_main_buttons();
1330
1331         page = cgi_pathinfo();
1332
1333         /* Root gets full functionality */
1334         if (have_read_access && strcmp(page, "globals")==0) {
1335                 globals_page();
1336         } else if (have_read_access && strcmp(page,"shares")==0) {
1337                 shares_page();
1338         } else if (have_read_access && strcmp(page,"printers")==0) {
1339                 printers_page();
1340         } else if (have_read_access && strcmp(page,"status")==0) {
1341                 status_page();
1342         } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1343                 viewconfig_page();
1344         } else if (strcmp(page,"passwd")==0) {
1345                 passwd_page();
1346         } else if (have_read_access && strcmp(page,"wizard")==0) {
1347                 wizard_page();
1348         } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1349                 wizard_params_page();
1350         } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1351                 rewritecfg_file();
1352         } else {
1353                 welcome_page();
1354         }
1355
1356         print_footer();
1357         return 0;
1358 }
1359
1360 /** @} **/