don't show equivalent enum options in swat
[samba.git] / source3 / web / swat.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Samba Web Administration Tool
5    Copyright (C) Andrew Tridgell 1997-1998
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #ifdef SYSLOG
23 #undef SYSLOG
24 #endif
25
26 #include "includes.h"
27 #include "smb.h"
28
29 #define GLOBALS_SNUM -1
30
31 static pstring servicesf = CONFIGFILE;
32 static BOOL demo_mode = False;
33 static BOOL have_write_access = False;
34 static BOOL have_read_access = False;
35 static int iNumNonAutoPrintServices = 0;
36
37 /*
38  * Password Management Globals
39  */
40 #define SWAT_USER "username"
41 #define OLD_PSWD "old_passwd"
42 #define NEW_PSWD "new_passwd"
43 #define NEW2_PSWD "new2_passwd"
44 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
45 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
46 #define ADD_USER_FLAG "add_user_flag"
47 #define DELETE_USER_FLAG "delete_user_flag"
48 #define DISABLE_USER_FLAG "disable_user_flag"
49 #define ENABLE_USER_FLAG "enable_user_flag"
50 #define RHOST "remote_host"
51
52 /* we need these because we link to locking*.o */
53  void become_root(BOOL save_dir) {}
54  void unbecome_root(BOOL restore_dir) {}
55
56 /****************************************************************************
57 ****************************************************************************/
58 static int enum_index(int value, 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(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 *stripspace(char *str)
81 {
82 static char newstring[1024];
83 char *p = newstring;
84
85         while (*str) {
86                 if (*str != ' ') *p++ = *str;
87                 ++str;
88         }
89         *p = '\0';
90         return newstring;
91 }
92
93 static char *make_parm_name(char *label)
94 {
95         static char parmname[1024];
96         char *p = parmname;
97
98         while (*label) {
99                 if (*label == ' ') *p++ = '_';
100                 else *p++ = *label;
101                 ++label;
102         }
103         *p = '\0';
104         return parmname;
105 }
106
107 /****************************************************************************
108   include a lump of html in a page 
109 ****************************************************************************/
110 static int include_html(char *fname)
111 {
112         FILE *f = sys_fopen(fname,"r");
113         char buf[1024];
114         int ret;
115
116         if (!f) {
117                 printf("ERROR: Can't open %s\n", fname);
118                 return 0;
119         }
120
121         while (!feof(f)) {
122                 ret = fread(buf, 1, sizeof(buf), f);
123                 if (ret <= 0) break;
124                 fwrite(buf, 1, ret, stdout);
125         }
126
127         fclose(f);
128         return 1;
129 }
130
131 /****************************************************************************
132   start the page with standard stuff 
133 ****************************************************************************/
134 static void print_header(void)
135 {
136         if (!cgi_waspost()) {
137                 printf("Expires: 0\r\n");
138         }
139         printf("Content-type: text/html\r\n\r\n");
140
141         if (!include_html("include/header.html")) {
142                 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
143                 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
144         }
145 }
146
147 /****************************************************************************
148  finish off the page 
149 ****************************************************************************/
150 static void print_footer(void)
151 {
152         if (!include_html("include/footer.html")) {
153                 printf("\n</BODY>\n</HTML>\n");
154         }
155 }
156
157 /****************************************************************************
158   display one editable parameter in a form 
159 ****************************************************************************/
160 static void show_parameter(int snum, struct parm_struct *parm)
161 {
162         int i;
163         void *ptr = parm->ptr;
164
165         if (parm->class == P_LOCAL && snum >= 0) {
166                 ptr = lp_local_ptr(snum, ptr);
167         }
168
169         printf("<tr><td><A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\">Help</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s</td><td>", 
170                stripspace(parm->label), parm->label);
171
172         switch (parm->type) {
173         case P_CHAR:
174                 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
175                        make_parm_name(parm->label), *(char *)ptr);
176                 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
177                         make_parm_name(parm->label),(char)(parm->def.cvalue));
178                 break;
179
180         case P_STRING:
181         case P_USTRING:
182                 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
183                        make_parm_name(parm->label), *(char **)ptr);
184                 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
185                         make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
186                 break;
187
188         case P_GSTRING:
189         case P_UGSTRING:
190                 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
191                        make_parm_name(parm->label), (char *)ptr);
192                 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
193                         make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
194                 break;
195
196         case P_BOOL:
197                 printf("<select name=\"parm_%s\">",make_parm_name(parm->label)); 
198                 printf("<option %s>Yes", (*(BOOL *)ptr)?"selected":"");
199                 printf("<option %s>No", (*(BOOL *)ptr)?"":"selected");
200                 printf("</select>");
201                 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
202                         make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?0:1);
203                 break;
204
205         case P_BOOLREV:
206                 printf("<select name=\"parm_%s\">",make_parm_name(parm->label)); 
207                 printf("<option %s>Yes", (*(BOOL *)ptr)?"":"selected");
208                 printf("<option %s>No", (*(BOOL *)ptr)?"selected":"");
209                 printf("</select>");
210                 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
211                         make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?1:0);
212                 break;
213
214         case P_INTEGER:
215                 printf("<input type=text size=8 name=\"parm_%s\" value=%d>", make_parm_name(parm->label), *(int *)ptr);
216                 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
217                         make_parm_name(parm->label),(int)(parm->def.ivalue));
218                 break;
219
220         case P_OCTAL:
221                 printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm->label), octal_string(*(int *)ptr));
222                 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
223                        make_parm_name(parm->label),
224                        octal_string((int)(parm->def.ivalue)));
225                 break;
226
227         case P_ENUM:
228                 printf("<select name=\"parm_%s\">",make_parm_name(parm->label)); 
229                 for (i=0;parm->enum_list[i].name;i++) {
230                         if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
231                                 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
232                         }
233                 }
234                 printf("</select>");
235                 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
236                         make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
237                 break;
238         case P_SEP:
239                 break;
240         }
241         printf("</td></tr>\n");
242 }
243
244 /****************************************************************************
245   display a set of parameters for a service 
246 ****************************************************************************/
247 static void show_parameters(int snum, int allparameters, int advanced, int printers)
248 {
249         int i = 0;
250         struct parm_struct *parm;
251         char *heading = NULL;
252         char *last_heading = NULL;
253
254         while ((parm = lp_next_parameter(snum, &i, allparameters))) {
255                 if (snum < 0 && parm->class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
256                         continue;
257                 if (parm->class == P_SEPARATOR) {
258                         heading = parm->label;
259                         continue;
260                 }
261                 if (parm->flags & FLAG_HIDE) continue;
262                 if (snum >= 0) {
263                         if (printers & !(parm->flags & FLAG_PRINT)) continue;
264                         if (!printers & !(parm->flags & FLAG_SHARE)) continue;
265                 }
266                 if (!advanced) {
267                         if (!(parm->flags & FLAG_BASIC)) {
268                                 void *ptr = parm->ptr;
269
270                                 if (parm->class == P_LOCAL && snum >= 0) {
271                                         ptr = lp_local_ptr(snum, ptr);
272                                 }
273
274                                 switch (parm->type) {
275                                 case P_CHAR:
276                                         if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
277                                         break;
278
279                                 case P_STRING:
280                                 case P_USTRING:
281                                         if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
282                                         break;
283
284                                 case P_GSTRING:
285                                 case P_UGSTRING:
286                                         if (!strcmp((char *)ptr,(char *)(parm->def.svalue))) continue;
287                                         break;
288
289                                 case P_BOOL:
290                                 case P_BOOLREV:
291                                         if (*(BOOL *)ptr == (BOOL)(parm->def.bvalue)) continue;
292                                         break;
293
294                                 case P_INTEGER:
295                                 case P_OCTAL:
296                                         if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
297                                         break;
298
299
300                                 case P_ENUM:
301                                         if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
302                                         break;
303                                 case P_SEP:
304                                         continue;
305                                 }
306                         }
307                         if (printers && !(parm->flags & FLAG_PRINT)) continue;
308                 }
309                 if (heading && heading != last_heading) {
310                         printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", heading);
311                         last_heading = heading;
312                 }
313                 show_parameter(snum, parm);
314         }
315 }
316
317 /****************************************************************************
318   load the smb.conf file into loadparm.
319 ****************************************************************************/
320 static BOOL load_config(BOOL save_def)
321 {
322         lp_resetnumservices();
323         return lp_load(servicesf,False,save_def,False);
324 }
325
326 /****************************************************************************
327   write a config file 
328 ****************************************************************************/
329 static void write_config(FILE *f, BOOL show_defaults)
330 {
331         fprintf(f, "# Samba config file created using SWAT\n");
332         fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
333         fprintf(f, "# Date: %s\n\n", timestring(False));
334         
335         lp_dump(f, show_defaults, iNumNonAutoPrintServices);    
336 }
337
338 /****************************************************************************
339   save and reoad the smb.conf config file 
340 ****************************************************************************/
341 static int save_reload(int snum)
342 {
343         FILE *f;
344
345         f = sys_fopen(servicesf,"w");
346         if (!f) {
347                 printf("failed to open %s for writing\n", servicesf);
348                 return 0;
349         }
350
351         write_config(f, False);
352         if (snum)
353                 lp_dump_one(f, False, snum);
354         fclose(f);
355
356         lp_killunused(NULL);
357
358         if (!load_config(False)) {
359                 printf("Can't reload %s\n", servicesf);
360                 return 0;
361         }
362         iNumNonAutoPrintServices = lp_numservices();
363         load_printers();
364
365         return 1;
366 }
367
368 /****************************************************************************
369   commit one parameter 
370 ****************************************************************************/
371 static void commit_parameter(int snum, struct parm_struct *parm, char *v)
372 {
373         int i;
374         char *s;
375
376         if (snum < 0 && parm->class == P_LOCAL) {
377                 /* this handles the case where we are changing a local
378                    variable globally. We need to change the parameter in 
379                    all shares where it is currently set to the default */
380                 for (i=0;i<lp_numservices();i++) {
381                         s = lp_servicename(i);
382                         if (s && (*s) && lp_is_default(i, parm)) {
383                                 lp_do_parameter(i, parm->label, v);
384                         }
385                 }
386         }
387
388         lp_do_parameter(snum, parm->label, v);
389 }
390
391 /****************************************************************************
392   commit a set of parameters for a service 
393 ****************************************************************************/
394 static void commit_parameters(int snum)
395 {
396         int i = 0;
397         struct parm_struct *parm;
398         pstring label;
399         char *v;
400
401         while ((parm = lp_next_parameter(snum, &i, 1))) {
402                 slprintf(label, sizeof(label)-1, "parm_%s", make_parm_name(parm->label));
403                 if ((v = cgi_variable(label))) {
404                         if (parm->flags & FLAG_HIDE) continue;
405                         commit_parameter(snum, parm, v); 
406                 }
407         }
408 }
409
410 /****************************************************************************
411   spit out the html for a link with an image 
412 ****************************************************************************/
413 static void image_link(char *name,char *hlink, char *src)
414 {
415         printf("<A HREF=\"%s/%s\"><img src=\"/swat/%s\" alt=\"%s\"></A>\n", 
416                cgi_baseurl(), hlink, src, name);
417 }
418
419 /****************************************************************************
420   display the main navigation controls at the top of each page along
421   with a title 
422 ****************************************************************************/
423 static void show_main_buttons(void)
424 {
425         char *p;
426         
427         if ((p = cgi_user_name()) && strcmp(p, "root")) {
428                 printf("Logged in as <b>%s</b><p>\n", p);
429         }
430
431         image_link("Home", "", "images/home.gif");
432         if (have_write_access) {
433                 image_link("Globals", "globals", "images/globals.gif");
434                 image_link("Shares", "shares", "images/shares.gif");
435                 image_link("Printers", "printers", "images/printers.gif");
436         }
437         if (have_read_access) {
438                 image_link("Status", "status", "images/status.gif");
439                 image_link("View Config", "viewconfig","images/viewconfig.gif");
440         }
441         image_link("Password Management", "passwd", "images/passwd.gif");
442
443         printf("<HR>\n");
444 }
445
446 /****************************************************************************
447   display a welcome page  
448 ****************************************************************************/
449 static void welcome_page(void)
450 {
451         include_html("help/welcome.html");
452 }
453
454 /****************************************************************************
455   display the current smb.conf  
456 ****************************************************************************/
457 static void viewconfig_page(void)
458 {
459         int full_view=0;
460
461         if (cgi_variable("full_view")) {
462                 full_view = 1;
463         }
464
465         printf("<H2>Current Config</H2>\n");
466         printf("<form method=post>\n");
467
468         if (full_view) {
469                 printf("<input type=submit name=\"normal_view\" value=\"Normal View\">\n");
470         } else {
471                 printf("<input type=submit name=\"full_view\" value=\"Full View\">\n");
472         }
473
474         printf("<p><pre>");
475         write_config(stdout, full_view);
476         printf("</pre>");
477         printf("</form>\n");
478 }
479
480 /****************************************************************************
481   display a globals editing page  
482 ****************************************************************************/
483 static void globals_page(void)
484 {
485         int advanced = 0;
486
487         printf("<H2>Global Variables</H2>\n");
488
489         if (cgi_variable("Advanced") && !cgi_variable("Basic"))
490                 advanced = 1;
491
492         if (cgi_variable("Commit")) {
493                 commit_parameters(GLOBALS_SNUM);
494                 save_reload(0);
495         }
496
497         printf("<FORM name=\"swatform\" method=post>\n");
498
499         if (have_write_access) {
500                 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
501         }
502
503         printf("<input type=reset name=\"Reset Values\" value=\"Reset Values\">\n");
504         if (advanced == 0) {
505                 printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
506         } else {
507                 printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
508         }
509         printf("<p>\n");
510         
511         printf("<table>\n");
512         show_parameters(GLOBALS_SNUM, 1, advanced, 0);
513         printf("</table>\n");
514
515         if (advanced) {
516                 printf("<input type=hidden name=\"Advanced\" value=1>\n");
517         }
518
519         printf("</FORM>\n");
520 }
521
522 /****************************************************************************
523   display a shares editing page  
524 ****************************************************************************/
525 static void shares_page(void)
526 {
527         char *share = cgi_variable("share");
528         char *s;
529         int snum=-1;
530         int i;
531         int advanced = 0;
532
533         if (share)
534                 snum = lp_servicenumber(share);
535
536         printf("<H2>Share Parameters</H2>\n");
537
538         if (cgi_variable("Advanced") && !cgi_variable("Basic"))
539                 advanced = 1;
540
541         if (cgi_variable("Commit") && snum >= 0) {
542                 commit_parameters(snum);
543                 save_reload(0);
544         }
545
546         if (cgi_variable("Delete") && snum >= 0) {
547                 lp_remove_service(snum);
548                 save_reload(0);
549                 share = NULL;
550                 snum = -1;
551         }
552
553         if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
554                 load_config(False);
555                 lp_copy_service(GLOBALS_SNUM, share);
556                 iNumNonAutoPrintServices = lp_numservices();
557                 save_reload(0);
558                 snum = lp_servicenumber(share);
559         }
560
561         printf("<FORM name=\"swatform\" method=post>\n");
562
563         printf("<table>\n");
564         printf("<tr>\n");
565         printf("<td><input type=submit name=selectshare value=\"Choose Share\"></td>\n");
566         printf("<td><select name=share>\n");
567         if (snum < 0)
568                 printf("<option value=\" \"> \n");
569         for (i=0;i<lp_numservices();i++) {
570                 s = lp_servicename(i);
571                 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
572                         printf("<option %s value=\"%s\">%s\n", 
573                                (share && strcmp(share,s)==0)?"SELECTED":"",
574                                s, s);
575                 }
576         }
577         printf("</select></td>\n");
578         if (have_write_access) {
579                 printf("<td><input type=submit name=\"Delete\" value=\"Delete Share\"></td>\n");
580         }
581         printf("</tr>\n");
582         printf("</table>");
583         printf("<table>");
584         if (have_write_access) {
585                 printf("<tr>\n");
586                 printf("<td><input type=submit name=createshare value=\"Create Share\"></td>\n");
587                 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
588         }
589         printf("</table>");
590
591
592         if (snum >= 0) {
593                 if (have_write_access) {
594                         printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
595                 }
596
597                 printf("<input type=reset name=\"Reset Values\" value=\"Reset Values\">\n");
598                 if (advanced == 0) {
599                         printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
600                 } else {
601                         printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
602                 }
603                 printf("<p>\n");
604         }
605
606         if (snum >= 0) {
607                 printf("<table>\n");
608                 show_parameters(snum, 1, advanced, 0);
609                 printf("</table>\n");
610         }
611
612         if (advanced) {
613                 printf("<input type=hidden name=\"Advanced\" value=1>\n");
614         }
615
616         printf("</FORM>\n");
617 }
618
619 /*************************************************************
620 change a password either locally or remotely
621 *************************************************************/
622 static BOOL change_password(const char *remote_machine, char *user_name, 
623                             char *old_passwd, char *new_passwd, 
624                                 int local_flags)
625 {
626         BOOL ret = False;
627         pstring err_str;
628         pstring msg_str;
629
630         if (demo_mode) {
631                 printf("password change in demo mode rejected\n<p>");
632                 return False;
633         }
634         
635         if (remote_machine != NULL) {
636                 ret = remote_password_change(remote_machine, user_name, old_passwd, 
637                                                                          new_passwd, err_str, sizeof(err_str));
638                 if(*err_str)
639                         printf("%s\n<p>", err_str);
640                 return ret;
641         }
642
643         if(!initialize_password_db()) {
644                 printf("Can't setup password database vectors.\n<p>");
645                 return False;
646         }
647         
648         ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
649                                          msg_str, sizeof(msg_str));
650
651         if(*msg_str)
652                 printf("%s\n<p>", msg_str);
653         if(*err_str)
654                 printf("%s\n<p>", err_str);
655
656         return ret;
657 }
658
659 /****************************************************************************
660   do the stuff required to add or change a password 
661 ****************************************************************************/
662 static void chg_passwd(void)
663 {
664         char *host;
665         BOOL rslt;
666         int local_flags = 0;
667
668         /* Make sure users name has been specified */
669         if (strlen(cgi_variable(SWAT_USER)) == 0) {
670                 printf("<p> Must specify \"User Name\" \n");
671                 return;
672         }
673
674         /*
675          * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
676          * so if that's what we're doing, skip the rest of the checks
677          */
678         if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
679
680                 /*
681                  * If current user is not root, make sure old password has been specified 
682                  * If REMOTE change, even root must provide old password 
683                  */
684                 if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
685                     ((cgi_variable(CHG_R_PASSWD_FLAG)) &&  (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
686                         printf("<p> Must specify \"Old Password\" \n");
687                         return;
688                 }
689
690                 /* If changing a users password on a remote hosts we have to know what host */
691                 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
692                         printf("<p> Must specify \"Remote Machine\" \n");
693                         return;
694                 }
695
696                 /* Make sure new passwords have been specified */
697                 if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
698                     (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
699                         printf("<p> Must specify \"New, and Re-typed Passwords\" \n");
700                         return;
701                 }
702
703                 /* Make sure new passwords was typed correctly twice */
704                 if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
705                         printf("<p> Re-typed password didn't match new password\n");
706                         return;
707                 }
708         }
709
710         if (cgi_variable(CHG_R_PASSWD_FLAG)) {
711                 host = cgi_variable(RHOST);
712         } else if (am_root()) {
713                 host = NULL;
714         } else {
715                 host = "127.0.0.1";
716         }
717
718         /*
719          * Set up the local flags.
720          */
721
722         local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
723         local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
724         local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
725         local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
726
727         rslt = change_password(host,
728                                cgi_variable(SWAT_USER),
729                                cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
730                                    local_flags);
731
732         if(local_flags == 0) {
733                 if (rslt == True) {
734                         printf("<p> The passwd for '%s' has been changed. \n", cgi_variable(SWAT_USER));
735                 } else {
736                         printf("<p> The passwd for '%s' has NOT been changed. \n",cgi_variable(SWAT_USER));
737                 }
738         }
739         
740         return;
741 }
742
743 /****************************************************************************
744   display a password editing page  
745 ****************************************************************************/
746 static void passwd_page(void)
747 {
748         char *new_name = cgi_user_name();
749
750         /* 
751          * After the first time through here be nice. If the user
752          * changed the User box text to another users name, remember it.
753          */
754         if (cgi_variable(SWAT_USER)) {
755                 new_name = cgi_variable(SWAT_USER);
756         } 
757
758         if (!new_name) new_name = "";
759
760         printf("<H2>Server Password Management</H2>\n");
761
762         printf("<FORM name=\"swatform\" method=post>\n");
763
764         printf("<table>\n");
765
766         /* 
767          * Create all the dialog boxes for data collection
768          */
769         printf("<tr><td> User Name : </td>\n");
770         printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
771         if (!am_root()) {
772                 printf("<tr><td> Old Password : </td>\n");
773                 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
774         }
775         printf("<tr><td> New Password : </td>\n");
776         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
777         printf("<tr><td> Re-type New Password : </td>\n");
778         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
779         printf("</table>\n");
780
781         /*
782          * Create all the control buttons for requesting action
783          */
784         printf("<input type=submit name=%s value=\"Change Password\">\n", 
785                CHG_S_PASSWD_FLAG);
786         if (demo_mode || am_root()) {
787                 printf("<input type=submit name=%s value=\"Add New User\">\n",
788                        ADD_USER_FLAG);
789                 printf("<input type=submit name=%s value=\"Delete User\">\n",
790                        DELETE_USER_FLAG);
791                 printf("<input type=submit name=%s value=\"Disable User\">\n", 
792                        DISABLE_USER_FLAG);
793                 printf("<input type=submit name=%s value=\"Enable User\">\n", 
794                        ENABLE_USER_FLAG);
795         }
796         printf("<p></FORM>\n");
797
798         /*
799          * Do some work if change, add, disable or enable was
800          * requested. It could be this is the first time through this
801          * code, so there isn't anything to do.  */
802         if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
803             (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
804                 chg_passwd();           
805         }
806
807         printf("<H2>Client/Server Password Management</H2>\n");
808
809         printf("<FORM name=\"swatform\" method=post>\n");
810
811         printf("<table>\n");
812
813         /* 
814          * Create all the dialog boxes for data collection
815          */
816         printf("<tr><td> User Name : </td>\n");
817         printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
818         printf("<tr><td> Old Password : </td>\n");
819         printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
820         printf("<tr><td> New Password : </td>\n");
821         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
822         printf("<tr><td> Re-type New Password : </td>\n");
823         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
824         printf("<tr><td> Remote Machine : </td>\n");
825         printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
826
827         printf("</table>");
828
829         /*
830          * Create all the control buttons for requesting action
831          */
832         printf("<input type=submit name=%s value=\"Change Password\">", 
833                CHG_R_PASSWD_FLAG);
834
835         printf("<p></FORM>\n");
836
837         /*
838          * Do some work if a request has been made to change the
839          * password somewhere other than the server. It could be this
840          * is the first time through this code, so there isn't
841          * anything to do.  */
842         if (cgi_variable(CHG_R_PASSWD_FLAG)) {
843                 chg_passwd();           
844         }
845
846 }
847
848 /****************************************************************************
849   display a printers editing page  
850 ****************************************************************************/
851 static void printers_page(void)
852 {
853         char *share = cgi_variable("share");
854         char *s;
855         int snum=-1;
856         int i;
857         int advanced = 0;
858
859         if (share)
860                 snum = lp_servicenumber(share);
861
862         printf("<H2>Printer Parameters</H2>\n");
863
864         printf("<H3>Important Note:</H3>\n");
865         printf("Printer names marked with [*] in the Choose Printer drop-down box ");
866         printf("are autoloaded printers from ");
867         printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">Printcap Name</A>.\n");
868         printf("Attempting to delete these printers from SWAT will have no effect.\n");
869
870         if (cgi_variable("Advanced") && !cgi_variable("Basic"))
871                 advanced = 1;
872
873         if (cgi_variable("Commit") && snum >= 0) {
874                 commit_parameters(snum);
875                 if (snum >= iNumNonAutoPrintServices)
876                     save_reload(snum);
877                 else
878                     save_reload(0);
879         }
880
881         if (cgi_variable("Delete") && snum >= 0) {
882                 lp_remove_service(snum);
883                 save_reload(0);
884                 share = NULL;
885                 snum = -1;
886         }
887
888         if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
889                 load_config(False);
890                 lp_copy_service(GLOBALS_SNUM, share);
891                 iNumNonAutoPrintServices = lp_numservices();
892                 snum = lp_servicenumber(share);
893                 lp_do_parameter(snum, "print ok", "Yes");
894                 save_reload(0);
895                 snum = lp_servicenumber(share);
896         }
897
898         printf("<FORM name=\"swatform\" method=post>\n");
899
900         printf("<table>\n");
901         printf("<tr><td><input type=submit name=selectshare value=\"Choose Printer\"></td>\n");
902         printf("<td><select name=share>\n");
903         if (snum < 0 || !lp_print_ok(snum))
904                 printf("<option value=\" \"> \n");
905         for (i=0;i<lp_numservices();i++) {
906                 s = lp_servicename(i);
907                 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
908                     if (i >= iNumNonAutoPrintServices)
909                         printf("<option %s value=\"%s\">[*]%s\n",
910                                (share && strcmp(share,s)==0)?"SELECTED":"",
911                                s, s);
912                     else
913                         printf("<option %s value=\"%s\">%s\n", 
914                                (share && strcmp(share,s)==0)?"SELECTED":"",
915                                s, s);
916                 }
917         }
918         printf("</select></td>");
919         if (have_write_access) {
920                 printf("<td><input type=submit name=\"Delete\" value=\"Delete Printer\"></td>\n");
921         }
922         printf("</tr>");
923         printf("</table>\n");
924
925         if (have_write_access) {
926                 printf("<table>\n");
927                 printf("<tr><td><input type=submit name=createshare value=\"Create Printer\"></td>\n");
928                 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
929                 printf("</table>");
930         }
931
932
933         if (snum >= 0) {
934                 if (have_write_access) {
935                         printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
936                 }
937                 printf("<input type=reset name=\"Reset Values\" value=\"Reset Values\">\n");
938                 if (advanced == 0) {
939                         printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
940                 } else {
941                         printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
942                 }
943                 printf("<p>\n");
944         }
945
946         if (snum >= 0) {
947                 printf("<table>\n");
948                 show_parameters(snum, 1, advanced, 1);
949                 printf("</table>\n");
950         }
951
952         if (advanced) {
953                 printf("<input type=hidden name=\"Advanced\" value=1>\n");
954         }
955
956         printf("</FORM>\n");
957 }
958
959 /****************************************************************************
960   MAIN()
961 ****************************************************************************/
962  int main(int argc, char *argv[])
963 {
964         extern char *optarg;
965         extern int optind;
966         extern FILE *dbf;
967         int opt;
968         char *page;
969
970         fault_setup(NULL);
971
972 #if defined(HAVE_SET_AUTH_PARAMETERS)
973         set_auth_parameters(argc, argv);
974 #endif /* HAVE_SET_AUTH_PARAMETERS */
975
976         /* just in case it goes wild ... */
977         alarm(300);
978
979         /* we don't want any SIGPIPE messages */
980         BlockSignals(True,SIGPIPE);
981
982         dbf = sys_fopen("/dev/null", "w");
983         if (!dbf) dbf = stderr;
984
985         /* we don't want stderr screwing us up */
986         close(2);
987         open("/dev/null", O_WRONLY);
988
989         while ((opt = getopt(argc, argv,"s:a")) != EOF) {
990                 switch (opt) {
991                 case 's':
992                         pstrcpy(servicesf,optarg);
993                         break;    
994                 case 'a':
995                         demo_mode = True;
996                         break;    
997                 }
998         }
999
1000         charset_initialise();
1001         load_config(True);
1002         iNumNonAutoPrintServices = lp_numservices();
1003         load_printers();
1004
1005         cgi_setup(SWATDIR, !demo_mode);
1006
1007         print_header();
1008         
1009         cgi_load_variables(NULL);
1010
1011         if (!file_exist(servicesf, NULL)) {
1012                 have_read_access = True;
1013                 have_write_access = True;
1014         } else {
1015                 /* check if the authenticated user has write access - if not then
1016                    don't show write options */
1017                 have_write_access = (access(servicesf,W_OK) == 0);
1018
1019                 /* if the user doesn't have read access to smb.conf then
1020                    don't let them view it */
1021                 have_read_access = (access(servicesf,R_OK) == 0);
1022         }
1023
1024
1025         show_main_buttons();
1026
1027         page = cgi_pathinfo();
1028
1029         /* Root gets full functionality */
1030         if (have_read_access && strcmp(page, "globals")==0) {
1031                 globals_page();
1032         } else if (have_read_access && strcmp(page,"shares")==0) {
1033                 shares_page();
1034         } else if (have_read_access && strcmp(page,"printers")==0) {
1035                 printers_page();
1036         } else if (have_read_access && strcmp(page,"status")==0) {
1037                 status_page();
1038         } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1039                 viewconfig_page();
1040         } else if (strcmp(page,"passwd")==0) {
1041                 passwd_page();
1042         } else {
1043                 welcome_page();
1044         }
1045
1046         print_footer();
1047         return 0;
1048 }