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