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