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.
33 #define GLOBALS_SNUM -1
35 static BOOL demo_mode = False;
36 static BOOL have_write_access = False;
37 static BOOL have_read_access = False;
38 static int iNumNonAutoPrintServices = 0;
41 * Password Management Globals
43 #define SWAT_USER "username"
44 #define OLD_PSWD "old_passwd"
45 #define NEW_PSWD "new_passwd"
46 #define NEW2_PSWD "new2_passwd"
47 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
48 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
49 #define ADD_USER_FLAG "add_user_flag"
50 #define DELETE_USER_FLAG "delete_user_flag"
51 #define DISABLE_USER_FLAG "disable_user_flag"
52 #define ENABLE_USER_FLAG "enable_user_flag"
53 #define RHOST "remote_host"
55 /* we need these because we link to locking*.o */
56 void become_root(void) {}
57 void unbecome_root(void) {}
59 /****************************************************************************
60 ****************************************************************************/
61 static int enum_index(int value, const struct enum_list *enumlist)
64 for (i=0;enumlist[i].name;i++)
65 if (value == enumlist[i].value) break;
69 static char *fix_backslash(const char *str)
71 static char newstring[1024];
75 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
83 static char *stripspaceupper(const char *str)
85 static char newstring[1024];
89 if (*str != ' ') *p++ = toupper(*str);
96 static char *make_parm_name(const char *label)
98 static char parmname[1024];
102 if (*label == ' ') *p++ = '_';
110 /****************************************************************************
111 include a lump of html in a page
112 ****************************************************************************/
113 static int include_html(const char *fname)
119 fd = web_open(fname, O_RDONLY, 0);
122 d_printf("ERROR: Can't open %s\n", fname);
126 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
134 /****************************************************************************
135 start the page with standard stuff
136 ****************************************************************************/
137 static void print_header(void)
139 if (!cgi_waspost()) {
140 d_printf("Expires: 0\r\n");
142 d_printf("Content-type: text/html\r\n\r\n");
144 if (!include_html("include/header.html")) {
145 d_printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
146 d_printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
150 /* *******************************************************************
151 show parameter label with translated name in the following form
152 because showing original and translated label in one line looks
153 too long, and showing translated label only is unusable for
155 -------------------------------
156 HELP security [combo box][button]
158 -------------------------------
159 (capital words are translated by gettext.)
160 if no translation is available, then same form as original is
162 "i18n_translated_parm" class is used to change the color of the
163 translated parameter with CSS.
164 **************************************************************** */
165 static const char* get_parm_translated(
166 const char* pAnchor, const char* pHelp, const char* pLabel)
168 const char* pTranslated = _(pLabel);
169 static pstring output;
170 if(strcmp(pLabel, pTranslated) != 0)
172 snprintf(output, sizeof(output),
173 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
174 pAnchor, pHelp, pLabel, pTranslated);
177 snprintf(output, sizeof(output),
178 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
179 pAnchor, pHelp, pLabel);
182 /****************************************************************************
184 ****************************************************************************/
185 static void print_footer(void)
187 if (!include_html("include/footer.html")) {
188 d_printf("\n</BODY>\n</HTML>\n");
192 /****************************************************************************
193 display one editable parameter in a form
194 ****************************************************************************/
195 static void show_parameter(int snum, struct parm_struct *parm)
198 void *ptr = parm->ptr;
200 if (parm->class == P_LOCAL && snum >= 0) {
201 ptr = lp_local_ptr(snum, ptr);
204 printf("<tr><td>%s</td><td>", get_parm_translated(stripspaceupper(parm->label), _("Help"), parm->label));
205 switch (parm->type) {
207 d_printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
208 make_parm_name(parm->label), *(char *)ptr);
209 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
210 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
214 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"",
215 make_parm_name(parm->label));
216 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
217 char **list = *(char ***)ptr;
218 for (;*list;list++) {
219 d_printf("%s%s", *list, ((*(list+1))?" ":""));
223 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
224 _("Set Default"), make_parm_name(parm->label));
225 if (parm->def.lvalue) {
226 char **list = (char **)(parm->def.lvalue);
227 for (; *list; list++) {
228 d_printf("%s%s", *list, ((*(list+1))?" ":""));
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)));
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);
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);
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));
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)));
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));
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, unsigned int parm_filter, int printers)
296 struct parm_struct *parm;
297 const char *heading = NULL;
298 const 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))
303 if (parm->class == P_SEPARATOR) {
304 heading = parm->label;
307 if (parm->flags & FLAG_HIDE) continue;
309 if (printers & !(parm->flags & FLAG_PRINT)) continue;
310 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
312 if (parm_filter == FLAG_BASIC) {
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) {
322 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
326 if (!str_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
331 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
336 if (*(BOOL *)ptr == (BOOL)(parm->def.bvalue)) continue;
341 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
346 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
352 if (printers && !(parm->flags & FLAG_PRINT)) continue;
354 if (parm_filter == FLAG_WIZARD) {
355 if (!((parm->flags & FLAG_WIZARD))) continue;
357 if (parm_filter == FLAG_ADVANCED) {
358 if (!((parm->flags & FLAG_ADVANCED))) continue;
360 if (heading && heading != last_heading) {
361 d_printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
362 last_heading = heading;
364 show_parameter(snum, parm);
368 /****************************************************************************
369 load the smb.conf file into loadparm.
370 ****************************************************************************/
371 static BOOL load_config(BOOL save_def)
373 lp_resetnumservices();
374 return lp_load(dyn_CONFIGFILE,False,save_def,False);
377 /****************************************************************************
379 ****************************************************************************/
380 static void write_config(FILE *f, BOOL show_defaults)
382 fprintf(f, "# Samba config file created using SWAT\n");
383 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
384 fprintf(f, "# Date: %s\n\n", timestring(False));
386 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
389 /****************************************************************************
390 save and reload the smb.conf config file
391 ****************************************************************************/
392 static int save_reload(int snum)
397 f = sys_fopen(dyn_CONFIGFILE,"w");
399 d_printf("failed to open %s for writing\n", dyn_CONFIGFILE);
403 /* just in case they have used the buggy xinetd to create the file */
404 if (fstat(fileno(f), &st) == 0 &&
405 (st.st_mode & S_IWOTH)) {
406 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
409 write_config(f, False);
411 lp_dump_one(f, False, snum);
416 if (!load_config(False)) {
417 d_printf("Can't reload %s\n", dyn_CONFIGFILE);
420 iNumNonAutoPrintServices = lp_numservices();
426 /****************************************************************************
428 ****************************************************************************/
429 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
434 if (snum < 0 && parm->class == P_LOCAL) {
435 /* this handles the case where we are changing a local
436 variable globally. We need to change the parameter in
437 all shares where it is currently set to the default */
438 for (i=0;i<lp_numservices();i++) {
439 s = lp_servicename(i);
440 if (s && (*s) && lp_is_default(i, parm)) {
441 lp_do_parameter(i, parm->label, v);
446 lp_do_parameter(snum, parm->label, v);
449 /****************************************************************************
450 commit a set of parameters for a service
451 ****************************************************************************/
452 static void commit_parameters(int snum)
455 struct parm_struct *parm;
459 while ((parm = lp_next_parameter(snum, &i, 1))) {
460 slprintf(label, sizeof(label)-1, "parm_%s", make_parm_name(parm->label));
461 if ((v = cgi_variable(label))) {
462 if (parm->flags & FLAG_HIDE) continue;
463 commit_parameter(snum, parm, v);
468 /****************************************************************************
469 spit out the html for a link with an image
470 ****************************************************************************/
471 static void image_link(const char *name, const char *hlink, const char *src)
473 d_printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
474 cgi_baseurl(), hlink, src, name);
477 /****************************************************************************
478 display the main navigation controls at the top of each page along
480 ****************************************************************************/
481 static void show_main_buttons(void)
485 if ((p = cgi_user_name()) && strcmp(p, "root")) {
486 d_printf(_("Logged in as <b>%s</b><p>\n"), p);
489 image_link(_("Home"), "", "images/home.gif");
490 if (have_write_access) {
491 image_link(_("Globals"), "globals", "images/globals.gif");
492 image_link(_("Shares"), "shares", "images/shares.gif");
493 image_link(_("Printers"), "printers", "images/printers.gif");
494 image_link(_("Wizard"), "wizard", "images/wizard.gif");
496 if (have_read_access) {
497 image_link(_("Status"), "status", "images/status.gif");
498 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
500 image_link(_("Password Management"), "passwd", "images/passwd.gif");
505 /****************************************************************************
506 * Handle Display/Edit Mode CGI
507 ****************************************************************************/
508 static void ViewModeBoxes(int mode)
510 d_printf("<p>%s\n", _("Configuration View: "));
511 d_printf("<input type=radio name=\"ViewMode\" value=0 %s>Basic\n", (mode == 0) ? "checked" : "");
512 d_printf("<input type=radio name=\"ViewMode\" value=1 %s>Advanced\n", (mode == 1) ? "checked" : "");
513 d_printf("<input type=radio name=\"ViewMode\" value=2 %s>Developer\n", (mode == 2) ? "checked" : "");
514 d_printf("</p><br>\n");
517 /****************************************************************************
518 display a welcome page
519 ****************************************************************************/
520 static void welcome_page(void)
522 include_html("help/welcome.html");
525 /****************************************************************************
526 display the current smb.conf
527 ****************************************************************************/
528 static void viewconfig_page(void)
532 if (cgi_variable("full_view")) {
536 d_printf("<H2>%s</H2>\n", _("Current Config"));
537 d_printf("<form method=post>\n");
540 d_printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
542 d_printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
545 d_printf("<p><pre>");
546 write_config(stdout, full_view);
548 d_printf("</form>\n");
551 /****************************************************************************
552 second screen of the wizard ... Fetch Configuration Parameters
553 ****************************************************************************/
554 static void wizard_params_page(void)
556 unsigned int parm_filter = FLAG_WIZARD;
558 /* Here we first set and commit all the parameters that were selected
559 in the previous screen. */
561 d_printf("<H2>Wizard Parameter Edit Page</H2>\n");
563 if (cgi_variable("Commit")) {
564 commit_parameters(GLOBALS_SNUM);
568 d_printf("<form name=\"swatform\" method=post action=wizard_params>\n");
570 if (have_write_access) {
571 d_printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
574 d_printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
577 d_printf("<table>\n");
578 show_parameters(GLOBALS_SNUM, 1, parm_filter, 0);
579 d_printf("</table>\n");
580 d_printf("</form>\n");
583 /****************************************************************************
584 Utility to just rewrite the smb.conf file - effectively just cleans it up
585 ****************************************************************************/
586 static void rewritecfg_file(void)
588 commit_parameters(GLOBALS_SNUM);
590 d_printf("<H2>Note: smb.conf %s</H2>\n", _("file has been read and rewritten"));
593 /****************************************************************************
594 wizard to create/modify the smb.conf file
595 ****************************************************************************/
596 static void wizard_page(void)
598 /* Set some variables to collect data from smb.conf */
605 if (cgi_variable("Rewrite")) {
606 (void) rewritecfg_file();
610 if (cgi_variable("GetWizardParams")){
611 (void) wizard_params_page();
615 if (cgi_variable("Commit")){
616 SerType = atoi(cgi_variable("ServerType"));
617 winstype = atoi(cgi_variable("WINSType"));
618 have_home = lp_servicenumber(HOMES_NAME);
619 HomeExpo = atoi(cgi_variable("HomeExpo"));
621 /* Plain text passwords are too badly broken - use encrypted passwords only */
622 lp_do_parameter( GLOBALS_SNUM, "encrypt passwords", "Yes");
626 /* Stand-alone Server */
627 lp_do_parameter( GLOBALS_SNUM, "security", "USER" );
628 lp_do_parameter( GLOBALS_SNUM, "domain logons", "No" );
632 lp_do_parameter( GLOBALS_SNUM, "security", "DOMAIN" );
633 lp_do_parameter( GLOBALS_SNUM, "domain logons", "No" );
636 /* Domain Controller */
637 lp_do_parameter( GLOBALS_SNUM, "security", "USER" );
638 lp_do_parameter( GLOBALS_SNUM, "domain logons", "Yes" );
641 switch ( winstype ) {
643 lp_do_parameter( GLOBALS_SNUM, "wins support", "No" );
644 lp_do_parameter( GLOBALS_SNUM, "wins server", "" );
647 lp_do_parameter( GLOBALS_SNUM, "wins support", "Yes" );
648 lp_do_parameter( GLOBALS_SNUM, "wins server", "" );
651 lp_do_parameter( GLOBALS_SNUM, "wins support", "No" );
652 lp_do_parameter( GLOBALS_SNUM, "wins server", cgi_variable("WINSAddr"));
656 /* Have to create Homes share? */
657 if ((HomeExpo == 1) && (have_home == -1)) {
660 pstrcpy(unix_share,HOMES_NAME);
662 lp_copy_service(GLOBALS_SNUM, unix_share);
663 iNumNonAutoPrintServices = lp_numservices();
664 have_home = lp_servicenumber(HOMES_NAME);
665 lp_do_parameter( have_home, "read only", "No");
666 lp_do_parameter( have_home, "valid users", "%S");
667 lp_do_parameter( have_home, "browseable", "No");
668 commit_parameters(have_home);
671 /* Need to Delete Homes share? */
672 if ((HomeExpo == 0) && (have_home != -1)) {
673 lp_remove_service(have_home);
677 commit_parameters(GLOBALS_SNUM);
682 /* Now determine smb.conf WINS settings */
683 if (lp_wins_support())
685 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
689 /* Do we have a homes share? */
690 have_home = lp_servicenumber(HOMES_NAME);
692 if ((winstype == 2) && lp_wins_support())
695 role = lp_server_role();
698 d_printf("<H2>Samba Configuration Wizard</H2>\n");
699 d_printf("<form method=post action=wizard>\n");
701 if (have_write_access) {
702 d_printf(_("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments.\n"));
703 d_printf(_("The same will happen if you press the commit button."));
704 d_printf("<br><br>");
705 d_printf("<center>");
706 d_printf("<input type=submit name=\"Rewrite\" value=%s> ",_("Rewrite smb.conf file"));
707 d_printf("<input type=submit name=\"Commit\" value=%s> ",_("Commit"));
708 d_printf("<input type=submit name=\"GetWizardParams\" value=%s>", _("Edit Parameter Values"));
709 d_printf("</center>");
713 d_printf("<center><table border=0>");
714 d_printf("<tr><td><b>%s</b></td>\n", "Server Type: ");
715 d_printf("<td><input type=radio name=\"ServerType\" value=0 %s> Stand Alone </td>", (role == ROLE_STANDALONE) ? "checked" : "");
716 d_printf("<td><input type=radio name=\"ServerType\" value=1 %s> Domain Member </td>", (role == ROLE_DOMAIN_MEMBER) ? "checked" : "");
717 d_printf("<td><input type=radio name=\"ServerType\" value=2 %s> Domain Controller </td>", (role == ROLE_DOMAIN_PDC) ? "checked" : "");
719 if (role == ROLE_DOMAIN_BDC) {
720 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Unusual Type in smb.conf - Please Select New Mode</font></td></tr>");
722 d_printf("<tr><td><b>%s</b></td>\n", "Configure WINS As: ");
723 d_printf("<td><input type=radio name=\"WINSType\" value=0 %s> Not Used </td>", (winstype == 0) ? "checked" : "");
724 d_printf("<td><input type=radio name=\"WINSType\" value=1 %s> Server for client use </td>", (winstype == 1) ? "checked" : "");
725 d_printf("<td><input type=radio name=\"WINSType\" value=2 %s> Client of another WINS server </td>", (winstype == 2) ? "checked" : "");
726 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());
728 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>");
729 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Please Select desired WINS mode above.</font></td></tr>");
732 d_printf("<tr><td><b>%s</b></td>\n","Expose Home Directories: ");
733 d_printf("<td><input type=radio name=\"HomeExpo\" value=1 %s> Yes</td>", (have_home == -1) ? "" : "checked ");
734 d_printf("<td><input type=radio name=\"HomeExpo\" value=0 %s> No</td>", (have_home == -1 ) ? "checked" : "");
735 d_printf("<td></td></tr>");
737 /* Enable this when we are ready ....
738 * d_printf("<tr><td><b>%s</b></td>\n","Is Print Server: ");
739 * d_printf("<td><input type=radio name=\"PtrSvr\" value=1 %s> Yes</td>");
740 * d_printf("<td><input type=radio name=\"PtrSvr\" value=0 %s> No</td>");
741 * d_printf("<td></td></tr>");
744 d_printf("</table></center>");
747 d_printf(_("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment.\n"));
748 d_printf("</form>\n");
752 /****************************************************************************
753 display a globals editing page
754 ****************************************************************************/
755 static void globals_page(void)
757 unsigned int parm_filter = FLAG_BASIC;
760 d_printf("<H2>%s</H2>\n", _("Global Variables"));
762 if (cgi_variable("Commit")) {
763 commit_parameters(GLOBALS_SNUM);
767 if ( cgi_variable("ViewMode") )
768 mode = atoi(cgi_variable("ViewMode"));
770 d_printf("<form name=\"swatform\" method=post action=globals>\n");
772 ViewModeBoxes( mode );
775 parm_filter = FLAG_BASIC;
778 parm_filter = FLAG_ADVANCED;
781 parm_filter = FLAG_DEVELOPER;
785 if (have_write_access) {
786 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
787 _("Commit Changes"));
790 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
794 d_printf("<table>\n");
795 show_parameters(GLOBALS_SNUM, 1, parm_filter, 0);
796 d_printf("</table>\n");
797 d_printf("</form>\n");
800 /****************************************************************************
801 display a shares editing page. share is in unix codepage, and must be in
802 dos codepage. FIXME !!! JRA.
803 ****************************************************************************/
804 static void shares_page(void)
806 const char *share = cgi_variable("share");
811 unsigned int parm_filter = FLAG_BASIC;
814 snum = lp_servicenumber(share);
816 d_printf("<H2>%s</H2>\n", _("Share Parameters"));
818 if (cgi_variable("Commit") && snum >= 0) {
819 commit_parameters(snum);
823 if (cgi_variable("Delete") && snum >= 0) {
824 lp_remove_service(snum);
830 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
832 lp_copy_service(GLOBALS_SNUM, share);
833 iNumNonAutoPrintServices = lp_numservices();
835 snum = lp_servicenumber(share);
838 d_printf("<FORM name=\"swatform\" method=post>\n");
840 d_printf("<table>\n");
841 if ( cgi_variable("ViewMode") )
842 mode = atoi(cgi_variable("ViewMode"));
843 ViewModeBoxes( mode );
846 parm_filter = FLAG_BASIC;
849 parm_filter = FLAG_ADVANCED;
852 parm_filter = FLAG_DEVELOPER;
855 d_printf("<br><tr>\n");
856 d_printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
857 d_printf("<td><select name=share>\n");
859 d_printf("<option value=\" \"> \n");
860 for (i=0;i<lp_numservices();i++) {
861 s = lp_servicename(i);
862 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
863 d_printf("<option %s value=\"%s\">%s\n",
864 (share && strcmp(share,s)==0)?"SELECTED":"",
868 d_printf("</select></td>\n");
869 if (have_write_access) {
870 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
873 d_printf("</table>");
875 if (have_write_access) {
877 d_printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
878 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
880 d_printf("</table>");
884 if (have_write_access) {
885 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
888 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
893 d_printf("<table>\n");
894 show_parameters(snum, 1, parm_filter, 0);
895 d_printf("</table>\n");
898 d_printf("</FORM>\n");
901 /*************************************************************
902 change a password either locally or remotely
903 *************************************************************/
904 static BOOL change_password(const char *remote_machine, const char *user_name,
905 const char *old_passwd, const char *new_passwd,
913 d_printf("%s<p>", _("password change in demo mode rejected\n"));
917 if (remote_machine != NULL) {
918 ret = remote_password_change(remote_machine, user_name, old_passwd,
919 new_passwd, err_str, sizeof(err_str));
921 d_printf("%s\n<p>", err_str);
925 if(!initialize_password_db(True)) {
926 d_printf("Can't setup password database vectors.\n<p>");
930 ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
931 msg_str, sizeof(msg_str));
934 d_printf("%s\n<p>", msg_str);
936 d_printf("%s\n<p>", err_str);
941 /****************************************************************************
942 do the stuff required to add or change a password
943 ****************************************************************************/
944 static void chg_passwd(void)
950 /* Make sure users name has been specified */
951 if (strlen(cgi_variable(SWAT_USER)) == 0) {
952 d_printf("<p>%s", _(" Must specify \"User Name\" \n"));
957 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
958 * so if that's what we're doing, skip the rest of the checks
960 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
963 * If current user is not root, make sure old password has been specified
964 * If REMOTE change, even root must provide old password
966 if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
967 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
968 d_printf("<p>%s", _(" Must specify \"Old Password\" \n"));
972 /* If changing a users password on a remote hosts we have to know what host */
973 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
974 d_printf("<p>%s", _(" Must specify \"Remote Machine\" \n"));
978 /* Make sure new passwords have been specified */
979 if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
980 (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
981 d_printf("<p>%s", _(" Must specify \"New, and Re-typed Passwords\" \n"));
985 /* Make sure new passwords was typed correctly twice */
986 if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
987 d_printf("<p>%s", _(" Re-typed password didn't match new password\n"));
992 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
993 host = cgi_variable(RHOST);
994 } else if (am_root()) {
1001 * Set up the local flags.
1004 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1005 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1006 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1007 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1009 rslt = change_password(host,
1010 cgi_variable(SWAT_USER),
1011 cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
1014 if(local_flags == 0) {
1017 d_printf(_(" The passwd for '%s' has been changed. \n"), cgi_variable(SWAT_USER));
1019 d_printf(_(" The passwd for '%s' has NOT been changed. \n"), cgi_variable(SWAT_USER));
1026 /****************************************************************************
1027 display a password editing page
1028 ****************************************************************************/
1029 static void passwd_page(void)
1031 const char *new_name = cgi_user_name();
1034 * After the first time through here be nice. If the user
1035 * changed the User box text to another users name, remember it.
1037 if (cgi_variable(SWAT_USER)) {
1038 new_name = cgi_variable(SWAT_USER);
1041 if (!new_name) new_name = "";
1043 d_printf("<H2>%s</H2>\n", _("Server Password Management"));
1045 d_printf("<FORM name=\"swatform\" method=post>\n");
1047 d_printf("<table>\n");
1050 * Create all the dialog boxes for data collection
1052 d_printf("<tr><td>%s</td>\n", _(" User Name : "));
1053 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1055 d_printf("<tr><td>%s</td>\n", _(" Old Password : "));
1056 d_printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1058 d_printf("<tr><td>%s</td>\n", _(" New Password : "));
1059 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1060 d_printf("<tr><td>%s</td>\n", _(" Re-type New Password : "));
1061 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1062 d_printf("</table>\n");
1065 * Create all the control buttons for requesting action
1067 d_printf("<input type=submit name=%s value=\"%s\">\n",
1068 CHG_S_PASSWD_FLAG, _("Change Password"));
1069 if (demo_mode || am_root()) {
1070 d_printf("<input type=submit name=%s value=\"%s\">\n",
1071 ADD_USER_FLAG, _("Add New User"));
1072 d_printf("<input type=submit name=%s value=\"%s\">\n",
1073 DELETE_USER_FLAG, _("Delete User"));
1074 d_printf("<input type=submit name=%s value=\"%s\">\n",
1075 DISABLE_USER_FLAG, _("Disable User"));
1076 d_printf("<input type=submit name=%s value=\"%s\">\n",
1077 ENABLE_USER_FLAG, _("Enable User"));
1079 d_printf("<p></FORM>\n");
1082 * Do some work if change, add, disable or enable was
1083 * requested. It could be this is the first time through this
1084 * code, so there isn't anything to do. */
1085 if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1086 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1090 d_printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1092 d_printf("<FORM name=\"swatform\" method=post>\n");
1094 d_printf("<table>\n");
1097 * Create all the dialog boxes for data collection
1099 d_printf("<tr><td>%s</td>\n", _(" User Name : "));
1100 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1101 d_printf("<tr><td>%s</td>\n", _(" Old Password : "));
1102 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1103 d_printf("<tr><td>%s</td>\n", _(" New Password : "));
1104 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1105 d_printf("<tr><td>%s</td>\n", _(" Re-type New Password : "));
1106 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1107 d_printf("<tr><td>%s</td>\n", _(" Remote Machine : "));
1108 d_printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1110 d_printf("</table>");
1113 * Create all the control buttons for requesting action
1115 d_printf("<input type=submit name=%s value=\"%s\">",
1116 CHG_R_PASSWD_FLAG, _("Change Password"));
1118 d_printf("<p></FORM>\n");
1121 * Do some work if a request has been made to change the
1122 * password somewhere other than the server. It could be this
1123 * is the first time through this code, so there isn't
1124 * anything to do. */
1125 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1131 /****************************************************************************
1132 display a printers editing page
1133 ****************************************************************************/
1134 static void printers_page(void)
1136 const char *share = cgi_variable("share");
1141 unsigned int parm_filter = FLAG_BASIC;
1144 snum = lp_servicenumber(share);
1146 d_printf("<H2>%s</H2>\n", _("Printer Parameters"));
1148 d_printf("<H3>%s</H3>\n", _("Important Note:"));
1149 d_printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
1150 d_printf(_("are autoloaded printers from "));
1151 d_printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1152 d_printf(_("Attempting to delete these printers from SWAT will have no effect.\n"));
1154 if (cgi_variable("Commit") && snum >= 0) {
1155 commit_parameters(snum);
1156 if (snum >= iNumNonAutoPrintServices)
1162 if (cgi_variable("Delete") && snum >= 0) {
1163 lp_remove_service(snum);
1169 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1171 lp_copy_service(GLOBALS_SNUM, share);
1172 iNumNonAutoPrintServices = lp_numservices();
1173 snum = lp_servicenumber(share);
1174 lp_do_parameter(snum, "print ok", "Yes");
1176 snum = lp_servicenumber(share);
1179 d_printf("<FORM name=\"swatform\" method=post>\n");
1181 if ( cgi_variable("ViewMode") )
1182 mode = atoi(cgi_variable("ViewMode"));
1183 ViewModeBoxes( mode );
1186 parm_filter = FLAG_BASIC;
1189 parm_filter = FLAG_ADVANCED;
1192 parm_filter = FLAG_DEVELOPER;
1195 d_printf("<table>\n");
1196 d_printf("<tr><td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Printer"));
1197 d_printf("<td><select name=share>\n");
1198 if (snum < 0 || !lp_print_ok(snum))
1199 d_printf("<option value=\" \"> \n");
1200 for (i=0;i<lp_numservices();i++) {
1201 s = lp_servicename(i);
1202 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1203 if (i >= iNumNonAutoPrintServices)
1204 d_printf("<option %s value=\"%s\">[*]%s\n",
1205 (share && strcmp(share,s)==0)?"SELECTED":"",
1208 d_printf("<option %s value=\"%s\">%s\n",
1209 (share && strcmp(share,s)==0)?"SELECTED":"",
1213 d_printf("</select></td>");
1214 if (have_write_access) {
1215 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1218 d_printf("</table>\n");
1220 if (have_write_access) {
1221 d_printf("<table>\n");
1222 d_printf("<tr><td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Printer"));
1223 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1224 d_printf("</table>");
1229 if (have_write_access) {
1230 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1232 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1237 d_printf("<table>\n");
1238 show_parameters(snum, 1, parm_filter, 1);
1239 d_printf("</table>\n");
1241 d_printf("</FORM>\n");
1246 * main function for SWAT.
1248 int main(int argc, char *argv[])
1250 extern char *optarg;
1256 umask(S_IWGRP | S_IWOTH);
1258 #if defined(HAVE_SET_AUTH_PARAMETERS)
1259 set_auth_parameters(argc, argv);
1260 #endif /* HAVE_SET_AUTH_PARAMETERS */
1262 /* just in case it goes wild ... */
1267 /* we don't want any SIGPIPE messages */
1268 BlockSignals(True,SIGPIPE);
1270 dbf = x_fopen("/dev/null", O_WRONLY, 0);
1271 if (!dbf) dbf = x_stderr;
1273 /* we don't want stderr screwing us up */
1275 open("/dev/null", O_WRONLY);
1277 while ((opt = getopt(argc, argv,"s:a")) != EOF) {
1280 pstrcpy(dyn_CONFIGFILE,optarg);
1288 setup_logging(argv[0],DEBUG_FILE);
1290 iNumNonAutoPrintServices = lp_numservices();
1293 cgi_setup(dyn_SWATDIR, !demo_mode);
1297 cgi_load_variables();
1299 if (!file_exist(dyn_CONFIGFILE, NULL)) {
1300 have_read_access = True;
1301 have_write_access = True;
1303 /* check if the authenticated user has write access - if not then
1304 don't show write options */
1305 have_write_access = (access(dyn_CONFIGFILE,W_OK) == 0);
1307 /* if the user doesn't have read access to smb.conf then
1308 don't let them view it */
1309 have_read_access = (access(dyn_CONFIGFILE,R_OK) == 0);
1312 show_main_buttons();
1314 page = cgi_pathinfo();
1316 /* Root gets full functionality */
1317 if (have_read_access && strcmp(page, "globals")==0) {
1319 } else if (have_read_access && strcmp(page,"shares")==0) {
1321 } else if (have_read_access && strcmp(page,"printers")==0) {
1323 } else if (have_read_access && strcmp(page,"status")==0) {
1325 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1327 } else if (strcmp(page,"passwd")==0) {
1329 } else if (have_read_access && strcmp(page,"wizard")==0) {
1331 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1332 wizard_params_page();
1333 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {