2 Unix SMB/Netbios implementation.
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.
29 #define GLOBALS_SNUM -1
31 static pstring servicesf = CONFIGFILE;
32 static BOOL demo_mode = False;
35 * Password Management Globals
37 #define SWAT_USER "username"
38 #define OLD_PSWD "old_passwd"
39 #define NEW_PSWD "new_passwd"
40 #define NEW2_PSWD "new2_passwd"
41 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
42 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
43 #define ADD_USER_FLAG "add_user_flag"
44 #define DISABLE_USER_FLAG "disable_user_flag"
45 #define ENABLE_USER_FLAG "enable_user_flag"
46 #define RHOST "remote_host"
48 /* we need these because we link to locking*.o */
49 void become_root(BOOL save_dir) {}
50 void unbecome_root(BOOL restore_dir) {}
52 /****************************************************************************
53 ****************************************************************************/
54 static int enum_index(int value, struct enum_list *enumlist)
57 for (i=0;enumlist[i].name;i++)
58 if (value == enumlist[i].value) break;
62 static char *fix_backslash(char *str)
64 static char newstring[1024];
68 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
76 static char *stripspace(char *str)
78 static char newstring[1024];
82 if (*str != ' ') *p++ = *str;
89 static char *make_parm_name(char *label)
91 static char parmname[1024];
95 if (*label == ' ') *p++ = '_';
103 /****************************************************************************
104 include a lump of html in a page
105 ****************************************************************************/
106 static int include_html(char *fname)
108 FILE *f = fopen(fname,"r");
113 printf("ERROR: Can't open %s\n", fname);
118 ret = fread(buf, 1, sizeof(buf), f);
120 fwrite(buf, 1, ret, stdout);
127 /****************************************************************************
128 start the page with standard stuff
129 ****************************************************************************/
130 static void print_header(void)
132 if (!cgi_waspost()) {
133 printf("Expires: 0\r\n");
135 printf("Content-type: text/html\r\n\r\n");
137 if (!include_html("include/header.html")) {
138 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
139 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
143 /****************************************************************************
145 ****************************************************************************/
146 static void print_footer(void)
148 if (!include_html("include/footer.html")) {
149 printf("\n</BODY>\n</HTML>\n");
153 /****************************************************************************
154 display one editable parameter in a form
155 ****************************************************************************/
156 static void show_parameter(int snum, struct parm_struct *parm)
159 void *ptr = parm->ptr;
161 if (parm->class == P_LOCAL && snum >= 0) {
162 ptr = lp_local_ptr(snum, ptr);
165 printf("<tr><td><A HREF=\"/swat/help/smb.conf.5.html#%s\">?</A> %s</td><td>",
166 stripspace(parm->label), parm->label);
168 switch (parm->type) {
170 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
171 make_parm_name(parm->label), *(char *)ptr);
172 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
173 make_parm_name(parm->label),(char)(parm->def.cvalue));
178 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
179 make_parm_name(parm->label), *(char **)ptr);
180 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
181 make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
186 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
187 make_parm_name(parm->label), (char *)ptr);
188 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
189 make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
193 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
194 printf("<option %s>Yes", (*(BOOL *)ptr)?"selected":"");
195 printf("<option %s>No", (*(BOOL *)ptr)?"":"selected");
197 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
198 make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?0:1);
202 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
203 printf("<option %s>Yes", (*(BOOL *)ptr)?"":"selected");
204 printf("<option %s>No", (*(BOOL *)ptr)?"selected":"");
206 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
207 make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?1:0);
211 printf("<input type=text size=8 name=\"parm_%s\" value=%d>", make_parm_name(parm->label), *(int *)ptr);
212 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
213 make_parm_name(parm->label),(int)(parm->def.ivalue));
217 printf("<input type=text size=8 name=\"parm_%s\" value=0%o>", make_parm_name(parm->label), *(int *)ptr);
218 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'0%o\'\">",
219 make_parm_name(parm->label),(int)(parm->def.ivalue));
223 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
224 for (i=0;parm->enum_list[i].name;i++)
225 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
227 printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
228 make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
233 printf("</td></tr>\n");
236 /****************************************************************************
237 display a set of parameters for a service
238 ****************************************************************************/
239 static void show_parameters(int snum, int allparameters, int advanced, int printers)
242 struct parm_struct *parm;
243 char *heading = NULL;
244 char *last_heading = NULL;
246 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
247 if (snum < 0 && parm->class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
249 if (parm->class == P_SEPARATOR) {
250 heading = parm->label;
253 if (parm->flags & FLAG_HIDE) continue;
255 if (!printers && !(parm->flags & FLAG_BASIC)) {
256 void *ptr = parm->ptr;
258 switch (parm->type) {
260 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
265 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
270 if (!strcmp((char *)ptr,(char *)(parm->def.svalue))) continue;
275 if (*(BOOL *)ptr == (BOOL)(parm->def.bvalue)) continue;
280 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
285 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
291 if (printers && !(parm->flags & FLAG_PRINT)) continue;
293 if (heading && heading != last_heading) {
294 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", heading);
295 last_heading = heading;
297 show_parameter(snum, parm);
301 /****************************************************************************
303 ****************************************************************************/
304 static void write_config(FILE *f, BOOL show_defaults)
306 fprintf(f, "# Samba config file created using SWAT\n");
307 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
308 fprintf(f, "# Date: %s\n\n", timestring());
310 lp_dump(f, show_defaults);
313 /****************************************************************************
314 save and reoad the smb.conf config file
315 ****************************************************************************/
316 static int save_reload(void)
320 f = fopen(servicesf,"w");
322 printf("failed to open %s for writing\n", servicesf);
326 write_config(f, False);
331 if (!lp_load(servicesf,False,False,False)) {
332 printf("Can't reload %s\n", servicesf);
339 /****************************************************************************
341 ****************************************************************************/
342 static void commit_parameter(int snum, struct parm_struct *parm, char *v)
347 if (snum < 0 && parm->class == P_LOCAL) {
348 /* this handles the case where we are changing a local
349 variable globally. We need to change the parameter in
350 all shares where it is currently set to the default */
351 for (i=0;i<lp_numservices();i++) {
352 s = lp_servicename(i);
353 if (s && (*s) && lp_is_default(i, parm)) {
354 lp_do_parameter(i, parm->label, v);
359 lp_do_parameter(snum, parm->label, v);
362 /****************************************************************************
363 commit a set of parameters for a service
364 ****************************************************************************/
365 static void commit_parameters(int snum)
368 struct parm_struct *parm;
372 while ((parm = lp_next_parameter(snum, &i, 1))) {
373 slprintf(label, sizeof(label)-1, "parm_%s", make_parm_name(parm->label));
374 if ((v = cgi_variable(label))) {
375 if (parm->flags & FLAG_HIDE) continue;
376 commit_parameter(snum, parm, v);
381 /****************************************************************************
382 load the smb.conf file into loadparm.
383 ****************************************************************************/
384 static void load_config(void)
386 if (!lp_load(servicesf,False,True,False)) {
387 printf("<b>Can't load %s - using defaults</b><p>\n",
392 /****************************************************************************
393 spit out the html for a link with an image
394 ****************************************************************************/
395 static void image_link(char *name,char *hlink, char *src)
397 printf("<A HREF=\"%s/%s\"><img src=\"/swat/%s\" alt=\"%s\"></A>\n",
398 cgi_baseurl(), hlink, src, name);
401 /****************************************************************************
402 display the main navigation controls at the top of each page along
404 ****************************************************************************/
405 static void show_main_buttons(void)
407 image_link("Home", "", "images/home.gif");
409 /* Root gets full functionality */
410 if (demo_mode || am_root()) {
411 image_link("Globals", "globals", "images/globals.gif");
412 image_link("Shares", "shares", "images/shares.gif");
413 image_link("Printers", "printers", "images/printers.gif");
414 image_link("Status", "status", "images/status.gif");
415 image_link("View Config", "viewconfig","images/viewconfig.gif");
418 /* Everyone gets this functionality */
419 image_link("Password Management", "passwd", "images/passwd.gif");
424 /****************************************************************************
425 display a welcome page
426 ****************************************************************************/
427 static void welcome_page(void)
429 include_html("help/welcome.html");
432 /****************************************************************************
433 display the current smb.conf
434 ****************************************************************************/
435 static void viewconfig_page(void)
439 if (cgi_variable("full_view")) {
443 printf("<H2>Current Config</H2>\n");
444 printf("<form method=post>\n");
447 printf("<input type=submit name=\"normal_view\" value=\"Normal View\">\n");
449 printf("<input type=submit name=\"full_view\" value=\"Full View\">\n");
453 write_config(stdout, full_view);
458 /****************************************************************************
459 display a globals editing page
460 ****************************************************************************/
461 static void globals_page(void)
465 printf("<H2>Global Variables</H2>\n");
467 if (cgi_variable("Advanced") && !cgi_variable("Basic"))
470 if (cgi_variable("Commit")) {
471 commit_parameters(GLOBALS_SNUM);
475 printf("<FORM name=\"swatform\" method=post>\n");
477 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
478 printf("<input type=reset name=\"Reset Values\" value=\"Reset Values\">\n");
480 printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
482 printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
487 show_parameters(GLOBALS_SNUM, 1, advanced, 0);
488 printf("</table>\n");
491 printf("<input type=hidden name=\"Advanced\" value=1>\n");
497 /****************************************************************************
498 display a shares editing page
499 ****************************************************************************/
500 static void shares_page(void)
502 char *share = cgi_variable("share");
509 snum = lp_servicenumber(share);
511 printf("<H2>Share Parameters</H2>\n");
513 if (cgi_variable("Advanced") && !cgi_variable("Basic"))
516 if (cgi_variable("Commit") && snum >= 0) {
517 commit_parameters(snum);
521 if (cgi_variable("Delete") && snum >= 0) {
522 lp_remove_service(snum);
528 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
529 lp_copy_service(GLOBALS_SNUM, share);
531 snum = lp_servicenumber(share);
534 printf("<FORM name=\"swatform\" method=post>\n");
537 printf("<tr><td><input type=submit name=selectshare value=\"Choose Share\"></td>\n");
538 printf("<td><select name=share>\n");
540 printf("<option value=\" \"> \n");
541 for (i=0;i<lp_numservices();i++) {
542 s = lp_servicename(i);
543 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
544 printf("<option %s value=\"%s\">%s\n",
545 (share && strcmp(share,s)==0)?"SELECTED":"",
549 printf("</select></td></tr><p>");
551 printf("<tr><td><input type=submit name=createshare value=\"Create Share\"></td>\n");
552 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
557 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
558 printf("<input type=submit name=\"Delete\" value=\"Delete Share\">\n");
560 printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
562 printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
569 show_parameters(snum, 1, advanced, 0);
570 printf("</table>\n");
574 printf("<input type=hidden name=\"Advanced\" value=1>\n");
580 /*************************************************************
581 change a password either locally or remotely
582 *************************************************************/
583 static BOOL change_password(const char *remote_machine, char *user_name,
584 char *old_passwd, char *new_passwd,
585 BOOL add_user, BOOL enable_user, BOOL disable_user)
592 printf("password change in demo mode rejected\n<p>");
596 if (remote_machine != NULL) {
597 ret = remote_password_change(remote_machine, user_name, old_passwd,
598 new_passwd, err_str, sizeof(err_str));
600 printf("%s\n<p>", err_str);
604 if(!initialize_password_db()) {
605 printf("Can't setup password database vectors.\n<p>");
609 ret = local_password_change(user_name, False, add_user, enable_user,
610 disable_user, False, new_passwd, err_str, sizeof(err_str),
611 msg_str, sizeof(msg_str));
614 printf("%s\n<p>", msg_str);
616 printf("%s\n<p>", err_str);
621 /****************************************************************************
622 do the stuff required to add or change a password
623 ****************************************************************************/
624 static void chg_passwd(void)
629 /* Make sure users name has been specified */
630 if (strlen(cgi_variable(SWAT_USER)) == 0) {
631 printf("<p> Must specify \"User Name\" \n");
636 * smbpasswd doesn't require anything but the users name to disable or enable the user,
637 * so if that's what we're doing, skip the rest of the checks
639 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG)) {
642 * If current user is not root, make sure old password has been specified
643 * If REMOTE change, even root must provide old password
645 if (((am_root() == False) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
646 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
647 printf("<p> Must specify \"Old Password\" \n");
651 /* If changing a users password on a remote hosts we have to know what host */
652 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
653 printf("<p> Must specify \"Remote Machine\" \n");
657 /* Make sure new passwords have been specified */
658 if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
659 (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
660 printf("<p> Must specify \"New, and Re-typed Passwords\" \n");
664 /* Make sure new passwords was typed correctly twice */
665 if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
666 printf("<p> Re-typed password didn't match new password\n");
671 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
672 host = cgi_variable(RHOST);
673 } else if (am_root()) {
678 rslt = change_password(host,
679 cgi_variable(SWAT_USER),
680 cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
681 cgi_variable(ADD_USER_FLAG)? True : False,
682 cgi_variable(ENABLE_USER_FLAG)? True : False,
683 cgi_variable(DISABLE_USER_FLAG)? True : False);
687 printf("<p> The passwd for '%s' has been changed. \n", cgi_variable(SWAT_USER));
689 printf("<p> The passwd for '%s' has NOT been changed. \n",cgi_variable(SWAT_USER));
695 /****************************************************************************
696 display a password editing page
697 ****************************************************************************/
698 static void passwd_page(void)
700 char *new_name = cgi_user_name();
703 * After the first time through here be nice. If the user
704 * changed the User box text to another users name, remember it.
706 if (cgi_variable(SWAT_USER)) {
707 new_name = cgi_variable(SWAT_USER);
710 if (!new_name) new_name = "";
712 printf("<H2>Server Password Management</H2>\n");
714 printf("<FORM name=\"swatform\" method=post>\n");
719 * Create all the dialog boxes for data collection
721 printf("<tr><td> User Name : </td>\n");
722 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
723 if (am_root() == False) {
724 printf("<tr><td> Old Password : </td>\n");
725 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
727 printf("<tr><td> New Password : </td>\n");
728 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
729 printf("<tr><td> Re-type New Password : </td>\n");
730 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
733 * Create all the control buttons for requesting action
735 printf("<tr><td><input type=submit name=%s value=\"Change Password\"></td></tr>\n", CHG_S_PASSWD_FLAG);
736 if (am_root() == True) {
737 printf("<tr><td><input type=submit name=%s value=\"Add New User\"></td></tr>\n", ADD_USER_FLAG);
738 printf("<tr><td><input type=submit name=%s value=\"Disable User\"></td></tr>\n", DISABLE_USER_FLAG);
739 printf("<tr><td><input type=submit name=%s value=\"Enable User\"></td></tr>\n", ENABLE_USER_FLAG);
743 * Do some work if change, add, disable or enable was requested. It could be
744 * this is the first time through this code, so there isn't anything to do.
746 if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) ||
747 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
751 printf("</table>\n");
755 printf("<H2>Client/Server Password Management</H2>\n");
757 printf("<FORM name=\"swatform\" method=post>\n");
762 * Create all the dialog boxes for data collection
764 printf("<tr><td> User Name : </td>\n");
765 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
766 printf("<tr><td> Old Password : </td>\n");
767 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
768 printf("<tr><td> New Password : </td>\n");
769 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
770 printf("<tr><td> Re-type New Password : </td>\n");
771 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
772 printf("<tr><td> Remote Machine : </td>\n");
773 printf("<td><input type=password size=30 name=%s></td></tr>\n",RHOST);
776 * Create all the control buttons for requesting action
778 printf("<tr><td><input type=submit name=%s value=\"Change Password\"></td></tr>", CHG_R_PASSWD_FLAG);
781 * Do some work if a request has been made to change the password somewhere other
782 * than the server. It could be this is the first time through this code, so there
783 * isn't anything to do.
785 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
794 /****************************************************************************
795 display a printers editing page
796 ****************************************************************************/
797 static void printers_page(void)
799 char *share = cgi_variable("share");
806 snum = lp_servicenumber(share);
808 printf("<H2>Printer Parameters</H2>\n");
810 if (cgi_variable("Advanced") && !cgi_variable("Basic"))
813 if (cgi_variable("Commit") && snum >= 0) {
814 commit_parameters(snum);
818 if (cgi_variable("Delete") && snum >= 0) {
819 lp_remove_service(snum);
825 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
826 lp_copy_service(GLOBALS_SNUM, share);
827 snum = lp_servicenumber(share);
828 lp_do_parameter(snum, "print ok", "Yes");
830 snum = lp_servicenumber(share);
833 printf("<FORM name=\"swatform\" method=post>\n");
836 printf("<tr><td><input type=submit name=selectshare value=\"Choose Printer\"></td>\n");
837 printf("<td><select name=share>\n");
838 if (snum < 0 || !lp_print_ok(snum))
839 printf("<option value=\" \"> \n");
840 for (i=0;i<lp_numservices();i++) {
841 s = lp_servicename(i);
842 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
843 printf("<option %s value=\"%s\">%s\n",
844 (share && strcmp(share,s)==0)?"SELECTED":"",
848 printf("</select></td></tr><p>");
850 printf("<tr><td><input type=submit name=createshare value=\"Create Printer\"></td>\n");
851 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
856 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
857 printf("<input type=submit name=\"Delete\" value=\"Delete Printer\">\n");
859 printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
861 printf("<input type=submit name=\"Basic\" value=\"Basic View\">\n");
868 show_parameters(snum, 1, advanced, 1);
869 printf("</table>\n");
873 printf("<input type=hidden name=\"Advanced\" value=1>\n");
879 /****************************************************************************
881 ****************************************************************************/
882 int main(int argc, char *argv[])
890 /* just in case it goes wild ... */
893 dbf = fopen("/dev/null", "w");
895 if (!dbf) dbf = stderr;
897 while ((opt = getopt(argc, argv,"s:a")) != EOF) {
900 pstrcpy(servicesf,optarg);
908 cgi_setup(SWATDIR, !demo_mode);
912 charset_initialise();
914 /* if this binary is setuid then run completely as root */
919 cgi_load_variables(NULL);
923 page = cgi_pathinfo();
925 /* Root gets full functionality */
926 if (demo_mode || am_root()) {
927 if (strcmp(page, "globals")==0) {
929 } else if (strcmp(page,"shares")==0) {
931 } else if (strcmp(page,"printers")==0) {
933 } else if (strcmp(page,"status")==0) {
935 } else if (strcmp(page,"viewconfig")==0) {
937 } else if (strcmp(page,"passwd")==0) {
943 /* Everyone gets this functionality */
944 if (strcmp(page,"passwd")==0) {