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