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