diff options
author | Andrew Tridgell <tridge@samba.org> | 1998-11-12 07:06:48 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 1998-11-12 07:06:48 +0000 |
commit | 29e36b713468d7e7de301c483fc340ef42b4a9fb (patch) | |
tree | fd97dcedea842356595ce290c2fb1f95d8448285 | |
parent | 4f368d8b924b76007809e967ac1f37f6a1ebdd68 (diff) | |
download | samba-29e36b713468d7e7de301c483fc340ef42b4a9fb.tar.gz samba-29e36b713468d7e7de301c483fc340ef42b4a9fb.tar.bz2 samba-29e36b713468d7e7de301c483fc340ef42b4a9fb.zip |
extracted the password change code from smbpasswd and used it in swat
instead of opening pipes and other horrible stuff.
(This used to be commit 49bf19710345a59a2d17cd449be1a132885ed821)
-rw-r--r-- | source3/Makefile.in | 5 | ||||
-rw-r--r-- | source3/include/proto.h | 11 | ||||
-rw-r--r-- | source3/lib/util.c | 53 | ||||
-rw-r--r-- | source3/libsmb/passchange.c | 100 | ||||
-rw-r--r-- | source3/passdb/smbpasschange.c | 162 | ||||
-rw-r--r-- | source3/smbd/uid.c | 2 | ||||
-rw-r--r-- | source3/utils/smbpasswd.c | 218 | ||||
-rw-r--r-- | source3/web/swat.c | 353 |
8 files changed, 385 insertions, 519 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index dcabf917d0..4dde76a60c 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -103,7 +103,8 @@ PARAM_OBJ = param/loadparm.o param/params.o LIBSMB_OBJ = libsmb/clientgen.o libsmb/namequery.o libsmb/nmblib.o \ libsmb/nterr.o libsmb/smbdes.o libsmb/smbencrypt.o \ - libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o + libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \ + libsmb/passchange.o RPC_SERVER_OBJ = rpc_server/srv_lsa.o \ rpc_server/srv_lsa_hnd.o rpc_server/srv_netlog.o \ @@ -132,7 +133,7 @@ LOCKING_OBJ = locking/locking.o locking/locking_shm.o locking/locking_slow.o \ locking/shmem.o locking/shmem_sysv.o PASSDB_OBJ = passdb/passdb.o passdb/smbpassfile.o passdb/smbpass.o \ - passdb/pass_check.o passdb/ldap.o passdb/nispass.o + passdb/pass_check.o passdb/ldap.o passdb/nispass.o passdb/smbpasschange.o SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \ smbd/dfree.o smbd/dir.o smbd/password.o smbd/conn.o smbd/fileio.o \ diff --git a/source3/include/proto.h b/source3/include/proto.h index 888e2af33f..2580491976 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -507,6 +507,11 @@ void sort_query_replies(char *data, int n, struct in_addr ip); char *get_nt_error_msg(uint32 nt_code); +/*The following definitions come from libsmb/passchange.c */ + +BOOL remote_password_change(const char *remote_machine, const char *user_name, + const char *old_passwd, const char *new_passwd); + /*The following definitions come from libsmb/pwd_cache.c */ void pwd_init(struct pwd_info *pwd); @@ -1212,6 +1217,12 @@ BOOL pdb_rid_is_user(uint32 rid); struct passdb_ops *file_initialize_password_db(void); +/*The following definitions come from passdb/smbpasschange.c */ + +BOOL local_password_change(char *user_name, BOOL trust_account, BOOL add_user, + BOOL enable_user, BOOL disable_user, BOOL set_no_password, + char *new_passwd); + /*The following definitions come from passdb/smbpassfile.c */ BOOL pw_file_lock(int fd, int type, int secs, int *plock_depth); diff --git a/source3/lib/util.c b/source3/lib/util.c index 2be1fcaf6f..1710205f3c 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -3095,3 +3095,56 @@ BOOL reg_split_key(char *full_keyname, uint32 *reg_type, char *key_name) return True; } + +/**************************************************************************** + become the specified uid - permanently ! +****************************************************************************/ +BOOL become_user_permanently(uid_t uid, gid_t gid) +{ + /* now completely lose our privilages. This is a fairly paranoid + way of doing it, but it does work on all systems that I know of */ + +#ifdef HAVE_SETRESUID + /* + * Firstly ensure all our uids are set to root. + */ + setresgid(0,0,0); + setresuid(0,0,0); + + /* + * Now ensure we change all our gids. + */ + setresgid(gid,gid,gid); + + /* + * Now ensure all the uids are the user. + */ + setresuid(uid,uid,uid); +#else + /* + * Firstly ensure all our uids are set to root. + */ + setuid(0); + seteuid(0); + + /* + * Now ensure we change all our gids. + */ + setgid(gid); + setegid(gid); + + /* + * Now ensure all the uids are the user. + */ + setuid(uid); + seteuid(uid); +#endif + + if (getuid() != uid || geteuid() != uid || + getgid() != gid || getegid() != gid) { + /* We failed to lose our privilages. */ + return False; + } + + return(True); +} diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c new file mode 100644 index 0000000000..7d89cbd3d7 --- /dev/null +++ b/source3/libsmb/passchange.c @@ -0,0 +1,100 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + SMB client password change routine + Copyright (C) Andrew Tridgell 1994-1998 + + 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. +*/ + +#include "includes.h" + + +extern pstring global_myname; +extern pstring scope; + +/************************************************************* +change a password on a remote machine using IPC calls +*************************************************************/ +BOOL remote_password_change(const char *remote_machine, const char *user_name, + const char *old_passwd, const char *new_passwd) +{ + struct nmb_name calling, called; + struct cli_state cli; + struct in_addr ip; + + if(!resolve_name( remote_machine, &ip, 0x20)) { + fprintf(stderr, "unable to find an IP address for machine %s.\n", + remote_machine ); + return False; + } + + ZERO_STRUCT(cli); + + if (!cli_initialise(&cli) || !cli_connect(&cli, remote_machine, &ip)) { + fprintf(stderr, "unable to connect to SMB server on machine %s. Error was : %s.\n", + remote_machine, cli_errstr(&cli) ); + return False; + } + + make_nmb_name(&calling, global_myname , 0x0 , scope); + make_nmb_name(&called , remote_machine, 0x20, scope); + + if (!cli_session_request(&cli, &calling, &called)) { + fprintf(stderr, "machine %s rejected the session setup. Error was : %s.\n", + remote_machine, cli_errstr(&cli) ); + cli_shutdown(&cli); + return False; + } + + cli.protocol = PROTOCOL_NT1; + + if (!cli_negprot(&cli)) { + fprintf(stderr, "machine %s rejected the negotiate protocol. Error was : %s.\n", + remote_machine, cli_errstr(&cli) ); + cli_shutdown(&cli); + return False; + } + + /* + * We should connect as the anonymous user here, in case + * the server has "must change password" checked... + * Thanks to <Nicholas.S.Jenkins@cdc.com> for this fix. + */ + + if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) { + fprintf(stderr, "machine %s rejected the session setup. Error was : %s.\n", + remote_machine, cli_errstr(&cli) ); + cli_shutdown(&cli); + return False; + } + + if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { + fprintf(stderr, "machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", + remote_machine, cli_errstr(&cli) ); + cli_shutdown(&cli); + return False; + } + + if(!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { + fprintf(stderr, "machine %s rejected the password change: Error was : %s.\n", + remote_machine, cli_errstr(&cli) ); + cli_shutdown(&cli); + return False; + } + + cli_shutdown(&cli); + return True; +} diff --git a/source3/passdb/smbpasschange.c b/source3/passdb/smbpasschange.c new file mode 100644 index 0000000000..4e2813316e --- /dev/null +++ b/source3/passdb/smbpasschange.c @@ -0,0 +1,162 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + change a password in a local smbpasswd file + Copyright (C) Andrew Tridgell 1998 + + 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. +*/ + +#include "includes.h" + + +/************************************************************* +add a new user to the local smbpasswd file +*************************************************************/ +static BOOL add_new_user(char *user_name, uid_t uid, BOOL trust_account, + BOOL disable_user, BOOL set_no_password, + uchar *new_p16, uchar *new_nt_p16) +{ + struct smb_passwd new_smb_pwent; + + /* Create a new smb passwd entry and set it to the given password. */ + new_smb_pwent.smb_userid = uid; + new_smb_pwent.smb_name = user_name; + new_smb_pwent.smb_passwd = NULL; + new_smb_pwent.smb_nt_passwd = NULL; + new_smb_pwent.acct_ctrl = (trust_account ? ACB_WSTRUST : ACB_NORMAL); + + if(disable_user) { + new_smb_pwent.acct_ctrl |= ACB_DISABLED; + } else if (set_no_password) { + new_smb_pwent.acct_ctrl |= ACB_PWNOTREQ; + } else { + new_smb_pwent.smb_passwd = new_p16; + new_smb_pwent.smb_nt_passwd = new_nt_p16; + } + + return add_smbpwd_entry(&new_smb_pwent); +} + + +/************************************************************* +change a password entry in the local smbpasswd file +*************************************************************/ +BOOL local_password_change(char *user_name, BOOL trust_account, BOOL add_user, + BOOL enable_user, BOOL disable_user, BOOL set_no_password, + char *new_passwd) +{ + struct passwd *pwd; + void *vp; + struct smb_passwd *smb_pwent; + uchar new_p16[16]; + uchar new_nt_p16[16]; + + pwd = getpwnam(user_name); + + /* + * Check for a machine account. + */ + + if(trust_account && !pwd) { + fprintf(stderr, "User %s does not exist in system password file (usually /etc/passwd). Cannot add machine account without a valid system user.\n", + user_name); + return False; + } + + /* Calculate the MD4 hash (NT compatible) of the new password. */ + nt_lm_owf_gen(new_passwd, new_nt_p16, new_p16); + + /* + * Open the smbpaswd file. + */ + vp = startsmbpwent(True); + if (!vp && errno == ENOENT) { + FILE *fp; + fprintf(stderr,"smbpasswd file did not exist - attempting to create it.\n"); + fp = fopen(lp_smb_passwd_file(), "w"); + if (fp) { + fprintf(fp, "# Samba SMB password file\n"); + fclose(fp); + vp = startsmbpwent(True); + } + } + + if (!vp) { + perror(lp_smb_passwd_file()); + return False; + } + + /* Get the smb passwd entry for this user */ + smb_pwent = getsmbpwnam(user_name); + if (smb_pwent == NULL) { + if(add_user == False) { + fprintf(stderr, "Failed to find entry for user %s.\n", + pwd->pw_name); + endsmbpwent(vp); + return False; + } + + if (add_new_user(user_name, pwd->pw_uid, trust_account, disable_user, + set_no_password, new_p16, new_nt_p16)) { + printf("Added user %s.\n", user_name); + endsmbpwent(vp); + return True; + } else { + fprintf(stderr, "Failed to add entry for user %s.\n", user_name); + endsmbpwent(vp); + return False; + } + } else { + /* the entry already existed */ + add_user = False; + } + + /* + * We are root - just write the new password + * and the valid last change time. + */ + + if(disable_user) { + smb_pwent->acct_ctrl |= ACB_DISABLED; + } else if (enable_user) { + if(smb_pwent->smb_passwd == NULL) { + smb_pwent->smb_passwd = new_p16; + smb_pwent->smb_nt_passwd = new_nt_p16; + } + smb_pwent->acct_ctrl &= ~ACB_DISABLED; + } else if (set_no_password) { + smb_pwent->acct_ctrl |= ACB_PWNOTREQ; + /* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */ + smb_pwent->smb_passwd = NULL; + smb_pwent->smb_nt_passwd = NULL; + } else { + smb_pwent->acct_ctrl &= ~ACB_PWNOTREQ; + smb_pwent->smb_passwd = new_p16; + smb_pwent->smb_nt_passwd = new_nt_p16; + } + + if(mod_smbpwd_entry(smb_pwent,True) == False) { + fprintf(stderr, "Failed to modify entry for user %s.\n", + pwd->pw_name); + endsmbpwent(vp); + return False; + } + + endsmbpwent(vp); + + return True; +} + diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 7cd8c8673c..7c951b461a 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -421,3 +421,5 @@ void unbecome_root(BOOL restore_dir) become_root_depth = 0; } + + diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index da7caacb11..2303bc56df 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/utils/smbpasswd.c @@ -19,10 +19,8 @@ #include "includes.h" -extern pstring scope; extern pstring myhostname; extern pstring global_myname; -extern fstring global_myworkgroup; extern int DEBUGLEVEL; @@ -213,222 +211,6 @@ static char *prompt_for_new_password(BOOL stdin_get) } - - -/************************************************************* -change a password on a remote machine using IPC calls -*************************************************************/ -static BOOL remote_password_change(const char *remote_machine, const char *user_name, - const char *old_passwd, const char *new_passwd) -{ - struct nmb_name calling, called; - struct cli_state cli; - struct in_addr ip; - - if(!resolve_name( remote_machine, &ip, 0x20)) { - fprintf(stderr, "unable to find an IP address for machine %s.\n", - remote_machine ); - return False; - } - - ZERO_STRUCT(cli); - - if (!cli_initialise(&cli) || !cli_connect(&cli, remote_machine, &ip)) { - fprintf(stderr, "unable to connect to SMB server on machine %s. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - return False; - } - - make_nmb_name(&calling, global_myname , 0x0 , scope); - make_nmb_name(&called , remote_machine, 0x20, scope); - - if (!cli_session_request(&cli, &calling, &called)) { - fprintf(stderr, "machine %s rejected the session setup. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - cli_shutdown(&cli); - return False; - } - - cli.protocol = PROTOCOL_NT1; - - if (!cli_negprot(&cli)) { - fprintf(stderr, "machine %s rejected the negotiate protocol. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - cli_shutdown(&cli); - return False; - } - - /* - * We should connect as the anonymous user here, in case - * the server has "must change password" checked... - * Thanks to <Nicholas.S.Jenkins@cdc.com> for this fix. - */ - - if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) { - fprintf(stderr, "machine %s rejected the session setup. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - cli_shutdown(&cli); - return False; - } - - if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { - fprintf(stderr, "machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - cli_shutdown(&cli); - return False; - } - - if(!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { - fprintf(stderr, "machine %s rejected the password change: Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - cli_shutdown(&cli); - return False; - } - - cli_shutdown(&cli); - return True; -} - - -/************************************************************* -add a new user to the local smbpasswd file -*************************************************************/ -static BOOL add_new_user(char *user_name, uid_t uid, BOOL trust_account, - BOOL disable_user, BOOL set_no_password, - uchar *new_p16, uchar *new_nt_p16) -{ - struct smb_passwd new_smb_pwent; - - /* Create a new smb passwd entry and set it to the given password. */ - new_smb_pwent.smb_userid = uid; - new_smb_pwent.smb_name = user_name; - new_smb_pwent.smb_passwd = NULL; - new_smb_pwent.smb_nt_passwd = NULL; - new_smb_pwent.acct_ctrl = (trust_account ? ACB_WSTRUST : ACB_NORMAL); - - if(disable_user) { - new_smb_pwent.acct_ctrl |= ACB_DISABLED; - } else if (set_no_password) { - new_smb_pwent.acct_ctrl |= ACB_PWNOTREQ; - } else { - new_smb_pwent.smb_passwd = new_p16; - new_smb_pwent.smb_nt_passwd = new_nt_p16; - } - - return add_smbpwd_entry(&new_smb_pwent); -} - - -/************************************************************* -change a password entry in the local smbpasswd file -*************************************************************/ -static BOOL local_password_change(char *user_name, BOOL trust_account, BOOL add_user, - BOOL enable_user, BOOL disable_user, BOOL set_no_password, - char *new_passwd) -{ - struct passwd *pwd; - void *vp; - struct smb_passwd *smb_pwent; - uchar new_p16[16]; - uchar new_nt_p16[16]; - - pwd = getpwnam(user_name); - - /* - * Check for a machine account. - */ - - if(trust_account && !pwd) { - fprintf(stderr, "User %s does not exist in system password file (usually /etc/passwd). Cannot add machine account without a valid system user.\n", - user_name); - return False; - } - - /* Calculate the MD4 hash (NT compatible) of the new password. */ - nt_lm_owf_gen(new_passwd, new_nt_p16, new_p16); - - /* - * Open the smbpaswd file. - */ - vp = startsmbpwent(True); - if (!vp && errno == ENOENT) { - FILE *fp; - fprintf(stderr,"smbpasswd file did not exist - attempting to create it.\n"); - fp = fopen(lp_smb_passwd_file(), "w"); - if (fp) { - fprintf(fp, "# Samba SMB password file\n"); - fclose(fp); - vp = startsmbpwent(True); - } - } - - if (!vp) { - perror(lp_smb_passwd_file()); - return False; - } - - /* Get the smb passwd entry for this user */ - smb_pwent = getsmbpwnam(user_name); - if (smb_pwent == NULL) { - if(add_user == False) { - fprintf(stderr, "Failed to find entry for user %s.\n", - pwd->pw_name); - endsmbpwent(vp); - return False; - } - - if (add_new_user(user_name, pwd->pw_uid, trust_account, disable_user, - set_no_password, new_p16, new_nt_p16)) { - printf("Added user %s.\n", user_name); - endsmbpwent(vp); - return True; - } else { - fprintf(stderr, "Failed to add entry for user %s.\n", user_name); - endsmbpwent(vp); - return False; - } - } else { - /* the entry already existed */ - add_user = False; - } - - /* - * We are root - just write the new password - * and the valid last change time. - */ - - if(disable_user) { - smb_pwent->acct_ctrl |= ACB_DISABLED; - } else if (enable_user) { - if(smb_pwent->smb_passwd == NULL) { - smb_pwent->smb_passwd = new_p16; - smb_pwent->smb_nt_passwd = new_nt_p16; - } - smb_pwent->acct_ctrl &= ~ACB_DISABLED; - } else if (set_no_password) { - smb_pwent->acct_ctrl |= ACB_PWNOTREQ; - /* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */ - smb_pwent->smb_passwd = NULL; - smb_pwent->smb_nt_passwd = NULL; - } else { - smb_pwent->acct_ctrl &= ~ACB_PWNOTREQ; - smb_pwent->smb_passwd = new_p16; - smb_pwent->smb_nt_passwd = new_nt_p16; - } - - if(mod_smbpwd_entry(smb_pwent,True) == False) { - fprintf(stderr, "Failed to modify entry for user %s.\n", - pwd->pw_name); - endsmbpwent(vp); - return False; - } - - endsmbpwent(vp); - - return True; -} - - /************************************************************* change a password either locally or remotely *************************************************************/ diff --git a/source3/web/swat.c b/source3/web/swat.c index 1ab90a3a3d..67582bc116 100644 --- a/source3/web/swat.c +++ b/source3/web/swat.c @@ -33,20 +33,18 @@ static pstring servicesf = CONFIGFILE; /* * Password Management Globals */ -char user[] = "username"; -char old_pswd[] = "old_passwd"; -char new_pswd[] = "new_passwd"; -char new2_pswd[] = "new2_passwd"; -char chg_passwd_flag[] = "chg_passwd_flag"; -char add_user_flag[] = "add_user_flag"; -char disable_user_flag[] = "disable_user_flag"; -char enable_user_flag[] = "enable_user_flag"; +#define USER "username" +#define OLD_PSWD "old_passwd" +#define NEW_PSWD "new_passwd" +#define NEW2_PSWD "new2_passwd" +#define CHG_PASSWD_FLAG "chg_passwd_flag" +#define ADD_USER_FLAG "add_user_flag" +#define DISABLE_USER_FLAG "disable_user_flag" +#define ENABLE_USER_FLAG "enable_user_flag" /* we need these because we link to locking*.o */ void become_root(BOOL save_dir) {} void unbecome_root(BOOL restore_dir) {} -/* We need this because we link to password.o */ -BOOL change_oem_password(struct smb_passwd *smbpw, char *new_passwd, BOOL override) {return False;} /**************************************************************************** ****************************************************************************/ @@ -87,8 +85,8 @@ char *p = newstring; static char *make_parm_name(char *label) { -static char parmname[1024]; -char *p = parmname; + static char parmname[1024]; + char *p = parmname; while (*label) { if (*label == ' ') *p++ = '_'; @@ -576,257 +574,24 @@ static void shares_page(void) printf("</FORM>\n"); } -/**************************************************************************** -****************************************************************************/ -static void sig_pipe ( int signo) +/************************************************************* +change a password either locally or remotely +*************************************************************/ +static BOOL change_password(const char *remote_machine, char *user_name, + char *old_passwd, char *new_passwd, + BOOL add_user, BOOL enable_user, BOOL disable_user) { - printf("<p> SIGPIPE caught\n"); -} - -/**************************************************************************** - create 2 pipes and use them to feed the smbpasswd program -****************************************************************************/ -static BOOL talk_to_smbpasswd(char *old, char *new) -{ - int i, n, fd1[2], fd2[2]; - pid_t pid; - BOOL rslt; - char line[MAX_STRINGLEN + 2]; /* one for newline, one for null */ - - if (signal(SIGPIPE, sig_pipe) == SIG_ERR) { - printf("<p> signal error"); + if (remote_machine != NULL) { + return remote_password_change(remote_machine, user_name, old_passwd, new_passwd); } - if ((pipe(fd1) < 0) || (pipe(fd2) < 0)) { - printf("<p> pipe error"); + if(!initialize_password_db()) { + printf("Can't setup password database vectors.\n"); + return False; } - - if ((pid = fork()) < 0) { - printf("<p> fork error"); - } - - /* - * Create this relationship with the pipes between the parent and - * the child as detailed below. - * - * parent -> fd1[1] -- fd1[0] -> child - * parent <- fd2[0] -- fd2[1] <- child - * - * fd1[0] is turned into child's stdin - * fd2[1] is turned into child's stdout - * fd2[1] is also turned into child's stderr - * - */ - else if (pid > 0) { /* parent */ - - int to_child = fd1[1]; - int from_child = fd2[0]; - int wstat; - - close(fd1[0]); /* parent doesn't need input side of pipe fd1 */ - close(fd2[1]); /* parent doesn't need output side of pipe fd2 */ - - /* - * smbpasswd doesn't require any input to disable or enable a user - */ - if (!cgi_variable(disable_user_flag) && !cgi_variable(enable_user_flag)) { - /* - * smbpasswd requires a regular old user to send their old password - */ - if (am_root() == False) { - n = (strlen(old) <= (MAX_STRINGLEN)) ? strlen(old) : (MAX_STRINGLEN); - strncpy( line, old, n); - line[n] = '\n'; n++; /* add carriage return */ - line[n] = 0; /* add null terminator, for debug */ - if (write( to_child, line, n) != n) { - printf("<p> error on write to child"); - } - } - - /* - * smbpasswd requires that the new password be sent to it twice - */ - for( i=0; i<2; i++) { - n = (strlen(new) <= (MAX_STRINGLEN)) ? strlen(new) : (MAX_STRINGLEN); - strncpy( line, new, n); - line[n] = '\n'; n++; /* add carriage return */ - line[n] = 0; /* add null terminator, for debug */ - if (write( to_child, line, n) != n) { - printf("<p> error on write to child"); - break; - } - } - } - - /* - * Wait for smbpasswd to finish - */ - if (sys_waitpid(pid, &wstat, 0) < 0) { - printf("<p> problem waiting"); - } - - /* - * Read the answer from the add program - */ - memset( line, '\0', sizeof(line)); - if ((n = read( from_child, line, MAX_STRINGLEN)) < 0) { - printf("<p> error on read from child"); - } - - /* - * Write the response from smbpasswd to user, if all is well - * line[] should be just a null terminated line. We could - * check for the null line and not print anything, but we - * really should be checking the exit code if we want to be - * sure. - */ - line[n] = 0; /* null terminate */ - printf("<p> %s\n",line); - - close(to_child); - close(from_child); - if (line[0] == '\0') { - rslt = True; /* All ok */ - } else { - rslt = False; /* Something didn't work */ - } - - } else { /* child */ - - int from_parent = fd1[0]; - int to_parent = fd2[1]; - - close(fd1[1]); /* child doesn't need output side of pipe fd1 */ - close(fd2[0]); /* child doesn't need input side of pipe fd2 */ - - /* - * Turn the from_parent pipe into the childs stdin - */ - if (from_parent != STDIN_FILENO) { - if (dup2( from_parent, STDIN_FILENO) != STDIN_FILENO) { - printf("<p> dup2 error of stdin"); - } - close( from_parent); - } - - /* - * Turn the to_parent pipe into the childs stdout - */ - if (to_parent != STDOUT_FILENO) { - if (dup2( to_parent, STDOUT_FILENO) != STDOUT_FILENO) { - printf("<p> dup2 error of stdout"); - } - close( to_parent); - } - /* - * Make the childs stderr the to_parent pipe also - */ - if (dup2( STDOUT_FILENO, STDERR_FILENO) != STDERR_FILENO) { - printf("<p> dup2 error of stdout"); - } - - - /* Root can do more */ - if (am_root() == True) { - if (cgi_variable(add_user_flag)) { - /* - * Add a user - */ - if (execl(SMB_PASSWD_PROGRAM, "smbpasswd", "-s", "-a", cgi_variable(user), (char *) 0) < 0) { - printf("<p> execl error of smbpasswd"); - } - } else if (cgi_variable(disable_user_flag)) { - /* - * Disable a user - */ - if (execl(SMB_PASSWD_PROGRAM, "smbpasswd", "-s", "-d", cgi_variable(user), (char *) 0) < 0) { - printf("<p> execl error of smbpasswd"); - } - } else if (cgi_variable(enable_user_flag)) { - /* - * Enable a user - */ - if (execl(SMB_PASSWD_PROGRAM, "smbpasswd", "-s", "-e", cgi_variable(user), (char *) 0) < 0) { - printf("<p> execl error of smbpasswd"); - } - } else { - /* - * Change a users password - */ - if (execl(SMB_PASSWD_PROGRAM, "smbpasswd", "-s", cgi_variable(user), (char *) 0) < 0) { - printf("<p> execl error of smbpasswd"); - } - } - } else { - /* - * Ordinary users can change any users passwd if they know the old passwd - */ - if (execl(SMB_PASSWD_PROGRAM, "smbpasswd", "-s", (char *) 0) < 0) { - printf("<p> execl error of smbpasswd"); - } - } - } - return(rslt); -} - -/**************************************************************************** - become the specified uid - permanently ! -****************************************************************************/ - -BOOL become_user_permanently(uid_t uid, gid_t gid) -{ - - if (geteuid() != 0) { - return(True); - } - - /* now completely lose our privilages. This is a fairly paranoid - way of doing it, but it does work on all systems that I know of */ - -#ifdef HAVE_SETRESUID - /* - * Firstly ensure all our uids are set to root. - */ - setresgid(0,0,0); - setresuid(0,0,0); - - /* - * Now ensure we change all our gids. - */ - setresgid(gid,gid,gid); - - /* - * Now ensure all the uids are the user. - */ - setresuid(uid,uid,uid); -#else - /* - * Firstly ensure all our uids are set to root. - */ - setuid(0); - seteuid(0); - - /* - * Now ensure we change all our gids. - */ - setgid(gid); - setegid(gid); - - /* - * Now ensure all the uids are the user. - */ - setuid(uid); - seteuid(uid); -#endif - - if (getuid() != uid || geteuid() != uid || - getgid() != gid || getegid() != gid) { - /* We failed to lose our privilages. */ - return False; - } - - return(True); + return local_password_change(user_name, False, add_user, enable_user, + disable_user, False, new_passwd); } /**************************************************************************** @@ -834,11 +599,10 @@ BOOL become_user_permanently(uid_t uid, gid_t gid) ****************************************************************************/ static void chg_passwd(void) { - struct passwd *pass = NULL; BOOL rslt; /* Make sure users name has been specified */ - if (strlen(cgi_variable(user)) == 0) { + if (strlen(cgi_variable(USER)) == 0) { printf("<p> Must specify \"User Name\" \n"); return; } @@ -847,50 +611,40 @@ static void chg_passwd(void) * smbpasswd doesn't require anything but the users name to 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)) { + if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG)) { /* If current user is not root, make sure old password has been specified */ - if ((am_root() == False) && (strlen( cgi_variable(old_pswd)) <= 0)) { + if ((am_root() == False) && (strlen( cgi_variable(OLD_PSWD)) <= 0)) { printf("<p> Must specify \"Old Password\" \n"); return; } /* Make sure new passwords have been specified */ - if ((strlen( cgi_variable(new_pswd )) <= 0) || - (strlen( cgi_variable(new2_pswd)) <= 0)) { + if ((strlen( cgi_variable(NEW_PSWD)) <= 0) || + (strlen( cgi_variable(NEW2_PSWD)) <= 0)) { printf("<p> Must specify \"New, and Re-typed Passwords\" \n"); return; } /* Make sure new passwords was typed correctly twice */ - if (strcmp(cgi_variable(new_pswd), cgi_variable(new2_pswd)) != 0) { + if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) { printf("<p> Re-typed password didn't match new password\n"); return; } } -#ifdef SWAT_DEBUG - if (pass) printf("<p> User uid %d gid %d \n", pass->pw_uid, pass->pw_gid); - printf("<p> Processes uid %d, euid %d, gid %d, egid %d \n",getuid(),geteuid(),getgid(),getegid()); - printf("<p> User Name %s \n", cgi_variable(user)); - printf("<p> Old passwd %s \n", cgi_variable(old_pswd) ? cgi_variable(old_pswd):""); - printf("<p> New passwd %s \n", cgi_variable(new_pswd)); - printf("<p> Re-typed New passwd %s \n", cgi_variable(new2_pswd)); - printf("<p> flags '%s', '%s', '%s' \n", - (cgi_variable( chg_passwd_flag) ? cgi_variable( chg_passwd_flag) : ""), - (cgi_variable( add_user_flag) ? cgi_variable( add_user_flag) : ""), - (cgi_variable( disable_user_flag) ? cgi_variable( disable_user_flag) : "")); - (cgi_variable( enable_user_flag) ? cgi_variable( enable_user_flag) : "")); -#endif /* SWAT_DEBUG */ - - - rslt = talk_to_smbpasswd( cgi_variable(old_pswd), cgi_variable(new_pswd)); - if (am_root() == False) { - if (rslt == True) { - printf("<p> The passwd for '%s' has been changed. \n",cgi_variable(user)); - } else { - printf("<p> The passwd for '%s' has NOT been changed. \n",cgi_variable(user)); - } + rslt = change_password(am_root() ? NULL : "127.0.0.1", + cgi_variable(USER), + cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD), + cgi_variable(ADD_USER_FLAG)? True : False, + cgi_variable(ENABLE_USER_FLAG)? True : False, + cgi_variable(DISABLE_USER_FLAG)? True : False); + + + if (rslt == True) { + printf("<p> The passwd for '%s' has been changed. \n", cgi_variable(USER)); + } else { + printf("<p> The passwd for '%s' has NOT been changed. \n",cgi_variable(USER)); } return; @@ -913,29 +667,30 @@ static void passwd_page(void) * 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(user) && - (strcmp(cgi_variable(user), get_user_name()))) { + if (cgi_variable(USER) && + (strcmp(cgi_variable(USER), get_user_name()))) { /* User is changing another accounts passwd */ - new_name = cgi_variable(user); + new_name = cgi_variable(USER); } else { /* User is changing there own passwd */ new_name = get_user_name(); } - printf("<p> User Name : <input type=text size=30 name=%s value=%s> \n", user, new_name); + printf("<p> User Name : <input type=text size=30 name=%s value=%s> \n", + USER, new_name); if (am_root() == False) { - printf("<p> Old Password: <input type=password size=30 name=%s>\n",old_pswd); + printf("<p> Old Password: <input type=password size=30 name=%s>\n",OLD_PSWD); } - printf("<p> New Password: <input type=password size=30 name=%s>\n",new_pswd); - printf("<p> Re-type New Password: <input type=password size=30 name=%s>\n",new2_pswd); + printf("<p> New Password: <input type=password size=30 name=%s>\n",NEW_PSWD); + printf("<p> Re-type New Password: <input type=password size=30 name=%s>\n",NEW2_PSWD); printf("</select></td></tr><p>"); printf("<tr><td>"); - printf("<input type=submit name=%s value=\"Change Password\">", chg_passwd_flag); + printf("<input type=submit name=%s value=\"Change Password\">", CHG_PASSWD_FLAG); if (am_root() == True) { - printf("<input type=submit name=%s value=\"Add New User\">", add_user_flag); - printf("<input type=submit name=%s value=\"Disable User\">", disable_user_flag); - printf("<input type=submit name=%s value=\"Enable User\">", enable_user_flag); + printf("<input type=submit name=%s value=\"Add New User\">", ADD_USER_FLAG); + printf("<input type=submit name=%s value=\"Disable User\">", DISABLE_USER_FLAG); + printf("<input type=submit name=%s value=\"Enable User\">", ENABLE_USER_FLAG); } printf("</td>\n"); @@ -943,7 +698,7 @@ static void passwd_page(void) * If we don't have user information then there's nothing to do. It's probably * the first time through this code. */ - if (cgi_variable(user)) { + if (cgi_variable(USER)) { chg_passwd(); } |