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