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)
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);
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;
316 if (!( parm_filter & FLAG_ADVANCED )) {
317 if (!(parm->flags & FLAG_BASIC)) {
318 void *ptr = parm->ptr;
320 if (parm->class == P_LOCAL && snum >= 0) {
321 ptr = lp_local_ptr(snum, ptr);
324 switch (parm->type) {
326 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
330 if (!str_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
335 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
340 if (!strcmp((char *)ptr,(char *)(parm->def.svalue))) continue;
345 if (*(BOOL *)ptr == (BOOL)(parm->def.bvalue)) continue;
350 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
355 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
361 if (printers && !(parm->flags & FLAG_PRINT)) continue;
364 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
366 if ((parm_filter & FLAG_ADVANCED) && !(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", _("Current View Is:  \n"));
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("<br>%s\n", _("Change View To: "));
526 d_printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
527 d_printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
528 d_printf("</p><br>\n");
531 /****************************************************************************
532 display a welcome page
533 ****************************************************************************/
534 static void welcome_page(void)
536 include_html("help/welcome.html");
539 /****************************************************************************
540 display the current smb.conf
541 ****************************************************************************/
542 static void viewconfig_page(void)
546 if (cgi_variable("full_view")) {
550 d_printf("<H2>%s</H2>\n", _("Current Config"));
551 d_printf("<form method=post>\n");
554 d_printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
556 d_printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
559 d_printf("<p><pre>");
560 write_config(stdout, full_view);
562 d_printf("</form>\n");
565 /****************************************************************************
566 second screen of the wizard ... Fetch Configuration Parameters
567 ****************************************************************************/
568 static void wizard_params_page(void)
570 unsigned int parm_filter = FLAG_WIZARD;
572 /* Here we first set and commit all the parameters that were selected
573 in the previous screen. */
575 d_printf("<H2>Wizard Parameter Edit Page</H2>\n");
577 if (cgi_variable("Commit")) {
578 commit_parameters(GLOBAL_SECTION_SNUM);
582 d_printf("<form name=\"swatform\" method=post action=wizard_params>\n");
584 if (have_write_access) {
585 d_printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
588 d_printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
591 d_printf("<table>\n");
592 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
593 d_printf("</table>\n");
594 d_printf("</form>\n");
597 /****************************************************************************
598 Utility to just rewrite the smb.conf file - effectively just cleans it up
599 ****************************************************************************/
600 static void rewritecfg_file(void)
602 commit_parameters(GLOBAL_SECTION_SNUM);
604 d_printf("<H2>Note: smb.conf %s</H2>\n", _("file has been read and rewritten"));
607 /****************************************************************************
608 wizard to create/modify the smb.conf file
609 ****************************************************************************/
610 static void wizard_page(void)
612 /* Set some variables to collect data from smb.conf */
619 if (cgi_variable("Rewrite")) {
620 (void) rewritecfg_file();
624 if (cgi_variable("GetWizardParams")){
625 (void) wizard_params_page();
629 if (cgi_variable("Commit")){
630 SerType = atoi(cgi_variable("ServerType"));
631 winstype = atoi(cgi_variable("WINSType"));
632 have_home = lp_servicenumber(HOMES_NAME);
633 HomeExpo = atoi(cgi_variable("HomeExpo"));
635 /* Plain text passwords are too badly broken - use encrypted passwords only */
636 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
640 /* Stand-alone Server */
641 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
642 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
646 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
647 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
650 /* Domain Controller */
651 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
652 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
655 switch ( winstype ) {
657 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
658 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
661 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
662 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
665 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
666 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable("WINSAddr"));
670 /* Have to create Homes share? */
671 if ((HomeExpo == 1) && (have_home == -1)) {
674 pstrcpy(unix_share,HOMES_NAME);
676 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
677 iNumNonAutoPrintServices = lp_numservices();
678 have_home = lp_servicenumber(HOMES_NAME);
679 lp_do_parameter( have_home, "read only", "No");
680 lp_do_parameter( have_home, "valid users", "%S");
681 lp_do_parameter( have_home, "browseable", "No");
682 commit_parameters(have_home);
685 /* Need to Delete Homes share? */
686 if ((HomeExpo == 0) && (have_home != -1)) {
687 lp_remove_service(have_home);
691 commit_parameters(GLOBAL_SECTION_SNUM);
696 /* Now determine smb.conf WINS settings */
697 if (lp_wins_support())
699 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
703 /* Do we have a homes share? */
704 have_home = lp_servicenumber(HOMES_NAME);
706 if ((winstype == 2) && lp_wins_support())
709 role = lp_server_role();
712 d_printf("<H2>Samba Configuration Wizard</H2>\n");
713 d_printf("<form method=post action=wizard>\n");
715 if (have_write_access) {
716 d_printf(_("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments.\n"));
717 d_printf(_("The same will happen if you press the commit button."));
718 d_printf("<br><br>");
719 d_printf("<center>");
720 d_printf("<input type=submit name=\"Rewrite\" value=%s> ",_("Rewrite smb.conf file"));
721 d_printf("<input type=submit name=\"Commit\" value=%s> ",_("Commit"));
722 d_printf("<input type=submit name=\"GetWizardParams\" value=%s>", _("Edit Parameter Values"));
723 d_printf("</center>");
727 d_printf("<center><table border=0>");
728 d_printf("<tr><td><b>%s</b></td>\n", "Server Type: ");
729 d_printf("<td><input type=radio name=\"ServerType\" value=0 %s> Stand Alone </td>", (role == ROLE_STANDALONE) ? "checked" : "");
730 d_printf("<td><input type=radio name=\"ServerType\" value=1 %s> Domain Member </td>", (role == ROLE_DOMAIN_MEMBER) ? "checked" : "");
731 d_printf("<td><input type=radio name=\"ServerType\" value=2 %s> Domain Controller </td>", (role == ROLE_DOMAIN_PDC) ? "checked" : "");
733 if (role == ROLE_DOMAIN_BDC) {
734 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Unusual Type in smb.conf - Please Select New Mode</font></td></tr>");
736 d_printf("<tr><td><b>%s</b></td>\n", "Configure WINS As: ");
737 d_printf("<td><input type=radio name=\"WINSType\" value=0 %s> Not Used </td>", (winstype == 0) ? "checked" : "");
738 d_printf("<td><input type=radio name=\"WINSType\" value=1 %s> Server for client use </td>", (winstype == 1) ? "checked" : "");
739 d_printf("<td><input type=radio name=\"WINSType\" value=2 %s> Client of another WINS server </td>", (winstype == 2) ? "checked" : "");
740 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());
742 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>");
743 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">Please Select desired WINS mode above.</font></td></tr>");
746 d_printf("<tr><td><b>%s</b></td>\n","Expose Home Directories: ");
747 d_printf("<td><input type=radio name=\"HomeExpo\" value=1 %s> Yes</td>", (have_home == -1) ? "" : "checked ");
748 d_printf("<td><input type=radio name=\"HomeExpo\" value=0 %s> No</td>", (have_home == -1 ) ? "checked" : "");
749 d_printf("<td></td></tr>");
751 /* Enable this when we are ready ....
752 * d_printf("<tr><td><b>%s</b></td>\n","Is Print Server: ");
753 * d_printf("<td><input type=radio name=\"PtrSvr\" value=1 %s> Yes</td>");
754 * d_printf("<td><input type=radio name=\"PtrSvr\" value=0 %s> No</td>");
755 * d_printf("<td></td></tr>");
758 d_printf("</table></center>");
761 d_printf(_("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment.\n"));
762 d_printf("</form>\n");
766 /****************************************************************************
767 display a globals editing page
768 ****************************************************************************/
769 static void globals_page(void)
771 unsigned int parm_filter = FLAG_BASIC;
774 d_printf("<H2>%s</H2>\n", _("Global Variables"));
776 if (cgi_variable("Commit")) {
777 commit_parameters(GLOBAL_SECTION_SNUM);
781 if ( cgi_variable("ViewMode") )
782 mode = atoi(cgi_variable("ViewMode"));
783 if ( cgi_variable("BasicMode"))
785 if ( cgi_variable("AdvMode"))
788 d_printf("<form name=\"swatform\" method=post action=globals>\n");
790 ViewModeBoxes( mode );
793 parm_filter = FLAG_BASIC;
796 parm_filter = FLAG_ADVANCED;
800 if (have_write_access) {
801 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
802 _("Commit Changes"));
805 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
809 d_printf("<table>\n");
810 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
811 d_printf("</table>\n");
812 d_printf("</form>\n");
815 /****************************************************************************
816 display a shares editing page. share is in unix codepage, and must be in
817 dos codepage. FIXME !!! JRA.
818 ****************************************************************************/
819 static void shares_page(void)
821 const char *share = cgi_variable("share");
826 unsigned int parm_filter = FLAG_BASIC;
829 snum = lp_servicenumber(share);
831 d_printf("<H2>%s</H2>\n", _("Share Parameters"));
833 if (cgi_variable("Commit") && snum >= 0) {
834 commit_parameters(snum);
838 if (cgi_variable("Delete") && snum >= 0) {
839 lp_remove_service(snum);
845 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
847 lp_copy_service(GLOBAL_SECTION_SNUM, share);
848 iNumNonAutoPrintServices = lp_numservices();
850 snum = lp_servicenumber(share);
853 d_printf("<FORM name=\"swatform\" method=post>\n");
855 d_printf("<table>\n");
857 if ( cgi_variable("ViewMode") )
858 mode = atoi(cgi_variable("ViewMode"));
859 if ( cgi_variable("BasicMode"))
861 if ( cgi_variable("AdvMode"))
864 ViewModeBoxes( mode );
867 parm_filter = FLAG_BASIC;
870 parm_filter = FLAG_ADVANCED;
873 d_printf("<br><tr>\n");
874 d_printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
875 d_printf("<td><select name=share>\n");
877 d_printf("<option value=\" \"> \n");
878 for (i=0;i<lp_numservices();i++) {
879 s = lp_servicename(i);
880 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
881 d_printf("<option %s value=\"%s\">%s\n",
882 (share && strcmp(share,s)==0)?"SELECTED":"",
886 d_printf("</select></td>\n");
887 if (have_write_access) {
888 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
891 d_printf("</table>");
893 if (have_write_access) {
895 d_printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
896 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
898 d_printf("</table>");
902 if (have_write_access) {
903 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
906 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
911 d_printf("<table>\n");
912 show_parameters(snum, 1, parm_filter, 0);
913 d_printf("</table>\n");
916 d_printf("</FORM>\n");
919 /*************************************************************
920 change a password either locally or remotely
921 *************************************************************/
922 static BOOL change_password(const char *remote_machine, const char *user_name,
923 const char *old_passwd, const char *new_passwd,
931 d_printf("%s<p>", _("password change in demo mode rejected\n"));
935 if (remote_machine != NULL) {
936 ret = remote_password_change(remote_machine, user_name, old_passwd,
937 new_passwd, err_str, sizeof(err_str));
939 d_printf("%s\n<p>", err_str);
943 if(!initialize_password_db(True)) {
944 d_printf("Can't setup password database vectors.\n<p>");
948 ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
949 msg_str, sizeof(msg_str));
952 d_printf("%s\n<p>", msg_str);
954 d_printf("%s\n<p>", err_str);
959 /****************************************************************************
960 do the stuff required to add or change a password
961 ****************************************************************************/
962 static void chg_passwd(void)
968 /* Make sure users name has been specified */
969 if (strlen(cgi_variable(SWAT_USER)) == 0) {
970 d_printf("<p>%s", _(" Must specify \"User Name\" \n"));
975 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
976 * so if that's what we're doing, skip the rest of the checks
978 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
981 * If current user is not root, make sure old password has been specified
982 * If REMOTE change, even root must provide old password
984 if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
985 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
986 d_printf("<p>%s", _(" Must specify \"Old Password\" \n"));
990 /* If changing a users password on a remote hosts we have to know what host */
991 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
992 d_printf("<p>%s", _(" Must specify \"Remote Machine\" \n"));
996 /* Make sure new passwords have been specified */
997 if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
998 (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
999 d_printf("<p>%s", _(" Must specify \"New, and Re-typed Passwords\" \n"));
1003 /* Make sure new passwords was typed correctly twice */
1004 if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
1005 d_printf("<p>%s", _(" Re-typed password didn't match new password\n"));
1010 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1011 host = cgi_variable(RHOST);
1012 } else if (am_root()) {
1019 * Set up the local flags.
1022 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1023 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1024 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1025 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1027 rslt = change_password(host,
1028 cgi_variable(SWAT_USER),
1029 cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
1032 if(local_flags == 0) {
1035 d_printf(_(" The passwd for '%s' has been changed. \n"), cgi_variable(SWAT_USER));
1037 d_printf(_(" The passwd for '%s' has NOT been changed. \n"), cgi_variable(SWAT_USER));
1044 /****************************************************************************
1045 display a password editing page
1046 ****************************************************************************/
1047 static void passwd_page(void)
1049 const char *new_name = cgi_user_name();
1052 * After the first time through here be nice. If the user
1053 * changed the User box text to another users name, remember it.
1055 if (cgi_variable(SWAT_USER)) {
1056 new_name = cgi_variable(SWAT_USER);
1059 if (!new_name) new_name = "";
1061 d_printf("<H2>%s</H2>\n", _("Server Password Management"));
1063 d_printf("<FORM name=\"swatform\" method=post>\n");
1065 d_printf("<table>\n");
1068 * Create all the dialog boxes for data collection
1070 d_printf("<tr><td>%s</td>\n", _(" User Name : "));
1071 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1073 d_printf("<tr><td>%s</td>\n", _(" Old Password : "));
1074 d_printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1076 d_printf("<tr><td>%s</td>\n", _(" New Password : "));
1077 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1078 d_printf("<tr><td>%s</td>\n", _(" Re-type New Password : "));
1079 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1080 d_printf("</table>\n");
1083 * Create all the control buttons for requesting action
1085 d_printf("<input type=submit name=%s value=\"%s\">\n",
1086 CHG_S_PASSWD_FLAG, _("Change Password"));
1087 if (demo_mode || am_root()) {
1088 d_printf("<input type=submit name=%s value=\"%s\">\n",
1089 ADD_USER_FLAG, _("Add New User"));
1090 d_printf("<input type=submit name=%s value=\"%s\">\n",
1091 DELETE_USER_FLAG, _("Delete User"));
1092 d_printf("<input type=submit name=%s value=\"%s\">\n",
1093 DISABLE_USER_FLAG, _("Disable User"));
1094 d_printf("<input type=submit name=%s value=\"%s\">\n",
1095 ENABLE_USER_FLAG, _("Enable User"));
1097 d_printf("<p></FORM>\n");
1100 * Do some work if change, add, disable or enable was
1101 * requested. It could be this is the first time through this
1102 * code, so there isn't anything to do. */
1103 if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1104 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1108 d_printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1110 d_printf("<FORM name=\"swatform\" method=post>\n");
1112 d_printf("<table>\n");
1115 * Create all the dialog boxes for data collection
1117 d_printf("<tr><td>%s</td>\n", _(" User Name : "));
1118 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1119 d_printf("<tr><td>%s</td>\n", _(" Old Password : "));
1120 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1121 d_printf("<tr><td>%s</td>\n", _(" New Password : "));
1122 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1123 d_printf("<tr><td>%s</td>\n", _(" Re-type New Password : "));
1124 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1125 d_printf("<tr><td>%s</td>\n", _(" Remote Machine : "));
1126 d_printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1128 d_printf("</table>");
1131 * Create all the control buttons for requesting action
1133 d_printf("<input type=submit name=%s value=\"%s\">",
1134 CHG_R_PASSWD_FLAG, _("Change Password"));
1136 d_printf("<p></FORM>\n");
1139 * Do some work if a request has been made to change the
1140 * password somewhere other than the server. It could be this
1141 * is the first time through this code, so there isn't
1142 * anything to do. */
1143 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1149 /****************************************************************************
1150 display a printers editing page
1151 ****************************************************************************/
1152 static void printers_page(void)
1154 const char *share = cgi_variable("share");
1159 unsigned int parm_filter = FLAG_BASIC;
1162 snum = lp_servicenumber(share);
1164 d_printf("<H2>%s</H2>\n", _("Printer Parameters"));
1166 d_printf("<H3>%s</H3>\n", _("Important Note:"));
1167 d_printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
1168 d_printf(_("are autoloaded printers from "));
1169 d_printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1170 d_printf(_("Attempting to delete these printers from SWAT will have no effect.\n"));
1172 if (cgi_variable("Commit") && snum >= 0) {
1173 commit_parameters(snum);
1174 if (snum >= iNumNonAutoPrintServices)
1180 if (cgi_variable("Delete") && snum >= 0) {
1181 lp_remove_service(snum);
1187 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1189 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1190 iNumNonAutoPrintServices = lp_numservices();
1191 snum = lp_servicenumber(share);
1192 lp_do_parameter(snum, "print ok", "Yes");
1194 snum = lp_servicenumber(share);
1197 d_printf("<FORM name=\"swatform\" method=post>\n");
1199 if ( cgi_variable("ViewMode") )
1200 mode = atoi(cgi_variable("ViewMode"));
1201 if ( cgi_variable("BasicMode"))
1203 if ( cgi_variable("AdvMode"))
1206 ViewModeBoxes( mode );
1209 parm_filter = FLAG_BASIC;
1212 parm_filter = FLAG_ADVANCED;
1215 d_printf("<table>\n");
1216 d_printf("<tr><td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Printer"));
1217 d_printf("<td><select name=share>\n");
1218 if (snum < 0 || !lp_print_ok(snum))
1219 d_printf("<option value=\" \"> \n");
1220 for (i=0;i<lp_numservices();i++) {
1221 s = lp_servicename(i);
1222 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1223 if (i >= iNumNonAutoPrintServices)
1224 d_printf("<option %s value=\"%s\">[*]%s\n",
1225 (share && strcmp(share,s)==0)?"SELECTED":"",
1228 d_printf("<option %s value=\"%s\">%s\n",
1229 (share && strcmp(share,s)==0)?"SELECTED":"",
1233 d_printf("</select></td>");
1234 if (have_write_access) {
1235 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1238 d_printf("</table>\n");
1240 if (have_write_access) {
1241 d_printf("<table>\n");
1242 d_printf("<tr><td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Printer"));
1243 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
1244 d_printf("</table>");
1249 if (have_write_access) {
1250 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1252 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1257 d_printf("<table>\n");
1258 show_parameters(snum, 1, parm_filter, 1);
1259 d_printf("</table>\n");
1261 d_printf("</FORM>\n");
1266 * main function for SWAT.
1268 int main(int argc, char *argv[])
1273 struct poptOption long_options[] = {
1275 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1281 umask(S_IWGRP | S_IWOTH);
1283 #if defined(HAVE_SET_AUTH_PARAMETERS)
1284 set_auth_parameters(argc, argv);
1285 #endif /* HAVE_SET_AUTH_PARAMETERS */
1287 /* just in case it goes wild ... */
1292 /* we don't want any SIGPIPE messages */
1293 BlockSignals(True,SIGPIPE);
1295 dbf = x_fopen("/dev/null", O_WRONLY, 0);
1296 if (!dbf) dbf = x_stderr;
1298 /* we don't want stderr screwing us up */
1300 open("/dev/null", O_WRONLY);
1302 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1304 /* Parse command line options */
1306 while((opt = poptGetNextOpt(pc)) != -1) { }
1308 poptFreeContext(pc);
1310 setup_logging(argv[0],False);
1312 iNumNonAutoPrintServices = lp_numservices();
1315 cgi_setup(dyn_SWATDIR, !demo_mode);
1319 cgi_load_variables();
1321 if (!file_exist(dyn_CONFIGFILE, NULL)) {
1322 have_read_access = True;
1323 have_write_access = True;
1325 /* check if the authenticated user has write access - if not then
1326 don't show write options */
1327 have_write_access = (access(dyn_CONFIGFILE,W_OK) == 0);
1329 /* if the user doesn't have read access to smb.conf then
1330 don't let them view it */
1331 have_read_access = (access(dyn_CONFIGFILE,R_OK) == 0);
1334 show_main_buttons();
1336 page = cgi_pathinfo();
1338 /* Root gets full functionality */
1339 if (have_read_access && strcmp(page, "globals")==0) {
1341 } else if (have_read_access && strcmp(page,"shares")==0) {
1343 } else if (have_read_access && strcmp(page,"printers")==0) {
1345 } else if (have_read_access && strcmp(page,"status")==0) {
1347 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1349 } else if (strcmp(page,"passwd")==0) {
1351 } else if (have_read_access && strcmp(page,"wizard")==0) {
1353 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1354 wizard_params_page();
1355 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {