diff options
author | Tim Potter <tpot@samba.org> | 1999-06-13 04:14:24 +0000 |
---|---|---|
committer | Tim Potter <tpot@samba.org> | 1999-06-13 04:14:24 +0000 |
commit | 731c7f2ecfe17651506ba05b88358360e4654a37 (patch) | |
tree | 57213f534b2bf1c8f53994a14884abbebfefde47 | |
parent | eaa085e8a7106d595235b36d1592ca38b47ba53f (diff) | |
download | samba-731c7f2ecfe17651506ba05b88358360e4654a37.tar.gz samba-731c7f2ecfe17651506ba05b88358360e4654a37.tar.xz samba-731c7f2ecfe17651506ba05b88358360e4654a37.zip |
Moved code that changes the pw_passwd entry (i.e shadow password and
weird unixware stuff) into _Get_Pwnam() to fix a memory allocation bug.
Note that the Get_Pwnam() function now returns a const struct passwd *
as a hint to other developers not to change entries in the struct
passwd.
(This used to be commit 36d7cb4ccc42268e8e6a7b783c945d1853624958)
-rw-r--r-- | source3/auth/pass_check.c | 64 | ||||
-rw-r--r-- | source3/lib/domain_namemap.c | 2 | ||||
-rw-r--r-- | source3/lib/username.c | 92 | ||||
-rw-r--r-- | source3/lib/util.c | 4 | ||||
-rw-r--r-- | source3/passdb/pass_check.c | 64 | ||||
-rw-r--r-- | source3/passdb/smbpasschange.c | 2 | ||||
-rw-r--r-- | source3/smbd/chgpasswd.c | 2 | ||||
-rw-r--r-- | source3/smbd/password.c | 4 | ||||
-rw-r--r-- | source3/smbd/reply.c | 2 | ||||
-rw-r--r-- | source3/smbd/service.c | 2 | ||||
-rw-r--r-- | source3/smbd/uid.c | 2 | ||||
-rw-r--r-- | source3/web/cgi.c | 2 |
12 files changed, 100 insertions, 142 deletions
diff --git a/source3/auth/pass_check.c b/source3/auth/pass_check.c index f07f0e1abb..7effbfef8d 100644 --- a/source3/auth/pass_check.c +++ b/source3/auth/pass_check.c @@ -753,7 +753,7 @@ BOOL pass_check(char *user,char *password, int pwlen, struct passwd *pwd, { pstring pass2; int level = lp_passwordlevel(); - struct passwd *pass; + const struct passwd *pass; if (password) password[pwlen] = 0; @@ -785,68 +785,6 @@ BOOL pass_check(char *user,char *password, int pwlen, struct passwd *pwd, return(False); } -#ifdef HAVE_GETSPNAM - { - struct spwd *spass; - - /* many shadow systems require you to be root to get - the password, in most cases this should already be - the case when this function is called, except - perhaps for IPC password changing requests */ - - spass = getspnam(pass->pw_name); - if (spass && spass->sp_pwdp) { - pass->pw_passwd = spass->sp_pwdp; - } - } -#elif defined(IA_UINFO) - { - /* Need to get password with SVR4.2's ia_ functions - instead of get{sp,pw}ent functions. Required by - UnixWare 2.x, tested on version - 2.1. (tangent@cyberport.com) */ - uinfo_t uinfo; - if (ia_openinfo(pass->pw_name, &uinfo) != -1) { - ia_get_logpwd(uinfo, &(pass->pw_passwd)); - } - } -#endif - -#ifdef HAVE_GETPRPWNAM - { - struct pr_passwd *pr_pw = getprpwnam(pass->pw_name); - if (pr_pw && pr_pw->ufld.fd_encrypt) - pass->pw_passwd = pr_pw->ufld.fd_encrypt; - } -#endif - -#ifdef OSF1_ENH_SEC - { - struct pr_passwd *mypasswd; - DEBUG(5,("Checking password for user %s in OSF1_ENH_SEC\n", - user)); - mypasswd = getprpwnam (user); - if (mypasswd) { - fstrcpy(pass->pw_name,mypasswd->ufld.fd_name); - fstrcpy(pass->pw_passwd,mypasswd->ufld.fd_encrypt); - } else { - DEBUG(5,("No entry for user %s in protected database !\n", - user)); - return(False); - } - } -#endif - -#ifdef ULTRIX_AUTH - { - AUTHORIZATION *ap = getauthuid(pass->pw_uid); - if (ap) { - fstrcpy(pass->pw_passwd, ap->a_password); - endauthent(); - } - } -#endif - /* extract relevant info */ fstrcpy(this_user,pass->pw_name); fstrcpy(this_salt,pass->pw_passwd); diff --git a/source3/lib/domain_namemap.c b/source3/lib/domain_namemap.c index 892263f084..156e4e7d35 100644 --- a/source3/lib/domain_namemap.c +++ b/source3/lib/domain_namemap.c @@ -364,7 +364,7 @@ static BOOL unix_name_to_nt_name_info(DOM_NAME_MAP *map, DOM_MAP_TYPE type) if (type == DOM_MAP_USER) { - struct passwd *pwptr = Get_Pwnam(map->unix_name, False); + const struct passwd *pwptr = Get_Pwnam(map->unix_name, False); if (pwptr == NULL) { DEBUG(0,("unix_name_to_nt_name_info: Get_Pwnam for user %s\ diff --git a/source3/lib/username.c b/source3/lib/username.c index ef172b63de..f5fbd31e11 100644 --- a/source3/lib/username.c +++ b/source3/lib/username.c @@ -83,7 +83,7 @@ static BOOL build_passwd_hash_table(void) DEBUG(3,("Building passwd hash table\n")); /* Free the allocated strings in old hash table */ for (i=0;i<pht->passwds_size;i++) { - free(pht->passwds[i].pw_name); + free(pht->passwds[i].pw_name); free(pht->passwds[i].pw_passwd); free(pht->passwds[i].pw_gecos); free(pht->passwds[i].pw_dir); @@ -302,7 +302,7 @@ get a users home directory. ****************************************************************************/ char *get_home_dir(char *user) { - struct passwd *pass; + const struct passwd *pass; static pstring home_dir; pass = Get_Pwnam(user, False); @@ -428,6 +428,86 @@ static struct passwd *_Get_Pwnam(char *s) ret = hashed_getpwnam(s); if (ret) { + + /* Deal with password information stored in shadows. Due to the + dynamic allocation of password cache stuff, the original password + needs to be freed and the new password mallocated to avoid + crashing the cache destructor code. */ + +#ifdef HAVE_GETSPNAM + { + struct spwd *spass; + + /* many shadow systems require you to be root to get + the password, in most cases this should already be + the case when this function is called, except + perhaps for IPC password changing requests */ + + spass = getspnam(ret->pw_name); + if (spass && spass->sp_pwdp) { + free(ret->pw_passwd); + ret->pw_passwd = strdup(spass->sp_pwdp); + } + } +#elif defined(IA_UINFO) + { + /* Need to get password with SVR4.2's ia_ functions + instead of get{sp,pw}ent functions. Required by + UnixWare 2.x, tested on version + 2.1. (tangent@cyberport.com) */ + /* Not sure how large the new password string should + be so I'm using a pstring instead. If anyone has + access to a UnixWare system perhaps they could + optimise this. (tpot@samba.org) */ + uinfo_t uinfo; + if (ia_openinfo(ret->pw_name, &uinfo) != -1) { + free(ret->pw_passwd); + ret->pw_passwd = malloc(FSTRING_LEN); + ia_get_logpwd(uinfo, &(ret->pw_passwd)); + } + } +#endif + +#ifdef HAVE_GETPRPWNAM + { + struct pr_passwd *pr_pw = getprpwnam(ret->pw_name); + if (pr_pw && pr_pw->ufld.fd_encrypt) { + free(ret->pw_passwd); + ret->pw_passwd = strdup(pr_pw->ufld.fd_encrypt); + } + } +#endif + +#ifdef OSF1_ENH_SEC + { + struct pr_passwd *mypasswd; + DEBUG(5,("Checking password for user %s in OSF1_ENH_SEC\n", + user)); + mypasswd = getprpwnam (user); + if (mypasswd) { + free(ret->pw_name); + free(ret->pw_passwd); + ret->pw_name = strdup(mypasswd->ufld.fd_name); + ret->pw_passwd = strdup(mypasswd->ufld.fd_encrypt); + } else { + DEBUG(5,("No entry for user %s in protected database !\n", + user)); + return(False); + } + } +#endif + +#ifdef ULTRIX_AUTH + { + AUTHORIZATION *ap = getauthuid(ret->pw_uid); + if (ap) { + free(ret->pw_passwd); + ret->pw_passwd = strdup(ap->a_password); + endauthent(); + } + } +#endif + #ifdef HAVE_GETPWANAM struct passwd_adjunct *pwret; pwret = getpwanam(s); @@ -447,9 +527,11 @@ static struct passwd *_Get_Pwnam(char *s) /**************************************************************************** a wrapper for getpwnam() that tries with all lower and all upper case if the initial name fails. Also tried with first letter capitalised -Note that this can change user! +Note that this can change user! Function returns const to emphasise +the fact that most of the members of the struct passwd * returned are +dynamically allocated. ****************************************************************************/ -struct passwd *Get_Pwnam(char *user,BOOL allow_change) +const struct passwd *Get_Pwnam(char *user,BOOL allow_change) { fstring user2; int last_char; @@ -538,7 +620,7 @@ static BOOL user_in_group_list(char *user,char *gname) #ifdef HAVE_GETGRNAM struct group *gptr; char **member; - struct passwd *pass = Get_Pwnam(user,False); + const struct passwd *pass = Get_Pwnam(user,False); if (pass) { diff --git a/source3/lib/util.c b/source3/lib/util.c index d1519cd8d2..3211c6687a 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -2125,7 +2125,7 @@ void standard_sub_basic(char *str) { char *s, *p; char pidstr[10]; - struct passwd *pass; + const struct passwd *pass; char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user; for (s = str ; s && *s && (p = strchr(s,'%')); s = p ) @@ -2498,7 +2498,7 @@ turn a user name into a uid ********************************************************************/ BOOL nametouid(const char *name, uid_t *uid) { - struct passwd *pass = Get_Pwnam((char *)name, False); + const struct passwd *pass = Get_Pwnam((char *)name, False); if (pass) { *uid = pass->pw_uid; diff --git a/source3/passdb/pass_check.c b/source3/passdb/pass_check.c index f07f0e1abb..7effbfef8d 100644 --- a/source3/passdb/pass_check.c +++ b/source3/passdb/pass_check.c @@ -753,7 +753,7 @@ BOOL pass_check(char *user,char *password, int pwlen, struct passwd *pwd, { pstring pass2; int level = lp_passwordlevel(); - struct passwd *pass; + const struct passwd *pass; if (password) password[pwlen] = 0; @@ -785,68 +785,6 @@ BOOL pass_check(char *user,char *password, int pwlen, struct passwd *pwd, return(False); } -#ifdef HAVE_GETSPNAM - { - struct spwd *spass; - - /* many shadow systems require you to be root to get - the password, in most cases this should already be - the case when this function is called, except - perhaps for IPC password changing requests */ - - spass = getspnam(pass->pw_name); - if (spass && spass->sp_pwdp) { - pass->pw_passwd = spass->sp_pwdp; - } - } -#elif defined(IA_UINFO) - { - /* Need to get password with SVR4.2's ia_ functions - instead of get{sp,pw}ent functions. Required by - UnixWare 2.x, tested on version - 2.1. (tangent@cyberport.com) */ - uinfo_t uinfo; - if (ia_openinfo(pass->pw_name, &uinfo) != -1) { - ia_get_logpwd(uinfo, &(pass->pw_passwd)); - } - } -#endif - -#ifdef HAVE_GETPRPWNAM - { - struct pr_passwd *pr_pw = getprpwnam(pass->pw_name); - if (pr_pw && pr_pw->ufld.fd_encrypt) - pass->pw_passwd = pr_pw->ufld.fd_encrypt; - } -#endif - -#ifdef OSF1_ENH_SEC - { - struct pr_passwd *mypasswd; - DEBUG(5,("Checking password for user %s in OSF1_ENH_SEC\n", - user)); - mypasswd = getprpwnam (user); - if (mypasswd) { - fstrcpy(pass->pw_name,mypasswd->ufld.fd_name); - fstrcpy(pass->pw_passwd,mypasswd->ufld.fd_encrypt); - } else { - DEBUG(5,("No entry for user %s in protected database !\n", - user)); - return(False); - } - } -#endif - -#ifdef ULTRIX_AUTH - { - AUTHORIZATION *ap = getauthuid(pass->pw_uid); - if (ap) { - fstrcpy(pass->pw_passwd, ap->a_password); - endauthent(); - } - } -#endif - /* extract relevant info */ fstrcpy(this_user,pass->pw_name); fstrcpy(this_salt,pass->pw_passwd); diff --git a/source3/passdb/smbpasschange.c b/source3/passdb/smbpasschange.c index a46ce81c10..a0d9b1b143 100644 --- a/source3/passdb/smbpasschange.c +++ b/source3/passdb/smbpasschange.c @@ -69,7 +69,7 @@ BOOL local_password_change(char *user_name, char *err_str, size_t err_str_len, char *msg_str, size_t msg_str_len) { - struct passwd *pwd; + const struct passwd *pwd; struct smb_passwd *smb_pwent; static struct smb_passwd new_pwent; static uchar new_p16[16]; diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index 734f72c08d..f84ae0ccb5 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -110,7 +110,7 @@ static int dochild(int master,char *slavedev, char *name, char *passwordprogram, { int slave; struct termios stermios; - struct passwd *pass = Get_Pwnam(name,True); + const struct passwd *pass = Get_Pwnam(name,True); int gid; int uid; diff --git a/source3/smbd/password.c b/source3/smbd/password.c index daead8bb82..c05b82ef15 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -415,7 +415,7 @@ BOOL pass_check_smb(char *user, char *domain, uchar *chal, uchar *lm_pwd, uchar *nt_pwd, struct passwd *pwd, uchar user_sess_key[16]) { - struct passwd *pass; + const struct passwd *pass; struct smb_passwd *smb_pass; if (!lm_pwd || !nt_pwd) @@ -877,7 +877,7 @@ BOOL check_hosts_equiv(char *user) { char *fname = NULL; pstring rhostsfile; - struct passwd *pass = Get_Pwnam(user,True); + const struct passwd *pass = Get_Pwnam(user,True); if (!pass) return(False); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index b20236d6f4..faf9c051d2 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -774,7 +774,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int user we should become. */ { - struct passwd *pw = Get_Pwnam(user,False); + const struct passwd *pw = Get_Pwnam(user,False); if (!pw) { DEBUG(1,("Username %s is invalid on this system\n",user)); return(ERROR(ERRSRV,ERRbadpw)); diff --git a/source3/smbd/service.c b/source3/smbd/service.c index 7628f9c8f0..becfd01504 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -194,7 +194,7 @@ int find_service(char *service) connection_struct *make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid, int *ecode) { int snum; - struct passwd *pass = NULL; + const struct passwd *pass = NULL; BOOL guest = False; BOOL force = False; extern int Client; diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index b2407ed5fc..92565b7507 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -163,7 +163,7 @@ become the guest user BOOL become_guest(void) { BOOL ret; - static struct passwd *pass=NULL; + static const struct passwd *pass=NULL; if (initial_uid != 0) return(True); diff --git a/source3/web/cgi.c b/source3/web/cgi.c index 275bf8999f..305c173a5d 100644 --- a/source3/web/cgi.c +++ b/source3/web/cgi.c @@ -333,7 +333,7 @@ handle a http authentication line static BOOL cgi_handle_authorization(char *line) { char *p, *user, *user_pass; - struct passwd *pass = NULL; + const struct passwd *pass = NULL; BOOL ret = False; if (strncasecmp(line,"Basic ", 6)) { |