2 Unix SMB/CIFS implementation.
3 Samba Web Administration Tool
5 Copyright (C) Andrew Tridgell 1997-2002
6 Copyright (C) John H Terpstra 2002
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 * @defgroup swat SWAT - Samba Web Administration Tool
28 * @brief Samba Web Administration Tool.
32 #include "../web/swat_proto.h"
34 #define GLOBALS_SNUM -1
36 static BOOL demo_mode = False;
37 static BOOL have_write_access = False;
38 static BOOL have_read_access = False;
39 static int iNumNonAutoPrintServices = 0;
42 * Password Management Globals
44 #define SWAT_USER "username"
45 #define OLD_PSWD "old_passwd"
46 #define NEW_PSWD "new_passwd"
47 #define NEW2_PSWD "new2_passwd"
48 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
49 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
50 #define ADD_USER_FLAG "add_user_flag"
51 #define DELETE_USER_FLAG "delete_user_flag"
52 #define DISABLE_USER_FLAG "disable_user_flag"
53 #define ENABLE_USER_FLAG "enable_user_flag"
54 #define RHOST "remote_host"
56 /* we need these because we link to locking*.o */
57 void become_root(void) {}
58 void unbecome_root(void) {}
60 /****************************************************************************
61 ****************************************************************************/
62 static int enum_index(int value, const struct enum_list *enumlist)
65 for (i=0;enumlist[i].name;i++)
66 if (value == enumlist[i].value) break;
70 static char *fix_backslash(const char *str)
72 static char newstring[1024];
76 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
84 static char *stripspaceupper(const char *str)
86 static char newstring[1024];
90 if (*str != ' ') *p++ = toupper(*str);
97 static char *make_parm_name(const char *label)
99 static char parmname[1024];
103 if (*label == ' ') *p++ = '_';
111 /****************************************************************************
112 include a lump of html in a page
113 ****************************************************************************/
114 static int include_html(const char *fname)
120 fd = web_open(fname, O_RDONLY, 0);
123 d_printf("ERROR: Can't open %s\n", fname);
127 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
135 /****************************************************************************
136 start the page with standard stuff
137 ****************************************************************************/
138 static void print_header(void)
140 if (!cgi_waspost()) {
141 d_printf("Expires: 0\r\n");
143 d_printf("Content-type: text/html\r\n\r\n");
145 if (!include_html("include/header.html")) {
146 d_printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
147 d_printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
151 /* *******************************************************************
152 show parameter label with translated name in the following form
153 because showing original and translated label in one line looks
154 too long, and showing translated label only is unusable for
156 -------------------------------
157 HELP security [combo box][button]
159 -------------------------------
160 (capital words are translated by gettext.)
161 if no translation is available, then same form as original is
163 "i18n_translated_parm" class is used to change the color of the
164 translated parameter with CSS.
165 **************************************************************** */
166 static const char* get_parm_translated(
167 const char* pAnchor, const char* pHelp, const char* pLabel)
169 const char* pTranslated = _(pLabel);
170 static pstring output;
171 if(strcmp(pLabel, pTranslated) != 0)
173 snprintf(output, sizeof(output),
174 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
175 pAnchor, pHelp, pLabel, pTranslated);
178 snprintf(output, sizeof(output),
179 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
180 pAnchor, pHelp, pLabel);
183 /****************************************************************************
185 ****************************************************************************/
186 static void print_footer(void)
188 if (!include_html("include/footer.html")) {
189 d_printf("\n</BODY>\n</HTML>\n");
193 /****************************************************************************
194 display one editable parameter in a form
195 ****************************************************************************/
196 static void show_parameter(int snum, struct parm_struct *parm)
199 void *ptr = parm->ptr;
201 if (parm->class == P_LOCAL && snum >= 0) {
202 ptr = lp_local_ptr(snum, ptr);
205 printf("<tr><td>%s</td><td>", get_parm_translated(stripspaceupper(parm->label), _("Help"), parm->label));
206 switch (parm->type) {
208 d_printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
209 make_parm_name(parm->label), *(char *)ptr);
210 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
211 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
215 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"",
216 make_parm_name(parm->label));
217 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
218 char **list = *(char ***)ptr;
219 for (;*list;list++) {
220 d_printf("%s%s", *list, ((*(list+1))?" ":""));
224 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
225 _("Set Default"), make_parm_name(parm->label));
226 if (parm->def.lvalue) {
227 char **list = (char **)(parm->def.lvalue);
228 for (; *list; list++) {
229 d_printf("%s%s", *list, ((*(list+1))?" ":""));
237 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
238 make_parm_name(parm->label), *(char **)ptr);
239 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
240 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
245 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
246 make_parm_name(parm->label), (char *)ptr);
247 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
248 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
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)?0:1);
261 d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
262 d_printf("<option %s>Yes", (*(BOOL *)ptr)?"":"selected");
263 d_printf("<option %s>No", (*(BOOL *)ptr)?"selected":"");
264 d_printf("</select>");
265 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
266 _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?1:0);
270 d_printf("<input type=text size=8 name=\"parm_%s\" value=%d>", make_parm_name(parm->label), *(int *)ptr);
271 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
272 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
276 d_printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm->label), octal_string(*(int *)ptr));
277 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
278 _("Set Default"), make_parm_name(parm->label),
279 octal_string((int)(parm->def.ivalue)));
283 d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
284 for (i=0;parm->enum_list[i].name;i++) {
285 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
286 d_printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
289 d_printf("</select>");
290 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
291 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
296 d_printf("</td></tr>\n");
299 /****************************************************************************
300 display a set of parameters for a service
301 ****************************************************************************/
302 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
305 struct parm_struct *parm;
306 const char *heading = NULL;
307 const char *last_heading = NULL;
309 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
310 if (snum < 0 && parm->class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
312 if (parm->class == P_SEPARATOR) {
313 heading = parm->label;
316 if (parm->flags & FLAG_HIDE) continue;
318 if (printers & !(parm->flags & FLAG_PRINT)) continue;
319 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
321 if (parm_filter == FLAG_BASIC) {
322 if (!(parm->flags & FLAG_BASIC)) {
323 void *ptr = parm->ptr;
325 if (parm->class == P_LOCAL && snum >= 0) {
326 ptr = lp_local_ptr(snum, ptr);
329 switch (parm->type) {
331 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
335 if (!str_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
340 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
345 if (!strcmp((char *)ptr,(char *)(parm->def.svalue))) continue;
350 if (*(BOOL *)ptr == (BOOL)(parm->def.bvalue)) continue;
355 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
360 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
366 if (printers && !(parm->flags & FLAG_PRINT)) continue;
368 if (parm_filter == FLAG_WIZARD) {
369 if (!((parm->flags & FLAG_WIZARD))) continue;
371 if (parm_filter == FLAG_ADVANCED) {
372 if (!((parm->flags & FLAG_ADVANCED))) continue;
374 if (heading && heading != last_heading) {
375 d_printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
376 last_heading = heading;
378 show_parameter(snum, parm);
382 /****************************************************************************
383 load the smb.conf file into loadparm.
384 ****************************************************************************/
385 static BOOL load_config(BOOL save_def)
387 lp_resetnumservices();
388 return lp_load(dyn_CONFIGFILE,False,save_def,False);
391 /****************************************************************************
393 ****************************************************************************/
394 static void write_config(FILE *f, BOOL show_defaults)
396 fprintf(f, "# Samba config file created using SWAT\n");
397 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
398 fprintf(f, "# Date: %s\n\n", timestring(False));
400 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
403 /****************************************************************************
404 save and reload the smb.conf config file
405 ****************************************************************************/
406 static int save_reload(int snum)
411 f = sys_fopen(dyn_CONFIGFILE,"w");
413 d_printf("failed to open %s for writing\n", dyn_CONFIGFILE);
417 /* just in case they have used the buggy xinetd to create the file */
418 if (fstat(fileno(f), &st) == 0 &&
419 (st.st_mode & S_IWOTH)) {
420 #if defined HAVE_FCHMOD
421 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
423 chmod(dyn_CONFIGFILE, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
427 write_config(f, False);
429 lp_dump_one(f, False, snum);
434 if (!load_config(False)) {
435 d_printf("Can't reload %s\n", dyn_CONFIGFILE);
438 iNumNonAutoPrintServices = lp_numservices();
444 /****************************************************************************
446 ****************************************************************************/
447 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
452 if (snum < 0 && parm->class == P_LOCAL) {
453 /* this handles the case where we are changing a local
454 variable globally. We need to change the parameter in
455 all shares where it is currently set to the default */
456 for (i=0;i<lp_numservices();i++) {
457 s = lp_servicename(i);
458 if (s && (*s) && lp_is_default(i, parm)) {
459 lp_do_parameter(i, parm->label, v);
464 lp_do_parameter(snum, parm->label, v);
467 /****************************************************************************
468 commit a set of parameters for a service
469 ****************************************************************************/
470 static void commit_parameters(int snum)
473 struct parm_struct *parm;
477 while ((parm = lp_next_parameter(snum, &i, 1))) {
478 slprintf(label, sizeof(label)-1, "parm_%s", make_parm_name(parm->label));
479 if ((v = cgi_variable(label))) {
480 if (parm->flags & FLAG_HIDE) continue;
481 commit_parameter(snum, parm, v);
486 /****************************************************************************
487 spit out the html for a link with an image
488 ****************************************************************************/
489 static void image_link(const char *name, const char *hlink, const char *src)
491 d_printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
492 cgi_baseurl(), hlink, src, name);
495 /****************************************************************************
496 display the main navigation controls at the top of each page along
498 ****************************************************************************/
499 static void show_main_buttons(void)
503 if ((p = cgi_user_name()) && strcmp(p, "root")) {
504 d_printf(_("Logged in as <b>%s</b><p>\n"), p);
507 image_link(_("Home"), "", "images/home.gif");
508 if (have_write_access) {
509 image_link(_("Globals"), "globals", "images/globals.gif");
510 image_link(_("Shares"), "shares", "images/shares.gif");
511 image_link(_("Printers"), "printers", "images/printers.gif");
512 image_link(_("Wizard"), "wizard", "images/wizard.gif");
514 if (have_read_access) {
515 image_link(_("Status"), "status", "images/status.gif");
516 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
518 image_link(_("Password Management"), "passwd", "images/passwd.gif");
523 /****************************************************************************
524 * Handle Display/Edit Mode CGI
525 ****************************************************************************/
526 static void ViewModeBoxes(int mode)
528 d_printf("<p>%s\n", _("Configuration View: "));
529 d_printf("<input type=radio name=\"ViewMode\" value=0 %s>Basic\n", (mode == 0) ? "checked" : "");
530 d_printf("<input type=radio name=\"ViewMode\" value=1 %s>Advanced\n", (mode == 1) ? "checked" : "");
531 d_printf("<input type=radio name=\"ViewMode\" value=2 %s>Developer\n", (mode == 2) ? "checked" : "");
532 d_printf("</p><br>\n");
535 /****************************************************************************
536 display a welcome page
537 ****************************************************************************/
538 static void welcome_page(void)
540 include_html("help/welcome.html");
543 /****************************************************************************
544 display the current smb.conf
545 ****************************************************************************/
546 static void viewconfig_page(void)
550 if (cgi_variable("full_view")) {
554 d_printf("<H2>%s</H2>\n", _("Current Config"));
555 d_printf("<form method=post>\n");
558 d_printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
560 d_printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
563 d_printf("<p><pre>");
564 write_config(stdout, full_view);
566 d_printf("</form>\n");
569 /****************************************************************************
570 second screen of the wizard ... Fetch Configuration Parameters
571 ****************************************************************************/
572 static void wizard_params_page(void)
574 unsigned int parm_filter = FLAG_WIZARD;
576 /* Here we first set and commit all the parameters that were selected
577 in the previous screen. */
579 d_printf("<H2>Wizard Parameter Edit Page</H2>\n");
581 if (cgi_variable("Commit")) {
582 commit_parameters(GLOBALS_SNUM);
586 d_printf("<form name=\"swatform\" method=post action=wizard_params>\n");
588 if (have_write_access) {
589 d_printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
592 d_printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
595 d_printf("<table>\n");
596 show_parameters(GLOBALS_SNUM, 1, parm_filter, 0);
597 d_printf("</table>\n");
598 d_printf("</form>\n");
601 /****************************************************************************
602 Utility to just rewrite the smb.conf file - effectively just cleans it up
603 ****************************************************************************/
604 static void rewritecfg_file(void)
606 commit_parameters(GLOBALS_SNUM);
608 d_printf("<H2>Note: smb.conf %s</H2>\n", _("file has been read and rewritten"));
611 /****************************************************************************
612 wizard to create/modify the smb.conf file
613 ****************************************************************************/
614 static void wizard_page(void)
616 /* Set some variables to collect data from smb.conf */
623 if (cgi_variable("Rewrite")) {
624 (void) rewritecfg_file();
628 if (cgi_variable("GetWizardParams")){
629 (void) wizard_params_page();
633 if (cgi_variable("Commit")){
634 SerType = atoi(cgi_variable("ServerType"));
635 winstype = atoi(cgi_variable("WINSType"));
636 have_home = lp_servicenumber(HOMES_NAME);
637 HomeExpo = atoi(cgi_variable("HomeExpo"));
639 /* Plain text passwords are too badly broken - use encrypted passwords only */
640 lp_do_parameter( GLOBALS_SNUM, "encrypt passwords", "Yes");
644 /* Stand-alone Server */
645 lp_do_parameter( GLOBALS_SNUM, "security", "USER" );
646 lp_do_parameter( GLOBALS_SNUM, "domain logons", "No" );
650 lp_do_parameter( GLOBALS_SNUM, "security", "DOMAIN" );
651 lp_do_parameter( GLOBALS_SNUM, "domain logons", "No" );
654 /* Domain Controller */
655 lp_do_parameter( GLOBALS_SNUM, "security", "USER" );
656 lp_do_parameter( GLOBALS_SNUM, "domain logons", "Yes" );
659 switch ( winstype ) {
661 lp_do_parameter( GLOBALS_SNUM, "wins support", "No" );
662 lp_do_parameter( GLOBALS_SNUM, "wins server", "" );
665 lp_do_parameter( GLOBALS_SNUM, "wins support", "Yes" );
666 lp_do_parameter( GLOBALS_SNUM, "wins server", "" );
669 lp_do_parameter( GLOBALS_SNUM, "wins support", "No" );
670 lp_do_parameter( GLOBALS_SNUM, "wins server", cgi_variable("WINSAddr"));
674 /* Have to create Homes share? */
675 if ((HomeExpo == 1) && (have_home == -1)) {
678 pstrcpy(unix_share,HOMES_NAME);
680 lp_copy_service(GLOBALS_SNUM, unix_share);
681 iNumNonAutoPrintServices = lp_numservices();
682 have_home = lp_servicenumber(HOMES_NAME);
683 lp_do_parameter( have_home, "read only", "No");
684 lp_do_parameter( have_home, "valid users", "%S");
685 lp_do_parameter( have_home, "browseable", "No");
686 commit_parameters(have_home);
689 /* Need to Delete Homes share? */
690 if ((HomeExpo == 0) && (have_home != -1)) {
691 lp_remove_service(have_home);
695 commit_parameters(GLOBALS_SNUM);
700 /* Now determine smb.conf WINS settings */
701 if (lp_wins_support())
703 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
707 /* Do we have a homes share? */
708 have_home = lp_servicenumber(HOMES_NAME);
710 if ((winstype == 2) && lp_wins_support())
713 role = lp_server_role();
716 d_printf("<H2>Samba Configuration Wizard</H2>\n");
717 d_printf("<form method=post action=wizard>\n");
719 if (have_write_access) {
720 d_printf(_("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments.\n"));
721 d_printf(_("The same will happen if you press the commit button."));
722 d_printf("<br><br>");
723 d_printf("<center>");
724 d_printf("<input type=submit name=\"Rewrite\" value=%s> ",_("Rewrite smb.conf file"));
725 d_printf("<input type=submit name=\"Commit\" value=%s> ",_("Commit"));
726 d_printf("<input type=submit name=\"GetWizardParams\" value=%s>", _("Edit Parameter Values"));
727 d_printf("</center>");
731 d_printf("<center><table border=0>");
732 d_printf("<tr><td><b>%s</b></td>\n", "Server Type: ");
733 d_printf("<td><input type=radio name=\"ServerType\" value=0 %s> Stand Alone </td>", (role == ROLE_STANDALONE) ? "checked" : "");
734 d_printf("<td><input type=radio name=\"ServerType\" value=1 %s> Domain Member </td>", (role == ROLE_DOMAIN_MEMBER) ? "checked" : "");
735 d_printf("<td><input type=radio name=\"ServerType\" value=2 %s> Domain Controller </td>", (role == ROLE_DOMAIN_PDC) ? "checked" : "");
737 if (role == ROLE_DOMAIN_BDC) {
738 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Unusual Type in smb.conf - Please Select New Mode</font></td></tr>");
740 d_printf("<tr><td><b>%s</b></td>\n", "Configure WINS As: ");
741 d_printf("<td><input type=radio name=\"WINSType\" value=0 %s> Not Used </td>", (winstype == 0) ? "checked" : "");
742 d_printf("<td><input type=radio name=\"WINSType\" value=1 %s> Server for client use </td>", (winstype == 1) ? "checked" : "");
743 d_printf("<td><input type=radio name=\"WINSType\" value=2 %s> Client of another WINS server </td>", (winstype == 2) ? "checked" : "");
744 d_printf("<tr><td></td><td></td><td></td><td>Remote WINS Server <input type=text size=\"16\" name=\"WINSAddr\" value=\"%s\"></td></tr>",lp_wins_server_list());
746 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Error: WINS Server Mode and WINS Support both set in smb.conf</font></td></tr>");
747 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Please Select desired WINS mode above.</font></td></tr>");
750 d_printf("<tr><td><b>%s</b></td>\n","Expose Home Directories: ");
751 d_printf("<td><input type=radio name=\"HomeExpo\" value=1 %s> Yes</td>", (have_home == -1) ? "" : "checked ");
752 d_printf("<td><input type=radio name=\"HomeExpo\" value=0 %s> No</td>", (have_home == -1 ) ? "checked" : "");
753 d_printf("<td></td></tr>");
755 /* Enable this when we are ready ....
756 * d_printf("<tr><td><b>%s</b></td>\n","Is Print Server: ");
757 * d_printf("<td><input type=radio name=\"PtrSvr\" value=1 %s> Yes</td>");
758 * d_printf("<td><input type=radio name=\"PtrSvr\" value=0 %s> No</td>");
759 * d_printf("<td></td></tr>");
762 d_printf("</table></center>");
765 d_printf(_("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment.\n"));
766 d_printf("</form>\n");
770 /****************************************************************************
771 display a globals editing page
772 ****************************************************************************/
773 static void globals_page(void)
775 unsigned int parm_filter = FLAG_BASIC;
778 d_printf("<H2>%s</H2>\n", _("Global Variables"));
780 if (cgi_variable("Commit")) {
781 commit_parameters(GLOBALS_SNUM);
785 if ( cgi_variable("ViewMode") )
786 mode = atoi(cgi_variable("ViewMode"));
788 d_printf("<form name=\"swatform\" method=post action=globals>\n");
790 ViewModeBoxes( mode );
793 parm_filter = FLAG_BASIC;
796 parm_filter = FLAG_ADVANCED;
799 parm_filter = FLAG_DEVELOPER;
803 if (have_write_access) {
804 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
805 _("Commit Changes"));
808 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
812 d_printf("<table>\n");
813 show_parameters(GLOBALS_SNUM, 1, parm_filter, 0);
814 d_printf("</table>\n");
815 d_printf("</form>\n");
818 /****************************************************************************
819 display a shares editing page. share is in unix codepage, and must be in
820 dos codepage. FIXME !!! JRA.
821 ****************************************************************************/
822 static void shares_page(void)
824 const char *share = cgi_variable("share");
829 unsigned int parm_filter = FLAG_BASIC;
832 snum = lp_servicenumber(share);
834 d_printf("<H2>%s</H2>\n", _("Share Parameters"));
836 if (cgi_variable("Commit") && snum >= 0) {
837 commit_parameters(snum);
841 if (cgi_variable("Delete") && snum >= 0) {
842 lp_remove_service(snum);
848 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
850 lp_copy_service(GLOBALS_SNUM, share);
851 iNumNonAutoPrintServices = lp_numservices();
853 snum = lp_servicenumber(share);
856 d_printf("<FORM name=\"swatform\" method=post>\n");
858 d_printf("<table>\n");
859 if ( cgi_variable("ViewMode") )
860 mode = atoi(cgi_variable("ViewMode"));
861 ViewModeBoxes( mode );
864 parm_filter = FLAG_BASIC;
867 parm_filter = FLAG_ADVANCED;
870 parm_filter = FLAG_DEVELOPER;
873 d_printf("<br><tr>\n");
874 d_printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
875 d_printf("<td><select name=share>\n");
877 d_printf("<option value=\" \"> \n");
878 for (i=0;i<lp_numservices();i++) {
879 s = lp_servicename(i);
880 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
881 d_printf("<option %s value=\"%s\">%s\n",
882 (share && strcmp(share,s)==0)?"SELECTED":"",
886 d_printf("</select></td>\n");
887 if (have_write_access) {
888 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
891 d_printf("</table>");
893 if (have_write_access) {
895 d_printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
896 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
898 d_printf("</table>");
902 if (have_write_access) {
903 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
906 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
911 d_printf("<table>\n");
912 show_parameters(snum, 1, parm_filter, 0);
913 d_printf("</table>\n");
916 d_printf("</FORM>\n");
919 /*************************************************************
920 change a password either locally or remotely
921 *************************************************************/
922 static BOOL change_password(const char *remote_machine, const char *user_name,
923 const char *old_passwd, const char *new_passwd,
931 d_printf("%s<p>", _("password change in demo mode rejected\n"));
935 if (remote_machine != NULL) {
936 ret = remote_password_change(remote_machine, user_name, old_passwd,
937 new_passwd, err_str, sizeof(err_str));
939 d_printf("%s\n<p>", err_str);
943 if(!initialize_password_db(True)) {
944 d_printf("Can't setup password database vectors.\n<p>");
948 ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
949 msg_str, sizeof(msg_str));
952 d_printf("%s\n<p>", msg_str);
954 d_printf("%s\n<p>", err_str);
959 /****************************************************************************
960 do the stuff required to add or change a password
961 ****************************************************************************/
962 static void chg_passwd(void)
968 /* Make sure users name has been specified */
969 if (strlen(cgi_variable(SWAT_USER)) == 0) {
970 d_printf("<p>%s", _(" Must specify \"User Name\" \n"));
975 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
976 * so if that's what we're doing, skip the rest of the checks
978 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
981 * If current user is not root, make sure old password has been specified
982 * If REMOTE change, even root must provide old password
984 if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
985 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
986 d_printf("<p>%s", _(" Must specify \"Old Password\" \n"));
990 /* If changing a users password on a remote hosts we have to know what host */
991 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
992 d_printf("<p>%s", _(" Must specify \"Remote Machine\" \n"));
996 /* Make sure new passwords have been specified */
997 if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
998 (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
999 d_printf("<p>%s", _(" Must specify \"New, and Re-typed Passwords\" \n"));
1003 /* Make sure new passwords was typed correctly twice */
1004 if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
1005 d_printf("<p>%s", _(" Re-typed password didn't match new password\n"));
1010 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1011 host = cgi_variable(RHOST);
1012 } else if (am_root()) {
1019 * Set up the local flags.
1022 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1023 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1024 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1025 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1027 rslt = change_password(host,
1028 cgi_variable(SWAT_USER),
1029 cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
1032 if(local_flags == 0) {
1035 d_printf(_(" The passwd for '%s' has been changed. \n"), cgi_variable(SWAT_USER));
1037 d_printf(_(" The passwd for '%s' has NOT been changed. \n"), cgi_variable(SWAT_USER));
1044 /****************************************************************************
1045 display a password editing page
1046 ****************************************************************************/
1047 static void passwd_page(void)
1049 const char *new_name = cgi_user_name();
1052 * After the first time through here be nice. If the user
1053 * changed the User box text to another users name, remember it.
1055 if (cgi_variable(SWAT_USER)) {
1056 new_name = cgi_variable(SWAT_USER);
1059 if (!new_name) new_name = "";
1061 d_printf("<H2>%s</H2>\n", _("Server Password Management"));
1063 d_printf("<FORM name=\"swatform\" method=post>\n");
1065 d_printf("<table>\n");
1068 * Create all the dialog boxes for data collection
1070 d_printf("<tr><td>%s</td>\n", _(" User Name : "));
1071 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1073 d_printf("<tr><td>%s</td>\n", _(" Old Password : "));
1074 d_printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1076 d_printf("<tr><td>%s</td>\n", _(" New Password : "));
1077 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1078 d_printf("<tr><td>%s</td>\n", _(" Re-type New Password : "));
1079 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1080 d_printf("</table>\n");
1083 * Create all the control buttons for requesting action
1085 d_printf("<input type=submit name=%s value=\"%s\">\n",
1086 CHG_S_PASSWD_FLAG, _("Change Password"));
1087 if (demo_mode || am_root()) {
1088 d_printf("<input type=submit name=%s value=\"%s\">\n",
1089 ADD_USER_FLAG, _("Add New User"));
1090 d_printf("<input type=submit name=%s value=\"%s\">\n",
1091 DELETE_USER_FLAG, _("Delete User"));
1092 d_printf("<input type=submit name=%s value=\"%s\">\n",
1093 DISABLE_USER_FLAG, _("Disable User"));
1094 d_printf("<input type=submit name=%s value=\"%s\">\n",
1095 ENABLE_USER_FLAG, _("Enable User"));
1097 d_printf("<p></FORM>\n");
1100 * Do some work if change, add, disable or enable was
1101 * requested. It could be this is the first time through this
1102 * code, so there isn't anything to do. */
1103 if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1104 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1108 d_printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1110 d_printf("<FORM name=\"swatform\" method=post>\n");
1112 d_printf("<table>\n");
1115 * Create all the dialog boxes for data collection
1117 d_printf("<tr><td>%s</td>\n", _(" User Name : "));
1118 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1119 d_printf("<tr><td>%s</td>\n", _(" Old Password : "));
1120 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1121 d_printf("<tr><td>%s</td>\n", _(" New Password : "));
1122 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1123 d_printf("<tr><td>%s</td>\n", _(" Re-type New Password : "));
1124 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1125 d_printf("<tr><td>%s</td>\n", _(" Remote Machine : "));
1126 d_printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1128 d_printf("</table>");
1131 * Create all the control buttons for requesting action
1133 d_printf("<input type=submit name=%s value=\"%s\">",
1134 CHG_R_PASSWD_FLAG, _("Change Password"));
1136 d_printf("<p></FORM>\n");
1139 * Do some work if a request has been made to change the
1140 * password somewhere other than the server. It could be this
1141 * is the first time through this code, so there isn't
1142 * anything to do. */
1143 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1149 /****************************************************************************
1150 display a printers editing page
1151 ****************************************************************************/
1152 static void printers_page(void)
1154 const char *share = cgi_variable("share");
1159 unsigned int parm_filter = FLAG_BASIC;
1162 snum = lp_servicenumber(share);
1164 d_printf("<H2>%s</H2>\n", _("Printer Parameters"));
1166 d_printf("<H3>%s</H3>\n", _("Important Note:"));
1167 d_printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
1168 d_printf(_("are autoloaded printers from "));
1169 d_printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1170 d_printf(_("Attempting to delete these printers from SWAT will have no effect.\n"));
1172 if (cgi_variable("Commit") && snum >= 0) {
1173 commit_parameters(snum);
1174 if (snum >= iNumNonAutoPrintServices)
1180 if (cgi_variable("Delete") && snum >= 0) {
1181 lp_remove_service(snum);
1187 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1189 lp_copy_service(GLOBALS_SNUM, share);
1190 iNumNonAutoPrintServices = lp_numservices();
1191 snum = lp_servicenumber(share);
1192 lp_do_parameter(snum, "print ok", "Yes");
1194 snum = lp_servicenumber(share);
1197 d_printf("<FORM name=\"swatform\" method=post>\n");
1199 if ( cgi_variable("ViewMode") )
1200 mode = atoi(cgi_variable("ViewMode"));
1201 ViewModeBoxes( mode );
1204 parm_filter = FLAG_BASIC;
1207 parm_filter = FLAG_ADVANCED;
1210 parm_filter = FLAG_DEVELOPER;
1213 d_printf("<table>\n");
1214 d_printf("<tr><td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Printer"));
1215 d_printf("<td><select name=share>\n");
1216 if (snum < 0 || !lp_print_ok(snum))
1217 d_printf("<option value=\" \"> \n");
1218 for (i=0;i<lp_numservices();i++) {
1219 s = lp_servicename(i);
1220 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1221 if (i >= iNumNonAutoPrintServices)
1222 d_printf("<option %s value=\"%s\">[*]%s\n",
1223 (share && strcmp(share,s)==0)?"SELECTED":"",
1226 d_printf("<option %s value=\"%s\">%s\n",
1227 (share && strcmp(share,s)==0)?"SELECTED":"",
1231 d_printf("</select></td>");
1232 if (have_write_access) {
1233 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1236 d_printf("</table>\n");
1238 if (have_write_access) {
1239 d_printf("<table>\n");
1240 d_printf("<tr><td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Printer"));
1241 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1242 d_printf("</table>");
1247 if (have_write_access) {
1248 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1250 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1255 d_printf("<table>\n");
1256 show_parameters(snum, 1, parm_filter, 1);
1257 d_printf("</table>\n");
1259 d_printf("</FORM>\n");
1264 * main function for SWAT.
1266 int main(int argc, char *argv[])
1271 struct poptOption long_options[] = {
1273 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1279 umask(S_IWGRP | S_IWOTH);
1281 #if defined(HAVE_SET_AUTH_PARAMETERS)
1282 set_auth_parameters(argc, argv);
1283 #endif /* HAVE_SET_AUTH_PARAMETERS */
1285 /* just in case it goes wild ... */
1290 /* we don't want any SIGPIPE messages */
1291 BlockSignals(True,SIGPIPE);
1293 dbf = x_fopen("/dev/null", O_WRONLY, 0);
1294 if (!dbf) dbf = x_stderr;
1296 /* we don't want stderr screwing us up */
1298 open("/dev/null", O_WRONLY);
1300 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1302 /* Parse command line options */
1304 while((opt = poptGetNextOpt(pc)) != -1) { }
1306 poptFreeContext(pc);
1308 setup_logging(argv[0],False);
1310 iNumNonAutoPrintServices = lp_numservices();
1313 cgi_setup(dyn_SWATDIR, !demo_mode);
1317 cgi_load_variables();
1319 if (!file_exist(dyn_CONFIGFILE, NULL)) {
1320 have_read_access = True;
1321 have_write_access = True;
1323 /* check if the authenticated user has write access - if not then
1324 don't show write options */
1325 have_write_access = (access(dyn_CONFIGFILE,W_OK) == 0);
1327 /* if the user doesn't have read access to smb.conf then
1328 don't let them view it */
1329 have_read_access = (access(dyn_CONFIGFILE,R_OK) == 0);
1332 show_main_buttons();
1334 page = cgi_pathinfo();
1336 /* Root gets full functionality */
1337 if (have_read_access && strcmp(page, "globals")==0) {
1339 } else if (have_read_access && strcmp(page,"shares")==0) {
1341 } else if (have_read_access && strcmp(page,"printers")==0) {
1343 } else if (have_read_access && strcmp(page,"status")==0) {
1345 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1347 } else if (strcmp(page,"passwd")==0) {
1349 } else if (have_read_access && strcmp(page,"wizard")==0) {
1351 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1352 wizard_params_page();
1353 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {