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