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