From f8e2baf39eb864481dd48f61404136b325cd73c2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 3 Nov 2001 23:34:24 +0000 Subject: Added NT_USER_TOKEN into server_info to fix extra groups problem. Got "medieval on our ass" about const warnings (as many as I could :-). Jeremy. (This used to be commit ee5e7ca547eff016818ba5c43b8ea0c9fa69b808) --- source3/smbd/auth_util.c | 70 +++++++++++++++++++++++++++++++++++++++-------- source3/smbd/dfree.c | 2 +- source3/smbd/password.c | 24 ++++++++++++---- source3/smbd/quotas.c | 12 ++++---- source3/smbd/sec_ctx.c | 40 --------------------------- source3/smbd/service.c | 2 +- source3/smbd/uid.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++- 7 files changed, 154 insertions(+), 67 deletions(-) (limited to 'source3/smbd') diff --git a/source3/smbd/auth_util.c b/source3/smbd/auth_util.c index 9de8142578..9a99b2643e 100644 --- a/source3/smbd/auth_util.c +++ b/source3/smbd/auth_util.c @@ -4,6 +4,7 @@ Authentication utility functions Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Andrew Bartlett 2001 + Copyright (C) Jeremy Allison 2000-2001 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 @@ -29,21 +30,23 @@ extern fstring remote_machine; extern pstring global_myname; /******************************************************************* -Get the next challenge value - no repeats. + Get the next challenge value - no repeats. ********************************************************************/ + void generate_next_challenge(char *challenge) { - unsigned char buf[8]; + unsigned char buf[8]; - generate_random_buffer(buf,8,False); + generate_random_buffer(buf,8,False); memcpy(saved_challenge, buf, 8); memcpy(challenge,buf,8); challenge_sent = True; } /******************************************************************* -set the last challenge sent, usually from a password server + Set the last challenge sent, usually from a password server. ********************************************************************/ + BOOL set_challenge(unsigned char *challenge) { memcpy(saved_challenge,challenge,8); @@ -52,16 +55,17 @@ BOOL set_challenge(unsigned char *challenge) } /******************************************************************* -get the last challenge sent + Get the last challenge sent. ********************************************************************/ + BOOL last_challenge(unsigned char *challenge) { - if (!challenge_sent) return(False); + if (!challenge_sent) + return(False); memcpy(challenge,saved_challenge,8); return(True); } - /**************************************************************************** Create a UNIX user on demand. ****************************************************************************/ @@ -72,7 +76,8 @@ static int smb_create_user(const char *unix_user, const char *homedir) int ret; pstrcpy(add_script, lp_adduser_script()); - if (! *add_script) return -1; + if (! *add_script) + return -1; all_string_sub(add_script, "%u", unix_user, sizeof(pstring)); if (homedir) all_string_sub(add_script, "%H", homedir, sizeof(pstring)); @@ -91,7 +96,8 @@ static int smb_delete_user(char *unix_user) int ret; pstrcpy(del_script, lp_deluser_script()); - if (! *del_script) return -1; + if (! *del_script) + return -1; all_string_sub(del_script, "%u", unix_user, sizeof(pstring)); ret = smbrun(del_script,NULL); DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret)); @@ -131,7 +137,7 @@ void smb_user_control(const auth_usersupplied_info *user_info, auth_serversuppli if (home_dir && (sys_stat(home_dir, &st) == -1) && (errno == ENOENT)) { - smb_create_user(user_info->internal_username.str, home_dir); + smb_create_user(user_info->internal_username.str, home_dir); } } } @@ -641,14 +647,14 @@ void free_user_info(auth_usersupplied_info **user_info) /*************************************************************************** Clear out a server_info struct that has been allocated ***************************************************************************/ + void free_server_info(auth_serversupplied_info **server_info) { if (*server_info != NULL) { pdb_free_sam(&(*server_info)->sam_account); /* call pam_end here, unless we know we are keeping it */ - SAFE_FREE((*server_info)->group_rids); - + delete_nt_token( &(*server_info)->ptok ); ZERO_STRUCT(**server_info); } SAFE_FREE(*server_info); @@ -657,6 +663,7 @@ void free_server_info(auth_serversupplied_info **server_info) /*************************************************************************** Make a server_info struct for a guest user ***************************************************************************/ + void make_server_info_guest(auth_serversupplied_info **server_info) { struct passwd *pass = sys_getpwnam(lp_guestaccount(-1)); @@ -666,3 +673,42 @@ void make_server_info_guest(auth_serversupplied_info **server_info) } } +/**************************************************************************** + Delete a SID token. +****************************************************************************/ + +void delete_nt_token(NT_USER_TOKEN **pptoken) +{ + if (*pptoken) { + NT_USER_TOKEN *ptoken = *pptoken; + SAFE_FREE( ptoken->user_sids ); + ZERO_STRUCTP(ptoken); + } + SAFE_FREE(*pptoken); +} + +/**************************************************************************** + Duplicate a SID token. +****************************************************************************/ + +NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken) +{ + NT_USER_TOKEN *token; + + if (!ptoken) + return NULL; + + if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) + return NULL; + + ZERO_STRUCTP(token); + + if ((token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids )) == NULL) { + SAFE_FREE(token); + return NULL; + } + + token->num_sids = ptoken->num_sids; + + return token; +} diff --git a/source3/smbd/dfree.c b/source3/smbd/dfree.c index 13a3e86c6e..51f0614941 100644 --- a/source3/smbd/dfree.c +++ b/source3/smbd/dfree.c @@ -121,7 +121,7 @@ static SMB_BIG_UINT disk_free(const char *path, BOOL small_query, } else sys_fsusage(path, dfree, dsize); - if (disk_quotas((char *)path, &bsize_q, &dfree_q, &dsize_q)) { + if (disk_quotas(path, &bsize_q, &dfree_q, &dsize_q)) { (*bsize) = bsize_q; (*dfree) = MIN(*dfree,dfree_q); (*dsize) = MIN(*dsize,dsize_q); diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 01eabfda5e..429d72b4e5 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -117,7 +117,7 @@ char *validated_domain(uint16 vuid) Create the SID list for this user. ****************************************************************************/ -NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, BOOL is_guest) +NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, BOOL is_guest, NT_USER_TOKEN *sup_tok) { extern DOM_SID global_sid_World; extern DOM_SID global_sid_Network; @@ -137,6 +137,9 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, /* We always have uid/gid plus World and Network and Authenticated Users or Guest SIDs. */ num_sids = 5 + ngroups; + if (sup_tok && sup_tok->num_sids) + num_sids += sup_tok->num_sids; + if ((token->user_sids = (DOM_SID *)malloc( num_sids*sizeof(DOM_SID))) == NULL) { SAFE_FREE(token); return NULL; @@ -149,13 +152,15 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, * se_access_check depends on this. */ - uid_to_sid( &psids[psid_ndx++], uid); + uid_to_sid( &psids[PRIMARY_USER_SID_INDEX], uid); + psid_ndx++; /* * Primary group SID is second in token. Convention. */ - gid_to_sid( &psids[psid_ndx++], gid); + gid_to_sid( &psids[PRIMARY_GROUP_SID_INDEX], gid); + psid_ndx++; /* Now add the group SIDs. */ @@ -165,6 +170,10 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, } } + /* Now add the additional SIDs from the supplimentary token. */ + for (i = 0; i < sup_tok->num_sids; i++) + sid_copy( &psids[psid_ndx++], &sup_tok->user_sids[i] ); + /* * Finally add the "standard" SIDs. * The only difference between guest and "anonymous" (which we @@ -218,8 +227,8 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name, BOOL gu ZERO_STRUCTP(vuser); - puid = pdb_get_uid(server_info->sam_account); - pgid = pdb_get_gid(server_info->sam_account); + puid = pdb_get_uid(server_info->sam_account); + pgid = pdb_get_gid(server_info->sam_account); if (!puid || !pgid) { DEBUG(0,("Attempted session setup with invalid user. No uid/gid in SAM_ACCOUNT\n")); @@ -261,8 +270,11 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name, BOOL gu initialise_groups(vuser->user.unix_name, vuser->uid, vuser->gid); get_current_groups( &vuser->n_groups, &vuser->groups); + if (server_info->ptok) + add_supplementary_nt_login_groups(&vuser->n_groups, &vuser->groups, &server_info->ptok); + /* Create an NT_USER_TOKEN struct for this user. */ - vuser->nt_user_token = create_nt_token(vuser->uid, vuser->gid, vuser->n_groups, vuser->groups, guest); + vuser->nt_user_token = create_nt_token(vuser->uid, vuser->gid, vuser->n_groups, vuser->groups, guest, server_info->ptok); DEBUG(3,("uid %d registered to name %s\n",(int)vuser->uid,vuser->user.unix_name)); diff --git a/source3/smbd/quotas.c b/source3/smbd/quotas.c index 76d1124aea..96670a985d 100644 --- a/source3/smbd/quotas.c +++ b/source3/smbd/quotas.c @@ -114,7 +114,7 @@ static int get_smb_linux_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA try to get the disk space from disk quotas (LINUX version) ****************************************************************************/ -BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { int r; SMB_STRUCT_STAT S; @@ -199,7 +199,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U try to get the disk space from disk quotas (CRAY VERSION) ****************************************************************************/ -BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { struct mntent *mnt; FILE *fd; @@ -479,7 +479,7 @@ try to get the disk space from disk quotas (SunOS & Solaris2 version) Quota code by Peter Urbanec (amiga@cse.unsw.edu.au). ****************************************************************************/ -BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { uid_t euser_id; int ret; @@ -639,7 +639,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U try to get the disk space from disk quotas - OSF1 version ****************************************************************************/ -BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { int r, save_errno; struct dqblk D; @@ -705,7 +705,7 @@ try to get the disk space from disk quotas (IRIX 6.2 version) #include #include -BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { uid_t euser_id; int r; @@ -843,7 +843,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U try to get the disk space from disk quotas - default version ****************************************************************************/ -BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) +BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize) { int r; struct dqblk D; diff --git a/source3/smbd/sec_ctx.c b/source3/smbd/sec_ctx.c index fd69521d4e..b774947d60 100644 --- a/source3/smbd/sec_ctx.c +++ b/source3/smbd/sec_ctx.c @@ -168,46 +168,6 @@ int get_current_groups(int *p_ngroups, gid_t **p_groups) return ngroups; } -/**************************************************************************** - Delete a SID token. -****************************************************************************/ - -void delete_nt_token(NT_USER_TOKEN **pptoken) -{ - if (*pptoken) { - NT_USER_TOKEN *ptoken = *pptoken; - SAFE_FREE( ptoken->user_sids ); - ZERO_STRUCTP(ptoken); - } - SAFE_FREE(*pptoken); -} - -/**************************************************************************** - Duplicate a SID token. -****************************************************************************/ - -NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken) -{ - NT_USER_TOKEN *token; - - if (!ptoken) - return NULL; - - if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) - return NULL; - - ZERO_STRUCTP(token); - - if ((token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids )) == NULL) { - SAFE_FREE(token); - return NULL; - } - - token->num_sids = ptoken->num_sids; - - return token; -} - /**************************************************************************** Initialize the groups a user belongs to. ****************************************************************************/ diff --git a/source3/smbd/service.c b/source3/smbd/service.c index f6296201ae..49fbee2607 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -533,7 +533,7 @@ connection_struct *make_connection(char *service, DATA_BLOB password, conn->nt_user_token = create_nt_token(conn->uid, conn->gid, conn->ngroups, conn->groups, - guest); + guest, NULL); /* * New code to check if there's a share security descripter diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index ae287cca76..b33c9ede17 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -181,7 +181,7 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid) if (vuser && vuser->guest) is_guest = True; - token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups, is_guest); + token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups, is_guest, NULL); must_free_token = True; } @@ -367,6 +367,75 @@ BOOL unbecome_user(void) return True; } +/***************************************************************** + Convert the suplimentary SIDs returned in a netlogon into UNIX + group gid_t's. Add to the total group array. +*****************************************************************/ + +void add_supplementary_nt_login_groups(int *n_groups, gid_t **pp_groups, NT_USER_TOKEN **pptok) +{ + int total_groups; + int current_n_groups = *n_groups; + gid_t *final_groups = NULL; + size_t i; + NT_USER_TOKEN *ptok = *pptok; + NT_USER_TOKEN *new_tok = NULL; + + if (!ptok || (ptok->num_sids == 0)) + return; + + new_tok = dup_nt_token(ptok); + if (!new_tok) { + DEBUG(0,("add_supplementary_nt_login_groups: Failed to malloc new token\n")); + return; + } + /* Leave the allocated space but empty the number of SIDs. */ + new_tok->num_sids = 0; + + total_groups = current_n_groups + ptok->num_sids; + + final_groups = (gid_t *)malloc(total_groups * sizeof(gid_t)); + if (!final_groups) { + DEBUG(0,("add_supplementary_nt_login_groups: Failed to malloc new groups.\n")); + delete_nt_token(&new_tok); + return; + } + + memcpy(final_groups, *pp_groups, current_n_groups * sizeof(gid_t)); + for (i = 0; i < ptok->num_sids; i++) { + enum SID_NAME_USE sid_type; + gid_t new_grp; + + if (sid_to_gid(&ptok->user_sids[i], &new_grp, &sid_type)) { + /* + * Don't add the gid_t if it is already in the current group + * list. Some UNIXen don't like the same group more than once. + */ + int j; + + for (j = 0; j < current_n_groups; j++) + if (final_groups[j] == new_grp) + break; + + if ( j == current_n_groups) { + /* Group not already present. */ + final_groups[current_n_groups++] = new_grp; + } + } else { + /* SID didn't map. Copy to the new token to be saved. */ + sid_copy(&new_tok->user_sids[new_tok->num_sids++], &ptok->user_sids[i]); + } + } + + SAFE_FREE(*pp_groups); + *pp_groups = final_groups; + *n_groups = current_n_groups; + + /* Replace the old token with the truncated one. */ + delete_nt_token(&ptok); + *pptok = new_tok; +} + /***************************************************************** *THE CANONICAL* convert name to SID function. Tries winbind first - then uses local lookup. -- cgit