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"), fname);
122 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
130 /****************************************************************************
131 start the page with standard stuff
132 ****************************************************************************/
133 static void print_header(void)
135 if (!cgi_waspost()) {
136 d_printf("Expires: 0\r\n");
138 d_printf("Content-type: text/html\r\n\r\n");
140 if (!include_html("include/header.html")) {
141 d_printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
142 d_printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
146 /* *******************************************************************
147 show parameter label with translated name in the following form
148 because showing original and translated label in one line looks
149 too long, and showing translated label only is unusable for
151 -------------------------------
152 HELP security [combo box][button]
154 -------------------------------
155 (capital words are translated by gettext.)
156 if no translation is available, then same form as original is
158 "i18n_translated_parm" class is used to change the color of the
159 translated parameter with CSS.
160 **************************************************************** */
161 static const char* get_parm_translated(
162 const char* pAnchor, const char* pHelp, const char* pLabel)
164 const char* pTranslated = _(pLabel);
165 static pstring output;
166 if(strcmp(pLabel, pTranslated) != 0)
169 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
170 pAnchor, pHelp, pLabel, pTranslated);
174 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
175 pAnchor, pHelp, pLabel);
178 /****************************************************************************
180 ****************************************************************************/
181 static void print_footer(void)
183 if (!include_html("include/footer.html")) {
184 d_printf("\n</BODY>\n</HTML>\n");
188 /****************************************************************************
189 display one editable parameter in a form
190 ****************************************************************************/
191 static void show_parameter(int snum, struct parm_struct *parm)
194 void *ptr = parm->ptr;
196 if (parm->class == P_LOCAL && snum >= 0) {
197 ptr = lp_local_ptr(snum, ptr);
200 printf("<tr><td>%s</td><td>", get_parm_translated(stripspaceupper(parm->label), _("Help"), parm->label));
201 switch (parm->type) {
203 d_printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
204 make_parm_name(parm->label), *(char *)ptr);
205 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
206 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
210 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"",
211 make_parm_name(parm->label));
212 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
213 char **list = *(char ***)ptr;
214 for (;*list;list++) {
215 d_printf("%s%s", *list, ((*(list+1))?" ":""));
219 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
220 _("Set Default"), make_parm_name(parm->label));
221 if (parm->def.lvalue) {
222 char **list = (char **)(parm->def.lvalue);
223 for (; *list; list++) {
224 d_printf("%s%s", *list, ((*(list+1))?" ":""));
232 d_printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
233 make_parm_name(parm->label), *(char **)ptr);
234 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
235 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
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)));
247 d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
248 d_printf("<option %s>Yes", (*(BOOL *)ptr)?"selected":"");
249 d_printf("<option %s>No", (*(BOOL *)ptr)?"":"selected");
250 d_printf("</select>");
251 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
252 _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?0:1);
256 d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
257 d_printf("<option %s>Yes", (*(BOOL *)ptr)?"":"selected");
258 d_printf("<option %s>No", (*(BOOL *)ptr)?"selected":"");
259 d_printf("</select>");
260 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
261 _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?1:0);
265 d_printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
266 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
267 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
271 d_printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm->label), octal_string(*(int *)ptr));
272 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
273 _("Set Default"), make_parm_name(parm->label),
274 octal_string((int)(parm->def.ivalue)));
278 d_printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
279 for (i=0;parm->enum_list[i].name;i++) {
280 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
281 d_printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
284 d_printf("</select>");
285 d_printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
286 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
291 d_printf("</td></tr>\n");
294 /****************************************************************************
295 display a set of parameters for a service
296 ****************************************************************************/
297 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
300 struct parm_struct *parm;
301 const char *heading = NULL;
302 const char *last_heading = NULL;
304 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
305 if (snum < 0 && parm->class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
307 if (parm->class == P_SEPARATOR) {
308 heading = parm->label;
311 if (parm->flags & FLAG_HIDE) continue;
313 if (printers & !(parm->flags & FLAG_PRINT)) continue;
314 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
317 if (!( parm_filter & FLAG_ADVANCED )) {
318 if (!(parm->flags & FLAG_BASIC)) {
319 void *ptr = parm->ptr;
321 if (parm->class == P_LOCAL && snum >= 0) {
322 ptr = lp_local_ptr(snum, ptr);
325 switch (parm->type) {
327 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
331 if (!str_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
336 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
341 if (!strcmp((char *)ptr,(char *)(parm->def.svalue))) continue;
346 if (*(BOOL *)ptr == (BOOL)(parm->def.bvalue)) continue;
351 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
356 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
362 if (printers && !(parm->flags & FLAG_PRINT)) continue;
365 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
367 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
369 if (heading && heading != last_heading) {
370 d_printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
371 last_heading = heading;
373 show_parameter(snum, parm);
377 /****************************************************************************
378 load the smb.conf file into loadparm.
379 ****************************************************************************/
380 static BOOL load_config(BOOL save_def)
382 lp_resetnumservices();
383 return lp_load(dyn_CONFIGFILE,False,save_def,False);
386 /****************************************************************************
388 ****************************************************************************/
389 static void write_config(FILE *f, BOOL show_defaults)
391 fprintf(f, "# Samba config file created using SWAT\n");
392 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
393 fprintf(f, "# Date: %s\n\n", timestring(False));
395 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
398 /****************************************************************************
399 save and reload the smb.conf config file
400 ****************************************************************************/
401 static int save_reload(int snum)
406 f = sys_fopen(dyn_CONFIGFILE,"w");
408 d_printf(_("failed to open %s for writing"), dyn_CONFIGFILE);
413 /* just in case they have used the buggy xinetd to create the file */
414 if (fstat(fileno(f), &st) == 0 &&
415 (st.st_mode & S_IWOTH)) {
416 #if defined HAVE_FCHMOD
417 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
419 chmod(dyn_CONFIGFILE, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
423 write_config(f, False);
425 lp_dump_one(f, False, snum);
430 if (!load_config(False)) {
431 d_printf(_("Can't reload %s"), dyn_CONFIGFILE);
435 iNumNonAutoPrintServices = lp_numservices();
441 /****************************************************************************
443 ****************************************************************************/
444 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
449 if (snum < 0 && parm->class == P_LOCAL) {
450 /* this handles the case where we are changing a local
451 variable globally. We need to change the parameter in
452 all shares where it is currently set to the default */
453 for (i=0;i<lp_numservices();i++) {
454 s = lp_servicename(i);
455 if (s && (*s) && lp_is_default(i, parm)) {
456 lp_do_parameter(i, parm->label, v);
461 lp_do_parameter(snum, parm->label, v);
464 /****************************************************************************
465 commit a set of parameters for a service
466 ****************************************************************************/
467 static void commit_parameters(int snum)
470 struct parm_struct *parm;
474 while ((parm = lp_next_parameter(snum, &i, 1))) {
475 slprintf(label, sizeof(label)-1, "parm_%s", make_parm_name(parm->label));
476 if ((v = cgi_variable(label))) {
477 if (parm->flags & FLAG_HIDE) continue;
478 commit_parameter(snum, parm, v);
483 /****************************************************************************
484 spit out the html for a link with an image
485 ****************************************************************************/
486 static void image_link(const char *name, const char *hlink, const char *src)
488 d_printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
489 cgi_baseurl(), hlink, src, name);
492 /****************************************************************************
493 display the main navigation controls at the top of each page along
495 ****************************************************************************/
496 static void show_main_buttons(void)
500 if ((p = cgi_user_name()) && strcmp(p, "root")) {
501 d_printf(_("Logged in as <b>%s</b>"), p);
505 image_link(_("Home"), "", "images/home.gif");
506 if (have_write_access) {
507 image_link(_("Globals"), "globals", "images/globals.gif");
508 image_link(_("Shares"), "shares", "images/shares.gif");
509 image_link(_("Printers"), "printers", "images/printers.gif");
510 image_link(_("Wizard"), "wizard", "images/wizard.gif");
512 if (have_read_access) {
513 image_link(_("Status"), "status", "images/status.gif");
514 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
516 image_link(_("Password Management"), "passwd", "images/passwd.gif");
521 /****************************************************************************
522 * Handle Display/Edit Mode CGI
523 ****************************************************************************/
524 static void ViewModeBoxes(int mode)
526 d_printf("<p>%s: \n", _("Current View Is"));
527 d_printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
528 d_printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
529 d_printf("<br>%s: \n", _("Change View To"));
530 d_printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
531 d_printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
532 d_printf("</p><br>\n");
535 /****************************************************************************
536 display a welcome page
537 ****************************************************************************/
538 static void welcome_page(void)
540 include_html("help/welcome.html");
543 /****************************************************************************
544 display the current smb.conf
545 ****************************************************************************/
546 static void viewconfig_page(void)
550 if (cgi_variable("full_view")) {
554 d_printf("<H2>%s</H2>\n", _("Current Config"));
555 d_printf("<form method=post>\n");
558 d_printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
560 d_printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
563 d_printf("<p><pre>");
564 write_config(stdout, full_view);
566 d_printf("</form>\n");
569 /****************************************************************************
570 second screen of the wizard ... Fetch Configuration Parameters
571 ****************************************************************************/
572 static void wizard_params_page(void)
574 unsigned int parm_filter = FLAG_WIZARD;
576 /* Here we first set and commit all the parameters that were selected
577 in the previous screen. */
579 d_printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
581 if (cgi_variable("Commit")) {
582 commit_parameters(GLOBAL_SECTION_SNUM);
586 d_printf("<form name=\"swatform\" method=post action=wizard_params>\n");
588 if (have_write_access) {
589 d_printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
592 d_printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
595 d_printf("<table>\n");
596 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
597 d_printf("</table>\n");
598 d_printf("</form>\n");
601 /****************************************************************************
602 Utility to just rewrite the smb.conf file - effectively just cleans it up
603 ****************************************************************************/
604 static void rewritecfg_file(void)
606 commit_parameters(GLOBAL_SECTION_SNUM);
608 d_printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
611 /****************************************************************************
612 wizard to create/modify the smb.conf file
613 ****************************************************************************/
614 static void wizard_page(void)
616 /* Set some variables to collect data from smb.conf */
623 if (cgi_variable("Rewrite")) {
624 (void) rewritecfg_file();
628 if (cgi_variable("GetWizardParams")){
629 (void) wizard_params_page();
633 if (cgi_variable("Commit")){
634 SerType = atoi(cgi_variable("ServerType"));
635 winstype = atoi(cgi_variable("WINSType"));
636 have_home = lp_servicenumber(HOMES_NAME);
637 HomeExpo = atoi(cgi_variable("HomeExpo"));
639 /* Plain text passwords are too badly broken - use encrypted passwords only */
640 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
644 /* Stand-alone Server */
645 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
646 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
650 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
651 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
654 /* Domain Controller */
655 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
656 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
659 switch ( winstype ) {
661 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
662 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
665 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
666 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
669 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
670 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable("WINSAddr"));
674 /* Have to create Homes share? */
675 if ((HomeExpo == 1) && (have_home == -1)) {
678 pstrcpy(unix_share,HOMES_NAME);
680 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
681 iNumNonAutoPrintServices = lp_numservices();
682 have_home = lp_servicenumber(HOMES_NAME);
683 lp_do_parameter( have_home, "read only", "No");
684 lp_do_parameter( have_home, "valid users", "%S");
685 lp_do_parameter( have_home, "browseable", "No");
686 commit_parameters(have_home);
689 /* Need to Delete Homes share? */
690 if ((HomeExpo == 0) && (have_home != -1)) {
691 lp_remove_service(have_home);
695 commit_parameters(GLOBAL_SECTION_SNUM);
700 /* Now determine smb.conf WINS settings */
701 if (lp_wins_support())
703 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
707 /* Do we have a homes share? */
708 have_home = lp_servicenumber(HOMES_NAME);
710 if ((winstype == 2) && lp_wins_support())
713 role = lp_server_role();
716 d_printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
717 d_printf("<form method=post action=wizard>\n");
719 if (have_write_access) {
720 d_printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
721 d_printf("%s", _("The same will happen if you press the commit button."));
722 d_printf("<br><br>\n");
723 d_printf("<center>");
724 d_printf("<input type=submit name=\"Rewrite\" value=\"%s\"> ",_("Rewrite smb.conf file"));
725 d_printf("<input type=submit name=\"Commit\" value=\"%s\"> ",_("Commit"));
726 d_printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
727 d_printf("</center>\n");
731 d_printf("<center><table border=0>");
732 d_printf("<tr><td><b>%s: </b></td>\n", _("Server Type"));
733 d_printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s </td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
734 d_printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s </td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
735 d_printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s </td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
737 if (role == ROLE_DOMAIN_BDC) {
738 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
740 d_printf("<tr><td><b>%s: </b></td>\n", _("Configure WINS As"));
741 d_printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s </td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
742 d_printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s </td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
743 d_printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s </td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
745 d_printf("<tr><td></td><td></td><td></td><td>%s <input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
747 /* Print out the list of wins servers */
748 if(lp_wins_server_list()) {
750 const char **wins_servers = lp_wins_server_list();
751 for(i = 0; wins_servers[i]; i++) d_printf("%s ", wins_servers[i]);
754 d_printf("\"></td></tr>\n");
756 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Error: WINS Server Mode and WINS Support both set in smb.conf"));
757 d_printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
759 d_printf("<tr><td><b>%s: </b></td>\n", _("Expose Home Directories"));
760 d_printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
761 d_printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
762 d_printf("<td></td></tr>\n");
764 /* Enable this when we are ready ....
765 * d_printf("<tr><td><b>%s: </b></td>\n", _("Is Print Server"));
766 * d_printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
767 * d_printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
768 * d_printf("<td></td></tr>\n");
771 d_printf("</table></center>");
774 d_printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
775 d_printf("</form>\n");
779 /****************************************************************************
780 display a globals editing page
781 ****************************************************************************/
782 static void globals_page(void)
784 unsigned int parm_filter = FLAG_BASIC;
787 d_printf("<H2>%s</H2>\n", _("Global Parameters"));
789 if (cgi_variable("Commit")) {
790 commit_parameters(GLOBAL_SECTION_SNUM);
794 if ( cgi_variable("ViewMode") )
795 mode = atoi(cgi_variable("ViewMode"));
796 if ( cgi_variable("BasicMode"))
798 if ( cgi_variable("AdvMode"))
801 d_printf("<form name=\"swatform\" method=post action=globals>\n");
803 ViewModeBoxes( mode );
806 parm_filter = FLAG_BASIC;
809 parm_filter = FLAG_ADVANCED;
813 if (have_write_access) {
814 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
815 _("Commit Changes"));
818 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
822 d_printf("<table>\n");
823 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
824 d_printf("</table>\n");
825 d_printf("</form>\n");
828 /****************************************************************************
829 display a shares editing page. share is in unix codepage, and must be in
830 dos codepage. FIXME !!! JRA.
831 ****************************************************************************/
832 static void shares_page(void)
834 const char *share = cgi_variable("share");
839 unsigned int parm_filter = FLAG_BASIC;
842 snum = lp_servicenumber(share);
844 d_printf("<H2>%s</H2>\n", _("Share Parameters"));
846 if (cgi_variable("Commit") && snum >= 0) {
847 commit_parameters(snum);
851 if (cgi_variable("Delete") && snum >= 0) {
852 lp_remove_service(snum);
858 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
860 lp_copy_service(GLOBAL_SECTION_SNUM, share);
861 iNumNonAutoPrintServices = lp_numservices();
863 snum = lp_servicenumber(share);
866 d_printf("<FORM name=\"swatform\" method=post>\n");
868 d_printf("<table>\n");
870 if ( cgi_variable("ViewMode") )
871 mode = atoi(cgi_variable("ViewMode"));
872 if ( cgi_variable("BasicMode"))
874 if ( cgi_variable("AdvMode"))
877 ViewModeBoxes( mode );
880 parm_filter = FLAG_BASIC;
883 parm_filter = FLAG_ADVANCED;
886 d_printf("<br><tr>\n");
887 d_printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
888 d_printf("<td><select name=share>\n");
890 d_printf("<option value=\" \"> \n");
891 for (i=0;i<lp_numservices();i++) {
892 s = lp_servicename(i);
893 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
894 d_printf("<option %s value=\"%s\">%s\n",
895 (share && strcmp(share,s)==0)?"SELECTED":"",
899 d_printf("</select></td>\n");
900 if (have_write_access) {
901 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
904 d_printf("</table>");
906 if (have_write_access) {
908 d_printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
909 d_printf("<td><input type=text size=30 name=newshare></td></tr>\n");
911 d_printf("</table>");
915 if (have_write_access) {
916 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
919 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
924 d_printf("<table>\n");
925 show_parameters(snum, 1, parm_filter, 0);
926 d_printf("</table>\n");
929 d_printf("</FORM>\n");
932 /*************************************************************
933 change a password either locally or remotely
934 *************************************************************/
935 static BOOL change_password(const char *remote_machine, const char *user_name,
936 const char *old_passwd, const char *new_passwd,
944 d_printf("%s\n<p>", _("password change in demo mode rejected"));
948 if (remote_machine != NULL) {
949 ret = remote_password_change(remote_machine, user_name, old_passwd,
950 new_passwd, err_str, sizeof(err_str));
952 d_printf("%s\n<p>", err_str);
956 if(!initialize_password_db(True)) {
957 d_printf("%s\n<p>", _("Can't setup password database vectors."));
961 ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
962 msg_str, sizeof(msg_str));
965 d_printf("%s\n<p>", msg_str);
967 d_printf("%s\n<p>", err_str);
972 /****************************************************************************
973 do the stuff required to add or change a password
974 ****************************************************************************/
975 static void chg_passwd(void)
981 /* Make sure users name has been specified */
982 if (strlen(cgi_variable(SWAT_USER)) == 0) {
983 d_printf("<p>%s\n", _(" Must specify \"User Name\" "));
988 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
989 * so if that's what we're doing, skip the rest of the checks
991 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
994 * If current user is not root, make sure old password has been specified
995 * If REMOTE change, even root must provide old password
997 if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
998 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
999 d_printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1003 /* If changing a users password on a remote hosts we have to know what host */
1004 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
1005 d_printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1009 /* Make sure new passwords have been specified */
1010 if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
1011 (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
1012 d_printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1016 /* Make sure new passwords was typed correctly twice */
1017 if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
1018 d_printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1023 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1024 host = cgi_variable(RHOST);
1025 } else if (am_root()) {
1032 * Set up the local flags.
1035 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1036 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1037 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1038 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1040 rslt = change_password(host,
1041 cgi_variable(SWAT_USER),
1042 cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
1045 if(local_flags == 0) {
1048 d_printf(_(" The passwd for '%s' has been changed."), cgi_variable(SWAT_USER));
1051 d_printf(_(" The passwd for '%s' has NOT been changed."), cgi_variable(SWAT_USER));
1059 /****************************************************************************
1060 display a password editing page
1061 ****************************************************************************/
1062 static void passwd_page(void)
1064 const char *new_name = cgi_user_name();
1067 * After the first time through here be nice. If the user
1068 * changed the User box text to another users name, remember it.
1070 if (cgi_variable(SWAT_USER)) {
1071 new_name = cgi_variable(SWAT_USER);
1074 if (!new_name) new_name = "";
1076 d_printf("<H2>%s</H2>\n", _("Server Password Management"));
1078 d_printf("<FORM name=\"swatform\" method=post>\n");
1080 d_printf("<table>\n");
1083 * Create all the dialog boxes for data collection
1085 d_printf("<tr><td> %s : </td>\n", _("User Name"));
1086 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1088 d_printf("<tr><td> %s : </td>\n", _("Old Password"));
1089 d_printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1091 d_printf("<tr><td> %s : </td>\n", _("New Password"));
1092 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1093 d_printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1094 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1095 d_printf("</table>\n");
1098 * Create all the control buttons for requesting action
1100 d_printf("<input type=submit name=%s value=\"%s\">\n",
1101 CHG_S_PASSWD_FLAG, _("Change Password"));
1102 if (demo_mode || am_root()) {
1103 d_printf("<input type=submit name=%s value=\"%s\">\n",
1104 ADD_USER_FLAG, _("Add New User"));
1105 d_printf("<input type=submit name=%s value=\"%s\">\n",
1106 DELETE_USER_FLAG, _("Delete User"));
1107 d_printf("<input type=submit name=%s value=\"%s\">\n",
1108 DISABLE_USER_FLAG, _("Disable User"));
1109 d_printf("<input type=submit name=%s value=\"%s\">\n",
1110 ENABLE_USER_FLAG, _("Enable User"));
1112 d_printf("<p></FORM>\n");
1115 * Do some work if change, add, disable or enable was
1116 * requested. It could be this is the first time through this
1117 * code, so there isn't anything to do. */
1118 if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1119 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1123 d_printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1125 d_printf("<FORM name=\"swatform\" method=post>\n");
1127 d_printf("<table>\n");
1130 * Create all the dialog boxes for data collection
1132 d_printf("<tr><td> %s : </td>\n", _("User Name"));
1133 d_printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1134 d_printf("<tr><td> %s : </td>\n", _("Old Password"));
1135 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1136 d_printf("<tr><td> %s : </td>\n", _("New Password"));
1137 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1138 d_printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1139 d_printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1140 d_printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1141 d_printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1143 d_printf("</table>");
1146 * Create all the control buttons for requesting action
1148 d_printf("<input type=submit name=%s value=\"%s\">",
1149 CHG_R_PASSWD_FLAG, _("Change Password"));
1151 d_printf("<p></FORM>\n");
1154 * Do some work if a request has been made to change the
1155 * password somewhere other than the server. It could be this
1156 * is the first time through this code, so there isn't
1157 * anything to do. */
1158 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1164 /****************************************************************************
1165 display a printers editing page
1166 ****************************************************************************/
1167 static void printers_page(void)
1169 const char *share = cgi_variable("share");
1174 unsigned int parm_filter = FLAG_BASIC;
1177 snum = lp_servicenumber(share);
1179 d_printf("<H2>%s</H2>\n", _("Printer Parameters"));
1181 d_printf("<H3>%s</H3>\n", _("Important Note:"));
1182 d_printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
1183 d_printf(_("are autoloaded printers from "));
1184 d_printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1185 d_printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1187 if (cgi_variable("Commit") && snum >= 0) {
1188 commit_parameters(snum);
1189 if (snum >= iNumNonAutoPrintServices)
1195 if (cgi_variable("Delete") && snum >= 0) {
1196 lp_remove_service(snum);
1202 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1204 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1205 iNumNonAutoPrintServices = lp_numservices();
1206 snum = lp_servicenumber(share);
1207 lp_do_parameter(snum, "print ok", "Yes");
1209 snum = lp_servicenumber(share);
1212 d_printf("<FORM name=\"swatform\" method=post>\n");
1214 if ( cgi_variable("ViewMode") )
1215 mode = atoi(cgi_variable("ViewMode"));
1216 if ( cgi_variable("BasicMode"))
1218 if ( cgi_variable("AdvMode"))
1221 ViewModeBoxes( mode );
1224 parm_filter = FLAG_BASIC;
1227 parm_filter = FLAG_ADVANCED;
1230 d_printf("<table>\n");
1231 d_printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1232 d_printf("<td><select name=\"share\">\n");
1233 if (snum < 0 || !lp_print_ok(snum))
1234 d_printf("<option value=\" \"> \n");
1235 for (i=0;i<lp_numservices();i++) {
1236 s = lp_servicename(i);
1237 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1238 if (i >= iNumNonAutoPrintServices)
1239 d_printf("<option %s value=\"%s\">[*]%s\n",
1240 (share && strcmp(share,s)==0)?"SELECTED":"",
1243 d_printf("<option %s value=\"%s\">%s\n",
1244 (share && strcmp(share,s)==0)?"SELECTED":"",
1248 d_printf("</select></td>");
1249 if (have_write_access) {
1250 d_printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1253 d_printf("</table>\n");
1255 if (have_write_access) {
1256 d_printf("<table>\n");
1257 d_printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1258 d_printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1259 d_printf("</table>");
1264 if (have_write_access) {
1265 d_printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1267 d_printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1272 d_printf("<table>\n");
1273 show_parameters(snum, 1, parm_filter, 1);
1274 d_printf("</table>\n");
1276 d_printf("</FORM>\n");
1281 * main function for SWAT.
1283 int main(int argc, char *argv[])
1288 struct poptOption long_options[] = {
1290 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1296 umask(S_IWGRP | S_IWOTH);
1298 #if defined(HAVE_SET_AUTH_PARAMETERS)
1299 set_auth_parameters(argc, argv);
1300 #endif /* HAVE_SET_AUTH_PARAMETERS */
1302 /* just in case it goes wild ... */
1307 /* we don't want any SIGPIPE messages */
1308 BlockSignals(True,SIGPIPE);
1310 dbf = x_fopen("/dev/null", O_WRONLY, 0);
1311 if (!dbf) dbf = x_stderr;
1313 /* we don't want stderr screwing us up */
1315 open("/dev/null", O_WRONLY);
1317 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1319 /* Parse command line options */
1321 while((opt = poptGetNextOpt(pc)) != -1) { }
1323 poptFreeContext(pc);
1325 setup_logging(argv[0],False);
1327 iNumNonAutoPrintServices = lp_numservices();
1330 cgi_setup(dyn_SWATDIR, !demo_mode);
1334 cgi_load_variables();
1336 if (!file_exist(dyn_CONFIGFILE, NULL)) {
1337 have_read_access = True;
1338 have_write_access = True;
1340 /* check if the authenticated user has write access - if not then
1341 don't show write options */
1342 have_write_access = (access(dyn_CONFIGFILE,W_OK) == 0);
1344 /* if the user doesn't have read access to smb.conf then
1345 don't let them view it */
1346 have_read_access = (access(dyn_CONFIGFILE,R_OK) == 0);
1349 show_main_buttons();
1351 page = cgi_pathinfo();
1353 /* Root gets full functionality */
1354 if (have_read_access && strcmp(page, "globals")==0) {
1356 } else if (have_read_access && strcmp(page,"shares")==0) {
1358 } else if (have_read_access && strcmp(page,"printers")==0) {
1360 } else if (have_read_access && strcmp(page,"status")==0) {
1362 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1364 } else if (strcmp(page,"passwd")==0) {
1366 } else if (have_read_access && strcmp(page,"wizard")==0) {
1368 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1369 wizard_params_page();
1370 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {