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