better layout of password options.
[samba.git] / source / 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\">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         pstring err_str;
588         pstring msg_str;
589
590         if (demo_mode) {
591                 printf("password change in demo mode rejected\n<p>");
592                 return False;
593         }
594         
595         if (remote_machine != NULL) {
596                 ret = remote_password_change(remote_machine, user_name, old_passwd, 
597                                                                          new_passwd, err_str, sizeof(err_str));
598                 if(*err_str)
599                         printf("%s\n<p>", err_str);
600                 return ret;
601         }
602
603         if(!initialise_password_db()) {
604                 printf("Can't setup password database vectors.\n<p>");
605                 return False;
606         }
607         
608         ret = local_password_change(user_name, False, add_user, enable_user, 
609                                      disable_user, False, new_passwd, err_str, sizeof(err_str),
610                                          msg_str, sizeof(msg_str));
611
612         if(*msg_str)
613                 printf("%s\n<p>", msg_str);
614         if(*err_str)
615                 printf("%s\n<p>", err_str);
616
617         return ret;
618 }
619
620 /****************************************************************************
621   do the stuff required to add or change a password 
622 ****************************************************************************/
623 static void chg_passwd(void)
624 {
625         char *host;
626         BOOL rslt;
627
628         /* Make sure users name has been specified */
629         if (strlen(cgi_variable(SWAT_USER)) == 0) {
630                 printf("<p> Must specify \"User Name\" \n");
631                 return;
632         }
633
634         /*
635          * smbpasswd doesn't require anything but the users name to disable or enable the user,
636          * so if that's what we're doing, skip the rest of the checks
637          */
638         if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG)) {
639
640                 /*
641                  * If current user is not root, make sure old password has been specified 
642                  * If REMOTE change, even root must provide old password 
643                  */
644                 if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
645                     ((cgi_variable(CHG_R_PASSWD_FLAG)) &&  (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
646                         printf("<p> Must specify \"Old Password\" \n");
647                         return;
648                 }
649
650                 /* If changing a users password on a remote hosts we have to know what host */
651                 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
652                         printf("<p> Must specify \"Remote Machine\" \n");
653                         return;
654                 }
655
656                 /* Make sure new passwords have been specified */
657                 if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
658                     (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
659                         printf("<p> Must specify \"New, and Re-typed Passwords\" \n");
660                         return;
661                 }
662
663                 /* Make sure new passwords was typed correctly twice */
664                 if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
665                         printf("<p> Re-typed password didn't match new password\n");
666                         return;
667                 }
668         }
669
670         if (cgi_variable(CHG_R_PASSWD_FLAG)) {
671                 host = cgi_variable(RHOST);
672         } else if (am_root()) {
673                 host = NULL;
674         } else {
675                 host = "127.0.0.1";
676         }
677         rslt = change_password(host,
678                                cgi_variable(SWAT_USER),
679                                cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
680                                cgi_variable(ADD_USER_FLAG)? True : False,
681                                cgi_variable(ENABLE_USER_FLAG)? True : False,
682                                cgi_variable(DISABLE_USER_FLAG)? True : False);
683
684
685         if (rslt == True) {
686                 printf("<p> The passwd for '%s' has been changed. \n", cgi_variable(SWAT_USER));
687         } else {
688                 printf("<p> The passwd for '%s' has NOT been changed. \n",cgi_variable(SWAT_USER));
689         }
690         
691         return;
692 }
693
694 /****************************************************************************
695   display a password editing page  
696 ****************************************************************************/
697 static void passwd_page(void)
698 {
699         char *new_name = cgi_user_name();
700
701         /* 
702          * After the first time through here be nice. If the user
703          * changed the User box text to another users name, remember it.
704          */
705         if (cgi_variable(SWAT_USER)) {
706                 new_name = cgi_variable(SWAT_USER);
707         } 
708
709         if (!new_name) new_name = "";
710
711         printf("<H2>Server Password Management</H2>\n");
712
713         printf("<FORM name=\"swatform\" method=post>\n");
714
715         printf("<table>\n");
716
717         /* 
718          * Create all the dialog boxes for data collection
719          */
720         printf("<tr><td> User Name : </td>\n");
721         printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
722         if (!am_root()) {
723                 printf("<tr><td> Old Password : </td>\n");
724                 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
725         }
726         printf("<tr><td> New Password : </td>\n");
727         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
728         printf("<tr><td> Re-type New Password : </td>\n");
729         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
730         printf("</table>\n");
731
732         /*
733          * Create all the control buttons for requesting action
734          */
735         printf("<input type=submit name=%s value=\"Change Password\">\n", 
736                CHG_S_PASSWD_FLAG);
737         if (demo_mode || am_root()) {
738                 printf("<input type=submit name=%s value=\"Add New User\">\n",
739                        ADD_USER_FLAG);
740                 printf("<input type=submit name=%s value=\"Disable User\">\n", 
741                        DISABLE_USER_FLAG);
742                 printf("<input type=submit name=%s value=\"Enable User\">\n", 
743                        ENABLE_USER_FLAG);
744         }
745         printf("<p></FORM>\n");
746
747         /*
748          * Do some work if change, add, disable or enable was
749          * requested. It could be this is the first time through this
750          * code, so there isn't anything to do.  */
751         if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) ||
752             (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
753                 chg_passwd();           
754         }
755
756         printf("<H2>Client/Server Password Management</H2>\n");
757
758         printf("<FORM name=\"swatform\" method=post>\n");
759
760         printf("<table>\n");
761
762         /* 
763          * Create all the dialog boxes for data collection
764          */
765         printf("<tr><td> User Name : </td>\n");
766         printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
767         printf("<tr><td> Old Password : </td>\n");
768         printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
769         printf("<tr><td> New Password : </td>\n");
770         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
771         printf("<tr><td> Re-type New Password : </td>\n");
772         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
773         printf("<tr><td> Remote Machine : </td>\n");
774         printf("<td><input type=password size=30 name=%s></td></tr>\n",RHOST);
775
776         printf("</table>");
777
778         /*
779          * Create all the control buttons for requesting action
780          */
781         printf("<input type=submit name=%s value=\"Change Password\">", 
782                CHG_R_PASSWD_FLAG);
783
784         printf("<p></FORM>\n");
785
786         /*
787          * Do some work if a request has been made to change the
788          * password somewhere other than the server. It could be this
789          * is the first time through this code, so there isn't
790          * anything to do.  */
791         if (cgi_variable(CHG_R_PASSWD_FLAG)) {
792                 chg_passwd();           
793         }
794
795 }
796
797 /****************************************************************************
798   display a printers editing page  
799 ****************************************************************************/
800 static void printers_page(void)
801 {
802         char *share = cgi_variable("share");
803         char *s;
804         int snum=-1;
805         int i;
806         int advanced = 0;
807
808         if (share)
809                 snum = lp_servicenumber(share);
810
811         printf("<H2>Printer Parameters</H2>\n");
812
813         if (cgi_variable("Advanced") && !cgi_variable("Basic"))
814                 advanced = 1;
815
816         if (cgi_variable("Commit") && snum >= 0) {
817                 commit_parameters(snum);
818                 save_reload();
819         }
820
821         if (cgi_variable("Delete") && snum >= 0) {
822                 lp_remove_service(snum);
823                 save_reload();
824                 share = NULL;
825                 snum = -1;
826         }
827
828         if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
829                 lp_copy_service(GLOBALS_SNUM, share);
830                 snum = lp_servicenumber(share);
831                 lp_do_parameter(snum, "print ok", "Yes");
832                 save_reload();
833                 snum = lp_servicenumber(share);
834         }
835
836         printf("<FORM name=\"swatform\" method=post>\n");
837
838         printf("<table>\n");
839         printf("<tr><td><input type=submit name=selectshare value=\"Choose Printer\"></td>\n");
840         printf("<td><select name=share>\n");
841         if (snum < 0 || !lp_print_ok(snum))
842                 printf("<option value=\" \"> \n");
843         for (i=0;i<lp_numservices();i++) {
844                 s = lp_servicename(i);
845                 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
846                         printf("<option %s value=\"%s\">%s\n", 
847                                (share && strcmp(share,s)==0)?"SELECTED":"",
848                                s, s);
849                 }
850         }
851         printf("</select></td></tr><p>");
852
853         printf("<tr><td><input type=submit name=createshare value=\"Create Printer\"></td>\n");
854         printf("<td><input type=text size=30 name=newshare></td></tr>\n");
855         printf("</table>");
856
857
858         if (snum >= 0) {
859                 if (have_write_access) {
860                         printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
861                 }
862                 printf("<input type=submit name=\"Delete\" value=\"Delete Printer\">\n");
863                 if (advanced == 0) {
864                         printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
865                 } else {
866                         printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
867                 }
868                 printf("<p>\n");
869         }
870
871         if (snum >= 0) {
872                 printf("<table>\n");
873                 show_parameters(snum, 1, advanced, 1);
874                 printf("</table>\n");
875         }
876
877         if (advanced) {
878                 printf("<input type=hidden name=\"Advanced\" value=1>\n");
879         }
880
881         printf("</FORM>\n");
882 }
883
884 /****************************************************************************
885   MAIN()
886 ****************************************************************************/
887  int main(int argc, char *argv[])
888 {
889         extern char *optarg;
890         extern int optind;
891         extern FILE *dbf;
892         int opt;
893         char *page;
894
895         /* just in case it goes wild ... */
896         alarm(300);
897
898         dbf = sys_fopen("/dev/null", "w");
899
900         if (!dbf) dbf = stderr;
901
902         while ((opt = getopt(argc, argv,"s:a")) != EOF) {
903                 switch (opt) {
904                 case 's':
905                         pstrcpy(servicesf,optarg);
906                         break;    
907                 case 'a':
908                         demo_mode = True;
909                         break;    
910                 }
911         }
912
913         charset_initialise();
914         load_config();
915
916         cgi_setup(SWATDIR, !demo_mode);
917
918         print_header();
919         
920         cgi_load_variables(NULL);
921
922         show_main_buttons();
923
924         page = cgi_pathinfo();
925
926         /* check if the authenticated user has write access - if not then
927            don't show write options */
928         have_write_access = (access(servicesf,W_OK) == 0);
929
930         /* Root gets full functionality */
931         if (strcmp(page, "globals")==0) {
932                 globals_page();
933         } else if (strcmp(page,"shares")==0) {
934                 shares_page();
935         } else if (strcmp(page,"printers")==0) {
936                 printers_page();
937         } else if (strcmp(page,"status")==0) {
938                 status_page();
939         } else if (strcmp(page,"viewconfig")==0) {
940                 viewconfig_page();
941         } else if (strcmp(page,"passwd")==0) {
942                 passwd_page();
943         } else {
944                 welcome_page();
945         }
946
947         print_footer();
948         return 0;
949 }