diff options
-rw-r--r-- | source3/Makefile.in | 6 | ||||
-rw-r--r-- | source3/auth/auth_unix.c | 2 | ||||
-rw-r--r-- | source3/auth/auth_util.c | 6 | ||||
-rw-r--r-- | source3/auth/pass_check.c | 24 | ||||
-rw-r--r-- | source3/groupdb/mapping.c | 3 | ||||
-rw-r--r-- | source3/include/smb.h | 2 | ||||
-rw-r--r-- | source3/lib/substitute.c | 1 | ||||
-rw-r--r-- | source3/lib/username.c | 34 | ||||
-rw-r--r-- | source3/lib/util_pw.c | 134 | ||||
-rw-r--r-- | source3/passdb/passdb.c | 14 | ||||
-rw-r--r-- | source3/passdb/pdb_ldap.c | 9 | ||||
-rw-r--r-- | source3/passdb/pdb_smbpasswd.c | 8 | ||||
-rw-r--r-- | source3/passdb/pdb_tdb.c | 8 | ||||
-rw-r--r-- | source3/rpc_server/srv_samr_nt.c | 17 | ||||
-rw-r--r-- | source3/smbd/chgpasswd.c | 7 | ||||
-rw-r--r-- | source3/smbd/password.c | 16 | ||||
-rw-r--r-- | source3/smbd/sesssetup.c | 7 | ||||
-rw-r--r-- | source3/smbd/uid.c | 13 | ||||
-rw-r--r-- | source3/web/cgi.c | 4 |
19 files changed, 243 insertions, 72 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 00da4cf74f..a024ba664e 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -114,8 +114,10 @@ LIB_OBJ = lib/charcnv.o lib/debug.o lib/fault.o \ lib/getsmbpass.o lib/interface.o lib/md4.o \ lib/interfaces.o lib/pidfile.o lib/replace.o \ lib/signal.o lib/system.o lib/time.o \ - lib/ufc.o lib/genrand.o lib/username.o lib/util_getent.o lib/access.o lib/smbrun.o \ - lib/bitmap.o lib/crc32.o lib/snprintf.o lib/dprintf.o lib/xfile.o lib/wins_srv.o \ + lib/ufc.o lib/genrand.o lib/username.o \ + lib/util_getent.o lib/util_pw.o lib/access.o lib/smbrun.o \ + lib/bitmap.o lib/crc32.o lib/snprintf.o lib/dprintf.o \ + lib/xfile.o lib/wins_srv.o \ lib/util_str.o lib/util_sid.o \ lib/util_unistr.o lib/util_file.o \ lib/util.o lib/util_sock.o lib/util_sec.o smbd/ssl.o \ diff --git a/source3/auth/auth_unix.c b/source3/auth/auth_unix.c index 69c24b8213..73a4c51b4f 100644 --- a/source3/auth/auth_unix.c +++ b/source3/auth/auth_unix.c @@ -96,7 +96,7 @@ static NTSTATUS check_unix_security(const struct auth_context *auth_context, pass = Get_Pwnam(user_info->internal_username.str); - /** This call assumes a ASCII password, no charset transformation is + /** @todo This call assumes a ASCII password, no charset transformation is done. We may need to revisit this **/ nt_status = pass_check(pass, pass ? pass->pw_name : user_info->internal_username.str, diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index d2748e30d4..643c2e1996 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -554,16 +554,18 @@ void free_server_info(auth_serversupplied_info **server_info) BOOL make_server_info_guest(auth_serversupplied_info **server_info) { - struct passwd *pass = sys_getpwnam(lp_guestaccount()); + struct passwd *pass = getpwnam_alloc(lp_guestaccount()); if (pass) { if (!make_server_info_pw(server_info, pass)) { + passwd_free(&pass); return False; } (*server_info)->guest = True; + passwd_free(&pass); return True; } - DEBUG(0,("make_server_info_guest: sys_getpwnam() failed on guest account!\n")); + DEBUG(0,("make_server_info_guest: getpwnam_alloc() failed on guest account!\n")); return False; } diff --git a/source3/auth/pass_check.c b/source3/auth/pass_check.c index 77839e4bb0..0101e0fe18 100644 --- a/source3/auth/pass_check.c +++ b/source3/auth/pass_check.c @@ -589,9 +589,10 @@ match is found and is used to update the encrypted password file return NT_STATUS_OK on correct match, appropriate error otherwise ****************************************************************************/ -NTSTATUS pass_check(struct passwd *pass, char *user, char *password, +NTSTATUS pass_check(const struct passwd *input_pass, char *user, char *password, int pwlen, BOOL (*fn) (char *, char *), BOOL run_cracker) { + struct passwd *pass; pstring pass2; int level = lp_passwordlevel(); @@ -620,15 +621,17 @@ NTSTATUS pass_check(struct passwd *pass, char *user, char *password, DEBUG(4, ("pass_check: Checking (PAM) password for user %s (l=%d)\n", user, pwlen)); -#else /* Not using PAM or Kerebos */ +#else /* Not using PAM */ DEBUG(4, ("pass_check: Checking password for user %s (l=%d)\n", user, pwlen)); - if (!pass) { + if (!input_pass) { DEBUG(3, ("Couldn't find user %s\n", user)); return NT_STATUS_NO_SUCH_USER; } + pass = make_modifyable_passwd(input_pass); + #ifdef HAVE_GETSPNAM { struct spwd *spass; @@ -662,6 +665,15 @@ NTSTATUS pass_check(struct passwd *pass, char *user, char *password, } #endif +#ifdef HAVE_GETPWANAM + { + struct passwd_adjunct *pwret; + pwret = getpwanam(s); + if (pwret && pwret->pwa_passwd) + pstrcpy(pass->pw_passwd,pwret->pwa_passwd); + } +#endif + #ifdef OSF1_ENH_SEC { struct pr_passwd *mypasswd; @@ -698,22 +710,27 @@ NTSTATUS pass_check(struct passwd *pass, char *user, char *password, this_salt[2] = 0; #endif + /* Copy into global for the convenience of looping code */ fstrcpy(this_crypted, pass->pw_passwd); if (!*this_crypted) { if (!lp_null_passwords()) { DEBUG(2, ("Disallowing %s with null password\n", this_user)); + passwd_free(&pass); return NT_STATUS_LOGON_FAILURE; } if (!*password) { DEBUG(3, ("Allowing access to %s with null password\n", this_user)); + passwd_free(&pass); return NT_STATUS_OK; } } + passwd_free(&pass); + #endif /* defined(WITH_PAM) */ /* try it as it came to us */ @@ -736,6 +753,7 @@ NTSTATUS pass_check(struct passwd *pass, char *user, char *password, * need to proceed as we know it hasn't been case modified by the * client */ if (strhasupper(password) && strhaslower(password)) { + passwd_free(&pass); return nt_status; } diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index c4166ac259..f71a184bb8 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -1083,10 +1083,11 @@ BOOL get_uid_list_of_group(gid_t gid, uid_t **uid, int *num_uids) } else (*uid) = u; - if( (pwd=getpwnam(gr)) !=NULL) { + if( (pwd=getpwnam_alloc(gr)) !=NULL) { (*uid)[*num_uids]=pwd->pw_uid; (*num_uids)++; } + passwd_free(&pwd); gr = grp->gr_mem[++i]; } DEBUG(10, ("got [%d] members\n", *num_uids)); diff --git a/source3/include/smb.h b/source3/include/smb.h index bbc2d597ac..b80e3d62ec 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1618,6 +1618,8 @@ typedef struct user_struct gid_t gid; /* gid of a validated user */ userdom_struct user; + char *homedir; + BOOL guest; /* following groups stuff added by ih */ diff --git a/source3/lib/substitute.c b/source3/lib/substitute.c index 5a2bc1d890..c02ec9556a 100644 --- a/source3/lib/substitute.c +++ b/source3/lib/substitute.c @@ -92,7 +92,6 @@ static size_t expand_env_var(char *p, int len) static char *automount_path(const char *user_name) { static pstring server_path; - struct passwd *pass; /* use the passwd entry as the default */ /* this will be the default if WITH_AUTOMOUNT is not used or fails */ diff --git a/source3/lib/username.c b/source3/lib/username.c index 81408f4569..9541ebeb08 100644 --- a/source3/lib/username.c +++ b/source3/lib/username.c @@ -205,29 +205,7 @@ BOOL map_username(char *user) } /**************************************************************************** - Get_Pwnam wrapper -****************************************************************************/ - -static struct passwd *_Get_Pwnam(const char *s) -{ - struct passwd *ret; - - ret = sys_getpwnam(s); - if (ret) { -#ifdef HAVE_GETPWANAM - struct passwd_adjunct *pwret; - pwret = getpwanam(s); - if (pwret && pwret->pwa_passwd) - pstrcpy(ret->pw_passwd,pwret->pwa_passwd); -#endif - } - - return(ret); -} - - -/**************************************************************************** - * A wrapper for getpwnam(). The following variations are tried: + * A wrapper for sys_getpwnam(). The following variations are tried: * - as transmitted * - in all lower case if this differs from transmitted * - in all upper case if this differs from transmitted @@ -248,23 +226,23 @@ struct passwd *Get_Pwnam_internals(const char *user, char *user2) common case on UNIX systems */ strlower(user2); DEBUG(5,("Trying _Get_Pwnam(), username as lowercase is %s\n",user2)); - ret = _Get_Pwnam(user2); + ret = sys_getpwnam(user2); if(ret) goto done; /* Try as given, if username wasn't originally lowercase */ if(strcmp(user,user2) != 0) { DEBUG(5,("Trying _Get_Pwnam(), username as given is %s\n",user)); - ret = _Get_Pwnam(user); + ret = sys_getpwnam(user); if(ret) goto done; - } + } /* Try as uppercase, if username wasn't originally uppercase */ strupper(user2); if(strcmp(user,user2) != 0) { DEBUG(5,("Trying _Get_Pwnam(), username as uppercase is %s\n",user2)); - ret = _Get_Pwnam(user2); + ret = sys_getpwnam(user2); if(ret) goto done; } @@ -272,7 +250,7 @@ struct passwd *Get_Pwnam_internals(const char *user, char *user2) /* Try all combinations up to usernamelevel */ strlower(user2); DEBUG(5,("Checking combinations of %d uppercase letters in %s\n",lp_usernamelevel(),user2)); - ret = uname_string_combinations(user2, _Get_Pwnam, lp_usernamelevel()); + ret = uname_string_combinations(user2, sys_getpwnam, lp_usernamelevel()); done: DEBUG(5,("Get_Pwnam %s find a valid username!\n",ret ? "did":"didn't")); diff --git a/source3/lib/util_pw.c b/source3/lib/util_pw.c new file mode 100644 index 0000000000..3367a6cdc0 --- /dev/null +++ b/source3/lib/util_pw.c @@ -0,0 +1,134 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0. + + Safe versions of getpw* calls + + Copyright (C) Andrew Bartlett 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. +*/ + +#include "includes.h" + +struct passwd *make_modifyable_passwd(const struct passwd *from) +{ + struct passwd *ret = smb_xmalloc(sizeof(*ret)); +/* This is the assumed shape of the members by certain parts of the code... + fstring pw_name; + fstring pw_passwd; + fstring pw_gecos; + pstring pw_dir; + pstring pw_shell; +*/ + char *pw_name = smb_xmalloc(sizeof(fstring)); + char *pw_passwd = smb_xmalloc(sizeof(fstring)); + char *pw_gecos = smb_xmalloc(sizeof(fstring)); + char *pw_dir = smb_xmalloc(sizeof(pstring)); + char *pw_shell = smb_xmalloc(sizeof(pstring)); + + ZERO_STRUCTP(ret); + + /* + * Now point the struct's members as the + * newly allocated buffers: + */ + + ret->pw_name = pw_name; + fstrcpy(ret->pw_name, from->pw_name); + + ret->pw_passwd = pw_passwd; + fstrcpy(ret->pw_passwd, from->pw_passwd); + + ret->pw_uid = from->pw_uid; + ret->pw_gid = from->pw_gid; + + ret->pw_gecos = pw_gecos; + fstrcpy(ret->pw_gecos, from->pw_gecos); + + ret->pw_dir = pw_dir; + pstrcpy(ret->pw_dir, from->pw_dir); + + ret->pw_shell = pw_shell; + pstrcpy(ret->pw_shell, from->pw_shell); + + return ret; +} + +static struct passwd *alloc_copy_passwd(const struct passwd *from) +{ + struct passwd *ret = smb_xmalloc(sizeof(*ret)); + ZERO_STRUCTP(ret); + ret->pw_name = smb_xstrdup(from->pw_name); + ret->pw_passwd = smb_xstrdup(from->pw_passwd); + ret->pw_uid = from->pw_uid; + ret->pw_gid = from->pw_gid; + ret->pw_gecos = smb_xstrdup(from->pw_gecos); + ret->pw_dir = smb_xstrdup(from->pw_dir); + ret->pw_shell = smb_xstrdup(from->pw_shell); + return ret; +} + +void passwd_free (struct passwd **buf) +{ + if (!*buf) { + DEBUG(0, ("attempted double-free of allocated passwd\n")); + return; + } + + SAFE_FREE((*buf)->pw_name); + SAFE_FREE((*buf)->pw_passwd); + SAFE_FREE((*buf)->pw_gecos); + SAFE_FREE((*buf)->pw_dir); + SAFE_FREE((*buf)->pw_shell); + + SAFE_FREE(*buf); +} + +struct passwd *getpwnam_alloc(const char *name) +{ + struct passwd *temp; + + temp = getpwnam(name); + + if (!temp) { +#if 0 + if (errno == ENOMEM) { + /* what now? */ + } +#endif + return NULL; + } + + return alloc_copy_passwd(temp); +} + +struct passwd *getpwuid_alloc(uid_t uid) +{ + struct passwd *temp; + + temp = getpwuid(uid); + + if (!temp) { +#if 0 + if (errno == ENOMEM) { + /* what now? */ + } +#endif + return NULL; + } + + return alloc_copy_passwd(temp); +} diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 92447b3766..f8d8d00287 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -770,12 +770,14 @@ BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type) /* * Ensure this uid really does exist. */ - if(!(pass = sys_getpwuid(*puid))) + if(!(pass = getpwuid_alloc(*puid))) return False; DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_to_string( str, psid), (unsigned int)*puid, pass->pw_name )); + passwd_free(&pass); + *name_type = SID_NAME_USER; return True; @@ -1003,7 +1005,7 @@ BOOL local_password_change(const char *user_name, int local_flags, * Check for a local account - if we're adding only. */ - if(!(pwd = sys_getpwnam(user_name))) { + if(!(pwd = getpwnam_alloc(user_name))) { slprintf(err_str, err_str_len - 1, "User %s does not \ exist in system password file (usually /etc/passwd). Cannot add \ account without a valid local system user.\n", user_name); @@ -1016,9 +1018,11 @@ account without a valid local system user.\n", user_name); if (!NT_STATUS_IS_OK(pdb_init_sam_pw(&sam_pass, pwd))){ slprintf(err_str, err_str_len-1, "Failed initialise SAM_ACCOUNT for user %s.\n", user_name); + passwd_free(&pwd); return False; } - + + passwd_free(&pwd); if (local_flags & LOCAL_TRUST_ACCOUNT) { if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST)) { @@ -1154,13 +1158,15 @@ BOOL pdb_getsampwuid (SAM_ACCOUNT* user, uid_t uid) * and then lokup the user by name in the sam. */ - if ((pw=sys_getpwuid(uid)) == NULL) { + if ((pw=getpwuid_alloc(uid)) == NULL) { DEBUG(0,("pdb_getsampwuid: getpwuid(%d) return NULL. User does not exist in Unix accounts!\n", uid)); return False; } fstrcpy (name, pw->pw_name); + passwd_free(&pw); + return pdb_getsampwnam (user, name); } diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index c4ff5cca9c..b687f494cc 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -499,7 +499,7 @@ static BOOL init_sam_from_ldap (SAM_ACCOUNT * sampass, /* These values MAY be in LDAP, but they can also be retrieved through * sys_getpw*() which is how we're doing it */ - sys_user = sys_getpwnam(username); + sys_user = getpwnam_alloc(username); if (sys_user == NULL) { DEBUG (2,("init_sam_from_ldap: User [%s] does not ave a uid!\n", username)); return False; @@ -524,6 +524,11 @@ static BOOL init_sam_from_ldap (SAM_ACCOUNT * sampass, if (acct_ctrl == 0) acct_ctrl |= ACB_NORMAL; + pdb_set_uid(sampass, sys_user->pw_uid); + pdb_set_gid(sampass, sys_user->pw_gid); + + /* We are done with this now */ + passwd_free(&sys_user); pdb_set_acct_ctrl(sampass, acct_ctrl); pdb_set_logon_time(sampass, logon_time); @@ -536,8 +541,6 @@ static BOOL init_sam_from_ldap (SAM_ACCOUNT * sampass, pdb_set_hours_len(sampass, hours_len); pdb_set_logon_divs(sampass, logon_divs); - pdb_set_uid(sampass, sys_user->pw_uid); - pdb_set_gid(sampass, sys_user->pw_gid); pdb_set_user_rid(sampass, user_rid); pdb_set_group_rid(sampass, group_rid); diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c index 3d81c0c457..a464312ad6 100644 --- a/source3/passdb/pdb_smbpasswd.c +++ b/source3/passdb/pdb_smbpasswd.c @@ -34,7 +34,7 @@ struct smb_passwd { uid_t smb_userid; /* this is actually the unix uid_t */ - char *smb_name; /* username string */ + const char *smb_name; /* username string */ const unsigned char *smb_passwd; /* Null if no password */ const unsigned char *smb_nt_passwd; /* Null if no password */ @@ -1149,7 +1149,7 @@ static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampas ZERO_STRUCTP(smb_pw); smb_pw->smb_userid=uid; - smb_pw->smb_name=(char*)pdb_get_username(sampass); + smb_pw->smb_name=(const char*)pdb_get_username(sampass); smb_pw->smb_passwd=pdb_get_lanman_passwd(sampass); smb_pw->smb_nt_passwd=pdb_get_nt_passwd(sampass); @@ -1200,7 +1200,7 @@ static BOOL build_sam_account(SAM_ACCOUNT *sam_pass, const struct smb_passwd *pw FIXME!!! This is where we should look up an internal mapping of allocated uid for machine accounts as well --jerry */ - pwfile = sys_getpwnam(pw_buf->smb_name); + pwfile = getpwnam_alloc(pw_buf->smb_name); if (pwfile == NULL) { DEBUG(0,("build_sam_account: smbpasswd database is corrupt! username %s not in unix passwd database!\n", pw_buf->smb_name)); return False; @@ -1268,6 +1268,8 @@ static BOOL build_sam_account(SAM_ACCOUNT *sam_pass, const struct smb_passwd *pw /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */ /*pdb_set_group_rid (sam_pass, DOMAIN_GROUP_RID_USERS); */ } + + passwd_free(&pwfile); return True; } diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index 90976b3fef..1f234edc93 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -469,7 +469,7 @@ BOOL pdb_getsampwent(SAM_ACCOUNT *user) /* validate the account and fill in UNIX uid and gid. sys_getpwnam() is used instaed of Get_Pwnam() as we do not need to try case permutations */ - if ((pw=sys_getpwnam(pdb_get_username(user))) == NULL) { + if ((pw=getpwnam_alloc(pdb_get_username(user))) == NULL) { DEBUG(0,("pdb_getsampwent: getpwnam(%s) return NULL. User does not exist!\n", pdb_get_username(user))); return False; @@ -480,6 +480,8 @@ BOOL pdb_getsampwent(SAM_ACCOUNT *user) pdb_set_uid(user, uid); pdb_set_gid(user, gid); + passwd_free(&pw); + /* 21 days from present */ pdb_set_pass_must_change_time(user, time(NULL)+1814400); @@ -564,7 +566,7 @@ BOOL pdb_getsampwnam (SAM_ACCOUNT *user, const char *sname) /* validate the account and fill in UNIX uid and gid. sys_getpwnam() is used instead of Get_Pwnam() as we do not need to try case permutations */ - if ((pw=sys_getpwnam(pdb_get_username(user)))) { + if ((pw=getpwnam_alloc(pdb_get_username(user)))) { uid = pw->pw_uid; gid = pw->pw_gid; pdb_set_uid(user, uid); @@ -590,6 +592,8 @@ BOOL pdb_getsampwnam (SAM_ACCOUNT *user, const char *sname) return False; } + passwd_free(&pw); + return True; } diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index a54bf0d175..c17e22ada2 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -659,6 +659,7 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM char *sep; struct sys_grent *glist; struct sys_grent *grp; + struct passwd *pw; sep = lp_winbind_separator(); @@ -696,8 +697,18 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM } /* Don't return user private groups... */ - if (Get_Pwnam(smap.nt_name) != 0) { + + /* + * We used to do a Get_Pwnam() here, but this has been + * trimmed back to the common case for private groups + * to save lookups and to use the _alloc interface. + * + * This also matches the group mapping code + */ + + if ((pw = getpwnam_alloc(smap.nt_name)) != 0) { DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name )); + passwd_free(&pw); continue; } @@ -1245,9 +1256,9 @@ NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_ (void)map_username(user_name); /* - * Do any UNIX username case mangling. + * UNIX username case mangling not required, pass_oem_change + * is case insensitive. */ - (void)Get_Pwnam_Modify( user_name); if (!pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash, q_u->nt_newpass.pass, q_u->nt_oldhash.hash)) diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index 741f5ef0aa..b22ccacbf1 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -732,6 +732,7 @@ BOOL pass_oem_change(char *user, uchar * ntdata, uchar * nthash) { fstring new_passwd; + const char *unix_user; SAM_ACCOUNT *sampass = NULL; BOOL ret = check_oem_password(user, lmdata, lmhash, ntdata, nthash, &sampass, new_passwd, sizeof(new_passwd)); @@ -745,8 +746,10 @@ BOOL pass_oem_change(char *user, * available. JRA. */ - if ((ret) && lp_unix_password_sync()) - ret = chgpasswd(user, "", new_passwd, True); + unix_user = pdb_get_username(sampass); + + if ((ret) && (unix_user) && (*unix_user) && lp_unix_password_sync()) + ret = chgpasswd(unix_user, "", new_passwd, True); if (ret) ret = change_oem_password(sampass, new_passwd); diff --git a/source3/smbd/password.c b/source3/smbd/password.c index a9d80d36fd..3e942e6f99 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -64,6 +64,8 @@ void invalidate_vuid(uint16 vuid) if (vuser == NULL) return; + SAFE_FREE(vuser->homedir); + session_yield(vuser); DLIST_REMOVE(validated_users, vuser); @@ -255,6 +257,14 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name) fstrcpy(vuser->user.domain, pdb_get_domain(server_info->sam_account)); fstrcpy(vuser->user.full_name, pdb_get_fullname(server_info->sam_account)); + { + /* Keep the homedir handy */ + const char *homedir = pdb_get_homedir(server_info->sam_account); + if (homedir) { + vuser->homedir = smb_xstrdup(homedir); + } + } + DEBUG(10,("register_vuid: (%u,%u) %s %s %s guest=%d\n", (unsigned int)vuser->uid, (unsigned int)vuser->gid, @@ -289,6 +299,12 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name) return -1; } + /* Register a home dir service for this user */ + if ((!vuser->guest) && vuser->homedir && *(vuser->homedir) + && (lp_servicenumber(vuser->user.unix_name) < 0)) { + add_home_service(vuser->user.unix_name, vuser->homedir); + } + return vuser->vuid; } diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 519817432d..0e5830fc24 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -782,13 +782,6 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, if (server_info->guest) { SSVAL(outbuf,smb_vwv2,1); - } else { - const char *home_dir = pdb_get_homedir(server_info->sam_account); - const char *username = pdb_get_username(server_info->sam_account); - if ((home_dir && *home_dir) - && (lp_servicenumber(username) < 0)) { - add_home_service(username, home_dir); - } } /* register the name and uid as being validated, so further connections diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 650d9270cb..8df08a0e72 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -31,26 +31,21 @@ extern struct current_user current_user; BOOL change_to_guest(void) { static struct passwd *pass=NULL; - static uid_t guest_uid = (uid_t)-1; - static gid_t guest_gid = (gid_t)-1; - static fstring guest_name; if (!pass) { - pass = sys_getpwnam(lp_guestaccount()); + /* Don't need to free() this as its stored in a static */ + pass = getpwnam_alloc(lp_guestaccount()); if (!pass) return(False); - guest_uid = pass->pw_uid; - guest_gid = pass->pw_gid; - fstrcpy(guest_name, pass->pw_name); } #ifdef AIX /* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before setting IDs */ - initgroups(guest_name, guest_gid); + initgroups(pass->pw_name, pass->pw_gid); #endif - set_sec_ctx(guest_uid, guest_gid, 0, NULL, NULL); + set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL); current_user.conn = NULL; current_user.vuid = UID_FIELD_INVALID; diff --git a/source3/web/cgi.c b/source3/web/cgi.c index 9a029684ce..a8cb543dfb 100644 --- a/source3/web/cgi.c +++ b/source3/web/cgi.c @@ -388,7 +388,7 @@ static BOOL cgi_handle_authorization(char *line) * Try and get the user from the UNIX password file. */ - pass = sys_getpwnam(user); + pass = getpwnam_alloc(user); /* * Validate the password they have given. @@ -406,6 +406,7 @@ static BOOL cgi_handle_authorization(char *line) /* Save the users name */ C_user = strdup(user); + passwd_free(&pass); return True; } } @@ -414,6 +415,7 @@ err: cgi_setup_error("401 Bad Authorization", "", "username or password incorrect"); + passwd_free(&pass); return False; } |