Cleanup size_t return values in callers of convert_string_allocate
[kamenim/samba-autobuild/.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         while (*str) {
90                 if ( *str == '\"') {
91                         newstring_len += quote_len;
92                 } else {
93                         newstring_len++;
94                 }
95                 ++str;
96         }
97         newstring = TALLOC_ARRAY(ctx, char, newstring_len);
98         if (!newstring) {
99                 return "";
100         }
101         for (p = newstring; *str; str++) {
102                 if ( *str == '\"') {
103                         strncpy( p, "&quot;", quote_len);
104                         p += quote_len;
105                 } else {
106                         *p++ = *str;
107                 }
108                 ++str;
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_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
388                                         break;
389
390                                 case P_STRING:
391                                 case P_USTRING:
392                                         if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
393                                         break;
394
395                                 case P_BOOL:
396                                 case P_BOOLREV:
397                                         if (*(bool *)ptr == (bool)(parm->def.bvalue)) continue;
398                                         break;
399
400                                 case P_INTEGER:
401                                 case P_OCTAL:
402                                         if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
403                                         break;
404
405
406                                 case P_ENUM:
407                                         if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
408                                         break;
409                                 case P_SEP:
410                                         continue;
411                                         }
412                         }
413                         if (printers && !(parm->flags & FLAG_PRINT)) continue;
414                 }
415
416                 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
417                 
418                 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
419                 
420                 if (heading && heading != last_heading) {
421                         printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
422                         last_heading = heading;
423                 }
424                 show_parameter(snum, parm);
425         }
426 }
427
428 /****************************************************************************
429   load the smb.conf file into loadparm.
430 ****************************************************************************/
431 static bool load_config(bool save_def)
432 {
433         lp_resetnumservices();
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", NULL)) {
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                         iNumNonAutoPrintServices = lp_numservices();
744                         have_home = lp_servicenumber(HOMES_NAME);
745                         lp_do_parameter( have_home, "read only", "No");
746                         lp_do_parameter( have_home, "valid users", "%S");
747                         lp_do_parameter( have_home, "browseable", "No");
748                         commit_parameters(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         }
912
913         if (cgi_variable("Delete") && snum >= 0) {
914                 lp_remove_service(snum);
915                 save_reload(0);
916                 share = NULL;
917                 snum = -1;
918         }
919
920         if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
921                 load_config(False);
922                 lp_copy_service(GLOBAL_SECTION_SNUM, share);
923                 iNumNonAutoPrintServices = lp_numservices();
924                 save_reload(0);
925                 snum = lp_servicenumber(share);
926         }
927
928         printf("<FORM name=\"swatform\" method=post>\n");
929
930         printf("<table>\n");
931
932         if ( cgi_variable("ViewMode") )
933                 mode = atoi(cgi_variable_nonull("ViewMode"));
934         if ( cgi_variable("BasicMode"))
935                 mode = 0;
936         if ( cgi_variable("AdvMode"))
937                 mode = 1;
938
939         ViewModeBoxes( mode );
940         switch ( mode ) {
941                 case 0:
942                         parm_filter = FLAG_BASIC;
943                         break;
944                 case 1:
945                         parm_filter = FLAG_ADVANCED;
946                         break;
947         }
948         printf("<br><tr>\n");
949         printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
950         printf("<td><select name=share>\n");
951         if (snum < 0)
952                 printf("<option value=\" \"> \n");
953         for (i=0;i<lp_numservices();i++) {
954                 s = lp_servicename(i);
955                 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
956                         push_utf8_allocate(&utf8_s, s, &converted_size);
957                         printf("<option %s value=\"%s\">%s\n", 
958                                (share && strcmp(share,s)==0)?"SELECTED":"",
959                                utf8_s, utf8_s);
960                         SAFE_FREE(utf8_s);
961                         
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         }
1265
1266         if (cgi_variable("Delete") && snum >= 0) {
1267                 lp_remove_service(snum);
1268                 save_reload(0);
1269                 share = NULL;
1270                 snum = -1;
1271         }
1272
1273         if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1274                 load_config(False);
1275                 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1276                 iNumNonAutoPrintServices = lp_numservices();
1277                 snum = lp_servicenumber(share);
1278                 lp_do_parameter(snum, "print ok", "Yes");
1279                 save_reload(0);
1280                 snum = lp_servicenumber(share);
1281         }
1282
1283         printf("<FORM name=\"swatform\" method=post>\n");
1284
1285         if ( cgi_variable("ViewMode") )
1286                 mode = atoi(cgi_variable_nonull("ViewMode"));
1287         if ( cgi_variable("BasicMode"))
1288                 mode = 0;
1289         if ( cgi_variable("AdvMode"))
1290                 mode = 1;
1291
1292         ViewModeBoxes( mode );
1293         switch ( mode ) {
1294                 case 0:
1295                         parm_filter = FLAG_BASIC;
1296                         break;
1297                 case 1:
1298                         parm_filter = FLAG_ADVANCED;
1299                         break;
1300         }
1301         printf("<table>\n");
1302         printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1303         printf("<td><select name=\"share\">\n");
1304         if (snum < 0 || !lp_print_ok(snum))
1305                 printf("<option value=\" \"> \n");
1306         for (i=0;i<lp_numservices();i++) {
1307                 s = lp_servicename(i);
1308                 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1309                     if (i >= iNumNonAutoPrintServices)
1310                         printf("<option %s value=\"%s\">[*]%s\n",
1311                                (share && strcmp(share,s)==0)?"SELECTED":"",
1312                                s, s);
1313                     else
1314                         printf("<option %s value=\"%s\">%s\n", 
1315                                (share && strcmp(share,s)==0)?"SELECTED":"",
1316                                s, s);
1317                 }
1318         }
1319         printf("</select></td>");
1320         if (have_write_access) {
1321                 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1322         }
1323         printf("</tr>");
1324         printf("</table>\n");
1325
1326         if (have_write_access) {
1327                 printf("<table>\n");
1328                 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1329                 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1330                 printf("</table>");
1331         }
1332
1333
1334         if (snum >= 0) {
1335                 if (have_write_access) {
1336                         printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1337                 }
1338                 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1339                 printf("<p>\n");
1340         }
1341
1342         if (snum >= 0) {
1343                 printf("<table>\n");
1344                 show_parameters(snum, 1, parm_filter, 1);
1345                 printf("</table>\n");
1346         }
1347         printf("</FORM>\n");
1348 }
1349
1350 /*
1351   when the _() translation macro is used there is no obvious place to free
1352   the resulting string and there is no easy way to give a static pointer.
1353   All we can do is rotate between some static buffers and hope a single d_printf()
1354   doesn't have more calls to _() than the number of buffers
1355 */
1356
1357 const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid)
1358 {
1359         const char *msgstr;
1360         const char *ret;
1361
1362         msgstr = lang_msg(msgid);
1363         if (!msgstr) {
1364                 return msgid;
1365         }
1366
1367         ret = talloc_strdup(ctx, msgstr);
1368
1369         lang_msg_free(msgstr);
1370         if (!ret) {
1371                 return msgid;
1372         }
1373
1374         return ret;
1375 }
1376
1377 /**
1378  * main function for SWAT.
1379  **/
1380  int main(int argc, char *argv[])
1381 {
1382         const char *page;
1383         poptContext pc;
1384         struct poptOption long_options[] = {
1385                 POPT_AUTOHELP
1386                 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1387                 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" }, 
1388                 POPT_COMMON_SAMBA
1389                 POPT_TABLEEND
1390         };
1391         TALLOC_CTX *frame = talloc_stackframe();
1392
1393         fault_setup(NULL);
1394         umask(S_IWGRP | S_IWOTH);
1395
1396 #if defined(HAVE_SET_AUTH_PARAMETERS)
1397         set_auth_parameters(argc, argv);
1398 #endif /* HAVE_SET_AUTH_PARAMETERS */
1399
1400         /* just in case it goes wild ... */
1401         alarm(300);
1402
1403         setlinebuf(stdout);
1404
1405         /* we don't want any SIGPIPE messages */
1406         BlockSignals(True,SIGPIPE);
1407
1408         dbf = x_fopen("/dev/null", O_WRONLY, 0);
1409         if (!dbf) dbf = x_stderr;
1410
1411         /* we don't want stderr screwing us up */
1412         close(2);
1413         open("/dev/null", O_WRONLY);
1414
1415         pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1416
1417         /* Parse command line options */
1418
1419         while(poptGetNextOpt(pc) != -1) { }
1420
1421         poptFreeContext(pc);
1422
1423         load_case_tables();
1424
1425         setup_logging(argv[0],False);
1426         load_config(True);
1427         load_interfaces();
1428         iNumNonAutoPrintServices = lp_numservices();
1429         load_printers();
1430
1431         cgi_setup(get_dyn_SWATDIR(), !demo_mode);
1432
1433         print_header();
1434
1435         cgi_load_variables();
1436
1437         if (!file_exist(get_dyn_CONFIGFILE(), NULL)) {
1438                 have_read_access = True;
1439                 have_write_access = True;
1440         } else {
1441                 /* check if the authenticated user has write access - if not then
1442                    don't show write options */
1443                 have_write_access = (access(get_dyn_CONFIGFILE(),W_OK) == 0);
1444
1445                 /* if the user doesn't have read access to smb.conf then
1446                    don't let them view it */
1447                 have_read_access = (access(get_dyn_CONFIGFILE(),R_OK) == 0);
1448         }
1449
1450         show_main_buttons();
1451
1452         page = cgi_pathinfo();
1453
1454         /* Root gets full functionality */
1455         if (have_read_access && strcmp(page, "globals")==0) {
1456                 globals_page();
1457         } else if (have_read_access && strcmp(page,"shares")==0) {
1458                 shares_page();
1459         } else if (have_read_access && strcmp(page,"printers")==0) {
1460                 printers_page();
1461         } else if (have_read_access && strcmp(page,"status")==0) {
1462                 status_page();
1463         } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1464                 viewconfig_page();
1465         } else if (strcmp(page,"passwd")==0) {
1466                 passwd_page();
1467         } else if (have_read_access && strcmp(page,"wizard")==0) {
1468                 wizard_page();
1469         } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1470                 wizard_params_page();
1471         } else if (have_read_access && strcmp(page,"rewritecfg")==0) {
1472                 rewritecfg_file();
1473         } else {
1474                 welcome_page();
1475         }
1476
1477         print_footer();
1478
1479         TALLOC_FREE(frame);
1480         return 0;
1481 }
1482
1483 /** @} **/