diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/password.c | 113 | ||||
-rw-r--r-- | source3/smbd/process.c | 3 | ||||
-rw-r--r-- | source3/smbd/sec_ctx.c | 34 | ||||
-rw-r--r-- | source3/smbd/service.c | 4 | ||||
-rw-r--r-- | source3/smbd/uid.c | 23 | ||||
-rw-r--r-- | source3/smbd/unix_acls.c | 8 |
6 files changed, 91 insertions, 94 deletions
diff --git a/source3/smbd/password.c b/source3/smbd/password.c index f9291b8705..0372e7a0f9 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -113,6 +113,16 @@ user_struct *get_valid_user_struct(uint16 vuid) } /**************************************************************************** + Delete the SID list for this user. +****************************************************************************/ + +static void delete_nt_token(NT_USER_TOKEN *token) +{ + safe_free( token->user_sids ); + ZERO_STRUCTP(token); +} + +/**************************************************************************** invalidate a uid ****************************************************************************/ void invalidate_vuid(uint16 vuid) @@ -133,8 +143,7 @@ void invalidate_vuid(uint16 vuid) vuser->groups = NULL; - if (vuser->group_sids != NULL) - free (vuser->group_sids); + delete_nt_token(&vuser->nt_user_token); } @@ -162,61 +171,54 @@ char *validated_domain(uint16 vuid) /**************************************************************************** -Setup the groups a user belongs to. + Initialize the groups a user belongs to. ****************************************************************************/ -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)) - { +int initialize_groups(char *user, uid_t uid, gid_t gid) +{ + if (initgroups(user,gid) == -1) { DEBUG(0,("Unable to initgroups. Error was %s\n", strerror(errno) )); - if (getuid() == 0) - { - if (gid < 0 || gid > 32767 || uid < 0 || uid > 32767) - { + if (getuid() == 0) { + if (gid < 0 || gid > 32767 || uid < 0 || uid > 32767) { DEBUG(0,("This is probably a problem with the account %s\n", user)); } } return -1; } + return 0; +} - ngroups = sys_getgroups(0,&grp); - if (ngroups <= 0) - { - ngroups = groups_max(); - } +/**************************************************************************** + Create the SID list for this user. +****************************************************************************/ - if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL) - { - DEBUG(0,("setup_groups malloc fail !\n")); - return -1; - } +void setup_nt_token(NT_USER_TOKEN *token, uid_t uid, gid_t gid, int ngroups, gid_t *groups) +{ + DOM_SID *psids; + int i; - ngroups = sys_getgroups(ngroups,groups); + ZERO_STRUCTP(token); - (*p_ngroups) = ngroups; - (*p_groups) = groups; + if ((token->user_sids = (DOM_SID *)malloc( (ngroups + 2)*sizeof(DOM_SID))) == NULL) + return; - DEBUG( 3, ( "%s is in %d groups: ", user, ngroups ) ); - for (i = 0; i < ngroups; i++ ) - { - DEBUG( 3, ( "%s%d", (i ? ", " : ""), (int)groups[i] ) ); - } - DEBUG( 3, ( "\n" ) ); + psids = token->user_sids; - return 0; -} + token->num_sids = ngroups + 2; + + uid_to_sid( &psids[0], uid); + gid_to_sid( &psids[1], gid); + for (i = 0; i < ngroups; i++) + gid_to_sid( &psids[i+2], groups[i]); +} /**************************************************************************** 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, char *domain,BOOL guest) { @@ -227,37 +229,15 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, if(lp_security() == SEC_SHARE) return UID_FIELD_INVALID; -#if 0 - /* - * After observing MS-Exchange services writing to a Samba share - * I belive this code is incorrect. Each service does its own - * sessionsetup_and_X for the same user, and as each service shuts - * down, it does a user_logoff_and_X. As we are consolidating multiple - * sessionsetup_and_X's onto the same vuid here, when the first service - * shuts down, it invalidates all the open files for the other services. - * Hence I am removing this code and forcing each sessionsetup_and_X - * to get a new vuid. - * Jeremy Allison. (jallison@whistle.com). - */ - - int i; - for(i = 0; i < num_validated_users; i++) { - vuser = &validated_users[i]; - if ( vuser->uid == uid ) - return (uint16)(i + VUID_OFFSET); /* User already validated */ - } -#endif - validated_users = (user_struct *)Realloc(validated_users, sizeof(user_struct)* (num_validated_users+1)); - if (!validated_users) - { + if (!validated_users) { DEBUG(0,("Failed to realloc users struct!\n")); num_validated_users = 0; return UID_FIELD_INVALID; - } + } vuser = &validated_users[num_validated_users]; num_validated_users++; @@ -274,22 +254,21 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, /* Find all the groups this uid is in and store them. Used by become_user() */ - setup_groups(unix_name,domain,uid,gid, - &vuser->n_groups, - &vuser->groups); + initialize_groups(unix_name, uid, gid); + get_current_groups( &vuser->n_groups, &vuser->groups); - setup_user_sids(vuser); + /* Create an NT_USER_TOKEN struct for this user. */ + setup_nt_token(&vuser->nt_user_token, uid,gid, vuser->n_groups, vuser->groups); DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name)); DEBUG(3, ("Clearing default real name\n")); fstrcpy(vuser->user.full_name, "<Full Name>"); if (lp_unix_realname()) { - if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) - { + if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) { DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,pwfile->pw_gecos)); fstrcpy(vuser->user.full_name, pwfile->pw_gecos); - } + } } memset(&vuser->dc, '\0', sizeof(vuser->dc)); diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 2662db5896..37d8f8dd73 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -561,8 +561,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize } /* load service specific parameters */ - if (conn && - !become_service(conn,(flags & AS_USER)?True:False)) { + if (conn && !become_service(conn,(flags & AS_USER)?True:False)) { return(ERROR(ERRSRV,ERRaccess)); } diff --git a/source3/smbd/sec_ctx.c b/source3/smbd/sec_ctx.c index f7ea1e2d86..432cb223e2 100644 --- a/source3/smbd/sec_ctx.c +++ b/source3/smbd/sec_ctx.c @@ -125,17 +125,37 @@ static void gain_root(void) /* Get the list of current groups */ -static void get_current_groups(int *ngroups, gid_t **groups) +int get_current_groups(int *p_ngroups, gid_t **p_groups) { - *ngroups = getgroups(0, NULL); - *groups = (gid_t *)malloc(*ngroups * sizeof(gid_t)); + int i; + gid_t grp; + int ngroups = sys_getgroups(0,&grp); + gid_t *groups; + + (*p_ngroups) = 0; + (*p_groups) = NULL; + + if (ngroups <= 0) + return -1; + + if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL) { + DEBUG(0,("setup_groups malloc fail !\n")); + return -1; + } + + if ((ngroups = sys_getgroups(ngroups,groups)) == -1) + return -1; + + (*p_ngroups) = ngroups; + (*p_groups) = groups; - if (!groups) { - DEBUG(0, ("Out of memory in get_current_groups\n")); - return; + DEBUG( 3, ( "get_current_groups: uid %u is in %u groups: ", (unsigned int)getuid() , ngroups ) ); + for (i = 0; i < ngroups; i++ ) { + DEBUG( 3, ( "%s%d", (i ? ", " : ""), (int)groups[i] ) ); } + DEBUG( 3, ( "\n" ) ); - getgroups(*ngroups, *groups); + return ngroups; } /* Create a new security context on the stack. It is the same as the old diff --git a/source3/smbd/service.c b/source3/smbd/service.c index 2eab50c482..d4760ca92d 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -511,8 +511,8 @@ 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,validated_domain(vuid),conn->uid,conn->gid, - &conn->ngroups,&conn->groups); + initialize_groups(conn->user, conn->uid, conn->gid); + get_current_groups(&conn->ngroups,&conn->groups); /* check number of connections */ if (!claim_connection(conn, diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 172e872020..4cb2c512b6 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -38,7 +38,8 @@ BOOL become_guest(void) if (!pass) pass = Get_Pwnam(lp_guestaccount(-1),True); - if (!pass) return(False); + if (!pass) + return(False); #ifdef AIX /* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before @@ -60,19 +61,21 @@ BOOL become_guest(void) static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) { - int i; - for (i=0;i<conn->uid_cache.entries;i++) - if (conn->uid_cache.list[i] == vuser->uid) return(True); + int i; + for (i=0;i<conn->uid_cache.entries;i++) + if (conn->uid_cache.list[i] == vuser->uid) + return(True); - if (!user_ok(vuser->user.unix_name,snum)) return(False); + if (!user_ok(vuser->user.unix_name,snum)) + return(False); - i = conn->uid_cache.entries % UID_CACHE_SIZE; - conn->uid_cache.list[i] = vuser->uid; + i = conn->uid_cache.entries % UID_CACHE_SIZE; + conn->uid_cache.list[i] = vuser->uid; - if (conn->uid_cache.entries < UID_CACHE_SIZE) - conn->uid_cache.entries++; + if (conn->uid_cache.entries < UID_CACHE_SIZE) + conn->uid_cache.entries++; - return(True); + return(True); } /**************************************************************************** diff --git a/source3/smbd/unix_acls.c b/source3/smbd/unix_acls.c index 7a2dc6ab6e..46c57af5de 100644 --- a/source3/smbd/unix_acls.c +++ b/source3/smbd/unix_acls.c @@ -28,12 +28,8 @@ static void create_file_sids(SMB_STRUCT_STAT *psbuf, DOM_SID *powner_sid, DOM_SID *pgroup_sid) { - extern DOM_SID global_sam_sid; - - sid_copy(powner_sid, &global_sam_sid); - sid_copy(pgroup_sid, &global_sam_sid); - sid_append_rid(powner_sid, pdb_uid_to_user_rid(psbuf->st_uid)); - sid_append_rid(pgroup_sid, pdb_gid_to_group_rid(psbuf->st_gid)); + uid_to_sid( powner_sid, psbuf->st_uid ); + gid_to_sid( pgroup_sid, psbuf->st_gid ); } /**************************************************************************** |