old merge from 2.2
[Samba/gbeck.git] / source / web / swat.c
blob3deaafbc76d5ceef3384389c555e400bc9e7a065
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 Samba Web Administration Tool
5 Copyright (C) Andrew Tridgell 1997-1998
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.
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.
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.
22 #include "includes.h"
24 #define GLOBALS_SNUM -1
26 static pstring servicesf = CONFIGFILE;
27 static BOOL demo_mode = False;
28 static BOOL have_write_access = False;
29 static BOOL have_read_access = False;
30 static int iNumNonAutoPrintServices = 0;
33 * Password Management Globals
35 #define SWAT_USER "username"
36 #define OLD_PSWD "old_passwd"
37 #define NEW_PSWD "new_passwd"
38 #define NEW2_PSWD "new2_passwd"
39 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
40 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
41 #define ADD_USER_FLAG "add_user_flag"
42 #define DELETE_USER_FLAG "delete_user_flag"
43 #define DISABLE_USER_FLAG "disable_user_flag"
44 #define ENABLE_USER_FLAG "enable_user_flag"
45 #define RHOST "remote_host"
47 /* we need these because we link to locking*.o */
48 void become_root(void) {}
49 void unbecome_root(void) {}
51 /****************************************************************************
52 ****************************************************************************/
53 static int enum_index(int value, struct enum_list *enumlist)
55 int i;
56 for (i=0;enumlist[i].name;i++)
57 if (value == enumlist[i].value) break;
58 return(i);
61 static char *fix_backslash(char *str)
63 static char newstring[1024];
64 char *p = newstring;
66 while (*str) {
67 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
68 else *p++ = *str;
69 ++str;
71 *p = '\0';
72 return newstring;
75 static char *stripspace(char *str)
77 static char newstring[1024];
78 char *p = newstring;
80 while (*str) {
81 if (*str != ' ') *p++ = *str;
82 ++str;
84 *p = '\0';
85 return newstring;
88 static char *make_parm_name(char *label)
90 static char parmname[1024];
91 char *p = parmname;
93 while (*label) {
94 if (*label == ' ') *p++ = '_';
95 else *p++ = *label;
96 ++label;
98 *p = '\0';
99 return parmname;
102 /****************************************************************************
103 include a lump of html in a page
104 ****************************************************************************/
105 static int include_html(char *fname)
107 int fd;
108 char buf[1024];
109 int ret;
111 fd = web_open(fname, O_RDONLY, 0);
113 if (fd == -1) {
114 d_printf("ERROR: Can't open %s\n", fname);
115 return 0;
118 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
119 write(1, buf, ret);
122 close(fd);
123 return 1;
126 /****************************************************************************
127 start the page with standard stuff
128 ****************************************************************************/
129 static void print_header(void)
131 if (!cgi_waspost()) {
132 d_printf("Expires: 0\r\n");
134 d_printf("Content-type: text/html\r\n\r\n");
136 if (!include_html("include/header.html")) {
137 d_printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
138 d_printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
142 /* *******************************************************************
143 show parameter label with translated name in the following form
144 because showing original and translated label in one line looks
145 too long, and showing translated label only is unusable for
146 heavy users.
147 -------------------------------
148 HELP security [combo box][button]
149 SECURITY
150 -------------------------------
151 (capital words are translated by gettext.)
152 if no translation is available, then same form as original is
153 used.
154 "i18n_translated_parm" class is used to change the color of the
155 translated parameter with CSS.
156 **************************************************************** */
157 static const char* get_parm_translated(
158 const char* pAnchor, const char* pHelp, const char* pLabel)
160 const char* pTranslated = _(pLabel);
161 static pstring output;
162 if(strcmp(pLabel, pTranslated) != 0)
164 snprintf(output, sizeof(output),
165 "<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>",
166 pAnchor, pHelp, pLabel, pTranslated);
167 return output;
169 snprintf(output, sizeof(output),
170 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
171 pAnchor, pHelp, pLabel);
172 return output;
174 /****************************************************************************
175 finish off the page
176 ****************************************************************************/
177 static void print_footer(void)
179 if (!include_html("include/footer.html")) {
180 d_printf("\n</BODY>\n</HTML>\n");
184 /****************************************************************************
185 display one editable parameter in a form
186 ****************************************************************************/
187 static void show_parameter(int snum, struct parm_struct *parm)
189 int i;
190 void *ptr = parm->ptr;
192 if (parm->class == P_LOCAL && snum >= 0) {
193 ptr = lp_local_ptr(snum, ptr);
196 printf("<tr><td>%s</td><td>", get_parm_translated(stripspace(parm->label), _("Help"), parm->label));
197 switch (parm->type) {
198 case P_CHAR:
199 d_printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
200 make_parm_name(parm->label), *(char *)ptr);
201 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
202 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
203 break;
205 case P_LIST:
206 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"",
207 make_parm_name(parm->label));
208 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
209 char **list = *(char ***)ptr;
210 for (;*list;list++) {
211 d_printf("%s%s", *list, ((*(list+1))?" ":""));
214 d_printf("\">");
215 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
216 _("Set Default"), make_parm_name(parm->label));
217 if (parm->def.lvalue) {
218 char **list = (char **)(parm->def.lvalue);
219 for (; *list; list++) {
220 d_printf("%s%s", *list, ((*(list+1))?" ":""));
223 d_printf("\'\">");
224 break;
226 case P_STRING:
227 case P_USTRING:
228 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
229 make_parm_name(parm->label), *(char **)ptr);
230 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
231 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
232 break;
234 case P_GSTRING:
235 case P_UGSTRING:
236 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
237 make_parm_name(parm->label), (char *)ptr);
238 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
239 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
240 break;
242 case P_BOOL:
243 d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
244 d_printf("<option %s>Yes", (*(BOOL *)ptr)?"selected":"");
245 d_printf("<option %s>No", (*(BOOL *)ptr)?"":"selected");
246 d_printf("</select>");
247 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
248 _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?0:1);
249 break;
251 case P_BOOLREV:
252 d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
253 d_printf("<option %s>Yes", (*(BOOL *)ptr)?"":"selected");
254 d_printf("<option %s>No", (*(BOOL *)ptr)?"selected":"");
255 d_printf("</select>");
256 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
257 _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?1:0);
258 break;
260 case P_INTEGER:
261 d_printf("<input type=text size=8 name=\"parm_%s\" value=%d>", make_parm_name(parm->label), *(int *)ptr);
262 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
263 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
264 break;
266 case P_OCTAL:
267 d_printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm->label), octal_string(*(int *)ptr));
268 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
269 _("Set Default"), make_parm_name(parm->label),
270 octal_string((int)(parm->def.ivalue)));
271 break;
273 case P_ENUM:
274 d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
275 for (i=0;parm->enum_list[i].name;i++) {
276 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
277 d_printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
280 d_printf("</select>");
281 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
282 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
283 break;
284 case P_SEP:
285 break;
287 d_printf("</td></tr>\n");
290 /****************************************************************************
291 display a set of parameters for a service
292 ****************************************************************************/
293 static void show_parameters(int snum, int allparameters, int advanced, int printers)
295 int i = 0;
296 struct parm_struct *parm;
297 char *heading = NULL;
298 char *last_heading = NULL;
300 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
301 if (snum < 0 && parm->class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
302 continue;
303 if (parm->class == P_SEPARATOR) {
304 heading = parm->label;
305 continue;
307 if (parm->flags & FLAG_HIDE) continue;
308 if (snum >= 0) {
309 if (printers & !(parm->flags & FLAG_PRINT)) continue;
310 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
312 if (!advanced) {
313 if (!(parm->flags & FLAG_BASIC)) {
314 void *ptr = parm->ptr;
316 if (parm->class == P_LOCAL && snum >= 0) {
317 ptr = lp_local_ptr(snum, ptr);
320 switch (parm->type) {
321 case P_CHAR:
322 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
323 break;
325 case P_LIST:
326 if (!lp_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
327 break;
329 case P_STRING:
330 case P_USTRING:
331 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
332 break;
334 case P_GSTRING:
335 case P_UGSTRING:
336 if (!strcmp((char *)ptr,(char *)(parm->def.svalue))) continue;
337 break;
339 case P_BOOL:
340 case P_BOOLREV:
341 if (*(BOOL *)ptr == (BOOL)(parm->def.bvalue)) continue;
342 break;
344 case P_INTEGER:
345 case P_OCTAL:
346 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
347 break;
350 case P_ENUM:
351 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
352 break;
353 case P_SEP:
354 continue;
357 if (printers && !(parm->flags & FLAG_PRINT)) continue;
359 if (heading && heading != last_heading) {
360 d_printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
361 last_heading = heading;
363 show_parameter(snum, parm);
367 /****************************************************************************
368 load the smb.conf file into loadparm.
369 ****************************************************************************/
370 static BOOL load_config(BOOL save_def)
372 lp_resetnumservices();
373 return lp_load(servicesf,False,save_def,False);
376 /****************************************************************************
377 write a config file
378 ****************************************************************************/
379 static void write_config(FILE *f, BOOL show_defaults)
381 fprintf(f, "# Samba config file created using SWAT\n");
382 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
383 fprintf(f, "# Date: %s\n\n", timestring(False));
385 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
388 /****************************************************************************
389 save and reoad the smb.conf config file
390 ****************************************************************************/
391 static int save_reload(int snum)
393 FILE *f;
394 struct stat st;
396 f = sys_fopen(servicesf,"w");
397 if (!f) {
398 d_printf("failed to open %s for writing\n", servicesf);
399 return 0;
402 /* just in case they have used the buggy xinetd to create the file */
403 if (fstat(fileno(f), &st) == 0 &&
404 (st.st_mode & S_IWOTH)) {
405 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
408 write_config(f, False);
409 if (snum)
410 lp_dump_one(f, False, snum);
411 fclose(f);
413 lp_killunused(NULL);
415 if (!load_config(False)) {
416 d_printf("Can't reload %s\n", servicesf);
417 return 0;
419 iNumNonAutoPrintServices = lp_numservices();
420 load_printers();
422 return 1;
425 /****************************************************************************
426 commit one parameter
427 ****************************************************************************/
428 static void commit_parameter(int snum, struct parm_struct *parm, char *v)
430 int i;
431 char *s;
433 if (snum < 0 && parm->class == P_LOCAL) {
434 /* this handles the case where we are changing a local
435 variable globally. We need to change the parameter in
436 all shares where it is currently set to the default */
437 for (i=0;i<lp_numservices();i++) {
438 s = lp_servicename(i);
439 if (s && (*s) && lp_is_default(i, parm)) {
440 lp_do_parameter(i, parm->label, v);
445 lp_do_parameter(snum, parm->label, v);
448 /****************************************************************************
449 commit a set of parameters for a service
450 ****************************************************************************/
451 static void commit_parameters(int snum)
453 int i = 0;
454 struct parm_struct *parm;
455 pstring label;
456 char *v;
458 while ((parm = lp_next_parameter(snum, &i, 1))) {
459 slprintf(label, sizeof(label)-1, "parm_%s", make_parm_name(parm->label));
460 if ((v = cgi_variable(label))) {
461 if (parm->flags & FLAG_HIDE) continue;
462 commit_parameter(snum, parm, v);
467 /****************************************************************************
468 spit out the html for a link with an image
469 ****************************************************************************/
470 static void image_link(const char *name, const char *hlink, const char *src)
472 d_printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
473 cgi_baseurl(), hlink, src, name);
476 /****************************************************************************
477 display the main navigation controls at the top of each page along
478 with a title
479 ****************************************************************************/
480 static void show_main_buttons(void)
482 char *p;
484 if ((p = cgi_user_name()) && strcmp(p, "root")) {
485 d_printf(_("Logged in as <b>%s</b><p>\n"), p);
488 image_link(_("Home"), "", "images/home.gif");
489 if (have_write_access) {
490 image_link(_("Globals"), "globals", "images/globals.gif");
491 image_link(_("Shares"), "shares", "images/shares.gif");
492 image_link(_("Printers"), "printers", "images/printers.gif");
494 if (have_read_access) {
495 image_link(_("Status"), "status", "images/status.gif");
496 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
498 image_link(_("Password Management"), "passwd", "images/passwd.gif");
500 d_printf("<HR>\n");
503 /****************************************************************************
504 display a welcome page
505 ****************************************************************************/
506 static void welcome_page(void)
508 include_html("help/welcome.html");
511 /****************************************************************************
512 display the current smb.conf
513 ****************************************************************************/
514 static void viewconfig_page(void)
516 int full_view=0;
518 if (cgi_variable("full_view")) {
519 full_view = 1;
522 d_printf("<H2>%s</H2>\n", _("Current Config"));
523 d_printf("<form method=post>\n");
525 if (full_view) {
526 d_printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
527 } else {
528 d_printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
531 d_printf("<p><pre>");
532 write_config(stdout, full_view);
533 d_printf("</pre>");
534 d_printf("</form>\n");
537 /****************************************************************************
538 display a globals editing page
539 ****************************************************************************/
540 static void globals_page(void)
542 int advanced = 0;
544 d_printf("<H2>%s</H2>\n", _("Global Variables"));
546 if (cgi_variable("Advanced") && !cgi_variable("Basic"))
547 advanced = 1;
549 if (cgi_variable("Commit")) {
550 commit_parameters(GLOBALS_SNUM);
551 save_reload(0);
554 d_printf("<FORM name=\"swatform\" method=post>\n");
556 if (have_write_access) {
557 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
558 _("Commit Changes"));
561 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
562 _("Reset Values"));
563 if (advanced == 0) {
564 d_printf("<input type=submit name=\"Advanced\" value=\"%s\">\n", _("Advanced View"));
565 } else {
566 d_printf("<input type=submit name=\"Basic\" value=\"%s\">\n", _("Basic View"));
568 d_printf("<p>\n");
570 d_printf("<table>\n");
571 show_parameters(GLOBALS_SNUM, 1, advanced, 0);
572 d_printf("</table>\n");
574 if (advanced) {
575 d_printf("<input type=hidden name=\"Advanced\" value=1>\n");
578 d_printf("</FORM>\n");
581 /****************************************************************************
582 display a shares editing page. share is in unix codepage, and must be in
583 dos codepage. FIXME !!! JRA.
584 ****************************************************************************/
585 static void shares_page(void)
587 char *share = cgi_variable("share");
588 char *s;
589 int snum = -1;
590 int i;
591 int advanced = 0;
593 if (share)
594 snum = lp_servicenumber(share);
596 d_printf("<H2>%s</H2>\n", _("Share Parameters"));
598 if (cgi_variable("Advanced") && !cgi_variable("Basic"))
599 advanced = 1;
601 if (cgi_variable("Commit") && snum >= 0) {
602 commit_parameters(snum);
603 save_reload(0);
606 if (cgi_variable("Delete") && snum >= 0) {
607 lp_remove_service(snum);
608 save_reload(0);
609 share = NULL;
610 snum = -1;
613 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
614 load_config(False);
615 lp_copy_service(GLOBALS_SNUM, share);
616 iNumNonAutoPrintServices = lp_numservices();
617 save_reload(0);
618 snum = lp_servicenumber(share);
621 d_printf("<FORM name=\"swatform\" method=post>\n");
623 d_printf("<table>\n");
624 d_printf("<tr>\n");
625 d_printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
626 d_printf("<td><select name=share>\n");
627 if (snum < 0)
628 d_printf("<option value=\" \"> \n");
629 for (i=0;i<lp_numservices();i++) {
630 s = lp_servicename(i);
631 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
632 d_printf("<option %s value=\"%s\">%s\n",
633 (share && strcmp(share,s)==0)?"SELECTED":"",
634 s, s);
637 d_printf("</select></td>\n");
638 if (have_write_access) {
639 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
641 d_printf("</tr>\n");
642 d_printf("</table>");
643 d_printf("<table>");
644 if (have_write_access) {
645 d_printf("<tr>\n");
646 d_printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
647 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
649 d_printf("</table>");
652 if (snum >= 0) {
653 if (have_write_access) {
654 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
657 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
658 if (advanced == 0) {
659 d_printf("<input type=submit name=\"Advanced\" value=\"%s\">\n", _("Advanced View"));
660 } else {
661 d_printf("<input type=submit name=\"Basic\" value=\"%s\">\n", _("Basic View"));
663 d_printf("<p>\n");
666 if (snum >= 0) {
667 d_printf("<table>\n");
668 show_parameters(snum, 1, advanced, 0);
669 d_printf("</table>\n");
672 if (advanced) {
673 d_printf("<input type=hidden name=\"Advanced\" value=1>\n");
676 d_printf("</FORM>\n");
679 /*************************************************************
680 change a password either locally or remotely
681 *************************************************************/
682 static BOOL change_password(const char *remote_machine, char *user_name,
683 char *old_passwd, char *new_passwd,
684 int local_flags)
686 BOOL ret = False;
687 pstring err_str;
688 pstring msg_str;
690 if (demo_mode) {
691 d_printf("%s<p>", _("password change in demo mode rejected\n"));
692 return False;
695 if (remote_machine != NULL) {
696 ret = remote_password_change(remote_machine, user_name, old_passwd,
697 new_passwd, err_str, sizeof(err_str));
698 if(*err_str)
699 d_printf("%s\n<p>", err_str);
700 return ret;
703 if(!initialize_password_db(True)) {
704 d_printf("Can't setup password database vectors.\n<p>");
705 return False;
708 ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
709 msg_str, sizeof(msg_str));
711 if(*msg_str)
712 d_printf("%s\n<p>", msg_str);
713 if(*err_str)
714 d_printf("%s\n<p>", err_str);
716 return ret;
719 /****************************************************************************
720 do the stuff required to add or change a password
721 ****************************************************************************/
722 static void chg_passwd(void)
724 char *host;
725 BOOL rslt;
726 int local_flags = 0;
728 /* Make sure users name has been specified */
729 if (strlen(cgi_variable(SWAT_USER)) == 0) {
730 d_printf("<p>%s", _(" Must specify \"User Name\" \n"));
731 return;
735 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
736 * so if that's what we're doing, skip the rest of the checks
738 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
741 * If current user is not root, make sure old password has been specified
742 * If REMOTE change, even root must provide old password
744 if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
745 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
746 d_printf("<p>%s", _(" Must specify \"Old Password\" \n"));
747 return;
750 /* If changing a users password on a remote hosts we have to know what host */
751 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
752 d_printf("<p>%s", _(" Must specify \"Remote Machine\" \n"));
753 return;
756 /* Make sure new passwords have been specified */
757 if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
758 (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
759 d_printf("<p>%s", _(" Must specify \"New, and Re-typed Passwords\" \n"));
760 return;
763 /* Make sure new passwords was typed correctly twice */
764 if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
765 d_printf("<p>%s", _(" Re-typed password didn't match new password\n"));
766 return;
770 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
771 host = cgi_variable(RHOST);
772 } else if (am_root()) {
773 host = NULL;
774 } else {
775 host = "127.0.0.1";
779 * Set up the local flags.
782 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
783 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
784 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
785 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
787 rslt = change_password(host,
788 cgi_variable(SWAT_USER),
789 cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
790 local_flags);
792 if(local_flags == 0) {
793 d_printf("<p>");
794 if (rslt == True) {
795 d_printf(_(" The passwd for '%s' has been changed. \n"), cgi_variable(SWAT_USER));
796 } else {
797 d_printf(_(" The passwd for '%s' has NOT been changed. \n"), cgi_variable(SWAT_USER));
801 return;
804 /****************************************************************************
805 display a password editing page
806 ****************************************************************************/
807 static void passwd_page(void)
809 char *new_name = cgi_user_name();
812 * After the first time through here be nice. If the user
813 * changed the User box text to another users name, remember it.
815 if (cgi_variable(SWAT_USER)) {
816 new_name = cgi_variable(SWAT_USER);
819 if (!new_name) new_name = "";
821 d_printf("<H2>%s</H2>\n", _("Server Password Management"));
823 d_printf("<FORM name=\"swatform\" method=post>\n");
825 d_printf("<table>\n");
828 * Create all the dialog boxes for data collection
830 d_printf("<tr><td>%s</td>\n", _(" User Name : "));
831 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
832 if (!am_root()) {
833 d_printf("<tr><td>%s</td>\n", _(" Old Password : "));
834 d_printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
836 d_printf("<tr><td>%s</td>\n", _(" New Password : "));
837 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
838 d_printf("<tr><td>%s</td>\n", _(" Re-type New Password : "));
839 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
840 d_printf("</table>\n");
843 * Create all the control buttons for requesting action
845 d_printf("<input type=submit name=%s value=\"%s\">\n",
846 CHG_S_PASSWD_FLAG, _("Change Password"));
847 if (demo_mode || am_root()) {
848 d_printf("<input type=submit name=%s value=\"%s\">\n",
849 ADD_USER_FLAG, _("Add New User"));
850 d_printf("<input type=submit name=%s value=\"%s\">\n",
851 DELETE_USER_FLAG, _("Delete User"));
852 d_printf("<input type=submit name=%s value=\"%s\">\n",
853 DISABLE_USER_FLAG, _("Disable User"));
854 d_printf("<input type=submit name=%s value=\"%s\">\n",
855 ENABLE_USER_FLAG, _("Enable User"));
857 d_printf("<p></FORM>\n");
860 * Do some work if change, add, disable or enable was
861 * requested. It could be this is the first time through this
862 * code, so there isn't anything to do. */
863 if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
864 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
865 chg_passwd();
868 d_printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
870 d_printf("<FORM name=\"swatform\" method=post>\n");
872 d_printf("<table>\n");
875 * Create all the dialog boxes for data collection
877 d_printf("<tr><td>%s</td>\n", _(" User Name : "));
878 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
879 d_printf("<tr><td>%s</td>\n", _(" Old Password : "));
880 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
881 d_printf("<tr><td>%s</td>\n", _(" New Password : "));
882 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
883 d_printf("<tr><td>%s</td>\n", _(" Re-type New Password : "));
884 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
885 d_printf("<tr><td>%s</td>\n", _(" Remote Machine : "));
886 d_printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
888 d_printf("</table>");
891 * Create all the control buttons for requesting action
893 d_printf("<input type=submit name=%s value=\"%s\">",
894 CHG_R_PASSWD_FLAG, _("Change Password"));
896 d_printf("<p></FORM>\n");
899 * Do some work if a request has been made to change the
900 * password somewhere other than the server. It could be this
901 * is the first time through this code, so there isn't
902 * anything to do. */
903 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
904 chg_passwd();
909 /****************************************************************************
910 display a printers editing page
911 ****************************************************************************/
912 static void printers_page(void)
914 char *share = cgi_variable("share");
915 char *s;
916 int snum=-1;
917 int i;
918 int advanced = 0;
920 if (share)
921 snum = lp_servicenumber(share);
923 d_printf("<H2>%s</H2>\n", _("Printer Parameters"));
925 d_printf("<H3>%s</H3>\n", _("Important Note:"));
926 d_printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
927 d_printf(_("are autoloaded printers from "));
928 d_printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
929 d_printf(_("Attempting to delete these printers from SWAT will have no effect.\n"));
931 if (cgi_variable("Advanced") && !cgi_variable("Basic"))
932 advanced = 1;
934 if (cgi_variable("Commit") && snum >= 0) {
935 commit_parameters(snum);
936 if (snum >= iNumNonAutoPrintServices)
937 save_reload(snum);
938 else
939 save_reload(0);
942 if (cgi_variable("Delete") && snum >= 0) {
943 lp_remove_service(snum);
944 save_reload(0);
945 share = NULL;
946 snum = -1;
949 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
950 load_config(False);
951 lp_copy_service(GLOBALS_SNUM, share);
952 iNumNonAutoPrintServices = lp_numservices();
953 snum = lp_servicenumber(share);
954 lp_do_parameter(snum, "print ok", "Yes");
955 save_reload(0);
956 snum = lp_servicenumber(share);
959 d_printf("<FORM name=\"swatform\" method=post>\n");
961 d_printf("<table>\n");
962 d_printf("<tr><td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Printer"));
963 d_printf("<td><select name=share>\n");
964 if (snum < 0 || !lp_print_ok(snum))
965 d_printf("<option value=\" \"> \n");
966 for (i=0;i<lp_numservices();i++) {
967 s = lp_servicename(i);
968 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
969 if (i >= iNumNonAutoPrintServices)
970 d_printf("<option %s value=\"%s\">[*]%s\n",
971 (share && strcmp(share,s)==0)?"SELECTED":"",
972 s, s);
973 else
974 d_printf("<option %s value=\"%s\">%s\n",
975 (share && strcmp(share,s)==0)?"SELECTED":"",
976 s, s);
979 d_printf("</select></td>");
980 if (have_write_access) {
981 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
983 d_printf("</tr>");
984 d_printf("</table>\n");
986 if (have_write_access) {
987 d_printf("<table>\n");
988 d_printf("<tr><td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Printer"));
989 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
990 d_printf("</table>");
994 if (snum >= 0) {
995 if (have_write_access) {
996 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
998 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
999 if (advanced == 0) {
1000 d_printf("<input type=submit name=\"Advanced\" value=\"%s\">\n", _("Advanced View"));
1001 } else {
1002 d_printf("<input type=submit name=\"Basic\" value=\"%s\">\n", _("Basic View"));
1004 d_printf("<p>\n");
1007 if (snum >= 0) {
1008 d_printf("<table>\n");
1009 show_parameters(snum, 1, advanced, 1);
1010 d_printf("</table>\n");
1013 if (advanced) {
1014 d_printf("<input type=hidden name=\"Advanced\" value=1>\n");
1017 d_printf("</FORM>\n");
1020 /****************************************************************************
1021 MAIN()
1022 ****************************************************************************/
1023 int main(int argc, char *argv[])
1025 extern char *optarg;
1026 extern int optind;
1027 int opt;
1028 char *page;
1030 fault_setup(NULL);
1031 umask(S_IWGRP | S_IWOTH);
1033 #if defined(HAVE_SET_AUTH_PARAMETERS)
1034 set_auth_parameters(argc, argv);
1035 #endif /* HAVE_SET_AUTH_PARAMETERS */
1037 /* just in case it goes wild ... */
1038 alarm(300);
1040 setlinebuf(stdout);
1042 /* we don't want any SIGPIPE messages */
1043 BlockSignals(True,SIGPIPE);
1045 dbf = x_fopen("/dev/null", O_WRONLY, 0);
1046 if (!dbf) dbf = x_stderr;
1048 /* we don't want stderr screwing us up */
1049 close(2);
1050 open("/dev/null", O_WRONLY);
1052 while ((opt = getopt(argc, argv,"s:a")) != EOF) {
1053 switch (opt) {
1054 case 's':
1055 pstrcpy(servicesf,optarg);
1056 break;
1057 case 'a':
1058 demo_mode = True;
1059 break;
1063 setup_logging(argv[0],False);
1064 load_config(True);
1065 iNumNonAutoPrintServices = lp_numservices();
1066 load_printers();
1068 cgi_setup(SWATDIR, !demo_mode);
1070 print_header();
1072 cgi_load_variables();
1074 if (!file_exist(servicesf, NULL)) {
1075 have_read_access = True;
1076 have_write_access = True;
1077 } else {
1078 /* check if the authenticated user has write access - if not then
1079 don't show write options */
1080 have_write_access = (access(servicesf,W_OK) == 0);
1082 /* if the user doesn't have read access to smb.conf then
1083 don't let them view it */
1084 have_read_access = (access(servicesf,R_OK) == 0);
1087 show_main_buttons();
1089 page = cgi_pathinfo();
1091 /* Root gets full functionality */
1092 if (have_read_access && strcmp(page, "globals")==0) {
1093 globals_page();
1094 } else if (have_read_access && strcmp(page,"shares")==0) {
1095 shares_page();
1096 } else if (have_read_access && strcmp(page,"printers")==0) {
1097 printers_page();
1098 } else if (have_read_access && strcmp(page,"status")==0) {
1099 status_page();
1100 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1101 viewconfig_page();
1102 } else if (strcmp(page,"passwd")==0) {
1103 passwd_page();
1104 } else {
1105 welcome_page();
1108 print_footer();
1109 return 0;