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