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