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 HAVE_SMB_REGISTER_PASSDB
35 #include "module_dummy.h"
37 #define GLOBALS_SNUM -1
39 static BOOL demo_mode = False;
40 static BOOL have_write_access = False;
41 static BOOL have_read_access = False;
42 static int iNumNonAutoPrintServices = 0;
45 * Password Management Globals
47 #define SWAT_USER "username"
48 #define OLD_PSWD "old_passwd"
49 #define NEW_PSWD "new_passwd"
50 #define NEW2_PSWD "new2_passwd"
51 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
52 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
53 #define ADD_USER_FLAG "add_user_flag"
54 #define DELETE_USER_FLAG "delete_user_flag"
55 #define DISABLE_USER_FLAG "disable_user_flag"
56 #define ENABLE_USER_FLAG "enable_user_flag"
57 #define RHOST "remote_host"
59 /* we need these because we link to locking*.o */
60 void become_root(void) {}
61 void unbecome_root(void) {}
63 /****************************************************************************
64 ****************************************************************************/
65 static int enum_index(int value, const struct enum_list *enumlist)
68 for (i=0;enumlist[i].name;i++)
69 if (value == enumlist[i].value) break;
73 static char *fix_backslash(const char *str)
75 static char newstring[1024];
79 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
87 static char *stripspaceupper(const char *str)
89 static char newstring[1024];
93 if (*str != ' ') *p++ = toupper(*str);
100 static char *make_parm_name(const char *label)
102 static char parmname[1024];
106 if (*label == ' ') *p++ = '_';
114 /****************************************************************************
115 include a lump of html in a page
116 ****************************************************************************/
117 static int include_html(const char *fname)
123 fd = web_open(fname, O_RDONLY, 0);
126 d_printf("ERROR: Can't open %s\n", fname);
130 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
138 /****************************************************************************
139 start the page with standard stuff
140 ****************************************************************************/
141 static void print_header(void)
143 if (!cgi_waspost()) {
144 d_printf("Expires: 0\r\n");
146 d_printf("Content-type: text/html\r\n\r\n");
148 if (!include_html("include/header.html")) {
149 d_printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
150 d_printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
154 /* *******************************************************************
155 show parameter label with translated name in the following form
156 because showing original and translated label in one line looks
157 too long, and showing translated label only is unusable for
159 -------------------------------
160 HELP security [combo box][button]
162 -------------------------------
163 (capital words are translated by gettext.)
164 if no translation is available, then same form as original is
166 "i18n_translated_parm" class is used to change the color of the
167 translated parameter with CSS.
168 **************************************************************** */
169 static const char* get_parm_translated(
170 const char* pAnchor, const char* pHelp, const char* pLabel)
172 const char* pTranslated = _(pLabel);
173 static pstring output;
174 if(strcmp(pLabel, pTranslated) != 0)
176 snprintf(output, sizeof(output),
177 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
178 pAnchor, pHelp, pLabel, pTranslated);
181 snprintf(output, sizeof(output),
182 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
183 pAnchor, pHelp, pLabel);
186 /****************************************************************************
188 ****************************************************************************/
189 static void print_footer(void)
191 if (!include_html("include/footer.html")) {
192 d_printf("\n</BODY>\n</HTML>\n");
196 /****************************************************************************
197 display one editable parameter in a form
198 ****************************************************************************/
199 static void show_parameter(int snum, struct parm_struct *parm)
202 void *ptr = parm->ptr;
204 if (parm->class == P_LOCAL && snum >= 0) {
205 ptr = lp_local_ptr(snum, ptr);
208 printf("<tr><td>%s</td><td>", get_parm_translated(stripspaceupper(parm->label), _("Help"), parm->label));
209 switch (parm->type) {
211 d_printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
212 make_parm_name(parm->label), *(char *)ptr);
213 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
214 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
218 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"",
219 make_parm_name(parm->label));
220 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
221 char **list = *(char ***)ptr;
222 for (;*list;list++) {
223 d_printf("%s%s", *list, ((*(list+1))?" ":""));
227 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
228 _("Set Default"), make_parm_name(parm->label));
229 if (parm->def.lvalue) {
230 char **list = (char **)(parm->def.lvalue);
231 for (; *list; list++) {
232 d_printf("%s%s", *list, ((*(list+1))?" ":""));
240 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
241 make_parm_name(parm->label), *(char **)ptr);
242 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
243 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
248 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
249 make_parm_name(parm->label), (char *)ptr);
250 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
251 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
255 d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
256 d_printf("<option %s>Yes", (*(BOOL *)ptr)?"selected":"");
257 d_printf("<option %s>No", (*(BOOL *)ptr)?"":"selected");
258 d_printf("</select>");
259 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
260 _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?0:1);
264 d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
265 d_printf("<option %s>Yes", (*(BOOL *)ptr)?"":"selected");
266 d_printf("<option %s>No", (*(BOOL *)ptr)?"selected":"");
267 d_printf("</select>");
268 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
269 _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?1:0);
273 d_printf("<input type=text size=8 name=\"parm_%s\" value=%d>", make_parm_name(parm->label), *(int *)ptr);
274 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
275 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
279 d_printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm->label), octal_string(*(int *)ptr));
280 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
281 _("Set Default"), make_parm_name(parm->label),
282 octal_string((int)(parm->def.ivalue)));
286 d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
287 for (i=0;parm->enum_list[i].name;i++) {
288 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
289 d_printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
292 d_printf("</select>");
293 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
294 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
299 d_printf("</td></tr>\n");
302 /****************************************************************************
303 display a set of parameters for a service
304 ****************************************************************************/
305 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
308 struct parm_struct *parm;
309 const char *heading = NULL;
310 const char *last_heading = NULL;
312 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
313 if (snum < 0 && parm->class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
315 if (parm->class == P_SEPARATOR) {
316 heading = parm->label;
319 if (parm->flags & FLAG_HIDE) continue;
321 if (printers & !(parm->flags & FLAG_PRINT)) continue;
322 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
324 if (parm_filter == FLAG_BASIC) {
325 if (!(parm->flags & FLAG_BASIC)) {
326 void *ptr = parm->ptr;
328 if (parm->class == P_LOCAL && snum >= 0) {
329 ptr = lp_local_ptr(snum, ptr);
332 switch (parm->type) {
334 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
338 if (!str_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
343 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
348 if (!strcmp((char *)ptr,(char *)(parm->def.svalue))) continue;
353 if (*(BOOL *)ptr == (BOOL)(parm->def.bvalue)) continue;
358 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
363 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
369 if (printers && !(parm->flags & FLAG_PRINT)) continue;
371 if (parm_filter == FLAG_WIZARD) {
372 if (!((parm->flags & FLAG_WIZARD))) continue;
374 if (parm_filter == FLAG_ADVANCED) {
375 if (!((parm->flags & FLAG_ADVANCED))) continue;
377 if (heading && heading != last_heading) {
378 d_printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
379 last_heading = heading;
381 show_parameter(snum, parm);
385 /****************************************************************************
386 load the smb.conf file into loadparm.
387 ****************************************************************************/
388 static BOOL load_config(BOOL save_def)
390 lp_resetnumservices();
391 return lp_load(dyn_CONFIGFILE,False,save_def,False);
394 /****************************************************************************
396 ****************************************************************************/
397 static void write_config(FILE *f, BOOL show_defaults)
399 fprintf(f, "# Samba config file created using SWAT\n");
400 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
401 fprintf(f, "# Date: %s\n\n", timestring(False));
403 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
406 /****************************************************************************
407 save and reload the smb.conf config file
408 ****************************************************************************/
409 static int save_reload(int snum)
414 f = sys_fopen(dyn_CONFIGFILE,"w");
416 d_printf("failed to open %s for writing\n", dyn_CONFIGFILE);
420 /* just in case they have used the buggy xinetd to create the file */
421 if (fstat(fileno(f), &st) == 0 &&
422 (st.st_mode & S_IWOTH)) {
423 #if defined HAVE_FCHMOD
424 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
426 chmod(dyn_CONFIGFILE, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
430 write_config(f, False);
432 lp_dump_one(f, False, snum);
437 if (!load_config(False)) {
438 d_printf("Can't reload %s\n", dyn_CONFIGFILE);
441 iNumNonAutoPrintServices = lp_numservices();
447 /****************************************************************************
449 ****************************************************************************/
450 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
455 if (snum < 0 && parm->class == P_LOCAL) {
456 /* this handles the case where we are changing a local
457 variable globally. We need to change the parameter in
458 all shares where it is currently set to the default */
459 for (i=0;i<lp_numservices();i++) {
460 s = lp_servicename(i);
461 if (s && (*s) && lp_is_default(i, parm)) {
462 lp_do_parameter(i, parm->label, v);
467 lp_do_parameter(snum, parm->label, v);
470 /****************************************************************************
471 commit a set of parameters for a service
472 ****************************************************************************/
473 static void commit_parameters(int snum)
476 struct parm_struct *parm;
480 while ((parm = lp_next_parameter(snum, &i, 1))) {
481 slprintf(label, sizeof(label)-1, "parm_%s", make_parm_name(parm->label));
482 if ((v = cgi_variable(label))) {
483 if (parm->flags & FLAG_HIDE) continue;
484 commit_parameter(snum, parm, v);
489 /****************************************************************************
490 spit out the html for a link with an image
491 ****************************************************************************/
492 static void image_link(const char *name, const char *hlink, const char *src)
494 d_printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
495 cgi_baseurl(), hlink, src, name);
498 /****************************************************************************
499 display the main navigation controls at the top of each page along
501 ****************************************************************************/
502 static void show_main_buttons(void)
506 if ((p = cgi_user_name()) && strcmp(p, "root")) {
507 d_printf(_("Logged in as <b>%s</b><p>\n"), p);
510 image_link(_("Home"), "", "images/home.gif");
511 if (have_write_access) {
512 image_link(_("Globals"), "globals", "images/globals.gif");
513 image_link(_("Shares"), "shares", "images/shares.gif");
514 image_link(_("Printers"), "printers", "images/printers.gif");
515 image_link(_("Wizard"), "wizard", "images/wizard.gif");
517 if (have_read_access) {
518 image_link(_("Status"), "status", "images/status.gif");
519 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
521 image_link(_("Password Management"), "passwd", "images/passwd.gif");
526 /****************************************************************************
527 * Handle Display/Edit Mode CGI
528 ****************************************************************************/
529 static void ViewModeBoxes(int mode)
531 d_printf("<p>%s\n", _("Configuration View: "));
532 d_printf("<input type=radio name=\"ViewMode\" value=0 %s>Basic\n", (mode == 0) ? "checked" : "");
533 d_printf("<input type=radio name=\"ViewMode\" value=1 %s>Advanced\n", (mode == 1) ? "checked" : "");
534 d_printf("<input type=radio name=\"ViewMode\" value=2 %s>Developer\n", (mode == 2) ? "checked" : "");
535 d_printf("</p><br>\n");
538 /****************************************************************************
539 display a welcome page
540 ****************************************************************************/
541 static void welcome_page(void)
543 include_html("help/welcome.html");
546 /****************************************************************************
547 display the current smb.conf
548 ****************************************************************************/
549 static void viewconfig_page(void)
553 if (cgi_variable("full_view")) {
557 d_printf("<H2>%s</H2>\n", _("Current Config"));
558 d_printf("<form method=post>\n");
561 d_printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
563 d_printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
566 d_printf("<p><pre>");
567 write_config(stdout, full_view);
569 d_printf("</form>\n");
572 /****************************************************************************
573 second screen of the wizard ... Fetch Configuration Parameters
574 ****************************************************************************/
575 static void wizard_params_page(void)
577 unsigned int parm_filter = FLAG_WIZARD;
579 /* Here we first set and commit all the parameters that were selected
580 in the previous screen. */
582 d_printf("<H2>Wizard Parameter Edit Page</H2>\n");
584 if (cgi_variable("Commit")) {
585 commit_parameters(GLOBALS_SNUM);
589 d_printf("<form name=\"swatform\" method=post action=wizard_params>\n");
591 if (have_write_access) {
592 d_printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
595 d_printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
598 d_printf("<table>\n");
599 show_parameters(GLOBALS_SNUM, 1, parm_filter, 0);
600 d_printf("</table>\n");
601 d_printf("</form>\n");
604 /****************************************************************************
605 Utility to just rewrite the smb.conf file - effectively just cleans it up
606 ****************************************************************************/
607 static void rewritecfg_file(void)
609 commit_parameters(GLOBALS_SNUM);
611 d_printf("<H2>Note: smb.conf %s</H2>\n", _("file has been read and rewritten"));
614 /****************************************************************************
615 wizard to create/modify the smb.conf file
616 ****************************************************************************/
617 static void wizard_page(void)
619 /* Set some variables to collect data from smb.conf */
626 if (cgi_variable("Rewrite")) {
627 (void) rewritecfg_file();
631 if (cgi_variable("GetWizardParams")){
632 (void) wizard_params_page();
636 if (cgi_variable("Commit")){
637 SerType = atoi(cgi_variable("ServerType"));
638 winstype = atoi(cgi_variable("WINSType"));
639 have_home = lp_servicenumber(HOMES_NAME);
640 HomeExpo = atoi(cgi_variable("HomeExpo"));
642 /* Plain text passwords are too badly broken - use encrypted passwords only */
643 lp_do_parameter( GLOBALS_SNUM, "encrypt passwords", "Yes");
647 /* Stand-alone Server */
648 lp_do_parameter( GLOBALS_SNUM, "security", "USER" );
649 lp_do_parameter( GLOBALS_SNUM, "domain logons", "No" );
653 lp_do_parameter( GLOBALS_SNUM, "security", "DOMAIN" );
654 lp_do_parameter( GLOBALS_SNUM, "domain logons", "No" );
657 /* Domain Controller */
658 lp_do_parameter( GLOBALS_SNUM, "security", "USER" );
659 lp_do_parameter( GLOBALS_SNUM, "domain logons", "Yes" );
662 switch ( winstype ) {
664 lp_do_parameter( GLOBALS_SNUM, "wins support", "No" );
665 lp_do_parameter( GLOBALS_SNUM, "wins server", "" );
668 lp_do_parameter( GLOBALS_SNUM, "wins support", "Yes" );
669 lp_do_parameter( GLOBALS_SNUM, "wins server", "" );
672 lp_do_parameter( GLOBALS_SNUM, "wins support", "No" );
673 lp_do_parameter( GLOBALS_SNUM, "wins server", cgi_variable("WINSAddr"));
677 /* Have to create Homes share? */
678 if ((HomeExpo == 1) && (have_home == -1)) {
681 pstrcpy(unix_share,HOMES_NAME);
683 lp_copy_service(GLOBALS_SNUM, unix_share);
684 iNumNonAutoPrintServices = lp_numservices();
685 have_home = lp_servicenumber(HOMES_NAME);
686 lp_do_parameter( have_home, "read only", "No");
687 lp_do_parameter( have_home, "valid users", "%S");
688 lp_do_parameter( have_home, "browseable", "No");
689 commit_parameters(have_home);
692 /* Need to Delete Homes share? */
693 if ((HomeExpo == 0) && (have_home != -1)) {
694 lp_remove_service(have_home);
698 commit_parameters(GLOBALS_SNUM);
703 /* Now determine smb.conf WINS settings */
704 if (lp_wins_support())
706 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
710 /* Do we have a homes share? */
711 have_home = lp_servicenumber(HOMES_NAME);
713 if ((winstype == 2) && lp_wins_support())
716 role = lp_server_role();
719 d_printf("<H2>Samba Configuration Wizard</H2>\n");
720 d_printf("<form method=post action=wizard>\n");
722 if (have_write_access) {
723 d_printf(_("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments.\n"));
724 d_printf(_("The same will happen if you press the commit button."));
725 d_printf("<br><br>");
726 d_printf("<center>");
727 d_printf("<input type=submit name=\"Rewrite\" value=%s> ",_("Rewrite smb.conf file"));
728 d_printf("<input type=submit name=\"Commit\" value=%s> ",_("Commit"));
729 d_printf("<input type=submit name=\"GetWizardParams\" value=%s>", _("Edit Parameter Values"));
730 d_printf("</center>");
734 d_printf("<center><table border=0>");
735 d_printf("<tr><td><b>%s</b></td>\n", "Server Type: ");
736 d_printf("<td><input type=radio name=\"ServerType\" value=0 %s> Stand Alone </td>", (role == ROLE_STANDALONE) ? "checked" : "");
737 d_printf("<td><input type=radio name=\"ServerType\" value=1 %s> Domain Member </td>", (role == ROLE_DOMAIN_MEMBER) ? "checked" : "");
738 d_printf("<td><input type=radio name=\"ServerType\" value=2 %s> Domain Controller </td>", (role == ROLE_DOMAIN_PDC) ? "checked" : "");
740 if (role == ROLE_DOMAIN_BDC) {
741 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Unusual Type in smb.conf - Please Select New Mode</font></td></tr>");
743 d_printf("<tr><td><b>%s</b></td>\n", "Configure WINS As: ");
744 d_printf("<td><input type=radio name=\"WINSType\" value=0 %s> Not Used </td>", (winstype == 0) ? "checked" : "");
745 d_printf("<td><input type=radio name=\"WINSType\" value=1 %s> Server for client use </td>", (winstype == 1) ? "checked" : "");
746 d_printf("<td><input type=radio name=\"WINSType\" value=2 %s> Client of another WINS server </td>", (winstype == 2) ? "checked" : "");
747 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());
749 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>");
750 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Please Select desired WINS mode above.</font></td></tr>");
753 d_printf("<tr><td><b>%s</b></td>\n","Expose Home Directories: ");
754 d_printf("<td><input type=radio name=\"HomeExpo\" value=1 %s> Yes</td>", (have_home == -1) ? "" : "checked ");
755 d_printf("<td><input type=radio name=\"HomeExpo\" value=0 %s> No</td>", (have_home == -1 ) ? "checked" : "");
756 d_printf("<td></td></tr>");
758 /* Enable this when we are ready ....
759 * d_printf("<tr><td><b>%s</b></td>\n","Is Print Server: ");
760 * d_printf("<td><input type=radio name=\"PtrSvr\" value=1 %s> Yes</td>");
761 * d_printf("<td><input type=radio name=\"PtrSvr\" value=0 %s> No</td>");
762 * d_printf("<td></td></tr>");
765 d_printf("</table></center>");
768 d_printf(_("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment.\n"));
769 d_printf("</form>\n");
773 /****************************************************************************
774 display a globals editing page
775 ****************************************************************************/
776 static void globals_page(void)
778 unsigned int parm_filter = FLAG_BASIC;
781 d_printf("<H2>%s</H2>\n", _("Global Variables"));
783 if (cgi_variable("Commit")) {
784 commit_parameters(GLOBALS_SNUM);
788 if ( cgi_variable("ViewMode") )
789 mode = atoi(cgi_variable("ViewMode"));
791 d_printf("<form name=\"swatform\" method=post action=globals>\n");
793 ViewModeBoxes( mode );
796 parm_filter = FLAG_BASIC;
799 parm_filter = FLAG_ADVANCED;
802 parm_filter = FLAG_DEVELOPER;
806 if (have_write_access) {
807 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
808 _("Commit Changes"));
811 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
815 d_printf("<table>\n");
816 show_parameters(GLOBALS_SNUM, 1, parm_filter, 0);
817 d_printf("</table>\n");
818 d_printf("</form>\n");
821 /****************************************************************************
822 display a shares editing page. share is in unix codepage, and must be in
823 dos codepage. FIXME !!! JRA.
824 ****************************************************************************/
825 static void shares_page(void)
827 const char *share = cgi_variable("share");
832 unsigned int parm_filter = FLAG_BASIC;
835 snum = lp_servicenumber(share);
837 d_printf("<H2>%s</H2>\n", _("Share Parameters"));
839 if (cgi_variable("Commit") && snum >= 0) {
840 commit_parameters(snum);
844 if (cgi_variable("Delete") && snum >= 0) {
845 lp_remove_service(snum);
851 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
853 lp_copy_service(GLOBALS_SNUM, share);
854 iNumNonAutoPrintServices = lp_numservices();
856 snum = lp_servicenumber(share);
859 d_printf("<FORM name=\"swatform\" method=post>\n");
861 d_printf("<table>\n");
862 if ( cgi_variable("ViewMode") )
863 mode = atoi(cgi_variable("ViewMode"));
864 ViewModeBoxes( mode );
867 parm_filter = FLAG_BASIC;
870 parm_filter = FLAG_ADVANCED;
873 parm_filter = FLAG_DEVELOPER;
876 d_printf("<br><tr>\n");
877 d_printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
878 d_printf("<td><select name=share>\n");
880 d_printf("<option value=\" \"> \n");
881 for (i=0;i<lp_numservices();i++) {
882 s = lp_servicename(i);
883 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
884 d_printf("<option %s value=\"%s\">%s\n",
885 (share && strcmp(share,s)==0)?"SELECTED":"",
889 d_printf("</select></td>\n");
890 if (have_write_access) {
891 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
894 d_printf("</table>");
896 if (have_write_access) {
898 d_printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
899 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
901 d_printf("</table>");
905 if (have_write_access) {
906 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
909 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
914 d_printf("<table>\n");
915 show_parameters(snum, 1, parm_filter, 0);
916 d_printf("</table>\n");
919 d_printf("</FORM>\n");
922 /*************************************************************
923 change a password either locally or remotely
924 *************************************************************/
925 static BOOL change_password(const char *remote_machine, const char *user_name,
926 const char *old_passwd, const char *new_passwd,
934 d_printf("%s<p>", _("password change in demo mode rejected\n"));
938 if (remote_machine != NULL) {
939 ret = remote_password_change(remote_machine, user_name, old_passwd,
940 new_passwd, err_str, sizeof(err_str));
942 d_printf("%s\n<p>", err_str);
946 if(!initialize_password_db(True)) {
947 d_printf("Can't setup password database vectors.\n<p>");
951 ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
952 msg_str, sizeof(msg_str));
955 d_printf("%s\n<p>", msg_str);
957 d_printf("%s\n<p>", err_str);
962 /****************************************************************************
963 do the stuff required to add or change a password
964 ****************************************************************************/
965 static void chg_passwd(void)
971 /* Make sure users name has been specified */
972 if (strlen(cgi_variable(SWAT_USER)) == 0) {
973 d_printf("<p>%s", _(" Must specify \"User Name\" \n"));
978 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
979 * so if that's what we're doing, skip the rest of the checks
981 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
984 * If current user is not root, make sure old password has been specified
985 * If REMOTE change, even root must provide old password
987 if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
988 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
989 d_printf("<p>%s", _(" Must specify \"Old Password\" \n"));
993 /* If changing a users password on a remote hosts we have to know what host */
994 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
995 d_printf("<p>%s", _(" Must specify \"Remote Machine\" \n"));
999 /* Make sure new passwords have been specified */
1000 if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
1001 (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
1002 d_printf("<p>%s", _(" Must specify \"New, and Re-typed Passwords\" \n"));
1006 /* Make sure new passwords was typed correctly twice */
1007 if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
1008 d_printf("<p>%s", _(" Re-typed password didn't match new password\n"));
1013 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1014 host = cgi_variable(RHOST);
1015 } else if (am_root()) {
1022 * Set up the local flags.
1025 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1026 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1027 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1028 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1030 rslt = change_password(host,
1031 cgi_variable(SWAT_USER),
1032 cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
1035 if(local_flags == 0) {
1038 d_printf(_(" The passwd for '%s' has been changed. \n"), cgi_variable(SWAT_USER));
1040 d_printf(_(" The passwd for '%s' has NOT been changed. \n"), cgi_variable(SWAT_USER));
1047 /****************************************************************************
1048 display a password editing page
1049 ****************************************************************************/
1050 static void passwd_page(void)
1052 const char *new_name = cgi_user_name();
1055 * After the first time through here be nice. If the user
1056 * changed the User box text to another users name, remember it.
1058 if (cgi_variable(SWAT_USER)) {
1059 new_name = cgi_variable(SWAT_USER);
1062 if (!new_name) new_name = "";
1064 d_printf("<H2>%s</H2>\n", _("Server Password Management"));
1066 d_printf("<FORM name=\"swatform\" method=post>\n");
1068 d_printf("<table>\n");
1071 * Create all the dialog boxes for data collection
1073 d_printf("<tr><td>%s</td>\n", _(" User Name : "));
1074 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1076 d_printf("<tr><td>%s</td>\n", _(" Old Password : "));
1077 d_printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1079 d_printf("<tr><td>%s</td>\n", _(" New Password : "));
1080 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1081 d_printf("<tr><td>%s</td>\n", _(" Re-type New Password : "));
1082 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1083 d_printf("</table>\n");
1086 * Create all the control buttons for requesting action
1088 d_printf("<input type=submit name=%s value=\"%s\">\n",
1089 CHG_S_PASSWD_FLAG, _("Change Password"));
1090 if (demo_mode || am_root()) {
1091 d_printf("<input type=submit name=%s value=\"%s\">\n",
1092 ADD_USER_FLAG, _("Add New User"));
1093 d_printf("<input type=submit name=%s value=\"%s\">\n",
1094 DELETE_USER_FLAG, _("Delete User"));
1095 d_printf("<input type=submit name=%s value=\"%s\">\n",
1096 DISABLE_USER_FLAG, _("Disable User"));
1097 d_printf("<input type=submit name=%s value=\"%s\">\n",
1098 ENABLE_USER_FLAG, _("Enable User"));
1100 d_printf("<p></FORM>\n");
1103 * Do some work if change, add, disable or enable was
1104 * requested. It could be this is the first time through this
1105 * code, so there isn't anything to do. */
1106 if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1107 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1111 d_printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1113 d_printf("<FORM name=\"swatform\" method=post>\n");
1115 d_printf("<table>\n");
1118 * Create all the dialog boxes for data collection
1120 d_printf("<tr><td>%s</td>\n", _(" User Name : "));
1121 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1122 d_printf("<tr><td>%s</td>\n", _(" Old Password : "));
1123 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1124 d_printf("<tr><td>%s</td>\n", _(" New Password : "));
1125 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1126 d_printf("<tr><td>%s</td>\n", _(" Re-type New Password : "));
1127 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1128 d_printf("<tr><td>%s</td>\n", _(" Remote Machine : "));
1129 d_printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1131 d_printf("</table>");
1134 * Create all the control buttons for requesting action
1136 d_printf("<input type=submit name=%s value=\"%s\">",
1137 CHG_R_PASSWD_FLAG, _("Change Password"));
1139 d_printf("<p></FORM>\n");
1142 * Do some work if a request has been made to change the
1143 * password somewhere other than the server. It could be this
1144 * is the first time through this code, so there isn't
1145 * anything to do. */
1146 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1152 /****************************************************************************
1153 display a printers editing page
1154 ****************************************************************************/
1155 static void printers_page(void)
1157 const char *share = cgi_variable("share");
1162 unsigned int parm_filter = FLAG_BASIC;
1165 snum = lp_servicenumber(share);
1167 d_printf("<H2>%s</H2>\n", _("Printer Parameters"));
1169 d_printf("<H3>%s</H3>\n", _("Important Note:"));
1170 d_printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
1171 d_printf(_("are autoloaded printers from "));
1172 d_printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1173 d_printf(_("Attempting to delete these printers from SWAT will have no effect.\n"));
1175 if (cgi_variable("Commit") && snum >= 0) {
1176 commit_parameters(snum);
1177 if (snum >= iNumNonAutoPrintServices)
1183 if (cgi_variable("Delete") && snum >= 0) {
1184 lp_remove_service(snum);
1190 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1192 lp_copy_service(GLOBALS_SNUM, share);
1193 iNumNonAutoPrintServices = lp_numservices();
1194 snum = lp_servicenumber(share);
1195 lp_do_parameter(snum, "print ok", "Yes");
1197 snum = lp_servicenumber(share);
1200 d_printf("<FORM name=\"swatform\" method=post>\n");
1202 if ( cgi_variable("ViewMode") )
1203 mode = atoi(cgi_variable("ViewMode"));
1204 ViewModeBoxes( mode );
1207 parm_filter = FLAG_BASIC;
1210 parm_filter = FLAG_ADVANCED;
1213 parm_filter = FLAG_DEVELOPER;
1216 d_printf("<table>\n");
1217 d_printf("<tr><td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Printer"));
1218 d_printf("<td><select name=share>\n");
1219 if (snum < 0 || !lp_print_ok(snum))
1220 d_printf("<option value=\" \"> \n");
1221 for (i=0;i<lp_numservices();i++) {
1222 s = lp_servicename(i);
1223 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1224 if (i >= iNumNonAutoPrintServices)
1225 d_printf("<option %s value=\"%s\">[*]%s\n",
1226 (share && strcmp(share,s)==0)?"SELECTED":"",
1229 d_printf("<option %s value=\"%s\">%s\n",
1230 (share && strcmp(share,s)==0)?"SELECTED":"",
1234 d_printf("</select></td>");
1235 if (have_write_access) {
1236 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1239 d_printf("</table>\n");
1241 if (have_write_access) {
1242 d_printf("<table>\n");
1243 d_printf("<tr><td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Printer"));
1244 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1245 d_printf("</table>");
1250 if (have_write_access) {
1251 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1253 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1258 d_printf("<table>\n");
1259 show_parameters(snum, 1, parm_filter, 1);
1260 d_printf("</table>\n");
1262 d_printf("</FORM>\n");
1267 * main function for SWAT.
1269 int main(int argc, char *argv[])
1274 struct poptOption long_options[] = {
1276 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1282 umask(S_IWGRP | S_IWOTH);
1284 #if defined(HAVE_SET_AUTH_PARAMETERS)
1285 set_auth_parameters(argc, argv);
1286 #endif /* HAVE_SET_AUTH_PARAMETERS */
1288 /* just in case it goes wild ... */
1293 /* we don't want any SIGPIPE messages */
1294 BlockSignals(True,SIGPIPE);
1296 dbf = x_fopen("/dev/null", O_WRONLY, 0);
1297 if (!dbf) dbf = x_stderr;
1299 /* we don't want stderr screwing us up */
1301 open("/dev/null", O_WRONLY);
1303 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1305 /* Parse command line options */
1307 while((opt = poptGetNextOpt(pc)) != -1) { }
1309 poptFreeContext(pc);
1311 setup_logging(argv[0],False);
1313 iNumNonAutoPrintServices = lp_numservices();
1316 cgi_setup(dyn_SWATDIR, !demo_mode);
1320 cgi_load_variables();
1322 if (!file_exist(dyn_CONFIGFILE, NULL)) {
1323 have_read_access = True;
1324 have_write_access = True;
1326 /* check if the authenticated user has write access - if not then
1327 don't show write options */
1328 have_write_access = (access(dyn_CONFIGFILE,W_OK) == 0);
1330 /* if the user doesn't have read access to smb.conf then
1331 don't let them view it */
1332 have_read_access = (access(dyn_CONFIGFILE,R_OK) == 0);
1335 show_main_buttons();
1337 page = cgi_pathinfo();
1339 /* Root gets full functionality */
1340 if (have_read_access && strcmp(page, "globals")==0) {
1342 } else if (have_read_access && strcmp(page,"shares")==0) {
1344 } else if (have_read_access && strcmp(page,"printers")==0) {
1346 } else if (have_read_access && strcmp(page,"status")==0) {
1348 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1350 } else if (strcmp(page,"passwd")==0) {
1352 } else if (have_read_access && strcmp(page,"wizard")==0) {
1354 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1355 wizard_params_page();
1356 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {