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