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