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