5e66b1c985c6b81bbdfa689b3605c572151c6888
[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("%s\n", _(" The passwd has been changed."));
1137                 } else {
1138                         printf("%s\n", _(" The passwd has NOT been changed."));
1139                 }
1140         }
1141
1142         return;
1143 }
1144
1145 /****************************************************************************
1146   display a password editing page  
1147 ****************************************************************************/
1148 static void passwd_page(void)
1149 {
1150         const char *new_name = cgi_user_name();
1151
1152         if (!new_name) new_name = "";
1153
1154         printf("<H2>%s</H2>\n", _("Server Password Management"));
1155
1156         printf("<FORM name=\"swatform\" method=post>\n");
1157
1158         printf("<table>\n");
1159
1160         /* 
1161          * Create all the dialog boxes for data collection
1162          */
1163         printf("<tr><td> %s : </td>\n", _("User Name"));
1164         printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1165         if (!am_root()) {
1166                 printf("<tr><td> %s : </td>\n", _("Old Password"));
1167                 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1168         }
1169         printf("<tr><td> %s : </td>\n", _("New Password"));
1170         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1171         printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1172         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1173         printf("</table>\n");
1174
1175         /*
1176          * Create all the control buttons for requesting action
1177          */
1178         printf("<input type=submit name=%s value=\"%s\">\n", 
1179                CHG_S_PASSWD_FLAG, _("Change Password"));
1180         if (demo_mode || am_root()) {
1181                 printf("<input type=submit name=%s value=\"%s\">\n",
1182                        ADD_USER_FLAG, _("Add New User"));
1183                 printf("<input type=submit name=%s value=\"%s\">\n",
1184                        DELETE_USER_FLAG, _("Delete User"));
1185                 printf("<input type=submit name=%s value=\"%s\">\n", 
1186                        DISABLE_USER_FLAG, _("Disable User"));
1187                 printf("<input type=submit name=%s value=\"%s\">\n", 
1188                        ENABLE_USER_FLAG, _("Enable User"));
1189         }
1190         printf("<p></FORM>\n");
1191
1192         /*
1193          * Do some work if change, add, disable or enable was
1194          * requested. It could be this is the first time through this
1195          * code, so there isn't anything to do.  */
1196         if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1197             (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1198                 chg_passwd();           
1199         }
1200
1201         printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1202
1203         printf("<FORM name=\"swatform\" method=post>\n");
1204
1205         printf("<table>\n");
1206
1207         /* 
1208          * Create all the dialog boxes for data collection
1209          */
1210         printf("<tr><td> %s : </td>\n", _("User Name"));
1211         printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1212         printf("<tr><td> %s : </td>\n", _("Old Password"));
1213         printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1214         printf("<tr><td> %s : </td>\n", _("New Password"));
1215         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1216         printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1217         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1218         printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1219         printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1220
1221         printf("</table>");
1222
1223         /*
1224          * Create all the control buttons for requesting action
1225          */
1226         printf("<input type=submit name=%s value=\"%s\">", 
1227                CHG_R_PASSWD_FLAG, _("Change Password"));
1228
1229         printf("<p></FORM>\n");
1230
1231         /*
1232          * Do some work if a request has been made to change the
1233          * password somewhere other than the server. It could be this
1234          * is the first time through this code, so there isn't
1235          * anything to do.  */
1236         if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1237                 chg_passwd();           
1238         }
1239
1240 }
1241
1242 /****************************************************************************
1243   display a printers editing page  
1244 ****************************************************************************/
1245 static void printers_page(void)
1246 {
1247         const char *share = cgi_variable("share");
1248         char *s;
1249         int snum=-1;
1250         int i;
1251         int mode = 0;
1252         unsigned int parm_filter = FLAG_BASIC;
1253
1254         if (share)
1255                 snum = lp_servicenumber(share);
1256
1257         printf("<H2>%s</H2>\n", _("Printer Parameters"));
1258  
1259         printf("<H3>%s</H3>\n", _("Important Note:"));
1260         printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
1261         printf("%s",_("are autoloaded printers from "));
1262         printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1263         printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1264
1265         if (cgi_variable("Commit") && snum >= 0) {
1266                 commit_parameters(snum);
1267                 if (snum >= iNumNonAutoPrintServices)
1268                     save_reload(snum);
1269                 else
1270                     save_reload(-1);
1271                 snum = lp_servicenumber(share);
1272         }
1273
1274         if (cgi_variable("Delete") && snum >= 0) {
1275                 lp_remove_service(snum);
1276                 save_reload(-1);
1277                 share = NULL;
1278                 snum = -1;
1279         }
1280
1281         if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1282                 snum = lp_servicenumber(share);
1283                 if (snum < 0 || snum >= iNumNonAutoPrintServices) {
1284                         load_config(False);
1285                         lp_copy_service(GLOBAL_SECTION_SNUM, share);
1286                         snum = lp_servicenumber(share);
1287                         lp_do_parameter(snum, "print ok", "Yes");
1288                         save_reload(snum);
1289                         snum = lp_servicenumber(share);
1290                 }
1291         }
1292
1293         printf("<FORM name=\"swatform\" method=post>\n");
1294
1295         if ( cgi_variable("ViewMode") )
1296                 mode = atoi(cgi_variable_nonull("ViewMode"));
1297         if ( cgi_variable("BasicMode"))
1298                 mode = 0;
1299         if ( cgi_variable("AdvMode"))
1300                 mode = 1;
1301
1302         ViewModeBoxes( mode );
1303         switch ( mode ) {
1304                 case 0:
1305                         parm_filter = FLAG_BASIC;
1306                         break;
1307                 case 1:
1308                         parm_filter = FLAG_ADVANCED;
1309                         break;
1310         }
1311         printf("<table>\n");
1312         printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1313         printf("<td><select name=\"share\">\n");
1314         if (snum < 0 || !lp_print_ok(snum))
1315                 printf("<option value=\" \"> \n");
1316         for (i=0;i<lp_numservices();i++) {
1317                 s = lp_servicename(i);
1318                 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1319                     if (i >= iNumNonAutoPrintServices)
1320                         printf("<option %s value=\"%s\">[*]%s\n",
1321                                (share && strcmp(share,s)==0)?"SELECTED":"",
1322                                s, s);
1323                     else
1324                         printf("<option %s value=\"%s\">%s\n", 
1325                                (share && strcmp(share,s)==0)?"SELECTED":"",
1326                                s, s);
1327                 }
1328         }
1329         printf("</select></td>");
1330         if (have_write_access) {
1331                 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1332         }
1333         printf("</tr>");
1334         printf("</table>\n");
1335
1336         if (have_write_access) {
1337                 printf("<table>\n");
1338                 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1339                 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1340                 printf("</table>");
1341         }
1342
1343
1344         if (snum >= 0) {
1345                 if (have_write_access) {
1346                         printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1347                 }
1348                 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1349                 printf("<p>\n");
1350         }
1351
1352         if (snum >= 0) {
1353                 printf("<table>\n");
1354                 show_parameters(snum, 1, parm_filter, 1);
1355                 printf("</table>\n");
1356         }
1357         printf("</FORM>\n");
1358 }
1359
1360 /*
1361   when the _() translation macro is used there is no obvious place to free
1362   the resulting string and there is no easy way to give a static pointer.
1363   All we can do is rotate between some static buffers and hope a single d_printf()
1364   doesn't have more calls to _() than the number of buffers
1365 */
1366
1367 const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1368 {
1369         const char *msgstr;
1370         const char *ret;
1371
1372         msgstr = lang_msg(msgid);
1373         if (!msgstr) {
1374                 return msgid;
1375         }
1376
1377         ret = talloc_strdup(ctx, msgstr);
1378
1379         lang_msg_free(msgstr);
1380         if (!ret) {
1381                 return msgid;
1382         }
1383
1384         return ret;
1385 }
1386
1387 /**
1388  * main function for SWAT.
1389  **/
1390  int main(int argc, char *argv[])
1391 {
1392         const char *page;
1393         poptContext pc;
1394         struct poptOption long_options[] = {
1395                 POPT_AUTOHELP
1396                 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1397                 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" }, 
1398                 POPT_COMMON_SAMBA
1399                 POPT_TABLEEND
1400         };
1401         TALLOC_CTX *frame = talloc_stackframe();
1402
1403         fault_setup();
1404         umask(S_IWGRP | S_IWOTH);
1405
1406 #if defined(HAVE_SET_AUTH_PARAMETERS)
1407         set_auth_parameters(argc, argv);
1408 #endif /* HAVE_SET_AUTH_PARAMETERS */
1409
1410         /* just in case it goes wild ... */
1411         alarm(300);
1412
1413         setlinebuf(stdout);
1414
1415         /* we don't want any SIGPIPE messages */
1416         BlockSignals(True,SIGPIPE);
1417
1418         debug_set_logfile("/dev/null");
1419
1420         /* we don't want stderr screwing us up */
1421         close(2);
1422         open("/dev/null", O_WRONLY);
1423         setup_logging("swat", DEBUG_FILE);
1424
1425         load_case_tables();
1426         
1427         pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1428
1429         /* Parse command line options */
1430
1431         while(poptGetNextOpt(pc) != -1) { }
1432
1433         poptFreeContext(pc);
1434
1435         /* This should set a more apporiate log file */
1436         load_config(True);
1437         reopen_logs();
1438         load_interfaces();
1439         iNumNonAutoPrintServices = lp_numservices();
1440         if (pcap_cache_loaded()) {
1441                 load_printers(server_event_context(),
1442                               server_messaging_context());
1443         }
1444
1445         cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1446
1447         print_header();
1448
1449         cgi_load_variables();
1450
1451         if (!file_exist(get_dyn_CONFIGFILE())) {
1452                 have_read_access = True;
1453                 have_write_access = True;
1454         } else {
1455                 /* check if the authenticated user has write access - if not then
1456                    don't show write options */
1457                 have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1458
1459                 /* if the user doesn't have read access to smb.conf then
1460                    don't let them view it */
1461                 have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1462         }
1463
1464         show_main_buttons();
1465
1466         page = cgi_pathinfo();
1467
1468         /* Root gets full functionality */
1469         if (have_read_access && strcmp(page, "globals")==0) {
1470                 globals_page();
1471         } else if (have_read_access && strcmp(page,"shares")==0) {
1472                 shares_page();
1473         } else if (have_read_access && strcmp(page,"printers")==0) {
1474                 printers_page();
1475         } else if (have_read_access && strcmp(page,"status")==0) {
1476                 status_page();
1477         } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1478                 viewconfig_page();
1479         } else if (strcmp(page,"passwd")==0) {
1480                 passwd_page();
1481         } else if (have_read_access && strcmp(page,"wizard")==0) {
1482                 wizard_page();
1483         } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1484                 wizard_params_page();
1485         } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1486                 rewritecfg_file();
1487         } else {
1488                 welcome_page();
1489         }
1490
1491         print_footer();
1492
1493         TALLOC_FREE(frame);
1494         return 0;
1495 }
1496
1497 /** @} **/