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