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