- new prototypes
[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 = 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\">?</A> %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 = 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 void load_config(void)
386 {
387         if (!lp_load(servicesf,False,True,False)) {
388                 printf("<b>Can't load %s - using defaults</b><p>\n", 
389                        servicesf);
390         }
391 }
392
393 /****************************************************************************
394   spit out the html for a link with an image 
395 ****************************************************************************/
396 static void image_link(char *name,char *hlink, char *src)
397 {
398         printf("<A HREF=\"%s/%s\"><img src=\"/swat/%s\" alt=\"%s\"></A>\n", 
399                cgi_baseurl(), hlink, src, name);
400 }
401
402 /****************************************************************************
403   display the main navigation controls at the top of each page along
404   with a title 
405 ****************************************************************************/
406 static void show_main_buttons(void)
407 {
408         image_link("Home", "", "images/home.gif");
409
410         image_link("Globals", "globals", "images/globals.gif");
411         image_link("Shares", "shares", "images/shares.gif");
412         image_link("Printers", "printers", "images/printers.gif");
413         image_link("Status", "status", "images/status.gif");
414         image_link("View Config", "viewconfig","images/viewconfig.gif");
415         image_link("Password Management", "passwd", "images/passwd.gif");
416
417         printf("<HR>\n");
418 }
419
420 /****************************************************************************
421   display a welcome page  
422 ****************************************************************************/
423 static void welcome_page(void)
424 {
425         include_html("help/welcome.html");
426 }
427
428 /****************************************************************************
429   display the current smb.conf  
430 ****************************************************************************/
431 static void viewconfig_page(void)
432 {
433         int full_view=0;
434
435         if (cgi_variable("full_view")) {
436                 full_view = 1;
437         }
438
439         printf("<H2>Current Config</H2>\n");
440         printf("<form method=post>\n");
441
442         if (full_view) {
443                 printf("<input type=submit name=\"normal_view\" value=\"Normal View\">\n");
444         } else {
445                 printf("<input type=submit name=\"full_view\" value=\"Full View\">\n");
446         }
447
448         printf("<p><pre>");
449         write_config(stdout, full_view);
450         printf("</pre>");
451         printf("</form>\n");
452 }
453
454 /****************************************************************************
455   display a globals editing page  
456 ****************************************************************************/
457 static void globals_page(void)
458 {
459         int advanced = 0;
460
461         printf("<H2>Global Variables</H2>\n");
462
463         if (cgi_variable("Advanced") && !cgi_variable("Basic"))
464                 advanced = 1;
465
466         if (cgi_variable("Commit")) {
467                 commit_parameters(GLOBALS_SNUM);
468                 save_reload();
469         }
470
471         printf("<FORM name=\"swatform\" method=post>\n");
472
473         if (have_write_access) {
474                 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
475         }
476
477         printf("<input type=reset name=\"Reset Values\" value=\"Reset Values\">\n");
478         if (advanced == 0) {
479                 printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
480         } else {
481                 printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
482         }
483         printf("<p>\n");
484         
485         printf("<table>\n");
486         show_parameters(GLOBALS_SNUM, 1, advanced, 0);
487         printf("</table>\n");
488
489         if (advanced) {
490                 printf("<input type=hidden name=\"Advanced\" value=1>\n");
491         }
492
493         printf("</FORM>\n");
494 }
495
496 /****************************************************************************
497   display a shares editing page  
498 ****************************************************************************/
499 static void shares_page(void)
500 {
501         char *share = cgi_variable("share");
502         char *s;
503         int snum=-1;
504         int i;
505         int advanced = 0;
506
507         if (share)
508                 snum = lp_servicenumber(share);
509
510         printf("<H2>Share Parameters</H2>\n");
511
512         if (cgi_variable("Advanced") && !cgi_variable("Basic"))
513                 advanced = 1;
514
515         if (cgi_variable("Commit") && snum >= 0) {
516                 commit_parameters(snum);
517                 save_reload();
518         }
519
520         if (cgi_variable("Delete") && snum >= 0) {
521                 lp_remove_service(snum);
522                 save_reload();
523                 share = NULL;
524                 snum = -1;
525         }
526
527         if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
528                 lp_copy_service(GLOBALS_SNUM, share);
529                 save_reload();
530                 snum = lp_servicenumber(share);
531         }
532
533         printf("<FORM name=\"swatform\" method=post>\n");
534
535         printf("<table>\n");
536         printf("<tr><td><input type=submit name=selectshare value=\"Choose Share\"></td>\n");
537         printf("<td><select name=share>\n");
538         if (snum < 0)
539                 printf("<option value=\" \"> \n");
540         for (i=0;i<lp_numservices();i++) {
541                 s = lp_servicename(i);
542                 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
543                         printf("<option %s value=\"%s\">%s\n", 
544                                (share && strcmp(share,s)==0)?"SELECTED":"",
545                                s, s);
546                 }
547         }
548         printf("</select></td></tr><p>");
549
550         printf("<tr><td><input type=submit name=createshare value=\"Create Share\"></td>\n");
551         printf("<td><input type=text size=30 name=newshare></td></tr>\n");
552         printf("</table>");
553
554
555         if (snum >= 0) {
556                 if (have_write_access) {
557                         printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
558                 }
559
560                 printf("<input type=submit name=\"Delete\" value=\"Delete Share\">\n");
561                 if (advanced == 0) {
562                         printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
563                 } else {
564                         printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
565                 }
566                 printf("<p>\n");
567         }
568
569         if (snum >= 0) {
570                 printf("<table>\n");
571                 show_parameters(snum, 1, advanced, 0);
572                 printf("</table>\n");
573         }
574
575         if (advanced) {
576                 printf("<input type=hidden name=\"Advanced\" value=1>\n");
577         }
578
579         printf("</FORM>\n");
580 }
581
582 /*************************************************************
583 change a password either locally or remotely
584 *************************************************************/
585 static BOOL change_password(const char *remote_machine, char *user_name, 
586                             char *old_passwd, char *new_passwd, 
587                             BOOL add_user, BOOL enable_user, BOOL disable_user)
588 {
589         BOOL ret = False;
590         pstring err_str;
591         pstring msg_str;
592
593         if (demo_mode) {
594                 printf("password change in demo mode rejected\n<p>");
595                 return False;
596         }
597         
598         if (remote_machine != NULL) {
599                 ret = remote_password_change(remote_machine, user_name, old_passwd, 
600                                                                          new_passwd, err_str, sizeof(err_str));
601                 if(*err_str)
602                         printf("%s\n<p>", err_str);
603                 return ret;
604         }
605
606         if(!initialize_password_db()) {
607                 printf("Can't setup password database vectors.\n<p>");
608                 return False;
609         }
610         
611         ret = local_password_change(user_name, False, add_user, enable_user, 
612                                      disable_user, False, new_passwd, err_str, sizeof(err_str),
613                                          msg_str, sizeof(msg_str));
614
615         if(*msg_str)
616                 printf("%s\n<p>", msg_str);
617         if(*err_str)
618                 printf("%s\n<p>", err_str);
619
620         return ret;
621 }
622
623 /****************************************************************************
624   do the stuff required to add or change a password 
625 ****************************************************************************/
626 static void chg_passwd(void)
627 {
628         char *host;
629         BOOL rslt;
630
631         /* Make sure users name has been specified */
632         if (strlen(cgi_variable(SWAT_USER)) == 0) {
633                 printf("<p> Must specify \"User Name\" \n");
634                 return;
635         }
636
637         /*
638          * smbpasswd doesn't require anything but the users name to disable or enable the user,
639          * so if that's what we're doing, skip the rest of the checks
640          */
641         if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG)) {
642
643                 /*
644                  * If current user is not root, make sure old password has been specified 
645                  * If REMOTE change, even root must provide old password 
646                  */
647                 if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
648                     ((cgi_variable(CHG_R_PASSWD_FLAG)) &&  (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
649                         printf("<p> Must specify \"Old Password\" \n");
650                         return;
651                 }
652
653                 /* If changing a users password on a remote hosts we have to know what host */
654                 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
655                         printf("<p> Must specify \"Remote Machine\" \n");
656                         return;
657                 }
658
659                 /* Make sure new passwords have been specified */
660                 if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
661                     (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
662                         printf("<p> Must specify \"New, and Re-typed Passwords\" \n");
663                         return;
664                 }
665
666                 /* Make sure new passwords was typed correctly twice */
667                 if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
668                         printf("<p> Re-typed password didn't match new password\n");
669                         return;
670                 }
671         }
672
673         if (cgi_variable(CHG_R_PASSWD_FLAG)) {
674                 host = cgi_variable(RHOST);
675         } else if (am_root()) {
676                 host = NULL;
677         } else {
678                 host = "127.0.0.1";
679         }
680         rslt = change_password(host,
681                                cgi_variable(SWAT_USER),
682                                cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
683                                cgi_variable(ADD_USER_FLAG)? True : False,
684                                cgi_variable(ENABLE_USER_FLAG)? True : False,
685                                cgi_variable(DISABLE_USER_FLAG)? True : False);
686
687
688         if (rslt == True) {
689                 printf("<p> The passwd for '%s' has been changed. \n", cgi_variable(SWAT_USER));
690         } else {
691                 printf("<p> The passwd for '%s' has NOT been changed. \n",cgi_variable(SWAT_USER));
692         }
693         
694         return;
695 }
696
697 /****************************************************************************
698   display a password editing page  
699 ****************************************************************************/
700 static void passwd_page(void)
701 {
702         char *new_name = cgi_user_name();
703
704         /* 
705          * After the first time through here be nice. If the user
706          * changed the User box text to another users name, remember it.
707          */
708         if (cgi_variable(SWAT_USER)) {
709                 new_name = cgi_variable(SWAT_USER);
710         } 
711
712         if (!new_name) new_name = "";
713
714         printf("<H2>Server Password Management</H2>\n");
715
716         printf("<FORM name=\"swatform\" method=post>\n");
717
718         printf("<table>\n");
719
720         /* 
721          * Create all the dialog boxes for data collection
722          */
723         printf("<tr><td> User Name : </td>\n");
724         printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
725         if (!am_root()) {
726                 printf("<tr><td> Old Password : </td>\n");
727                 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
728         }
729         printf("<tr><td> New Password : </td>\n");
730         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
731         printf("<tr><td> Re-type New Password : </td>\n");
732         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
733
734         /*
735          * Create all the control buttons for requesting action
736          */
737         printf("<tr><td><input type=submit name=%s value=\"Change Password\"></td></tr>\n", CHG_S_PASSWD_FLAG);
738         if (demo_mode || am_root()) {
739                 printf("<tr><td><input type=submit name=%s value=\"Add New User\"></td></tr>\n", ADD_USER_FLAG);
740                 printf("<tr><td><input type=submit name=%s value=\"Disable User\"></td></tr>\n", DISABLE_USER_FLAG);
741                 printf("<tr><td><input type=submit name=%s value=\"Enable User\"></td></tr>\n", ENABLE_USER_FLAG);
742         }
743
744         /*
745          * Do some work if change, add, disable or enable was requested. It could be
746          * this is the first time through this code, so there isn't anything to do.
747          */
748         if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) ||
749             (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
750                 chg_passwd();           
751         }
752
753         printf("</table>\n");
754
755         printf("</FORM>\n");
756
757         printf("<H2>Client/Server Password Management</H2>\n");
758
759         printf("<FORM name=\"swatform\" method=post>\n");
760
761         printf("<table>\n");
762
763         /* 
764          * Create all the dialog boxes for data collection
765          */
766         printf("<tr><td> User Name : </td>\n");
767         printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
768         printf("<tr><td> Old Password : </td>\n");
769         printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
770         printf("<tr><td> New Password : </td>\n");
771         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
772         printf("<tr><td> Re-type New Password : </td>\n");
773         printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
774         printf("<tr><td> Remote Machine : </td>\n");
775         printf("<td><input type=password size=30 name=%s></td></tr>\n",RHOST);
776
777         /*
778          * Create all the control buttons for requesting action
779          */
780         printf("<tr><td><input type=submit name=%s value=\"Change Password\"></td></tr>", CHG_R_PASSWD_FLAG);
781
782         /*
783          * Do some work if a request has been made to change the password somewhere other
784          * than the server. It could be this is the first time through this code, so there 
785          * isn't anything to do.
786          */
787         if (cgi_variable(CHG_R_PASSWD_FLAG)) {
788                 chg_passwd();           
789         }
790
791         printf("</table>");
792
793         printf("</FORM>\n");
794 }
795
796 /****************************************************************************
797   display a printers editing page  
798 ****************************************************************************/
799 static void printers_page(void)
800 {
801         char *share = cgi_variable("share");
802         char *s;
803         int snum=-1;
804         int i;
805         int advanced = 0;
806
807         if (share)
808                 snum = lp_servicenumber(share);
809
810         printf("<H2>Printer Parameters</H2>\n");
811
812         if (cgi_variable("Advanced") && !cgi_variable("Basic"))
813                 advanced = 1;
814
815         if (cgi_variable("Commit") && snum >= 0) {
816                 commit_parameters(snum);
817                 save_reload();
818         }
819
820         if (cgi_variable("Delete") && snum >= 0) {
821                 lp_remove_service(snum);
822                 save_reload();
823                 share = NULL;
824                 snum = -1;
825         }
826
827         if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
828                 lp_copy_service(GLOBALS_SNUM, share);
829                 snum = lp_servicenumber(share);
830                 lp_do_parameter(snum, "print ok", "Yes");
831                 save_reload();
832                 snum = lp_servicenumber(share);
833         }
834
835         printf("<FORM name=\"swatform\" method=post>\n");
836
837         printf("<table>\n");
838         printf("<tr><td><input type=submit name=selectshare value=\"Choose Printer\"></td>\n");
839         printf("<td><select name=share>\n");
840         if (snum < 0 || !lp_print_ok(snum))
841                 printf("<option value=\" \"> \n");
842         for (i=0;i<lp_numservices();i++) {
843                 s = lp_servicename(i);
844                 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
845                         printf("<option %s value=\"%s\">%s\n", 
846                                (share && strcmp(share,s)==0)?"SELECTED":"",
847                                s, s);
848                 }
849         }
850         printf("</select></td></tr><p>");
851
852         printf("<tr><td><input type=submit name=createshare value=\"Create Printer\"></td>\n");
853         printf("<td><input type=text size=30 name=newshare></td></tr>\n");
854         printf("</table>");
855
856
857         if (snum >= 0) {
858                 if (have_write_access) {
859                         printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
860                 }
861                 printf("<input type=submit name=\"Delete\" value=\"Delete Printer\">\n");
862                 if (advanced == 0) {
863                         printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
864                 } else {
865                         printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
866                 }
867                 printf("<p>\n");
868         }
869
870         if (snum >= 0) {
871                 printf("<table>\n");
872                 show_parameters(snum, 1, advanced, 1);
873                 printf("</table>\n");
874         }
875
876         if (advanced) {
877                 printf("<input type=hidden name=\"Advanced\" value=1>\n");
878         }
879
880         printf("</FORM>\n");
881 }
882
883 /****************************************************************************
884   MAIN()
885 ****************************************************************************/
886  int main(int argc, char *argv[])
887 {
888         extern char *optarg;
889         extern int optind;
890         extern FILE *dbf;
891         int opt;
892         char *page;
893
894         /* just in case it goes wild ... */
895         alarm(300);
896
897         dbf = fopen("/dev/null", "w");
898
899         if (!dbf) dbf = stderr;
900
901         while ((opt = getopt(argc, argv,"s:a")) != EOF) {
902                 switch (opt) {
903                 case 's':
904                         pstrcpy(servicesf,optarg);
905                         break;    
906                 case 'a':
907                         demo_mode = True;
908                         break;    
909                 }
910         }
911
912         cgi_setup(SWATDIR, !demo_mode);
913
914         print_header();
915         
916         charset_initialise();
917
918         /* if this binary is setuid then run completely as root */
919         setuid(0);
920
921         load_config();
922
923         cgi_load_variables(NULL);
924
925         show_main_buttons();
926
927         page = cgi_pathinfo();
928
929         /* check if the authenticated user has write access - if not then
930            don't show write options */
931         have_write_access = (access(servicesf,W_OK) == 0);
932
933         /* Root gets full functionality */
934         if (strcmp(page, "globals")==0) {
935                 globals_page();
936         } else if (strcmp(page,"shares")==0) {
937                 shares_page();
938         } else if (strcmp(page,"printers")==0) {
939                 printers_page();
940         } else if (strcmp(page,"status")==0) {
941                 status_page();
942         } else if (strcmp(page,"viewconfig")==0) {
943                 viewconfig_page();
944         } else if (strcmp(page,"passwd")==0) {
945                 passwd_page();
946         } else {
947                 welcome_page();
948         }
949
950         print_footer();
951         return 0;
952 }