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"
55 /****************************************************************************
56 ****************************************************************************/
57 static int enum_index(int value, const struct enum_list *enumlist)
60 for (i=0;enumlist[i].name;i++)
61 if (value == enumlist[i].value) break;
65 static char *fix_backslash(const char *str)
67 static char newstring[1024];
71 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
79 static char *stripspaceupper(const char *str)
81 static char newstring[1024];
85 if (*str != ' ') *p++ = toupper(*str);
92 static char *make_parm_name(const char *label)
94 static char parmname[1024];
98 if (*label == ' ') *p++ = '_';
106 /****************************************************************************
107 include a lump of html in a page
108 ****************************************************************************/
109 static int include_html(const char *fname)
115 fd = web_open(fname, O_RDONLY, 0);
118 printf(_("ERROR: Can't open %s"), fname);
123 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
131 /****************************************************************************
132 start the page with standard stuff
133 ****************************************************************************/
134 static void print_header(void)
136 if (!cgi_waspost()) {
137 printf("Expires: 0\r\n");
139 printf("Content-type: text/html\r\n\r\n");
141 if (!include_html("include/header.html")) {
142 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
143 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
147 /* *******************************************************************
148 show parameter label with translated name in the following form
149 because showing original and translated label in one line looks
150 too long, and showing translated label only is unusable for
152 -------------------------------
153 HELP security [combo box][button]
155 -------------------------------
156 (capital words are translated by gettext.)
157 if no translation is available, then same form as original is
159 "i18n_translated_parm" class is used to change the color of the
160 translated parameter with CSS.
161 **************************************************************** */
162 static const char* get_parm_translated(
163 const char* pAnchor, const char* pHelp, const char* pLabel)
165 const char* pTranslated = _(pLabel);
166 static pstring output;
167 if(strcmp(pLabel, pTranslated) != 0)
170 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
171 pAnchor, pHelp, pLabel, pTranslated);
175 "<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
176 pAnchor, pHelp, pLabel);
179 /****************************************************************************
181 ****************************************************************************/
182 static void print_footer(void)
184 if (!include_html("include/footer.html")) {
185 printf("\n</BODY>\n</HTML>\n");
189 /****************************************************************************
190 display one editable parameter in a form
191 ****************************************************************************/
192 static void show_parameter(int snum, struct parm_struct *parm)
195 void *ptr = parm->ptr;
197 if (parm->class == P_LOCAL && snum >= 0) {
198 ptr = lp_local_ptr(snum, ptr);
201 printf("<tr><td>%s</td><td>", get_parm_translated(stripspaceupper(parm->label), _("Help"), parm->label));
202 switch (parm->type) {
204 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
205 make_parm_name(parm->label), *(char *)ptr);
206 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
207 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
211 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
212 make_parm_name(parm->label));
213 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
214 char **list = *(char ***)ptr;
215 for (;*list;list++) {
216 /* enclose in quotes if the string contains a space */
217 if ( strchr_m(*list, ' ') )
218 printf("\'%s\'%s", *list, ((*(list+1))?", ":""));
220 printf("%s%s", *list, ((*(list+1))?", ":""));
224 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
225 _("Set Default"), make_parm_name(parm->label));
226 if (parm->def.lvalue) {
227 char **list = (char **)(parm->def.lvalue);
228 for (; *list; list++) {
229 /* enclose in quotes if the string contains a space */
230 if ( strchr_m(*list, ' ') )
231 printf("\'%s\'%s", *list, ((*(list+1))?", ":""));
233 printf("%s%s", *list, ((*(list+1))?", ":""));
241 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
242 make_parm_name(parm->label), *(char **)ptr);
243 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
244 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
249 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
250 make_parm_name(parm->label), (char *)ptr);
251 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
252 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
256 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
257 printf("<option %s>Yes", (*(BOOL *)ptr)?"selected":"");
258 printf("<option %s>No", (*(BOOL *)ptr)?"":"selected");
260 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
261 _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?0:1);
265 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
266 printf("<option %s>Yes", (*(BOOL *)ptr)?"":"selected");
267 printf("<option %s>No", (*(BOOL *)ptr)?"selected":"");
269 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
270 _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?1:0);
274 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
275 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
276 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
280 printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm->label), octal_string(*(int *)ptr));
281 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
282 _("Set Default"), make_parm_name(parm->label),
283 octal_string((int)(parm->def.ivalue)));
287 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
288 for (i=0;parm->enum_list[i].name;i++) {
289 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
290 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
294 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
295 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
300 printf("</td></tr>\n");
303 /****************************************************************************
304 display a set of parameters for a service
305 ****************************************************************************/
306 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
309 struct parm_struct *parm;
310 const char *heading = NULL;
311 const char *last_heading = NULL;
313 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
314 if (snum < 0 && parm->class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
316 if (parm->class == P_SEPARATOR) {
317 heading = parm->label;
320 if (parm->flags & FLAG_HIDE) continue;
322 if (printers & !(parm->flags & FLAG_PRINT)) continue;
323 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
326 if (!( parm_filter & FLAG_ADVANCED )) {
327 if (!(parm->flags & FLAG_BASIC)) {
328 void *ptr = parm->ptr;
330 if (parm->class == P_LOCAL && snum >= 0) {
331 ptr = lp_local_ptr(snum, ptr);
334 switch (parm->type) {
336 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
340 if (!str_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
345 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
350 if (!strcmp((char *)ptr,(char *)(parm->def.svalue))) continue;
355 if (*(BOOL *)ptr == (BOOL)(parm->def.bvalue)) continue;
360 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
365 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
371 if (printers && !(parm->flags & FLAG_PRINT)) continue;
374 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
376 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
378 if (heading && heading != last_heading) {
379 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
380 last_heading = heading;
382 show_parameter(snum, parm);
386 /****************************************************************************
387 load the smb.conf file into loadparm.
388 ****************************************************************************/
389 static BOOL load_config(BOOL save_def)
391 lp_resetnumservices();
392 return lp_load(dyn_CONFIGFILE,False,save_def,False);
395 /****************************************************************************
397 ****************************************************************************/
398 static void write_config(FILE *f, BOOL show_defaults)
400 fprintf(f, "# Samba config file created using SWAT\n");
401 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
402 fprintf(f, "# Date: %s\n\n", timestring(False));
404 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
407 /****************************************************************************
408 save and reload the smb.conf config file
409 ****************************************************************************/
410 static int save_reload(int snum)
415 f = sys_fopen(dyn_CONFIGFILE,"w");
417 printf(_("failed to open %s for writing"), dyn_CONFIGFILE);
422 /* just in case they have used the buggy xinetd to create the file */
423 if (fstat(fileno(f), &st) == 0 &&
424 (st.st_mode & S_IWOTH)) {
425 #if defined HAVE_FCHMOD
426 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
428 chmod(dyn_CONFIGFILE, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
432 write_config(f, False);
434 lp_dump_one(f, False, snum);
439 if (!load_config(False)) {
440 printf(_("Can't reload %s"), dyn_CONFIGFILE);
444 iNumNonAutoPrintServices = lp_numservices();
450 /****************************************************************************
452 ****************************************************************************/
453 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
458 if (snum < 0 && parm->class == P_LOCAL) {
459 /* this handles the case where we are changing a local
460 variable globally. We need to change the parameter in
461 all shares where it is currently set to the default */
462 for (i=0;i<lp_numservices();i++) {
463 s = lp_servicename(i);
464 if (s && (*s) && lp_is_default(i, parm)) {
465 lp_do_parameter(i, parm->label, v);
470 lp_do_parameter(snum, parm->label, v);
473 /****************************************************************************
474 commit a set of parameters for a service
475 ****************************************************************************/
476 static void commit_parameters(int snum)
479 struct parm_struct *parm;
483 while ((parm = lp_next_parameter(snum, &i, 1))) {
484 slprintf(label, sizeof(label)-1, "parm_%s", make_parm_name(parm->label));
485 if ((v = cgi_variable(label))) {
486 if (parm->flags & FLAG_HIDE) continue;
487 commit_parameter(snum, parm, v);
492 /****************************************************************************
493 spit out the html for a link with an image
494 ****************************************************************************/
495 static void image_link(const char *name, const char *hlink, const char *src)
497 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
498 cgi_baseurl(), hlink, src, name);
501 /****************************************************************************
502 display the main navigation controls at the top of each page along
504 ****************************************************************************/
505 static void show_main_buttons(void)
509 if ((p = cgi_user_name()) && strcmp(p, "root")) {
510 printf(_("Logged in as <b>%s</b>"), p);
514 image_link(_("Home"), "", "images/home.gif");
515 if (have_write_access) {
516 image_link(_("Globals"), "globals", "images/globals.gif");
517 image_link(_("Shares"), "shares", "images/shares.gif");
518 image_link(_("Printers"), "printers", "images/printers.gif");
519 image_link(_("Wizard"), "wizard", "images/wizard.gif");
521 if (have_read_access) {
522 image_link(_("Status"), "status", "images/status.gif");
523 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
525 image_link(_("Password Management"), "passwd", "images/passwd.gif");
530 /****************************************************************************
531 * Handle Display/Edit Mode CGI
532 ****************************************************************************/
533 static void ViewModeBoxes(int mode)
535 printf("<p>%s: \n", _("Current View Is"));
536 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
537 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
538 printf("<br>%s: \n", _("Change View To"));
539 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
540 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
541 printf("</p><br>\n");
544 /****************************************************************************
545 display a welcome page
546 ****************************************************************************/
547 static void welcome_page(void)
549 include_html("help/welcome.html");
552 /****************************************************************************
553 display the current smb.conf
554 ****************************************************************************/
555 static void viewconfig_page(void)
559 if (cgi_variable("full_view")) {
563 printf("<H2>%s</H2>\n", _("Current Config"));
564 printf("<form method=post>\n");
567 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
569 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
573 write_config(stdout, full_view);
578 /****************************************************************************
579 second screen of the wizard ... Fetch Configuration Parameters
580 ****************************************************************************/
581 static void wizard_params_page(void)
583 unsigned int parm_filter = FLAG_WIZARD;
585 /* Here we first set and commit all the parameters that were selected
586 in the previous screen. */
588 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
590 if (cgi_variable("Commit")) {
591 commit_parameters(GLOBAL_SECTION_SNUM);
595 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
597 if (have_write_access) {
598 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
601 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
605 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
606 printf("</table>\n");
610 /****************************************************************************
611 Utility to just rewrite the smb.conf file - effectively just cleans it up
612 ****************************************************************************/
613 static void rewritecfg_file(void)
615 commit_parameters(GLOBAL_SECTION_SNUM);
617 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
620 /****************************************************************************
621 wizard to create/modify the smb.conf file
622 ****************************************************************************/
623 static void wizard_page(void)
625 /* Set some variables to collect data from smb.conf */
632 if (cgi_variable("Rewrite")) {
633 (void) rewritecfg_file();
637 if (cgi_variable("GetWizardParams")){
638 (void) wizard_params_page();
642 if (cgi_variable("Commit")){
643 SerType = atoi(cgi_variable("ServerType"));
644 winstype = atoi(cgi_variable("WINSType"));
645 have_home = lp_servicenumber(HOMES_NAME);
646 HomeExpo = atoi(cgi_variable("HomeExpo"));
648 /* Plain text passwords are too badly broken - use encrypted passwords only */
649 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
653 /* Stand-alone Server */
654 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
655 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
659 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
660 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
663 /* Domain Controller */
664 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
665 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
668 switch ( winstype ) {
670 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
671 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
674 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
675 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
678 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
679 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable("WINSAddr"));
683 /* Have to create Homes share? */
684 if ((HomeExpo == 1) && (have_home == -1)) {
687 pstrcpy(unix_share,HOMES_NAME);
689 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
690 iNumNonAutoPrintServices = lp_numservices();
691 have_home = lp_servicenumber(HOMES_NAME);
692 lp_do_parameter( have_home, "read only", "No");
693 lp_do_parameter( have_home, "valid users", "%S");
694 lp_do_parameter( have_home, "browseable", "No");
695 commit_parameters(have_home);
698 /* Need to Delete Homes share? */
699 if ((HomeExpo == 0) && (have_home != -1)) {
700 lp_remove_service(have_home);
704 commit_parameters(GLOBAL_SECTION_SNUM);
709 /* Now determine smb.conf WINS settings */
710 if (lp_wins_support())
712 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
716 /* Do we have a homes share? */
717 have_home = lp_servicenumber(HOMES_NAME);
719 if ((winstype == 2) && lp_wins_support())
722 role = lp_server_role();
725 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
726 printf("<form method=post action=wizard>\n");
728 if (have_write_access) {
729 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
730 printf("%s", _("The same will happen if you press the commit button."));
731 printf("<br><br>\n");
733 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> ",_("Rewrite smb.conf file"));
734 printf("<input type=submit name=\"Commit\" value=\"%s\"> ",_("Commit"));
735 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
736 printf("</center>\n");
740 printf("<center><table border=0>");
741 printf("<tr><td><b>%s: </b></td>\n", _("Server Type"));
742 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s </td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
743 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s </td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
744 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s </td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
746 if (role == ROLE_DOMAIN_BDC) {
747 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
749 printf("<tr><td><b>%s: </b></td>\n", _("Configure WINS As"));
750 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s </td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
751 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s </td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
752 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s </td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
754 printf("<tr><td></td><td></td><td></td><td>%s <input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
756 /* Print out the list of wins servers */
757 if(lp_wins_server_list()) {
759 const char **wins_servers = lp_wins_server_list();
760 for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
763 printf("\"></td></tr>\n");
765 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"));
766 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
768 printf("<tr><td><b>%s: </b></td>\n", _("Expose Home Directories"));
769 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
770 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
771 printf("<td></td></tr>\n");
773 /* Enable this when we are ready ....
774 * printf("<tr><td><b>%s: </b></td>\n", _("Is Print Server"));
775 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
776 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
777 * printf("<td></td></tr>\n");
780 printf("</table></center>");
783 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
788 /****************************************************************************
789 display a globals editing page
790 ****************************************************************************/
791 static void globals_page(void)
793 unsigned int parm_filter = FLAG_BASIC;
796 printf("<H2>%s</H2>\n", _("Global Parameters"));
798 if (cgi_variable("Commit")) {
799 commit_parameters(GLOBAL_SECTION_SNUM);
803 if ( cgi_variable("ViewMode") )
804 mode = atoi(cgi_variable("ViewMode"));
805 if ( cgi_variable("BasicMode"))
807 if ( cgi_variable("AdvMode"))
810 printf("<form name=\"swatform\" method=post action=globals>\n");
812 ViewModeBoxes( mode );
815 parm_filter = FLAG_BASIC;
818 parm_filter = FLAG_ADVANCED;
822 if (have_write_access) {
823 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
824 _("Commit Changes"));
827 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
832 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
833 printf("</table>\n");
837 /****************************************************************************
838 display a shares editing page. share is in unix codepage,
839 ****************************************************************************/
840 static void shares_page(void)
842 const char *share = cgi_variable("share");
848 unsigned int parm_filter = FLAG_BASIC;
851 snum = lp_servicenumber(share);
853 printf("<H2>%s</H2>\n", _("Share Parameters"));
855 if (cgi_variable("Commit") && snum >= 0) {
856 commit_parameters(snum);
860 if (cgi_variable("Delete") && snum >= 0) {
861 lp_remove_service(snum);
867 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
869 lp_copy_service(GLOBAL_SECTION_SNUM, share);
870 iNumNonAutoPrintServices = lp_numservices();
872 snum = lp_servicenumber(share);
875 printf("<FORM name=\"swatform\" method=post>\n");
879 if ( cgi_variable("ViewMode") )
880 mode = atoi(cgi_variable("ViewMode"));
881 if ( cgi_variable("BasicMode"))
883 if ( cgi_variable("AdvMode"))
886 ViewModeBoxes( mode );
889 parm_filter = FLAG_BASIC;
892 parm_filter = FLAG_ADVANCED;
895 printf("<br><tr>\n");
896 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
897 printf("<td><select name=share>\n");
899 printf("<option value=\" \"> \n");
900 for (i=0;i<lp_numservices();i++) {
901 s = lp_servicename(i);
902 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
903 push_utf8_allocate(&utf8_s, s);
904 printf("<option %s value=\"%s\">%s\n",
905 (share && strcmp(share,s)==0)?"SELECTED":"",
911 printf("</select></td>\n");
912 if (have_write_access) {
913 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
918 if (have_write_access) {
920 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
921 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
927 if (have_write_access) {
928 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
931 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
937 show_parameters(snum, 1, parm_filter, 0);
938 printf("</table>\n");
944 /*************************************************************
945 change a password either locally or remotely
946 *************************************************************/
947 static BOOL change_password(const char *remote_machine, const char *user_name,
948 const char *old_passwd, const char *new_passwd,
956 printf("%s\n<p>", _("password change in demo mode rejected"));
960 if (remote_machine != NULL) {
961 ret = remote_password_change(remote_machine, user_name, old_passwd,
962 new_passwd, err_str, sizeof(err_str));
964 printf("%s\n<p>", err_str);
968 if(!initialize_password_db(True)) {
969 printf("%s\n<p>", _("Can't setup password database vectors."));
973 ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
974 msg_str, sizeof(msg_str));
977 printf("%s\n<p>", msg_str);
979 printf("%s\n<p>", err_str);
984 /****************************************************************************
985 do the stuff required to add or change a password
986 ****************************************************************************/
987 static void chg_passwd(void)
993 /* Make sure users name has been specified */
994 if (strlen(cgi_variable(SWAT_USER)) == 0) {
995 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1000 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1001 * so if that's what we're doing, skip the rest of the checks
1003 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1006 * If current user is not root, make sure old password has been specified
1007 * If REMOTE change, even root must provide old password
1009 if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
1010 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
1011 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1015 /* If changing a users password on a remote hosts we have to know what host */
1016 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
1017 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1021 /* Make sure new passwords have been specified */
1022 if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
1023 (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
1024 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1028 /* Make sure new passwords was typed correctly twice */
1029 if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
1030 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1035 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1036 host = cgi_variable(RHOST);
1037 } else if (am_root()) {
1044 * Set up the local flags.
1047 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1048 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
1049 local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1050 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1051 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1052 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1055 rslt = change_password(host,
1056 cgi_variable(SWAT_USER),
1057 cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
1060 if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1063 printf(_(" The passwd for '%s' has been changed."), cgi_variable(SWAT_USER));
1066 printf(_(" The passwd for '%s' has NOT been changed."), cgi_variable(SWAT_USER));
1074 /****************************************************************************
1075 display a password editing page
1076 ****************************************************************************/
1077 static void passwd_page(void)
1079 const char *new_name = cgi_user_name();
1082 * After the first time through here be nice. If the user
1083 * changed the User box text to another users name, remember it.
1085 if (cgi_variable(SWAT_USER)) {
1086 new_name = cgi_variable(SWAT_USER);
1089 if (!new_name) new_name = "";
1091 printf("<H2>%s</H2>\n", _("Server Password Management"));
1093 printf("<FORM name=\"swatform\" method=post>\n");
1095 printf("<table>\n");
1098 * Create all the dialog boxes for data collection
1100 printf("<tr><td> %s : </td>\n", _("User Name"));
1101 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1103 printf("<tr><td> %s : </td>\n", _("Old Password"));
1104 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1106 printf("<tr><td> %s : </td>\n", _("New Password"));
1107 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1108 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1109 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1110 printf("</table>\n");
1113 * Create all the control buttons for requesting action
1115 printf("<input type=submit name=%s value=\"%s\">\n",
1116 CHG_S_PASSWD_FLAG, _("Change Password"));
1117 if (demo_mode || am_root()) {
1118 printf("<input type=submit name=%s value=\"%s\">\n",
1119 ADD_USER_FLAG, _("Add New User"));
1120 printf("<input type=submit name=%s value=\"%s\">\n",
1121 DELETE_USER_FLAG, _("Delete User"));
1122 printf("<input type=submit name=%s value=\"%s\">\n",
1123 DISABLE_USER_FLAG, _("Disable User"));
1124 printf("<input type=submit name=%s value=\"%s\">\n",
1125 ENABLE_USER_FLAG, _("Enable User"));
1127 printf("<p></FORM>\n");
1130 * Do some work if change, add, disable or enable was
1131 * requested. It could be this is the first time through this
1132 * code, so there isn't anything to do. */
1133 if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1134 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1138 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1140 printf("<FORM name=\"swatform\" method=post>\n");
1142 printf("<table>\n");
1145 * Create all the dialog boxes for data collection
1147 printf("<tr><td> %s : </td>\n", _("User Name"));
1148 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1149 printf("<tr><td> %s : </td>\n", _("Old Password"));
1150 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1151 printf("<tr><td> %s : </td>\n", _("New Password"));
1152 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1153 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1154 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1155 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1156 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1161 * Create all the control buttons for requesting action
1163 printf("<input type=submit name=%s value=\"%s\">",
1164 CHG_R_PASSWD_FLAG, _("Change Password"));
1166 printf("<p></FORM>\n");
1169 * Do some work if a request has been made to change the
1170 * password somewhere other than the server. It could be this
1171 * is the first time through this code, so there isn't
1172 * anything to do. */
1173 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1179 /****************************************************************************
1180 display a printers editing page
1181 ****************************************************************************/
1182 static void printers_page(void)
1184 const char *share = cgi_variable("share");
1189 unsigned int parm_filter = FLAG_BASIC;
1192 snum = lp_servicenumber(share);
1194 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1196 printf("<H3>%s</H3>\n", _("Important Note:"));
1197 printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
1198 printf(_("are autoloaded printers from "));
1199 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1200 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1202 if (cgi_variable("Commit") && snum >= 0) {
1203 commit_parameters(snum);
1204 if (snum >= iNumNonAutoPrintServices)
1210 if (cgi_variable("Delete") && snum >= 0) {
1211 lp_remove_service(snum);
1217 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1219 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1220 iNumNonAutoPrintServices = lp_numservices();
1221 snum = lp_servicenumber(share);
1222 lp_do_parameter(snum, "print ok", "Yes");
1224 snum = lp_servicenumber(share);
1227 printf("<FORM name=\"swatform\" method=post>\n");
1229 if ( cgi_variable("ViewMode") )
1230 mode = atoi(cgi_variable("ViewMode"));
1231 if ( cgi_variable("BasicMode"))
1233 if ( cgi_variable("AdvMode"))
1236 ViewModeBoxes( mode );
1239 parm_filter = FLAG_BASIC;
1242 parm_filter = FLAG_ADVANCED;
1245 printf("<table>\n");
1246 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1247 printf("<td><select name=\"share\">\n");
1248 if (snum < 0 || !lp_print_ok(snum))
1249 printf("<option value=\" \"> \n");
1250 for (i=0;i<lp_numservices();i++) {
1251 s = lp_servicename(i);
1252 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1253 if (i >= iNumNonAutoPrintServices)
1254 printf("<option %s value=\"%s\">[*]%s\n",
1255 (share && strcmp(share,s)==0)?"SELECTED":"",
1258 printf("<option %s value=\"%s\">%s\n",
1259 (share && strcmp(share,s)==0)?"SELECTED":"",
1263 printf("</select></td>");
1264 if (have_write_access) {
1265 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1268 printf("</table>\n");
1270 if (have_write_access) {
1271 printf("<table>\n");
1272 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1273 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1279 if (have_write_access) {
1280 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1282 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1287 printf("<table>\n");
1288 show_parameters(snum, 1, parm_filter, 1);
1289 printf("</table>\n");
1291 printf("</FORM>\n");
1296 * main function for SWAT.
1298 int main(int argc, char *argv[])
1303 struct poptOption long_options[] = {
1305 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1311 umask(S_IWGRP | S_IWOTH);
1313 #if defined(HAVE_SET_AUTH_PARAMETERS)
1314 set_auth_parameters(argc, argv);
1315 #endif /* HAVE_SET_AUTH_PARAMETERS */
1317 /* just in case it goes wild ... */
1322 /* we don't want any SIGPIPE messages */
1323 BlockSignals(True,SIGPIPE);
1325 dbf = x_fopen("/dev/null", O_WRONLY, 0);
1326 if (!dbf) dbf = x_stderr;
1328 /* we don't want stderr screwing us up */
1330 open("/dev/null", O_WRONLY);
1332 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1334 /* Parse command line options */
1336 while((opt = poptGetNextOpt(pc)) != -1) { }
1338 poptFreeContext(pc);
1340 setup_logging(argv[0],False);
1342 iNumNonAutoPrintServices = lp_numservices();
1345 cgi_setup(dyn_SWATDIR, !demo_mode);
1349 cgi_load_variables();
1351 if (!file_exist(dyn_CONFIGFILE, NULL)) {
1352 have_read_access = True;
1353 have_write_access = True;
1355 /* check if the authenticated user has write access - if not then
1356 don't show write options */
1357 have_write_access = (access(dyn_CONFIGFILE,W_OK) == 0);
1359 /* if the user doesn't have read access to smb.conf then
1360 don't let them view it */
1361 have_read_access = (access(dyn_CONFIGFILE,R_OK) == 0);
1364 show_main_buttons();
1366 page = cgi_pathinfo();
1368 /* Root gets full functionality */
1369 if (have_read_access && strcmp(page, "globals")==0) {
1371 } else if (have_read_access && strcmp(page,"shares")==0) {
1373 } else if (have_read_access && strcmp(page,"printers")==0) {
1375 } else if (have_read_access && strcmp(page,"status")==0) {
1377 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1379 } else if (strcmp(page,"passwd")==0) {
1381 } else if (have_read_access && strcmp(page,"wizard")==0) {
1383 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1384 wizard_params_page();
1385 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {