From f6844e0b7eb4412bc44c5533b09f856dc9272e75 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 4 May 2000 16:01:47 +0000 Subject: a minimal change to get appliance mode to work with winbindd we needed to accept usernames of the form DOMAIN/user, which means we needed to pass the domain to a getpwnam() like routine in certain critical spots. What I'd rather do is get rid of "char *user" everywhere and use the new userdom_struct, but that will have to wait a few days. (This used to be commit 8b7a10febead8be182e7d5b1d68259e31530b69c) --- source3/include/proto.h | 11 ++++++++--- source3/lib/username.c | 35 +++++++++++++++++++++++++++++++++++ source3/smbd/password.c | 30 ++++++++++++++++++++++-------- source3/smbd/reply.c | 6 +++--- source3/smbd/service.c | 4 ++-- 5 files changed, 70 insertions(+), 16 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index c2fe1bf880..9487f4254c 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -288,6 +288,8 @@ char *get_user_home_dir(char *user); BOOL map_username(char *user); struct passwd *Get_Pwnam(char *user,BOOL allow_change); BOOL user_in_list(char *user,char *list); +struct passwd *smb_getpwnam(char *user, char *domain, BOOL allow_change); +int smb_initgroups(char *user, char *domain, gid_t group); /*The following definitions come from lib/util.c */ @@ -2039,7 +2041,7 @@ void init_net_user_info3(NET_USER_INFO_3 *usr, DOM_GID *gids, uint32 user_flgs, - char sess_key[16], + char *sess_key, char *logon_srv, char *logon_dom, @@ -3182,8 +3184,11 @@ BOOL set_challenge(unsigned char *challenge); user_struct *get_valid_user_struct(uint16 vuid); void invalidate_vuid(uint16 vuid); char *validated_username(uint16 vuid); -int setup_groups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups); -uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, BOOL guest); +char *validated_domain(uint16 vuid); +int setup_groups(char *user, char *domain, + uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups); +uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, + char *domain,BOOL guest); void add_session_user(char *user); BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8); BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8], diff --git a/source3/lib/username.c b/source3/lib/username.c index 9a189980d5..2839ddab3d 100644 --- a/source3/lib/username.c +++ b/source3/lib/username.c @@ -423,3 +423,38 @@ static struct passwd * uname_string_combinations(char *s,struct passwd * (*fn)(c } return(NULL); } + + +/**************************************************************************** +these wrappers allow appliance mode to work. In appliance mode the username +takes the form DOMAIN/user +****************************************************************************/ +struct passwd *smb_getpwnam(char *user, char *domain, BOOL allow_change) +{ + struct passwd *pw; + fstring userdom; + + pw = Get_Pwnam(user, allow_change); + if (pw || !domain || !*domain) return pw; + + slprintf(userdom, sizeof(userdom), "%s/%s", domain, user); + + DEBUG(4,("smb_getpwnam trying userdom %s\n", userdom)); + + return Get_Pwnam(userdom, allow_change); +} + +int smb_initgroups(char *user, char *domain, gid_t group) +{ + fstring userdom; + int ret; + + ret = initgroups(user, group); + if (ret==0 || !domain || !*domain) return ret; + + slprintf(userdom, sizeof(userdom), "%s/%s", domain, user); + + DEBUG(4,("smb_initgroups trying userdom %s\n", userdom)); + + return initgroups(userdom, group); +} diff --git a/source3/smbd/password.c b/source3/smbd/password.c index a727d2feb3..782d04631a 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -137,23 +137,35 @@ return a validated username ****************************************************************************/ char *validated_username(uint16 vuid) { - user_struct *vuser = get_valid_user_struct(vuid); - if (vuser == NULL) - return 0; - return(vuser->user.unix_name); + user_struct *vuser = get_valid_user_struct(vuid); + if (vuser == NULL) + return 0; + return(vuser->user.unix_name); +} + +/**************************************************************************** +return a validated domain +****************************************************************************/ +char *validated_domain(uint16 vuid) +{ + user_struct *vuser = get_valid_user_struct(vuid); + if (vuser == NULL) + return 0; + return(vuser->user.domain); } /**************************************************************************** Setup the groups a user belongs to. ****************************************************************************/ -int setup_groups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups) +int setup_groups(char *user, char *domain, + uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups) { int i,ngroups; gid_t grp = 0; gid_t *groups = NULL; - if (-1 == initgroups(user,gid)) + if (-1 == smb_initgroups(user,domain,gid)) { DEBUG(0,("Unable to initgroups. Error was %s\n", strerror(errno) )); if (getuid() == 0) @@ -199,7 +211,8 @@ register a uid/name pair as being valid and that a valid password has been given. vuid is biased by an offset. This allows us to tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ -uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, BOOL guest) +uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, + char *domain,BOOL guest) { user_struct *vuser; struct passwd *pwfile; /* for getting real name from passwd file */ @@ -248,13 +261,14 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, vuser->guest = guest; fstrcpy(vuser->user.unix_name,unix_name); fstrcpy(vuser->user.smb_name,requested_name); + fstrcpy(vuser->user.domain,domain); vuser->n_groups = 0; vuser->groups = NULL; /* Find all the groups this uid is in and store them. Used by become_user() */ - setup_groups(unix_name,uid,gid, + setup_groups(unix_name,domain,uid,gid, &vuser->n_groups, &vuser->groups); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index ead59ebfc2..90d4200f5e 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -944,7 +944,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int } } - if (!Get_Pwnam(user,True)) { + if (!smb_getpwnam(user,domain,True)) { DEBUG(3,("No such user %s - using guest account\n",user)); pstrcpy(user,lp_guestaccount(-1)); guest = True; @@ -979,7 +979,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int user we should become. */ { - const struct passwd *pw = Get_Pwnam(user,False); + const struct passwd *pw = smb_getpwnam(user,domain,False); if (!pw) { DEBUG(1,("Username %s is invalid on this system\n",user)); return bad_password_error(inbuf,outbuf); @@ -993,7 +993,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int /* register the name and uid as being validated, so further connections to a uid can get through without a password, on the same VC */ - sess_vuid = register_vuid(uid,gid,user,sesssetup_user,guest); + sess_vuid = register_vuid(uid,gid,user,sesssetup_user,domain,guest); SSVAL(outbuf,smb_uid,sess_vuid); SSVAL(inbuf,smb_uid,sess_vuid); diff --git a/source3/smbd/service.c b/source3/smbd/service.c index ebc4c9a790..0701b854b7 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -293,7 +293,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int } /* find out some info about the user */ - pass = Get_Pwnam(user,True); + pass = smb_getpwnam(user,validated_domain(vuid),True); if (pass == NULL) { DEBUG(0,( "Couldn't find account %s\n",user)); @@ -504,7 +504,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int if (!IS_IPC(conn)) { /* Find all the groups this uid is in and store them. Used by become_user() */ - setup_groups(conn->user,conn->uid,conn->gid, + setup_groups(conn->user,validated_domain(vuid),conn->uid,conn->gid, &conn->ngroups,&conn->groups); /* check number of connections */ -- cgit