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 passwd_only = False;
36 static BOOL have_write_access = False;
37 static BOOL have_read_access = False;
38 static int iNumNonAutoPrintServices = 0;
41 * Password Management Globals
43 #define SWAT_USER "username"
44 #define OLD_PSWD "old_passwd"
45 #define NEW_PSWD "new_passwd"
46 #define NEW2_PSWD "new2_passwd"
47 #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
48 #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
49 #define ADD_USER_FLAG "add_user_flag"
50 #define DELETE_USER_FLAG "delete_user_flag"
51 #define DISABLE_USER_FLAG "disable_user_flag"
52 #define ENABLE_USER_FLAG "enable_user_flag"
53 #define RHOST "remote_host"
56 /****************************************************************************
57 ****************************************************************************/
58 static int enum_index(int value, const struct enum_list *enumlist)
61 for (i=0;enumlist[i].name;i++)
62 if (value == enumlist[i].value) break;
66 static char *fix_backslash(const char *str)
68 static char newstring[1024];
72 if (*str == '\\') {*p++ = '\\';*p++ = '\\';}
80 static char *fix_quotes(const char *str)
82 static pstring newstring;
84 size_t newstring_len = sizeof(newstring);
85 int quote_len = strlen(""");
88 if ( *str == '\"' && (newstring_len - PTR_DIFF(p, newstring) - 1) > quote_len ) {
89 strncpy( p, """, quote_len);
100 static char *stripspaceupper(const char *str)
102 static char newstring[1024];
106 if (*str != ' ') *p++ = toupper_ascii(*str);
113 static char *make_parm_name(const char *label)
115 static char parmname[1024];
119 if (*label == ' ') *p++ = '_';
127 /****************************************************************************
128 include a lump of html in a page
129 ****************************************************************************/
130 static int include_html(const char *fname)
136 fd = web_open(fname, O_RDONLY, 0);
139 printf(_("ERROR: Can't open %s"), fname);
144 while ((ret = read(fd, buf, sizeof(buf))) > 0) {
152 /****************************************************************************
153 start the page with standard stuff
154 ****************************************************************************/
155 static void print_header(void)
157 if (!cgi_waspost()) {
158 printf("Expires: 0\r\n");
160 printf("Content-type: text/html\r\n\r\n");
162 if (!include_html("include/header.html")) {
163 printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
164 printf("<HTML>\n<HEAD>\n<TITLE>Samba Web Administration Tool</TITLE>\n</HEAD>\n<BODY background=\"/swat/images/background.jpg\">\n\n");
168 /* *******************************************************************
169 show parameter label with translated name in the following form
170 because showing original and translated label in one line looks
171 too long, and showing translated label only is unusable for
173 -------------------------------
174 HELP security [combo box][button]
176 -------------------------------
177 (capital words are translated by gettext.)
178 if no translation is available, then same form as original is
180 "i18n_translated_parm" class is used to change the color of the
181 translated parameter with CSS.
182 **************************************************************** */
183 static const char* get_parm_translated(
184 const char* pAnchor, const char* pHelp, const char* pLabel)
186 const char* pTranslated = _(pLabel);
187 static pstring output;
188 if(strcmp(pLabel, pTranslated) != 0)
191 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s <br><span class=\"i18n_translated_parm\">%s</span>",
192 pAnchor, pHelp, pLabel, pTranslated);
196 "<A HREF=\"/swat/help/manpages/smb.conf.5.html#%s\" target=\"docs\"> %s</A> %s",
197 pAnchor, pHelp, pLabel);
200 /****************************************************************************
202 ****************************************************************************/
203 static void print_footer(void)
205 if (!include_html("include/footer.html")) {
206 printf("\n</BODY>\n</HTML>\n");
210 /****************************************************************************
211 display one editable parameter in a form
212 ****************************************************************************/
213 static void show_parameter(int snum, struct parm_struct *parm)
216 void *ptr = parm->ptr;
217 char *utf8_s1, *utf8_s2;
219 if (parm->p_class == P_LOCAL && snum >= 0) {
220 ptr = lp_local_ptr(snum, ptr);
223 printf("<tr><td>%s</td><td>", get_parm_translated(stripspaceupper(parm->label), _("Help"), parm->label));
224 switch (parm->type) {
226 printf("<input type=text size=2 name=\"parm_%s\" value=\"%c\">",
227 make_parm_name(parm->label), *(char *)ptr);
228 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%c\'\">",
229 _("Set Default"), make_parm_name(parm->label),(char)(parm->def.cvalue));
233 printf("<input type=text size=40 name=\"parm_%s\" value=\"",
234 make_parm_name(parm->label));
235 if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
236 char **list = *(char ***)ptr;
237 for (;*list;list++) {
238 /* enclose in HTML encoded quotes if the string contains a space */
239 if ( strchr_m(*list, ' ') ) {
240 push_utf8_allocate(&utf8_s1, *list);
241 push_utf8_allocate(&utf8_s2, ((*(list+1))?", ":""));
242 printf(""%s"%s", utf8_s1, utf8_s2);
244 push_utf8_allocate(&utf8_s1, *list);
245 push_utf8_allocate(&utf8_s2, ((*(list+1))?", ":""));
246 printf("%s%s", utf8_s1, utf8_s2);
253 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'",
254 _("Set Default"), make_parm_name(parm->label));
255 if (parm->def.lvalue) {
256 char **list = (char **)(parm->def.lvalue);
257 for (; *list; list++) {
258 /* enclose in HTML encoded quotes if the string contains a space */
259 if ( strchr_m(*list, ' ') )
260 printf(""%s"%s", *list, ((*(list+1))?", ":""));
262 printf("%s%s", *list, ((*(list+1))?", ":""));
270 push_utf8_allocate(&utf8_s1, *(char **)ptr);
271 printf("<input type=text size=40 name=\"parm_%s\" value=\"%s\">",
272 make_parm_name(parm->label), fix_quotes(utf8_s1));
274 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
275 _("Set Default"), make_parm_name(parm->label),fix_backslash((char *)(parm->def.svalue)));
279 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
280 printf("<option %s>Yes", (*(BOOL *)ptr)?"selected":"");
281 printf("<option %s>No", (*(BOOL *)ptr)?"":"selected");
283 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
284 _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?0:1);
288 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
289 printf("<option %s>Yes", (*(BOOL *)ptr)?"":"selected");
290 printf("<option %s>No", (*(BOOL *)ptr)?"selected":"");
292 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
293 _("Set Default"), make_parm_name(parm->label),(BOOL)(parm->def.bvalue)?1:0);
297 printf("<input type=text size=8 name=\"parm_%s\" value=\"%d\">", make_parm_name(parm->label), *(int *)ptr);
298 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%d\'\">",
299 _("Set Default"), make_parm_name(parm->label),(int)(parm->def.ivalue));
303 printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm->label), octal_string(*(int *)ptr));
304 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
305 _("Set Default"), make_parm_name(parm->label),
306 octal_string((int)(parm->def.ivalue)));
310 printf("<select name=\"parm_%s\">",make_parm_name(parm->label));
311 for (i=0;parm->enum_list[i].name;i++) {
312 if (i == 0 || parm->enum_list[i].value != parm->enum_list[i-1].value) {
313 printf("<option %s>%s",(*(int *)ptr)==parm->enum_list[i].value?"selected":"",parm->enum_list[i].name);
317 printf("<input type=button value=\"%s\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
318 _("Set Default"), make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
323 printf("</td></tr>\n");
326 /****************************************************************************
327 display a set of parameters for a service
328 ****************************************************************************/
329 static void show_parameters(int snum, int allparameters, unsigned int parm_filter, int printers)
332 struct parm_struct *parm;
333 const char *heading = NULL;
334 const char *last_heading = NULL;
336 while ((parm = lp_next_parameter(snum, &i, allparameters))) {
337 if (snum < 0 && parm->p_class == P_LOCAL && !(parm->flags & FLAG_GLOBAL))
339 if (parm->p_class == P_SEPARATOR) {
340 heading = parm->label;
343 if (parm->flags & FLAG_HIDE) continue;
345 if (printers & !(parm->flags & FLAG_PRINT)) continue;
346 if (!printers & !(parm->flags & FLAG_SHARE)) continue;
349 if (!( parm_filter & FLAG_ADVANCED )) {
350 if (!(parm->flags & FLAG_BASIC)) {
351 void *ptr = parm->ptr;
353 if (parm->p_class == P_LOCAL && snum >= 0) {
354 ptr = lp_local_ptr(snum, ptr);
357 switch (parm->type) {
359 if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
363 if (!str_list_compare(*(char ***)ptr, (char **)(parm->def.lvalue))) continue;
368 if (!strcmp(*(char **)ptr,(char *)(parm->def.svalue))) continue;
373 if (*(BOOL *)ptr == (BOOL)(parm->def.bvalue)) continue;
378 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
383 if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
389 if (printers && !(parm->flags & FLAG_PRINT)) continue;
392 if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
394 if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
396 if (heading && heading != last_heading) {
397 printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
398 last_heading = heading;
400 show_parameter(snum, parm);
404 /****************************************************************************
405 load the smb.conf file into loadparm.
406 ****************************************************************************/
407 static BOOL load_config(BOOL save_def)
409 lp_resetnumservices();
410 return lp_load(dyn_CONFIGFILE,False,save_def,False,True);
413 /****************************************************************************
415 ****************************************************************************/
416 static void write_config(FILE *f, BOOL show_defaults)
418 fprintf(f, "# Samba config file created using SWAT\n");
419 fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
420 fprintf(f, "# Date: %s\n\n", timestring(False));
422 lp_dump(f, show_defaults, iNumNonAutoPrintServices);
425 /****************************************************************************
426 save and reload the smb.conf config file
427 ****************************************************************************/
428 static int save_reload(int snum)
433 f = sys_fopen(dyn_CONFIGFILE,"w");
435 printf(_("failed to open %s for writing"), dyn_CONFIGFILE);
440 /* just in case they have used the buggy xinetd to create the file */
441 if (fstat(fileno(f), &st) == 0 &&
442 (st.st_mode & S_IWOTH)) {
443 #if defined HAVE_FCHMOD
444 fchmod(fileno(f), S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
446 chmod(dyn_CONFIGFILE, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);
450 write_config(f, False);
452 lp_dump_one(f, False, snum);
457 if (!load_config(False)) {
458 printf(_("Can't reload %s"), dyn_CONFIGFILE);
462 iNumNonAutoPrintServices = lp_numservices();
468 /****************************************************************************
470 ****************************************************************************/
471 static void commit_parameter(int snum, struct parm_struct *parm, const char *v)
476 if (snum < 0 && parm->p_class == P_LOCAL) {
477 /* this handles the case where we are changing a local
478 variable globally. We need to change the parameter in
479 all shares where it is currently set to the default */
480 for (i=0;i<lp_numservices();i++) {
481 s = lp_servicename(i);
482 if (s && (*s) && lp_is_default(i, parm)) {
483 lp_do_parameter(i, parm->label, v);
488 lp_do_parameter(snum, parm->label, v);
491 /****************************************************************************
492 commit a set of parameters for a service
493 ****************************************************************************/
494 static void commit_parameters(int snum)
497 struct parm_struct *parm;
501 while ((parm = lp_next_parameter(snum, &i, 1))) {
502 slprintf(label, sizeof(label)-1, "parm_%s", make_parm_name(parm->label));
503 if ((v = cgi_variable(label))) {
504 if (parm->flags & FLAG_HIDE) continue;
505 commit_parameter(snum, parm, v);
510 /****************************************************************************
511 spit out the html for a link with an image
512 ****************************************************************************/
513 static void image_link(const char *name, const char *hlink, const char *src)
515 printf("<A HREF=\"%s/%s\"><img border=\"0\" src=\"/swat/%s\" alt=\"%s\"></A>\n",
516 cgi_baseurl(), hlink, src, name);
519 /****************************************************************************
520 display the main navigation controls at the top of each page along
522 ****************************************************************************/
523 static void show_main_buttons(void)
527 if ((p = cgi_user_name()) && strcmp(p, "root")) {
528 printf(_("Logged in as <b>%s</b>"), p);
532 image_link(_("Home"), "", "images/home.gif");
533 if (have_write_access) {
534 image_link(_("Globals"), "globals", "images/globals.gif");
535 image_link(_("Shares"), "shares", "images/shares.gif");
536 image_link(_("Printers"), "printers", "images/printers.gif");
537 image_link(_("Wizard"), "wizard", "images/wizard.gif");
539 /* root always gets all buttons, otherwise look for -P */
540 if ( have_write_access || (!passwd_only && have_read_access) ) {
541 image_link(_("Status"), "status", "images/status.gif");
542 image_link(_("View Config"), "viewconfig", "images/viewconfig.gif");
544 image_link(_("Password Management"), "passwd", "images/passwd.gif");
549 /****************************************************************************
550 * Handle Display/Edit Mode CGI
551 ****************************************************************************/
552 static void ViewModeBoxes(int mode)
554 printf("<p>%s: \n", _("Current View Is"));
555 printf("<input type=radio name=\"ViewMode\" value=0 %s>%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
556 printf("<input type=radio name=\"ViewMode\" value=1 %s>%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
557 printf("<br>%s: \n", _("Change View To"));
558 printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
559 printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
560 printf("</p><br>\n");
563 /****************************************************************************
564 display a welcome page
565 ****************************************************************************/
566 static void welcome_page(void)
568 if (file_exist("help/welcome.html", NULL)) {
569 include_html("help/welcome.html");
571 include_html("help/welcome-no-samba-doc.html");
575 /****************************************************************************
576 display the current smb.conf
577 ****************************************************************************/
578 static void viewconfig_page(void)
582 if (cgi_variable("full_view")) {
586 printf("<H2>%s</H2>\n", _("Current Config"));
587 printf("<form method=post>\n");
590 printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
592 printf("<input type=submit name=\"full_view\" value=\"%s\">\n", _("Full View"));
596 write_config(stdout, full_view);
601 /****************************************************************************
602 second screen of the wizard ... Fetch Configuration Parameters
603 ****************************************************************************/
604 static void wizard_params_page(void)
606 unsigned int parm_filter = FLAG_WIZARD;
608 /* Here we first set and commit all the parameters that were selected
609 in the previous screen. */
611 printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
613 if (cgi_variable("Commit")) {
614 commit_parameters(GLOBAL_SECTION_SNUM);
618 printf("<form name=\"swatform\" method=post action=wizard_params>\n");
620 if (have_write_access) {
621 printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
624 printf("<input type=reset name=\"Reset Values\" value=\"Reset\">\n");
628 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
629 printf("</table>\n");
633 /****************************************************************************
634 Utility to just rewrite the smb.conf file - effectively just cleans it up
635 ****************************************************************************/
636 static void rewritecfg_file(void)
638 commit_parameters(GLOBAL_SECTION_SNUM);
640 printf("<H2>%s</H2>\n", _("Note: smb.conf file has been read and rewritten"));
643 /****************************************************************************
644 wizard to create/modify the smb.conf file
645 ****************************************************************************/
646 static void wizard_page(void)
648 /* Set some variables to collect data from smb.conf */
655 if (cgi_variable("Rewrite")) {
656 (void) rewritecfg_file();
660 if (cgi_variable("GetWizardParams")){
661 (void) wizard_params_page();
665 if (cgi_variable("Commit")){
666 SerType = atoi(cgi_variable("ServerType"));
667 winstype = atoi(cgi_variable("WINSType"));
668 have_home = lp_servicenumber(HOMES_NAME);
669 HomeExpo = atoi(cgi_variable("HomeExpo"));
671 /* Plain text passwords are too badly broken - use encrypted passwords only */
672 lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes");
676 /* Stand-alone Server */
677 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
678 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
682 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" );
683 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" );
686 /* Domain Controller */
687 lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" );
688 lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" );
691 switch ( winstype ) {
693 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
694 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
697 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" );
698 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" );
701 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" );
702 lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable("WINSAddr"));
706 /* Have to create Homes share? */
707 if ((HomeExpo == 1) && (have_home == -1)) {
710 pstrcpy(unix_share,HOMES_NAME);
712 lp_copy_service(GLOBAL_SECTION_SNUM, unix_share);
713 iNumNonAutoPrintServices = lp_numservices();
714 have_home = lp_servicenumber(HOMES_NAME);
715 lp_do_parameter( have_home, "read only", "No");
716 lp_do_parameter( have_home, "valid users", "%S");
717 lp_do_parameter( have_home, "browseable", "No");
718 commit_parameters(have_home);
721 /* Need to Delete Homes share? */
722 if ((HomeExpo == 0) && (have_home != -1)) {
723 lp_remove_service(have_home);
727 commit_parameters(GLOBAL_SECTION_SNUM);
732 /* Now determine smb.conf WINS settings */
733 if (lp_wins_support())
735 if (lp_wins_server_list() && strlen(*lp_wins_server_list()))
739 /* Do we have a homes share? */
740 have_home = lp_servicenumber(HOMES_NAME);
742 if ((winstype == 2) && lp_wins_support())
745 role = lp_server_role();
748 printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
749 printf("<form method=post action=wizard>\n");
751 if (have_write_access) {
752 printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
753 printf("%s", _("The same will happen if you press the commit button."));
754 printf("<br><br>\n");
756 printf("<input type=submit name=\"Rewrite\" value=\"%s\"> ",_("Rewrite smb.conf file"));
757 printf("<input type=submit name=\"Commit\" value=\"%s\"> ",_("Commit"));
758 printf("<input type=submit name=\"GetWizardParams\" value=\"%s\">", _("Edit Parameter Values"));
759 printf("</center>\n");
763 printf("<center><table border=0>");
764 printf("<tr><td><b>%s: </b></td>\n", _("Server Type"));
765 printf("<td><input type=radio name=\"ServerType\" value=\"0\" %s> %s </td>", ((role == ROLE_STANDALONE) ? "checked" : ""), _("Stand Alone"));
766 printf("<td><input type=radio name=\"ServerType\" value=\"1\" %s> %s </td>", ((role == ROLE_DOMAIN_MEMBER) ? "checked" : ""), _("Domain Member"));
767 printf("<td><input type=radio name=\"ServerType\" value=\"2\" %s> %s </td>", ((role == ROLE_DOMAIN_PDC) ? "checked" : ""), _("Domain Controller"));
769 if (role == ROLE_DOMAIN_BDC) {
770 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Unusual Type in smb.conf - Please Select New Mode"));
772 printf("<tr><td><b>%s: </b></td>\n", _("Configure WINS As"));
773 printf("<td><input type=radio name=\"WINSType\" value=\"0\" %s> %s </td>", ((winstype == 0) ? "checked" : ""), _("Not Used"));
774 printf("<td><input type=radio name=\"WINSType\" value=\"1\" %s> %s </td>", ((winstype == 1) ? "checked" : ""), _("Server for client use"));
775 printf("<td><input type=radio name=\"WINSType\" value=\"2\" %s> %s </td>", ((winstype == 2) ? "checked" : ""), _("Client of another WINS server"));
777 printf("<tr><td></td><td></td><td></td><td>%s <input type=text size=\"16\" name=\"WINSAddr\" value=\"", _("Remote WINS Server"));
779 /* Print out the list of wins servers */
780 if(lp_wins_server_list()) {
782 const char **wins_servers = lp_wins_server_list();
783 for(i = 0; wins_servers[i]; i++) printf("%s ", wins_servers[i]);
786 printf("\"></td></tr>\n");
788 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"));
789 printf("<tr><td></td><td colspan=3><font color=\"#ff0000\">%s</font></td></tr>\n", _("Please Select desired WINS mode above."));
791 printf("<tr><td><b>%s: </b></td>\n", _("Expose Home Directories"));
792 printf("<td><input type=radio name=\"HomeExpo\" value=\"1\" %s> Yes</td>", (have_home == -1) ? "" : "checked ");
793 printf("<td><input type=radio name=\"HomeExpo\" value=\"0\" %s> No</td>", (have_home == -1 ) ? "checked" : "");
794 printf("<td></td></tr>\n");
796 /* Enable this when we are ready ....
797 * printf("<tr><td><b>%s: </b></td>\n", _("Is Print Server"));
798 * printf("<td><input type=radio name=\"PtrSvr\" value=\"1\" %s> Yes</td>");
799 * printf("<td><input type=radio name=\"PtrSvr\" value=\"0\" %s> No</td>");
800 * printf("<td></td></tr>\n");
803 printf("</table></center>");
806 printf("%s\n", _("The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."));
811 /****************************************************************************
812 display a globals editing page
813 ****************************************************************************/
814 static void globals_page(void)
816 unsigned int parm_filter = FLAG_BASIC;
819 printf("<H2>%s</H2>\n", _("Global Parameters"));
821 if (cgi_variable("Commit")) {
822 commit_parameters(GLOBAL_SECTION_SNUM);
826 if ( cgi_variable("ViewMode") )
827 mode = atoi(cgi_variable("ViewMode"));
828 if ( cgi_variable("BasicMode"))
830 if ( cgi_variable("AdvMode"))
833 printf("<form name=\"swatform\" method=post action=globals>\n");
835 ViewModeBoxes( mode );
838 parm_filter = FLAG_BASIC;
841 parm_filter = FLAG_ADVANCED;
845 if (have_write_access) {
846 printf("<input type=submit name=\"Commit\" value=\"%s\">\n",
847 _("Commit Changes"));
850 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n",
855 show_parameters(GLOBAL_SECTION_SNUM, 1, parm_filter, 0);
856 printf("</table>\n");
860 /****************************************************************************
861 display a shares editing page. share is in unix codepage,
862 ****************************************************************************/
863 static void shares_page(void)
865 const char *share = cgi_variable("share");
871 unsigned int parm_filter = FLAG_BASIC;
874 snum = lp_servicenumber(share);
876 printf("<H2>%s</H2>\n", _("Share Parameters"));
878 if (cgi_variable("Commit") && snum >= 0) {
879 commit_parameters(snum);
883 if (cgi_variable("Delete") && snum >= 0) {
884 lp_remove_service(snum);
890 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
892 lp_copy_service(GLOBAL_SECTION_SNUM, share);
893 iNumNonAutoPrintServices = lp_numservices();
895 snum = lp_servicenumber(share);
898 printf("<FORM name=\"swatform\" method=post>\n");
902 if ( cgi_variable("ViewMode") )
903 mode = atoi(cgi_variable("ViewMode"));
904 if ( cgi_variable("BasicMode"))
906 if ( cgi_variable("AdvMode"))
909 ViewModeBoxes( mode );
912 parm_filter = FLAG_BASIC;
915 parm_filter = FLAG_ADVANCED;
918 printf("<br><tr>\n");
919 printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
920 printf("<td><select name=share>\n");
922 printf("<option value=\" \"> \n");
923 for (i=0;i<lp_numservices();i++) {
924 s = lp_servicename(i);
925 if (s && (*s) && strcmp(s,"IPC$") && !lp_print_ok(i)) {
926 push_utf8_allocate(&utf8_s, s);
927 printf("<option %s value=\"%s\">%s\n",
928 (share && strcmp(share,s)==0)?"SELECTED":"",
934 printf("</select></td>\n");
935 if (have_write_access) {
936 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Share"));
941 if (have_write_access) {
943 printf("<td><input type=submit name=createshare value=\"%s\"></td>\n", _("Create Share"));
944 printf("<td><input type=text size=30 name=newshare></td></tr>\n");
950 if (have_write_access) {
951 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
954 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
960 show_parameters(snum, 1, parm_filter, 0);
961 printf("</table>\n");
967 /*************************************************************
968 change a password either locally or remotely
969 *************************************************************/
970 static BOOL change_password(const char *remote_machine, const char *user_name,
971 const char *old_passwd, const char *new_passwd,
979 printf("%s\n<p>", _("password change in demo mode rejected"));
983 if (remote_machine != NULL) {
984 ret = remote_password_change(remote_machine, user_name, old_passwd,
985 new_passwd, err_str, sizeof(err_str));
987 printf("%s\n<p>", err_str);
988 return NT_STATUS_IS_OK(ret);
991 if(!initialize_password_db(True)) {
992 printf("%s\n<p>", _("Can't setup password database vectors."));
996 ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
997 msg_str, sizeof(msg_str));
1000 printf("%s\n<p>", msg_str);
1002 printf("%s\n<p>", err_str);
1004 return NT_STATUS_IS_OK(ret);
1007 /****************************************************************************
1008 do the stuff required to add or change a password
1009 ****************************************************************************/
1010 static void chg_passwd(void)
1014 int local_flags = 0;
1016 /* Make sure users name has been specified */
1017 if (strlen(cgi_variable(SWAT_USER)) == 0) {
1018 printf("<p>%s\n", _(" Must specify \"User Name\" "));
1023 * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
1024 * so if that's what we're doing, skip the rest of the checks
1026 if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
1029 * If current user is not root, make sure old password has been specified
1030 * If REMOTE change, even root must provide old password
1032 if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) ||
1033 ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(OLD_PSWD)) <= 0))) {
1034 printf("<p>%s\n", _(" Must specify \"Old Password\" "));
1038 /* If changing a users password on a remote hosts we have to know what host */
1039 if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) {
1040 printf("<p>%s\n", _(" Must specify \"Remote Machine\" "));
1044 /* Make sure new passwords have been specified */
1045 if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
1046 (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
1047 printf("<p>%s\n", _(" Must specify \"New, and Re-typed Passwords\" "));
1051 /* Make sure new passwords was typed correctly twice */
1052 if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
1053 printf("<p>%s\n", _(" Re-typed password didn't match new password "));
1058 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1059 host = cgi_variable(RHOST);
1060 } else if (am_root()) {
1067 * Set up the local flags.
1070 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
1071 local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0);
1072 local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0);
1073 local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
1074 local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
1075 local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
1078 rslt = change_password(host,
1079 cgi_variable(SWAT_USER),
1080 cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
1083 if(cgi_variable(CHG_S_PASSWD_FLAG)) {
1086 printf(_(" The passwd for '%s' has been changed."), cgi_variable(SWAT_USER));
1089 printf(_(" The passwd for '%s' has NOT been changed."), cgi_variable(SWAT_USER));
1097 /****************************************************************************
1098 display a password editing page
1099 ****************************************************************************/
1100 static void passwd_page(void)
1102 const char *new_name = cgi_user_name();
1105 * After the first time through here be nice. If the user
1106 * changed the User box text to another users name, remember it.
1108 if (cgi_variable(SWAT_USER)) {
1109 new_name = cgi_variable(SWAT_USER);
1112 if (!new_name) new_name = "";
1114 printf("<H2>%s</H2>\n", _("Server Password Management"));
1116 printf("<FORM name=\"swatform\" method=post>\n");
1118 printf("<table>\n");
1121 * Create all the dialog boxes for data collection
1123 printf("<tr><td> %s : </td>\n", _("User Name"));
1124 printf("<td><input type=text size=30 name=%s value=%s></td></tr> \n", SWAT_USER, new_name);
1126 printf("<tr><td> %s : </td>\n", _("Old Password"));
1127 printf("<td><input type=password size=30 name=%s></td></tr> \n",OLD_PSWD);
1129 printf("<tr><td> %s : </td>\n", _("New Password"));
1130 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1131 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1132 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1133 printf("</table>\n");
1136 * Create all the control buttons for requesting action
1138 printf("<input type=submit name=%s value=\"%s\">\n",
1139 CHG_S_PASSWD_FLAG, _("Change Password"));
1140 if (demo_mode || am_root()) {
1141 printf("<input type=submit name=%s value=\"%s\">\n",
1142 ADD_USER_FLAG, _("Add New User"));
1143 printf("<input type=submit name=%s value=\"%s\">\n",
1144 DELETE_USER_FLAG, _("Delete User"));
1145 printf("<input type=submit name=%s value=\"%s\">\n",
1146 DISABLE_USER_FLAG, _("Disable User"));
1147 printf("<input type=submit name=%s value=\"%s\">\n",
1148 ENABLE_USER_FLAG, _("Enable User"));
1150 printf("<p></FORM>\n");
1153 * Do some work if change, add, disable or enable was
1154 * requested. It could be this is the first time through this
1155 * code, so there isn't anything to do. */
1156 if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
1157 (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
1161 printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
1163 printf("<FORM name=\"swatform\" method=post>\n");
1165 printf("<table>\n");
1168 * Create all the dialog boxes for data collection
1170 printf("<tr><td> %s : </td>\n", _("User Name"));
1171 printf("<td><input type=text size=30 name=%s value=%s></td></tr>\n",SWAT_USER, new_name);
1172 printf("<tr><td> %s : </td>\n", _("Old Password"));
1173 printf("<td><input type=password size=30 name=%s></td></tr>\n",OLD_PSWD);
1174 printf("<tr><td> %s : </td>\n", _("New Password"));
1175 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW_PSWD);
1176 printf("<tr><td> %s : </td>\n", _("Re-type New Password"));
1177 printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
1178 printf("<tr><td> %s : </td>\n", _("Remote Machine"));
1179 printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
1184 * Create all the control buttons for requesting action
1186 printf("<input type=submit name=%s value=\"%s\">",
1187 CHG_R_PASSWD_FLAG, _("Change Password"));
1189 printf("<p></FORM>\n");
1192 * Do some work if a request has been made to change the
1193 * password somewhere other than the server. It could be this
1194 * is the first time through this code, so there isn't
1195 * anything to do. */
1196 if (cgi_variable(CHG_R_PASSWD_FLAG)) {
1202 /****************************************************************************
1203 display a printers editing page
1204 ****************************************************************************/
1205 static void printers_page(void)
1207 const char *share = cgi_variable("share");
1212 unsigned int parm_filter = FLAG_BASIC;
1215 snum = lp_servicenumber(share);
1217 printf("<H2>%s</H2>\n", _("Printer Parameters"));
1219 printf("<H3>%s</H3>\n", _("Important Note:"));
1220 printf(_("Printer names marked with [*] in the Choose Printer drop-down box "));
1221 printf(_("are autoloaded printers from "));
1222 printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
1223 printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
1225 if (cgi_variable("Commit") && snum >= 0) {
1226 commit_parameters(snum);
1227 if (snum >= iNumNonAutoPrintServices)
1233 if (cgi_variable("Delete") && snum >= 0) {
1234 lp_remove_service(snum);
1240 if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
1242 lp_copy_service(GLOBAL_SECTION_SNUM, share);
1243 iNumNonAutoPrintServices = lp_numservices();
1244 snum = lp_servicenumber(share);
1245 lp_do_parameter(snum, "print ok", "Yes");
1247 snum = lp_servicenumber(share);
1250 printf("<FORM name=\"swatform\" method=post>\n");
1252 if ( cgi_variable("ViewMode") )
1253 mode = atoi(cgi_variable("ViewMode"));
1254 if ( cgi_variable("BasicMode"))
1256 if ( cgi_variable("AdvMode"))
1259 ViewModeBoxes( mode );
1262 parm_filter = FLAG_BASIC;
1265 parm_filter = FLAG_ADVANCED;
1268 printf("<table>\n");
1269 printf("<tr><td><input type=submit name=\"selectshare\" value=\"%s\"></td>\n", _("Choose Printer"));
1270 printf("<td><select name=\"share\">\n");
1271 if (snum < 0 || !lp_print_ok(snum))
1272 printf("<option value=\" \"> \n");
1273 for (i=0;i<lp_numservices();i++) {
1274 s = lp_servicename(i);
1275 if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
1276 if (i >= iNumNonAutoPrintServices)
1277 printf("<option %s value=\"%s\">[*]%s\n",
1278 (share && strcmp(share,s)==0)?"SELECTED":"",
1281 printf("<option %s value=\"%s\">%s\n",
1282 (share && strcmp(share,s)==0)?"SELECTED":"",
1286 printf("</select></td>");
1287 if (have_write_access) {
1288 printf("<td><input type=submit name=\"Delete\" value=\"%s\"></td>\n", _("Delete Printer"));
1291 printf("</table>\n");
1293 if (have_write_access) {
1294 printf("<table>\n");
1295 printf("<tr><td><input type=submit name=\"createshare\" value=\"%s\"></td>\n", _("Create Printer"));
1296 printf("<td><input type=text size=30 name=\"newshare\"></td></tr>\n");
1302 if (have_write_access) {
1303 printf("<input type=submit name=\"Commit\" value=\"%s\">\n", _("Commit Changes"));
1305 printf("<input type=reset name=\"Reset Values\" value=\"%s\">\n", _("Reset Values"));
1310 printf("<table>\n");
1311 show_parameters(snum, 1, parm_filter, 1);
1312 printf("</table>\n");
1314 printf("</FORM>\n");
1319 * main function for SWAT.
1321 int main(int argc, char *argv[])
1325 struct poptOption long_options[] = {
1327 { "disable-authentication", 'a', POPT_ARG_VAL, &demo_mode, True, "Disable authentication (demo mode)" },
1328 { "password-menu-only", 'P', POPT_ARG_VAL, &passwd_only, True, "Show only change password menu" },
1334 umask(S_IWGRP | S_IWOTH);
1336 #if defined(HAVE_SET_AUTH_PARAMETERS)
1337 set_auth_parameters(argc, argv);
1338 #endif /* HAVE_SET_AUTH_PARAMETERS */
1340 /* just in case it goes wild ... */
1345 /* we don't want any SIGPIPE messages */
1346 BlockSignals(True,SIGPIPE);
1348 dbf = x_fopen("/dev/null", O_WRONLY, 0);
1349 if (!dbf) dbf = x_stderr;
1351 /* we don't want stderr screwing us up */
1353 open("/dev/null", O_WRONLY);
1355 pc = poptGetContext("swat", argc, (const char **) argv, long_options, 0);
1357 /* Parse command line options */
1359 while(poptGetNextOpt(pc) != -1) { }
1361 poptFreeContext(pc);
1363 setup_logging(argv[0],False);
1366 iNumNonAutoPrintServices = lp_numservices();
1369 cgi_setup(dyn_SWATDIR, !demo_mode);
1373 cgi_load_variables();
1375 if (!file_exist(dyn_CONFIGFILE, NULL)) {
1376 have_read_access = True;
1377 have_write_access = True;
1379 /* check if the authenticated user has write access - if not then
1380 don't show write options */
1381 have_write_access = (access(dyn_CONFIGFILE,W_OK) == 0);
1383 /* if the user doesn't have read access to smb.conf then
1384 don't let them view it */
1385 have_read_access = (access(dyn_CONFIGFILE,R_OK) == 0);
1388 show_main_buttons();
1390 page = cgi_pathinfo();
1392 /* Root gets full functionality */
1393 if (have_read_access && strcmp(page, "globals")==0) {
1395 } else if (have_read_access && strcmp(page,"shares")==0) {
1397 } else if (have_read_access && strcmp(page,"printers")==0) {
1399 } else if (have_read_access && strcmp(page,"status")==0) {
1401 } else if (have_read_access && strcmp(page,"viewconfig")==0) {
1403 } else if (strcmp(page,"passwd")==0) {
1405 } else if (have_read_access && strcmp(page,"wizard")==0) {
1407 } else if (have_read_access && strcmp(page,"wizard_params")==0) {
1408 wizard_params_page();
1409 } else if (have_read_access && strcmp(page,"rewritecfg")==0) {