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