/* Unix SMB/CIFS implementation. Samba Web Administration Tool Version 3.0.0 Copyright (C) Andrew Tridgell 1997-2002 Copyright (C) John H Terpstra 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /** * @defgroup swat SWAT - Samba Web Administration Tool * @{ * @file swat.c * * @brief Samba Web Administration Tool. **/ #include "includes.h" #include "web/swat_proto.h" static BOOL demo_mode = False; static BOOL passwd_only = False; static BOOL have_write_access = False; static BOOL have_read_access = False; static int iNumNonAutoPrintServices = 0; /* * Password Management Globals */ #define SWAT_USER "username" #define OLD_PSWD "old_passwd" #define NEW_PSWD "new_passwd" #define NEW2_PSWD "new2_passwd" #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag" #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag" #define ADD_USER_FLAG "add_user_flag" #define DELETE_USER_FLAG "delete_user_flag" #define DISABLE_USER_FLAG "disable_user_flag" #define ENABLE_USER_FLAG "enable_user_flag" #define RHOST "remote_host" /**************************************************************************** ****************************************************************************/ static int enum_index(int value, const struct enum_list *enumlist) { int i; for (i=0;enumlist[i].name;i++) if (value == enumlist[i].value) break; return(i); } static char *fix_backslash(const char *str) { static char newstring[1024]; char *p = newstring; while (*str) { if (*str == '\\') {*p++ = '\\';*p++ = '\\';} else *p++ = *str; ++str; } *p = '\0'; return newstring; } static char *fix_quotes(const char *str) { static pstring newstring; char *p = newstring; size_t newstring_len = sizeof(newstring); int quote_len = strlen("""); while (*str) { if ( *str == '\"' && (newstring_len - PTR_DIFF(p, newstring) - 1) > quote_len ) { strncpy( p, """, quote_len); p += quote_len; } else { *p++ = *str; } ++str; } *p = '\0'; return newstring; } static char *stripspaceupper(const char *str) { static char newstring[1024]; char *p = newstring; while (*str) { if (*str != ' ') *p++ = toupper(*str); ++str; } *p = '\0'; return newstring; } static char *make_parm_name(const char *label) { static char parmname[1024]; char *p = parmname; while (*label) { if (*label == ' ') *p++ = '_'; else *p++ = *label; ++label; } *p = '\0'; return parmname; } /**************************************************************************** include a lump of html in a page ****************************************************************************/ static int include_html(const char *fname) { int fd; char buf[1024]; int ret; fd = web_open(fname, O_RDONLY, 0); if (fd == -1) { printf(_("ERROR: Can't open %s"), fname); printf("\n"); return 0; } while ((ret = read(fd, buf, sizeof(buf))) > 0) { write(1, buf, ret); } close(fd); return 1; } /**************************************************************************** start the page with standard stuff ****************************************************************************/ static void print_header(void) { if (!cgi_waspost()) { printf("Expires: 0\r\n"); } printf("Content-type: text/html\r\n\r\n"); if (!include_html("include/header.html")) { printf("\n"); printf("\n
\n\n"); } } /**************************************************************************** * Handle Display/Edit Mode CGI ****************************************************************************/ static void ViewModeBoxes(int mode) { printf("
%s: \n", _("Current View Is"));
printf("%s\n", ((mode == 0) ? "checked" : ""), _("Basic"));
printf("%s\n", ((mode == 1) ? "checked" : ""), _("Advanced"));
printf("
%s: \n", _("Change View To"));
printf("\n", _("Basic"));
printf("\n", _("Advanced"));
printf("
Follow the links below to edit service-level parameters for file and printer shares.
\n"); printf("Shares may also be added via the links above.
\n"); printf("%s
\n", _("Note: smb.conf file has been read and rewritten")); printf("Return to the previous page.\n"); } /**************************************************************************** wizard to create/modify the smb.conf file ****************************************************************************/ static void wizard_page(void) { /* Set some variables to collect data from smb.conf */ int role = 0; int winstype = 0; int have_home = -1; int HomeExpo = 0; int SerType = 0; if (cgi_variable("Rewrite")) { (void) rewritecfg_file(); return; } if (cgi_variable("GetWizardParams")){ (void) wizard_params_page(); return; } if (cgi_variable("Commit")){ SerType = atoi(cgi_variable("ServerType")); winstype = atoi(cgi_variable("WINSType")); have_home = lp_servicenumber(HOMES_NAME); HomeExpo = atoi(cgi_variable("HomeExpo")); /* Plain text passwords are too badly broken - use encrypted passwords only */ lp_do_parameter( GLOBAL_SECTION_SNUM, "encrypt passwords", "Yes"); switch ( SerType ){ case 0: /* Stand-alone Server */ lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" ); lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" ); break; case 1: /* Domain Member */ lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "DOMAIN" ); lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "No" ); break; case 2: /* Domain Controller */ lp_do_parameter( GLOBAL_SECTION_SNUM, "security", "USER" ); lp_do_parameter( GLOBAL_SECTION_SNUM, "domain logons", "Yes" ); break; } switch ( winstype ) { case 0: lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" ); lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" ); break; case 1: lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "Yes" ); lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", "" ); break; case 2: lp_do_parameter( GLOBAL_SECTION_SNUM, "wins support", "No" ); lp_do_parameter( GLOBAL_SECTION_SNUM, "wins server", cgi_variable("WINSAddr")); break; } /* Have to create Homes share? */ if ((HomeExpo == 1) && (have_home == -1)) { pstring unix_share; pstrcpy(unix_share,HOMES_NAME); load_config(False); lp_copy_service(GLOBAL_SECTION_SNUM, unix_share); iNumNonAutoPrintServices = lp_numservices(); have_home = lp_servicenumber(HOMES_NAME); lp_do_parameter( have_home, "read only", "No"); lp_do_parameter( have_home, "valid users", "%S"); lp_do_parameter( have_home, "browseable", "No"); commit_parameters(have_home); } /* Need to Delete Homes share? */ if ((HomeExpo == 0) && (have_home != -1)) { lp_remove_service(have_home); have_home = -1; } commit_parameters(GLOBAL_SECTION_SNUM); save_reload(0); } else { /* Now determine smb.conf WINS settings */ if (lp_wins_support()) winstype = 1; if (lp_wins_server_list() && strlen(*lp_wins_server_list())) winstype = 2; /* Do we have a homes share? */ have_home = lp_servicenumber(HOMES_NAME); } if ((winstype == 2) && lp_wins_support()) winstype = 3; role = lp_server_role(); /* Here we go ... */ printf("
The following menu allows for editing of global parameters affecting your Samba configuration.
\n"); printf("", _("password change in demo mode rejected")); return False; } if (remote_machine != NULL) { ret = remote_password_change(remote_machine, user_name, old_passwd, new_passwd, err_str, sizeof(err_str)); if(*err_str) printf("%s\n
", err_str); return ret; } if(!initialize_password_db(True)) { printf("%s\n
", _("Can't setup password database vectors.")); return False; } ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str), msg_str, sizeof(msg_str)); if(*msg_str) printf("%s\n
", msg_str); if(*err_str) printf("%s\n
", err_str); return ret; } /**************************************************************************** do the stuff required to add or change a password ****************************************************************************/ static void chg_passwd(void) { const char *host; BOOL rslt; int local_flags = 0; /* Make sure users name has been specified */ if (strlen(cgi_variable(SWAT_USER)) == 0) { printf("
%s\n", _(" Must specify \"User Name\" ")); return; } /* * smbpasswd doesn't require anything but the users name to delete, disable or enable the user, * so if that's what we're doing, skip the rest of the checks */ if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) { /* * If current user is not root, make sure old password has been specified * If REMOTE change, even root must provide old password */ if (((!am_root()) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) || ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(OLD_PSWD)) <= 0))) { printf("
%s\n", _(" Must specify \"Old Password\" ")); return; } /* If changing a users password on a remote hosts we have to know what host */ if ((cgi_variable(CHG_R_PASSWD_FLAG)) && (strlen( cgi_variable(RHOST)) <= 0)) { printf("
%s\n", _(" Must specify \"Remote Machine\" ")); return; } /* Make sure new passwords have been specified */ if ((strlen( cgi_variable(NEW_PSWD)) <= 0) || (strlen( cgi_variable(NEW2_PSWD)) <= 0)) { printf("
%s\n", _(" Must specify \"New, and Re-typed Passwords\" ")); return; } /* Make sure new passwords was typed correctly twice */ if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) { printf("
%s\n", _(" Re-typed password didn't match new password ")); return; } } if (cgi_variable(CHG_R_PASSWD_FLAG)) { host = cgi_variable(RHOST); } else if (am_root()) { host = NULL; } else { host = "127.0.0.1"; } /* * Set up the local flags. */ local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0); local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_SET_PASSWORD : 0); local_flags |= (cgi_variable(CHG_S_PASSWD_FLAG) ? LOCAL_SET_PASSWORD : 0); local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0); local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0); local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0); rslt = change_password(host, cgi_variable(SWAT_USER), cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD), local_flags); if(cgi_variable(CHG_S_PASSWD_FLAG)) { printf("
"); if (rslt == True) { printf(_(" The passwd for '%s' has been changed."), cgi_variable(SWAT_USER)); printf("\n"); } else { printf(_(" The passwd for '%s' has NOT been changed."), cgi_variable(SWAT_USER)); printf("\n"); } } return; } /**************************************************************************** display a password editing page ****************************************************************************/ static void passwd_page(void) { const char *new_name = cgi_user_name(); /* * After the first time through here be nice. If the user * changed the User box text to another users name, remember it. */ if (cgi_variable(SWAT_USER)) { new_name = cgi_variable(SWAT_USER); } if (!new_name) new_name = ""; printf("