summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Potter <tpot@samba.org>1999-06-13 04:14:24 +0000
committerTim Potter <tpot@samba.org>1999-06-13 04:14:24 +0000
commit731c7f2ecfe17651506ba05b88358360e4654a37 (patch)
tree57213f534b2bf1c8f53994a14884abbebfefde47
parenteaa085e8a7106d595235b36d1592ca38b47ba53f (diff)
downloadsamba-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.c64
-rw-r--r--source3/lib/domain_namemap.c2
-rw-r--r--source3/lib/username.c92
-rw-r--r--source3/lib/util.c4
-rw-r--r--source3/passdb/pass_check.c64
-rw-r--r--source3/passdb/smbpasschange.c2
-rw-r--r--source3/smbd/chgpasswd.c2
-rw-r--r--source3/smbd/password.c4
-rw-r--r--source3/smbd/reply.c2
-rw-r--r--source3/smbd/service.c2
-rw-r--r--source3/smbd/uid.c2
-rw-r--r--source3/web/cgi.c2
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)) {