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