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