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