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