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 static BOOL demo_mode = False;
35 static BOOL have_write_access = False;
36 static BOOL have_read_access = False;
37 static int iNumNonAutoPrintServices = 0;
40 * Password Management Globals
42 #define SWAT_USER "username"
43 #define OLD_PSWD "old_passwd"
44 #define NEW_PSWD "new_passwd"
45 #define NEW2_PSWD "new2_passwd"
46 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
47 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
48 #define ADD_USER_FLAG "add_user_flag"
49 #define DELETE_USER_FLAG "delete_user_flag"
50 #define DISABLE_USER_FLAG "disable_user_flag"
51 #define ENABLE_USER_FLAG "enable_user_flag"
52 #define RHOST "remote_host"
54 /****************************************************************************
55 ****************************************************************************/
56 static int enum_index(int value, const struct enum_list *enumlist)
59 for (i=0;enumlist[i].name;i++)
60 if (value == enumlist[i].value) break;
64 static char *fix_backslash(const char *str)
66 static char newstring[1024];
70 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
78 static char *stripspaceupper(const char *str)
80 static char newstring[1024];
84 if (*str != ' ') *p++ = toupper(*str);
91 static char *make_parm_name(const char *label)
93 static char parmname[1024];
97 if (*label == ' ') *p++ = '_';
105 /****************************************************************************
106 include a lump of html in a page
107 ****************************************************************************/
108 static int include_html(const char *fname)
114 fd = web_open(fname, O_RDONLY, 0);
117 d_printf("ERROR: Can't open %s\n", fname);
121 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
129 /****************************************************************************
130 start the page with standard stuff
131 ****************************************************************************/
132 static void print_header(void)
134 if (!cgi_waspost()) {
135 d_printf("Expires: 0\r\n");
137 d_printf("Content-type: text/html\r\n\r\n");
139 if (!include_html("include/header.html")) {
140 d_printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
141 d_printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
145 /* *******************************************************************
146 show parameter label with translated name in the following form
147 because showing original and translated label in one line looks
148 too long, and showing translated label only is unusable for
150 -------------------------------
151 HELP security [combo box][button]
153 -------------------------------
154 (capital words are translated by gettext.)
155 if no translation is available, then same form as original is
157 "i18n_translated_parm" class is used to change the color of the
158 translated parameter with CSS.
159 **************************************************************** */
160 static const char* get_parm_translated(
161 const char* pAnchor, const char* pHelp, const char* pLabel)
163 const char* pTranslated = _(pLabel);
164 static pstring output;
165 if(strcmp(pLabel, pTranslated) != 0)
167 snprintf(output, sizeof(output),
168 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
169 pAnchor, pHelp, pLabel, pTranslated);
172 snprintf(output, sizeof(output),
173 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
174 pAnchor, pHelp, pLabel);
177 /****************************************************************************
179 ****************************************************************************/
180 static void print_footer(void)
182 if (!include_html("include/footer.html")) {
183 d_printf("\n</BODY>\n</HTML>\n");
187 /****************************************************************************
188 display one editable parameter in a form
189 ****************************************************************************/
190 static void show_parameter(int snum, struct parm_struct *parm)
193 void *ptr = parm->ptr;
195 if (parm->class == P_LOCAL && snum >= 0) {
196 ptr = lp_local_ptr(snum, ptr);
199 printf("<tr><td>%s</td><td>", get_parm_translated(stripspaceupper(parm->label), _("Help"), parm->label));
200 switch (parm->type) {
202 d_printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
203 make_parm_name(parm->label), *(char *)ptr);
204 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
205 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
209 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"",
210 make_parm_name(parm->label));
211 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
212 char **list = *(char ***)ptr;
213 for (;*list;list++) {
214 d_printf("%s%s", *list, ((*(list+1))?" ":""));
218 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
219 _("Set Default"), make_parm_name(parm->label));
220 if (parm->def.lvalue) {
221 char **list = (char **)(parm->def.lvalue);
222 for (; *list; list++) {
223 d_printf("%s%s", *list, ((*(list+1))?" ":""));
231 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
232 make_parm_name(parm->label), *(char **)ptr);
233 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
234 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
239 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
240 make_parm_name(parm->label), (char *)ptr);
241 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
242 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
246 d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
247 d_printf("<option %s>Yes", (*(BOOL *)ptr)?"selected":"");
248 d_printf("<option %s>No", (*(BOOL *)ptr)?"":"selected");
249 d_printf("</select>");
250 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
251 _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?0:1);
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)?1:0);
264 d_printf("<input type=text size=8 name=\"parm_%s\" value=%d>", make_parm_name(parm->label), *(int *)ptr);
265 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
266 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
270 d_printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm->label), octal_string(*(int *)ptr));
271 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
272 _("Set Default"), make_parm_name(parm->label),
273 octal_string((int)(parm->def.ivalue)));
277 d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
278 for (i=0;parm->enum_list[i].name;i++) {
279 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
280 d_printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
283 d_printf("</select>");
284 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
285 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
290 d_printf("</td></tr>\n");
293 /****************************************************************************
294 display a set of parameters for a service
295 ****************************************************************************/
296 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
299 struct parm_struct *parm;
300 const char *heading = NULL;
301 const char *last_heading = NULL;
303 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
304 if (snum < 0 && parm->class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
306 if (parm->class == P_SEPARATOR) {
307 heading = parm->label;
310 if (parm->flags & FLAG_HIDE) continue;
312 if (printers & !(parm->flags & FLAG_PRINT)) continue;
313 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
315 if (parm_filter == FLAG_BASIC) {
316 if (!(parm->flags & FLAG_BASIC)) {
317 void *ptr = parm->ptr;
319 if (parm->class == P_LOCAL && snum >= 0) {
320 ptr = lp_local_ptr(snum, ptr);
323 switch (parm->type) {
325 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
329 if (!str_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
334 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
339 if (!strcmp((char *)ptr,(char *)(parm->def.svalue))) continue;
344 if (*(BOOL *)ptr == (BOOL)(parm->def.bvalue)) continue;
349 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
354 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
360 if (printers && !(parm->flags & FLAG_PRINT)) continue;
362 if (parm_filter == FLAG_WIZARD) {
363 if (!((parm->flags & FLAG_WIZARD))) continue;
365 if (parm_filter == FLAG_ADVANCED) {
366 if (!((parm->flags & FLAG_ADVANCED))) continue;
368 if (heading && heading != last_heading) {
369 d_printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
370 last_heading = heading;
372 show_parameter(snum, parm);
376 /****************************************************************************
377 load the smb.conf file into loadparm.
378 ****************************************************************************/
379 static BOOL load_config(BOOL save_def)
381 lp_resetnumservices();
382 return lp_load(dyn_CONFIGFILE,False,save_def,False);
385 /****************************************************************************
387 ****************************************************************************/
388 static void write_config(FILE *f, BOOL show_defaults)
390 fprintf(f, "# Samba config file created using SWAT\n");
391 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
392 fprintf(f, "# Date: %s\n\n", timestring(False));
394 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
397 /****************************************************************************
398 save and reload the smb.conf config file
399 ****************************************************************************/
400 static int save_reload(int snum)
405 f = sys_fopen(dyn_CONFIGFILE,"w");
407 d_printf("failed to open %s for writing\n", dyn_CONFIGFILE);
411 /* just in case they have used the buggy xinetd to create the file */
412 if (fstat(fileno(f), &st) == 0 &&
413 (st.st_mode & S_IWOTH)) {
414 #if defined HAVE_FCHMOD
415 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
417 chmod(dyn_CONFIGFILE, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
421 write_config(f, False);
423 lp_dump_one(f, False, snum);
428 if (!load_config(False)) {
429 d_printf("Can't reload %s\n", dyn_CONFIGFILE);
432 iNumNonAutoPrintServices = lp_numservices();
438 /****************************************************************************
440 ****************************************************************************/
441 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
446 if (snum < 0 && parm->class == P_LOCAL) {
447 /* this handles the case where we are changing a local
448 variable globally. We need to change the parameter in
449 all shares where it is currently set to the default */
450 for (i=0;i<lp_numservices();i++) {
451 s = lp_servicename(i);
452 if (s && (*s) && lp_is_default(i, parm)) {
453 lp_do_parameter(i, parm->label, v);
458 lp_do_parameter(snum, parm->label, v);
461 /****************************************************************************
462 commit a set of parameters for a service
463 ****************************************************************************/
464 static void commit_parameters(int snum)
467 struct parm_struct *parm;
471 while ((parm = lp_next_parameter(snum, &i, 1))) {
472 slprintf(label, sizeof(label)-1, "parm_%s", make_parm_name(parm->label));
473 if ((v = cgi_variable(label))) {
474 if (parm->flags & FLAG_HIDE) continue;
475 commit_parameter(snum, parm, v);
480 /****************************************************************************
481 spit out the html for a link with an image
482 ****************************************************************************/
483 static void image_link(const char *name, const char *hlink, const char *src)
485 d_printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
486 cgi_baseurl(), hlink, src, name);
489 /****************************************************************************
490 display the main navigation controls at the top of each page along
492 ****************************************************************************/
493 static void show_main_buttons(void)
497 if ((p = cgi_user_name()) && strcmp(p, "root")) {
498 d_printf(_("Logged in as <b>%s</b><p>\n"), p);
501 image_link(_("Home"), "", "images/home.gif");
502 if (have_write_access) {
503 image_link(_("Globals"), "globals", "images/globals.gif");
504 image_link(_("Shares"), "shares", "images/shares.gif");
505 image_link(_("Printers"), "printers", "images/printers.gif");
506 image_link(_("Wizard"), "wizard", "images/wizard.gif");
508 if (have_read_access) {
509 image_link(_("Status"), "status", "images/status.gif");
510 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
512 image_link(_("Password Management"), "passwd", "images/passwd.gif");
517 /****************************************************************************
518 * Handle Display/Edit Mode CGI
519 ****************************************************************************/
520 static void ViewModeBoxes(int mode)
522 d_printf("<p>%s\n", _("Configuration View: "));
523 d_printf("<input type=radio name=\"ViewMode\" value=0 %s>Basic\n", (mode == 0) ? "checked" : "");
524 d_printf("<input type=radio name=\"ViewMode\" value=1 %s>Advanced\n", (mode == 1) ? "checked" : "");
525 d_printf("<input type=radio name=\"ViewMode\" value=2 %s>Developer\n", (mode == 2) ? "checked" : "");
526 d_printf("</p><br>\n");
529 /****************************************************************************
530 display a welcome page
531 ****************************************************************************/
532 static void welcome_page(void)
534 include_html("help/welcome.html");
537 /****************************************************************************
538 display the current smb.conf
539 ****************************************************************************/
540 static void viewconfig_page(void)
544 if (cgi_variable("full_view")) {
548 d_printf("<H2>%s</H2>\n", _("Current Config"));
549 d_printf("<form method=post>\n");
552 d_printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
554 d_printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
557 d_printf("<p><pre>");
558 write_config(stdout, full_view);
560 d_printf("</form>\n");
563 /****************************************************************************
564 second screen of the wizard ... Fetch Configuration Parameters
565 ****************************************************************************/
566 static void wizard_params_page(void)
568 unsigned int parm_filter = FLAG_WIZARD;
570 /* Here we first set and commit all the parameters that were selected
571 in the previous screen. */
573 d_printf("<H2>Wizard Parameter Edit Page</H2>\n");
575 if (cgi_variable("Commit")) {
576 commit_parameters(GLOBAL_SECTION_SNUM);
580 d_printf("<form name=\"swatform\" method=post action=wizard_params>\n");
582 if (have_write_access) {
583 d_printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
586 d_printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
589 d_printf("<table>\n");
590 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
591 d_printf("</table>\n");
592 d_printf("</form>\n");
595 /****************************************************************************
596 Utility to just rewrite the smb.conf file - effectively just cleans it up
597 ****************************************************************************/
598 static void rewritecfg_file(void)
600 commit_parameters(GLOBAL_SECTION_SNUM);
602 d_printf("<H2>Note: smb.conf %s</H2>\n", _("file has been read and rewritten"));
605 /****************************************************************************
606 wizard to create/modify the smb.conf file
607 ****************************************************************************/
608 static void wizard_page(void)
610 /* Set some variables to collect data from smb.conf */
617 if (cgi_variable("Rewrite")) {
618 (void) rewritecfg_file();
622 if (cgi_variable("GetWizardParams")){
623 (void) wizard_params_page();
627 if (cgi_variable("Commit")){
628 SerType = atoi(cgi_variable("ServerType"));
629 winstype = atoi(cgi_variable("WINSType"));
630 have_home = lp_servicenumber(HOMES_NAME);
631 HomeExpo = atoi(cgi_variable("HomeExpo"));
633 /* Plain text passwords are too badly broken - use encrypted passwords only */
634 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
638 /* Stand-alone Server */
639 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
640 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
644 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
645 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
648 /* Domain Controller */
649 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
650 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
653 switch ( winstype ) {
655 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
656 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
659 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
660 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
663 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
664 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable("WINSAddr"));
668 /* Have to create Homes share? */
669 if ((HomeExpo == 1) && (have_home == -1)) {
672 pstrcpy(unix_share,HOMES_NAME);
674 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
675 iNumNonAutoPrintServices = lp_numservices();
676 have_home = lp_servicenumber(HOMES_NAME);
677 lp_do_parameter( have_home, "read only", "No");
678 lp_do_parameter( have_home, "valid users", "%S");
679 lp_do_parameter( have_home, "browseable", "No");
680 commit_parameters(have_home);
683 /* Need to Delete Homes share? */
684 if ((HomeExpo == 0) && (have_home != -1)) {
685 lp_remove_service(have_home);
689 commit_parameters(GLOBAL_SECTION_SNUM);
694 /* Now determine smb.conf WINS settings */
695 if (lp_wins_support())
697 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
701 /* Do we have a homes share? */
702 have_home = lp_servicenumber(HOMES_NAME);
704 if ((winstype == 2) && lp_wins_support())
707 role = lp_server_role();
710 d_printf("<H2>Samba Configuration Wizard</H2>\n");
711 d_printf("<form method=post action=wizard>\n");
713 if (have_write_access) {
714 d_printf(_("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments.\n"));
715 d_printf(_("The same will happen if you press the commit button."));
716 d_printf("<br><br>");
717 d_printf("<center>");
718 d_printf("<input type=submit name=\"Rewrite\" value=%s> ",_("Rewrite smb.conf file"));
719 d_printf("<input type=submit name=\"Commit\" value=%s> ",_("Commit"));
720 d_printf("<input type=submit name=\"GetWizardParams\" value=%s>", _("Edit Parameter Values"));
721 d_printf("</center>");
725 d_printf("<center><table border=0>");
726 d_printf("<tr><td><b>%s</b></td>\n", "Server Type: ");
727 d_printf("<td><input type=radio name=\"ServerType\" value=0 %s> Stand Alone </td>", (role == ROLE_STANDALONE) ? "checked" : "");
728 d_printf("<td><input type=radio name=\"ServerType\" value=1 %s> Domain Member </td>", (role == ROLE_DOMAIN_MEMBER) ? "checked" : "");
729 d_printf("<td><input type=radio name=\"ServerType\" value=2 %s> Domain Controller </td>", (role == ROLE_DOMAIN_PDC) ? "checked" : "");
731 if (role == ROLE_DOMAIN_BDC) {
732 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Unusual Type in smb.conf - Please Select New Mode</font></td></tr>");
734 d_printf("<tr><td><b>%s</b></td>\n", "Configure WINS As: ");
735 d_printf("<td><input type=radio name=\"WINSType\" value=0 %s> Not Used </td>", (winstype == 0) ? "checked" : "");
736 d_printf("<td><input type=radio name=\"WINSType\" value=1 %s> Server for client use </td>", (winstype == 1) ? "checked" : "");
737 d_printf("<td><input type=radio name=\"WINSType\" value=2 %s> Client of another WINS server </td>", (winstype == 2) ? "checked" : "");
738 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());
740 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>");
741 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Please Select desired WINS mode above.</font></td></tr>");
744 d_printf("<tr><td><b>%s</b></td>\n","Expose Home Directories: ");
745 d_printf("<td><input type=radio name=\"HomeExpo\" value=1 %s> Yes</td>", (have_home == -1) ? "" : "checked ");
746 d_printf("<td><input type=radio name=\"HomeExpo\" value=0 %s> No</td>", (have_home == -1 ) ? "checked" : "");
747 d_printf("<td></td></tr>");
749 /* Enable this when we are ready ....
750 * d_printf("<tr><td><b>%s</b></td>\n","Is Print Server: ");
751 * d_printf("<td><input type=radio name=\"PtrSvr\" value=1 %s> Yes</td>");
752 * d_printf("<td><input type=radio name=\"PtrSvr\" value=0 %s> No</td>");
753 * d_printf("<td></td></tr>");
756 d_printf("</table></center>");
759 d_printf(_("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment.\n"));
760 d_printf("</form>\n");
764 /****************************************************************************
765 display a globals editing page
766 ****************************************************************************/
767 static void globals_page(void)
769 unsigned int parm_filter = FLAG_BASIC;
772 d_printf("<H2>%s</H2>\n", _("Global Variables"));
774 if (cgi_variable("Commit")) {
775 commit_parameters(GLOBAL_SECTION_SNUM);
779 if ( cgi_variable("ViewMode") )
780 mode = atoi(cgi_variable("ViewMode"));
782 d_printf("<form name=\"swatform\" method=post action=globals>\n");
784 ViewModeBoxes( mode );
787 parm_filter = FLAG_BASIC;
790 parm_filter = FLAG_ADVANCED;
793 parm_filter = FLAG_DEVELOPER;
797 if (have_write_access) {
798 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
799 _("Commit Changes"));
802 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
806 d_printf("<table>\n");
807 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
808 d_printf("</table>\n");
809 d_printf("</form>\n");
812 /****************************************************************************
813 display a shares editing page. share is in unix codepage, and must be in
814 dos codepage. FIXME !!! JRA.
815 ****************************************************************************/
816 static void shares_page(void)
818 const char *share = cgi_variable("share");
823 unsigned int parm_filter = FLAG_BASIC;
826 snum = lp_servicenumber(share);
828 d_printf("<H2>%s</H2>\n", _("Share Parameters"));
830 if (cgi_variable("Commit") && snum >= 0) {
831 commit_parameters(snum);
835 if (cgi_variable("Delete") && snum >= 0) {
836 lp_remove_service(snum);
842 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
844 lp_copy_service(GLOBAL_SECTION_SNUM, share);
845 iNumNonAutoPrintServices = lp_numservices();
847 snum = lp_servicenumber(share);
850 d_printf("<FORM name=\"swatform\" method=post>\n");
852 d_printf("<table>\n");
853 if ( cgi_variable("ViewMode") )
854 mode = atoi(cgi_variable("ViewMode"));
855 ViewModeBoxes( mode );
858 parm_filter = FLAG_BASIC;
861 parm_filter = FLAG_ADVANCED;
864 parm_filter = FLAG_DEVELOPER;
867 d_printf("<br><tr>\n");
868 d_printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
869 d_printf("<td><select name=share>\n");
871 d_printf("<option value=\" \"> \n");
872 for (i=0;i<lp_numservices();i++) {
873 s = lp_servicename(i);
874 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
875 d_printf("<option %s value=\"%s\">%s\n",
876 (share && strcmp(share,s)==0)?"SELECTED":"",
880 d_printf("</select></td>\n");
881 if (have_write_access) {
882 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
885 d_printf("</table>");
887 if (have_write_access) {
889 d_printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
890 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
892 d_printf("</table>");
896 if (have_write_access) {
897 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
900 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
905 d_printf("<table>\n");
906 show_parameters(snum, 1, parm_filter, 0);
907 d_printf("</table>\n");
910 d_printf("</FORM>\n");
913 /*************************************************************
914 change a password either locally or remotely
915 *************************************************************/
916 static BOOL change_password(const char *remote_machine, const char *user_name,
917 const char *old_passwd, const char *new_passwd,
925 d_printf("%s<p>", _("password change in demo mode rejected\n"));
929 if (remote_machine != NULL) {
930 ret = remote_password_change(remote_machine, user_name, old_passwd,
931 new_passwd, err_str, sizeof(err_str));
933 d_printf("%s\n<p>", err_str);
937 if(!initialize_password_db(True)) {
938 d_printf("Can't setup password database vectors.\n<p>");
942 ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
943 msg_str, sizeof(msg_str));
946 d_printf("%s\n<p>", msg_str);
948 d_printf("%s\n<p>", err_str);
953 /****************************************************************************
954 do the stuff required to add or change a password
955 ****************************************************************************/
956 static void chg_passwd(void)
962 /* Make sure users name has been specified */
963 if (strlen(cgi_variable(SWAT_USER)) == 0) {
964 d_printf("<p>%s", _(" Must specify \"User Name\" \n"));
969 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
970 * so if that's what we're doing, skip the rest of the checks
972 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
975 * If current user is not root, make sure old password has been specified
976 * If REMOTE change, even root must provide old password
978 if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
979 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
980 d_printf("<p>%s", _(" Must specify \"Old Password\" \n"));
984 /* If changing a users password on a remote hosts we have to know what host */
985 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
986 d_printf("<p>%s", _(" Must specify \"Remote Machine\" \n"));
990 /* Make sure new passwords have been specified */
991 if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
992 (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
993 d_printf("<p>%s", _(" Must specify \"New, and Re-typed Passwords\" \n"));
997 /* Make sure new passwords was typed correctly twice */
998 if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
999 d_printf("<p>%s", _(" Re-typed password didn't match new password\n"));
1004 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1005 host = cgi_variable(RHOST);
1006 } else if (am_root()) {
1013 * Set up the local flags.
1016 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1017 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1018 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1019 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1021 rslt = change_password(host,
1022 cgi_variable(SWAT_USER),
1023 cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
1026 if(local_flags == 0) {
1029 d_printf(_(" The passwd for '%s' has been changed. \n"), cgi_variable(SWAT_USER));
1031 d_printf(_(" The passwd for '%s' has NOT been changed. \n"), cgi_variable(SWAT_USER));
1038 /****************************************************************************
1039 display a password editing page
1040 ****************************************************************************/
1041 static void passwd_page(void)
1043 const char *new_name = cgi_user_name();
1046 * After the first time through here be nice. If the user
1047 * changed the User box text to another users name, remember it.
1049 if (cgi_variable(SWAT_USER)) {
1050 new_name = cgi_variable(SWAT_USER);
1053 if (!new_name) new_name = "";
1055 d_printf("<H2>%s</H2>\n", _("Server Password Management"));
1057 d_printf("<FORM name=\"swatform\" method=post>\n");
1059 d_printf("<table>\n");
1062 * Create all the dialog boxes for data collection
1064 d_printf("<tr><td>%s</td>\n", _(" User Name : "));
1065 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1067 d_printf("<tr><td>%s</td>\n", _(" Old Password : "));
1068 d_printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1070 d_printf("<tr><td>%s</td>\n", _(" New Password : "));
1071 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1072 d_printf("<tr><td>%s</td>\n", _(" Re-type New Password : "));
1073 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1074 d_printf("</table>\n");
1077 * Create all the control buttons for requesting action
1079 d_printf("<input type=submit name=%s value=\"%s\">\n",
1080 CHG_S_PASSWD_FLAG, _("Change Password"));
1081 if (demo_mode || am_root()) {
1082 d_printf("<input type=submit name=%s value=\"%s\">\n",
1083 ADD_USER_FLAG, _("Add New User"));
1084 d_printf("<input type=submit name=%s value=\"%s\">\n",
1085 DELETE_USER_FLAG, _("Delete User"));
1086 d_printf("<input type=submit name=%s value=\"%s\">\n",
1087 DISABLE_USER_FLAG, _("Disable User"));
1088 d_printf("<input type=submit name=%s value=\"%s\">\n",
1089 ENABLE_USER_FLAG, _("Enable User"));
1091 d_printf("<p></FORM>\n");
1094 * Do some work if change, add, disable or enable was
1095 * requested. It could be this is the first time through this
1096 * code, so there isn't anything to do. */
1097 if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1098 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1102 d_printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1104 d_printf("<FORM name=\"swatform\" method=post>\n");
1106 d_printf("<table>\n");
1109 * Create all the dialog boxes for data collection
1111 d_printf("<tr><td>%s</td>\n", _(" User Name : "));
1112 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1113 d_printf("<tr><td>%s</td>\n", _(" Old Password : "));
1114 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1115 d_printf("<tr><td>%s</td>\n", _(" New Password : "));
1116 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1117 d_printf("<tr><td>%s</td>\n", _(" Re-type New Password : "));
1118 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1119 d_printf("<tr><td>%s</td>\n", _(" Remote Machine : "));
1120 d_printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1122 d_printf("</table>");
1125 * Create all the control buttons for requesting action
1127 d_printf("<input type=submit name=%s value=\"%s\">",
1128 CHG_R_PASSWD_FLAG, _("Change Password"));
1130 d_printf("<p></FORM>\n");
1133 * Do some work if a request has been made to change the
1134 * password somewhere other than the server. It could be this
1135 * is the first time through this code, so there isn't
1136 * anything to do. */
1137 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1143 /****************************************************************************
1144 display a printers editing page
1145 ****************************************************************************/
1146 static void printers_page(void)
1148 const char *share = cgi_variable("share");
1153 unsigned int parm_filter = FLAG_BASIC;
1156 snum = lp_servicenumber(share);
1158 d_printf("<H2>%s</H2>\n", _("Printer Parameters"));
1160 d_printf("<H3>%s</H3>\n", _("Important Note:"));
1161 d_printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
1162 d_printf(_("are autoloaded printers from "));
1163 d_printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1164 d_printf(_("Attempting to delete these printers from SWAT will have no effect.\n"));
1166 if (cgi_variable("Commit") && snum >= 0) {
1167 commit_parameters(snum);
1168 if (snum >= iNumNonAutoPrintServices)
1174 if (cgi_variable("Delete") && snum >= 0) {
1175 lp_remove_service(snum);
1181 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1183 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1184 iNumNonAutoPrintServices = lp_numservices();
1185 snum = lp_servicenumber(share);
1186 lp_do_parameter(snum, "print ok", "Yes");
1188 snum = lp_servicenumber(share);
1191 d_printf("<FORM name=\"swatform\" method=post>\n");
1193 if ( cgi_variable("ViewMode") )
1194 mode = atoi(cgi_variable("ViewMode"));
1195 ViewModeBoxes( mode );
1198 parm_filter = FLAG_BASIC;
1201 parm_filter = FLAG_ADVANCED;
1204 parm_filter = FLAG_DEVELOPER;
1207 d_printf("<table>\n");
1208 d_printf("<tr><td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Printer"));
1209 d_printf("<td><select name=share>\n");
1210 if (snum < 0 || !lp_print_ok(snum))
1211 d_printf("<option value=\" \"> \n");
1212 for (i=0;i<lp_numservices();i++) {
1213 s = lp_servicename(i);
1214 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1215 if (i >= iNumNonAutoPrintServices)
1216 d_printf("<option %s value=\"%s\">[*]%s\n",
1217 (share && strcmp(share,s)==0)?"SELECTED":"",
1220 d_printf("<option %s value=\"%s\">%s\n",
1221 (share && strcmp(share,s)==0)?"SELECTED":"",
1225 d_printf("</select></td>");
1226 if (have_write_access) {
1227 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1230 d_printf("</table>\n");
1232 if (have_write_access) {
1233 d_printf("<table>\n");
1234 d_printf("<tr><td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Printer"));
1235 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1236 d_printf("</table>");
1241 if (have_write_access) {
1242 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1244 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1249 d_printf("<table>\n");
1250 show_parameters(snum, 1, parm_filter, 1);
1251 d_printf("</table>\n");
1253 d_printf("</FORM>\n");
1258 * main function for SWAT.
1260 int main(int argc, char *argv[])
1265 struct poptOption long_options[] = {
1267 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1273 umask(S_IWGRP | S_IWOTH);
1275 #if defined(HAVE_SET_AUTH_PARAMETERS)
1276 set_auth_parameters(argc, argv);
1277 #endif /* HAVE_SET_AUTH_PARAMETERS */
1279 /* just in case it goes wild ... */
1284 /* we don't want any SIGPIPE messages */
1285 BlockSignals(True,SIGPIPE);
1287 dbf = x_fopen("/dev/null", O_WRONLY, 0);
1288 if (!dbf) dbf = x_stderr;
1290 /* we don't want stderr screwing us up */
1292 open("/dev/null", O_WRONLY);
1294 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1296 /* Parse command line options */
1298 while((opt = poptGetNextOpt(pc)) != -1) { }
1300 poptFreeContext(pc);
1302 setup_logging(argv[0],False);
1304 iNumNonAutoPrintServices = lp_numservices();
1307 cgi_setup(dyn_SWATDIR, !demo_mode);
1311 cgi_load_variables();
1313 if (!file_exist(dyn_CONFIGFILE, NULL)) {
1314 have_read_access = True;
1315 have_write_access = True;
1317 /* check if the authenticated user has write access - if not then
1318 don't show write options */
1319 have_write_access = (access(dyn_CONFIGFILE,W_OK) == 0);
1321 /* if the user doesn't have read access to smb.conf then
1322 don't let them view it */
1323 have_read_access = (access(dyn_CONFIGFILE,R_OK) == 0);
1326 show_main_buttons();
1328 page = cgi_pathinfo();
1330 /* Root gets full functionality */
1331 if (have_read_access && strcmp(page, "globals")==0) {
1333 } else if (have_read_access && strcmp(page,"shares")==0) {
1335 } else if (have_read_access && strcmp(page,"printers")==0) {
1337 } else if (have_read_access && strcmp(page,"status")==0) {
1339 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1341 } else if (strcmp(page,"passwd")==0) {
1343 } else if (have_read_access && strcmp(page,"wizard")==0) {
1345 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1346 wizard_params_page();
1347 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {