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