r2771: Second (and last) part of Swat-i18n-Patch from Björn Jacke
[samba.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                 printf(_("ERROR: Can't open %s"), fname);
119                 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                 printf("Expires: 0\r\n");
138         }
139         printf("Content-type: text/html\r\n\r\n");
140
141         if (!include_html("include/header.html")) {
142                 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
143                 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                 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         printf("<tr><td>%s</td><td>", get_parm_translated(stripspaceupper(parm->label), _("Help"), parm->label));
202         switch (parm->type) {
203         case P_CHAR:
204                 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
205                        make_parm_name(parm->label), *(char *)ptr);
206                 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                 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                                         printf("\'%s\'%s", *list, ((*(list+1))?", ":""));
219                                 else
220                                         printf("%s%s", *list, ((*(list+1))?", ":""));
221                         }
222                 }
223                 printf("\">");
224                 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                                         printf("\'%s\'%s", *list, ((*(list+1))?", ":""));
232                                 else
233                                         printf("%s%s", *list, ((*(list+1))?", ":""));
234                         }
235                 }
236                 printf("\'\">");
237                 break;
238
239         case P_STRING:
240         case P_USTRING:
241                 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
242                        make_parm_name(parm->label), *(char **)ptr);
243                 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                 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
250                        make_parm_name(parm->label), (char *)ptr);
251                 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                 printf("<select name=\"parm_%s\">",make_parm_name(parm->label)); 
257                 printf("<option %s>Yes", (*(BOOL *)ptr)?"selected":"");
258                 printf("<option %s>No", (*(BOOL *)ptr)?"":"selected");
259                 printf("</select>");
260                 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                 printf("<select name=\"parm_%s\">",make_parm_name(parm->label)); 
266                 printf("<option %s>Yes", (*(BOOL *)ptr)?"":"selected");
267                 printf("<option %s>No", (*(BOOL *)ptr)?"selected":"");
268                 printf("</select>");
269                 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                 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
275                 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                 printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm->label), octal_string(*(int *)ptr));
281                 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                 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                                 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
291                         }
292                 }
293                 printf("</select>");
294                 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         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                         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                 printf(_("failed to open %s for writing"), dyn_CONFIGFILE);
418                 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                 printf(_("Can't reload %s"), dyn_CONFIGFILE);
441                 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         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                 printf(_("Logged in as <b>%s</b>"), p);
511                 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         printf("<HR>\n");
528 }
529
530 /****************************************************************************
531  * Handle Display/Edit Mode CGI
532  ****************************************************************************/
533 static void ViewModeBoxes(int mode)
534 {
535         printf("<p>%s:&nbsp;\n", _("Current View Is"));
536         printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
537         printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
538         printf("<br>%s:&nbsp;\n", _("Change View To"));
539         printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
540         printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
541         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         printf("<H2>%s</H2>\n", _("Current Config"));
564         printf("<form method=post>\n");
565
566         if (full_view) {
567                 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
568         } else {
569                 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
570         }
571
572         printf("<p><pre>");
573         write_config(stdout, full_view);
574         printf("</pre>");
575         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         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         printf("<form name=\"swatform\" method=post action=wizard_params>\n");
596
597         if (have_write_access) {
598                 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
599         }
600
601         printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
602         printf("<p>\n");
603         
604         printf("<table>\n");
605         show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
606         printf("</table>\n");
607         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         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         printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
726         printf("<form method=post action=wizard>\n");
727
728         if (have_write_access) {
729                 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
730                 printf("%s", _("The same will happen if you press the commit button."));
731                 printf("<br><br>\n");
732                 printf("<center>");
733                 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> &nbsp;&nbsp;",_("Rewrite smb.conf file"));
734                 printf("<input type=submit name=\"Commit\" value=\"%s\"> &nbsp;&nbsp;",_("Commit"));
735                 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
736                 printf("</center>\n");
737         }
738
739         printf("<hr>");
740         printf("<center><table border=0>");
741         printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Server Type"));
742         printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s&nbsp;</td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
743         printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member")); 
744         printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s&nbsp;</td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
745         printf("</tr>\n");
746         if (role == ROLE_DOMAIN_BDC) {
747                 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         printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Configure WINS As"));
750         printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s&nbsp;</td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
751         printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s&nbsp;</td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
752         printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s&nbsp;</td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
753         printf("</tr>\n");
754         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++) printf("%s ", wins_servers[i]);
761         }
762         
763         printf("\"></td></tr>\n");
764         if (winstype == 3) {
765                 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                 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
767         }
768         printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Expose Home Directories"));
769         printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
770         printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
771         printf("<td></td></tr>\n");
772         
773         /* Enable this when we are ready ....
774          * printf("<tr><td><b>%s:&nbsp;</b></td>\n", _("Is Print Server"));
775          * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
776          * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
777          * printf("<td></td></tr>\n");
778          */
779         
780         printf("</table></center>");
781         printf("<hr>");
782
783         printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
784         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         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         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         printf("<br>\n");
822         if (have_write_access) {
823                 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
824                         _("Commit Changes"));
825         }
826
827         printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", 
828                  _("Reset Values"));
829
830         printf("<p>\n");
831         printf("<table>\n");
832         show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
833         printf("</table>\n");
834         printf("</form>\n");
835 }
836
837 /****************************************************************************
838   display a shares editing page. share is in unix codepage, 
839 ****************************************************************************/
840 static void shares_page(void)
841 {
842         const char *share = cgi_variable("share");
843         char *s;
844         char *utf8_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         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         printf("<FORM name=\"swatform\" method=post>\n");
876
877         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         printf("<br><tr>\n");
896         printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
897         printf("<td><select name=share>\n");
898         if (snum < 0)
899                 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                         push_utf8_allocate(&utf8_s, s);
904                         printf("<option %s value=\"%s\">%s\n", 
905                                (share && strcmp(share,s)==0)?"SELECTED":"",
906                                utf8_s, utf8_s);
907                         SAFE_FREE(utf8_s);
908                         
909                 }
910         }
911         printf("</select></td>\n");
912         if (have_write_access) {
913                 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
914         }
915         printf("</tr>\n");
916         printf("</table>");
917         printf("<table>");
918         if (have_write_access) {
919                 printf("<tr>\n");
920                 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
921                 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
922         }
923         printf("</table>");
924
925
926         if (snum >= 0) {
927                 if (have_write_access) {
928                         printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
929                 }
930
931                 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
932                 printf("<p>\n");
933         }
934
935         if (snum >= 0) {
936                 printf("<table>\n");
937                 show_parameters(snum, 1, parm_filter, 0);
938                 printf("</table>\n");
939         }
940
941         printf("</FORM>\n");
942 }
943
944 /*************************************************************
945 change a password either locally or remotely
946 *************************************************************/
947 static BOOL change_password(const char *remote_machine, const char *user_name, 
948                             const char *old_passwd, const char *new_passwd, 
949                                 int local_flags)
950 {
951         BOOL ret = False;
952         pstring err_str;
953         pstring msg_str;
954
955         if (demo_mode) {
956                 printf("%s\n<p>", _("password change in demo mode rejected"));
957                 return False;
958         }
959         
960         if (remote_machine != NULL) {
961                 ret = remote_password_change(remote_machine, user_name, old_passwd, 
962                                                                          new_passwd, err_str, sizeof(err_str));
963                 if(*err_str)
964                         printf("%s\n<p>", err_str);
965                 return ret;
966         }
967
968         if(!initialize_password_db(True)) {
969                 printf("%s\n<p>", _("Can't setup password database vectors."));
970                 return False;
971         }
972         
973         ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
974                                          msg_str, sizeof(msg_str));
975
976         if(*msg_str)
977                 printf("%s\n<p>", msg_str);
978         if(*err_str)
979                 printf("%s\n<p>", err_str);
980
981         return ret;
982 }
983
984 /****************************************************************************
985   do the stuff required to add or change a password 
986 ****************************************************************************/
987 static void chg_passwd(void)
988 {
989         const char *host;
990         BOOL rslt;
991         int local_flags = 0;
992
993         /* Make sure users name has been specified */
994         if (strlen(cgi_variable(SWAT_USER)) == 0) {
995                 printf("<p>%s\n", _(" Must specify \"User Name\" "));
996                 return;
997         }
998
999         /*
1000          * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1001          * so if that's what we're doing, skip the rest of the checks
1002          */
1003         if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1004
1005                 /*
1006                  * If current user is not root, make sure old password has been specified 
1007                  * If REMOTE change, even root must provide old password 
1008                  */
1009                 if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
1010                     ((cgi_variable(CHG_R_PASSWD_FLAG)) &&  (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
1011                         printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1012                         return;
1013                 }
1014
1015                 /* If changing a users password on a remote hosts we have to know what host */
1016                 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
1017                         printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1018                         return;
1019                 }
1020
1021                 /* Make sure new passwords have been specified */
1022                 if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
1023                     (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
1024                         printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1025                         return;
1026                 }
1027
1028                 /* Make sure new passwords was typed correctly twice */
1029                 if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
1030                         printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1031                         return;
1032                 }
1033         }
1034
1035         if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1036                 host = cgi_variable(RHOST);
1037         } else if (am_root()) {
1038                 host = NULL;
1039         } else {
1040                 host = "127.0.0.1";
1041         }
1042
1043         /*
1044          * Set up the local flags.
1045          */
1046
1047         local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1048         local_flags |= (cgi_variable(ADD_USER_FLAG) ?  LOCAL_SET_PASSWORD : 0);
1049         local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1050         local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1051         local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1052         local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1053         
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(cgi_variable(CHG_S_PASSWD_FLAG)) {
1061                 printf("<p>");
1062                 if (rslt == True) {
1063                         printf(_(" The passwd for '%s' has been changed."), cgi_variable(SWAT_USER));
1064                         printf("\n");
1065                 } else {
1066                         printf(_(" The passwd for '%s' has NOT been changed."), cgi_variable(SWAT_USER));
1067                         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         printf("<H2>%s</H2>\n", _("Server Password Management"));
1092
1093         printf("<FORM name=\"swatform\" method=post>\n");
1094
1095         printf("<table>\n");
1096
1097         /* 
1098          * Create all the dialog boxes for data collection
1099          */
1100         printf("<tr><td> %s : </td>\n", _("User Name"));
1101         printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1102         if (!am_root()) {
1103                 printf("<tr><td> %s : </td>\n", _("Old Password"));
1104                 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1105         }
1106         printf("<tr><td> %s : </td>\n", _("New Password"));
1107         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1108         printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1109         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1110         printf("</table>\n");
1111
1112         /*
1113          * Create all the control buttons for requesting action
1114          */
1115         printf("<input type=submit name=%s value=\"%s\">\n", 
1116                CHG_S_PASSWD_FLAG, _("Change Password"));
1117         if (demo_mode || am_root()) {
1118                 printf("<input type=submit name=%s value=\"%s\">\n",
1119                        ADD_USER_FLAG, _("Add New User"));
1120                 printf("<input type=submit name=%s value=\"%s\">\n",
1121                        DELETE_USER_FLAG, _("Delete User"));
1122                 printf("<input type=submit name=%s value=\"%s\">\n", 
1123                        DISABLE_USER_FLAG, _("Disable User"));
1124                 printf("<input type=submit name=%s value=\"%s\">\n", 
1125                        ENABLE_USER_FLAG, _("Enable User"));
1126         }
1127         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         printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1139
1140         printf("<FORM name=\"swatform\" method=post>\n");
1141
1142         printf("<table>\n");
1143
1144         /* 
1145          * Create all the dialog boxes for data collection
1146          */
1147         printf("<tr><td> %s : </td>\n", _("User Name"));
1148         printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1149         printf("<tr><td> %s : </td>\n", _("Old Password"));
1150         printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1151         printf("<tr><td> %s : </td>\n", _("New Password"));
1152         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1153         printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1154         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1155         printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1156         printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1157
1158         printf("</table>");
1159
1160         /*
1161          * Create all the control buttons for requesting action
1162          */
1163         printf("<input type=submit name=%s value=\"%s\">", 
1164                CHG_R_PASSWD_FLAG, _("Change Password"));
1165
1166         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         printf("<H2>%s</H2>\n", _("Printer Parameters"));
1195  
1196         printf("<H3>%s</H3>\n", _("Important Note:"));
1197         printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
1198         printf(_("are autoloaded printers from "));
1199         printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1200         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         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         printf("<table>\n");
1246         printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1247         printf("<td><select name=\"share\">\n");
1248         if (snum < 0 || !lp_print_ok(snum))
1249                 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                         printf("<option %s value=\"%s\">[*]%s\n",
1255                                (share && strcmp(share,s)==0)?"SELECTED":"",
1256                                s, s);
1257                     else
1258                         printf("<option %s value=\"%s\">%s\n", 
1259                                (share && strcmp(share,s)==0)?"SELECTED":"",
1260                                s, s);
1261                 }
1262         }
1263         printf("</select></td>");
1264         if (have_write_access) {
1265                 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1266         }
1267         printf("</tr>");
1268         printf("</table>\n");
1269
1270         if (have_write_access) {
1271                 printf("<table>\n");
1272                 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1273                 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1274                 printf("</table>");
1275         }
1276
1277
1278         if (snum >= 0) {
1279                 if (have_write_access) {
1280                         printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1281                 }
1282                 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1283                 printf("<p>\n");
1284         }
1285
1286         if (snum >= 0) {
1287                 printf("<table>\n");
1288                 show_parameters(snum, 1, parm_filter, 1);
1289                 printf("</table>\n");
1290         }
1291         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 /** @} **/