diff options
Diffstat (limited to 'source/smbd/uid.c')
-rw-r--r-- | source/smbd/uid.c | 419 |
1 files changed, 1 insertions, 418 deletions
diff --git a/source/smbd/uid.c b/source/smbd/uid.c index b9cf0de3bd6..c68d00025c6 100644 --- a/source/smbd/uid.c +++ b/source/smbd/uid.c @@ -405,10 +405,9 @@ void add_supplementary_nt_login_groups(int *n_groups, gid_t **pp_groups, NT_USER 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)) { + if (NT_STATUS_IS_OK(sid_to_gid(&ptok->user_sids[i], &new_grp))) { /* * 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. @@ -530,419 +529,3 @@ BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE } return True; } - -/***************************************************************** - Id mapping cache. This is to avoid Winbind mappings already - seen by smbd to be queried too frequently, keeping winbindd - busy, and blocking smbd while winbindd is busy with other - stuff. Written by Michael Steffens <michael.steffens@hp.com>, - modified to use linked lists by jra. -*****************************************************************/ - -#define MAX_UID_SID_CACHE_SIZE 100 -#define TURNOVER_UID_SID_CACHE_SIZE 10 -#define MAX_GID_SID_CACHE_SIZE 100 -#define TURNOVER_GID_SID_CACHE_SIZE 10 - -static size_t n_uid_sid_cache = 0; -static size_t n_gid_sid_cache = 0; - -static struct uid_sid_cache { - struct uid_sid_cache *next, *prev; - uid_t uid; - DOM_SID sid; - enum SID_NAME_USE sidtype; -} *uid_sid_cache_head; - -static struct gid_sid_cache { - struct gid_sid_cache *next, *prev; - gid_t gid; - DOM_SID sid; - enum SID_NAME_USE sidtype; -} *gid_sid_cache_head; - -/***************************************************************** - Find a SID given a uid. -*****************************************************************/ - -static BOOL fetch_sid_from_uid_cache(DOM_SID *psid, enum SID_NAME_USE *psidtype, uid_t uid) -{ - struct uid_sid_cache *pc; - - for (pc = uid_sid_cache_head; pc; pc = pc->next) { - if (pc->uid == uid) { - fstring sid; - *psid = pc->sid; - *psidtype = pc->sidtype; - DEBUG(3,("fetch sid from uid cache %u -> %s\n", - (unsigned int)uid, sid_to_string(sid, psid))); - DLIST_PROMOTE(uid_sid_cache_head, pc); - return True; - } - } - return False; -} - -/***************************************************************** - Find a uid given a SID. -*****************************************************************/ - -static BOOL fetch_uid_from_cache(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE sidtype) -{ - struct uid_sid_cache *pc; - - for (pc = uid_sid_cache_head; pc; pc = pc->next) { - if (sid_compare(&pc->sid, psid) == 0) { - fstring sid; - *puid = pc->uid; - DEBUG(3,("fetch uid from cache %u -> %s\n", - (unsigned int)*puid, sid_to_string(sid, psid))); - DLIST_PROMOTE(uid_sid_cache_head, pc); - return True; - } - } - return False; -} - -/***************************************************************** - Store uid to SID mapping in cache. -*****************************************************************/ - -static void store_uid_sid_cache(const DOM_SID *psid, const enum SID_NAME_USE sidtype, uid_t uid) -{ - struct uid_sid_cache *pc; - - if (n_uid_sid_cache >= MAX_UID_SID_CACHE_SIZE && n_uid_sid_cache > TURNOVER_UID_SID_CACHE_SIZE) { - /* Delete the last TURNOVER_UID_SID_CACHE_SIZE entries. */ - struct uid_sid_cache *pc_next; - size_t i; - - for (i = 0, pc = uid_sid_cache_head; i < (n_uid_sid_cache - TURNOVER_UID_SID_CACHE_SIZE); i++, pc = pc->next) - ; - for(; pc; pc = pc_next) { - pc_next = pc->next; - DLIST_REMOVE(uid_sid_cache_head,pc); - SAFE_FREE(pc); - n_uid_sid_cache--; - } - } - - pc = (struct uid_sid_cache *)malloc(sizeof(struct uid_sid_cache)); - if (!pc) - return; - pc->uid = uid; - sid_copy(&pc->sid, psid); - pc->sidtype = sidtype; - DLIST_ADD(uid_sid_cache_head, pc); - n_uid_sid_cache++; -} - -/***************************************************************** - Find a SID given a gid. -*****************************************************************/ - -static BOOL fetch_sid_from_gid_cache(DOM_SID *psid, enum SID_NAME_USE *psidtype, gid_t gid) -{ - struct gid_sid_cache *pc; - - for (pc = gid_sid_cache_head; pc; pc = pc->next) { - if (pc->gid == gid) { - fstring sid; - *psid = pc->sid; - *psidtype = pc->sidtype; - DEBUG(3,("fetch sid from gid cache %u -> %s\n", - (unsigned int)gid, sid_to_string(sid, psid))); - DLIST_PROMOTE(gid_sid_cache_head, pc); - return True; - } - } - return False; -} - -/***************************************************************** - Find a gid given a SID. -*****************************************************************/ - -static BOOL fetch_gid_from_cache(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE sidtype) -{ - struct gid_sid_cache *pc; - - for (pc = gid_sid_cache_head; pc; pc = pc->next) { - if (sid_compare(&pc->sid, psid) == 0) { - fstring sid; - *pgid = pc->gid; - DEBUG(3,("fetch uid from cache %u -> %s\n", - (unsigned int)*pgid, sid_to_string(sid, psid))); - DLIST_PROMOTE(gid_sid_cache_head, pc); - return True; - } - } - return False; -} - -/***************************************************************** - Store gid to SID mapping in cache. -*****************************************************************/ - -static void store_gid_sid_cache(const DOM_SID *psid, const enum SID_NAME_USE sidtype, gid_t gid) -{ - struct gid_sid_cache *pc; - - if (n_gid_sid_cache >= MAX_GID_SID_CACHE_SIZE && n_gid_sid_cache > TURNOVER_GID_SID_CACHE_SIZE) { - /* Delete the last TURNOVER_GID_SID_CACHE_SIZE entries. */ - struct gid_sid_cache *pc_next; - size_t i; - - for (i = 0, pc = gid_sid_cache_head; i < (n_gid_sid_cache - TURNOVER_GID_SID_CACHE_SIZE); i++, pc = pc->next) - ; - for(; pc; pc = pc_next) { - pc_next = pc->next; - DLIST_REMOVE(gid_sid_cache_head,pc); - SAFE_FREE(pc); - n_gid_sid_cache--; - } - } - - pc = (struct gid_sid_cache *)malloc(sizeof(struct gid_sid_cache)); - if (!pc) - return; - pc->gid = gid; - sid_copy(&pc->sid, psid); - pc->sidtype = sidtype; - DLIST_ADD(gid_sid_cache_head, pc); - n_gid_sid_cache++; -} - - -/***************************************************************** - *THE CANONICAL* convert uid_t to SID function. - Tries winbind first - then uses local lookup. - Returns SID pointer. -*****************************************************************/ - -DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid) -{ - uid_t low, high; - enum SID_NAME_USE sidtype; - fstring sid; - - if (fetch_sid_from_uid_cache(psid, &sidtype, uid)) - return psid; - - if (lp_winbind_uid(&low, &high) && uid >= low && uid <= high) { - if (winbind_uid_to_sid(psid, uid)) { - - DEBUG(10,("uid_to_sid: winbindd %u -> %s\n", - (unsigned int)uid, sid_to_string(sid, psid))); - - if (psid) - store_uid_sid_cache(psid, SID_NAME_USER, uid); - return psid; - } - } - - /* Make sure we report failure, (when psid == NULL) */ - become_root(); - psid = local_uid_to_sid(psid, uid); - unbecome_root(); - - DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid))); - if (psid) - store_uid_sid_cache(psid, SID_NAME_USER, uid); - - return psid; -} - -/***************************************************************** - *THE CANONICAL* convert gid_t to SID function. - Tries winbind first - then uses local lookup. - Returns SID pointer. -*****************************************************************/ - -DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid) -{ - gid_t low, high; - enum SID_NAME_USE sidtype; - fstring sid; - - if (fetch_sid_from_gid_cache(psid, &sidtype, gid)) - return psid; - - if (lp_winbind_gid(&low, &high) && gid >= low && gid <= high) { - if (winbind_gid_to_sid(psid, gid)) { - - DEBUG(10,("gid_to_sid: winbindd %u -> %s\n", - (unsigned int)gid, sid_to_string(sid, psid))); - - if (psid) - store_gid_sid_cache(psid, SID_NAME_DOM_GRP, gid); - return psid; - } - } - - /* Make sure we report failure, (when psid == NULL) */ - become_root(); - psid = local_gid_to_sid(psid, gid); - unbecome_root(); - DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid))); - if (psid) - store_gid_sid_cache(psid, SID_NAME_DOM_GRP, gid); - - return psid; -} - -/***************************************************************** - *THE CANONICAL* convert SID to uid function. - Tries winbind first - then uses local lookup. - Returns True if this name is a user sid and the conversion - was done correctly, False if not. sidtype is set by this function. -*****************************************************************/ - -BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype) -{ - fstring sid_str; - - if (fetch_uid_from_cache(puid, psid, *sidtype)) - return True; - - /* if we know its local then don't try winbindd */ - if (sid_compare_domain(get_global_sam_sid(), psid) == 0) { - BOOL result; - become_root(); - result = local_sid_to_uid(puid, psid, sidtype); - unbecome_root(); - if (result) - store_uid_sid_cache(psid, *sidtype, *puid); - return result; - } - -/* (tridge) I commented out the slab of code below in order to support foreign SIDs - Do we really need to validate the type of SID we have in this case? -*/ -#if 0 - fstring dom_name, name; - enum SID_NAME_USE name_type; - - *sidtype = SID_NAME_UNKNOWN; - /* - * First we must look up the name and decide if this is a user sid. - */ - - if ( (!winbind_lookup_sid(psid, dom_name, name, &name_type)) || (name_type != SID_NAME_USER) ) { - BOOL result; - DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed - trying local.\n", - sid_to_string(sid_str, psid) )); - - become_root(); - result = local_sid_to_uid(puid, psid, sidtype); - unbecome_root(); - return result; - } - - /* - * Ensure this is a user sid. - */ - - if (name_type != SID_NAME_USER) { - DEBUG(10,("sid_to_uid: winbind lookup succeeded but SID is not a uid (%u)\n", - (unsigned int)name_type )); - return False; - } -#endif - *sidtype = SID_NAME_USER; - - /* - * Get the uid for this SID. - */ - - if (!winbind_sid_to_uid(puid, psid)) { - BOOL result; - DEBUG(10,("sid_to_uid: winbind lookup for sid %s failed.\n", - sid_to_string(sid_str, psid) )); - become_root(); - result = local_sid_to_uid(puid, psid, sidtype); - unbecome_root(); - if (result) - store_uid_sid_cache(psid, *sidtype, *puid); - return result; - } - - DEBUG(10,("sid_to_uid: winbindd %s -> %u\n", - sid_to_string(sid_str, psid), - (unsigned int)*puid )); - - store_uid_sid_cache(psid, *sidtype, *puid); - return True; -} - -/***************************************************************** - *THE CANONICAL* convert SID to gid function. - Tries winbind first - then uses local lookup. - Returns True if this name is a user sid and the conversion - was done correctly, False if not. -*****************************************************************/ - -BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype) -{ - fstring dom_name, name, sid_str; - enum SID_NAME_USE name_type; - - *sidtype = SID_NAME_UNKNOWN; - - if (fetch_gid_from_cache(pgid, psid, *sidtype)) - return True; - - /* - * First we must look up the name and decide if this is a group sid. - */ - - /* if we know its local then don't try winbindd */ - if (sid_compare_domain(get_global_sam_sid(), psid) == 0) { - BOOL result; - become_root(); - result = local_sid_to_gid(pgid, psid, sidtype); - unbecome_root(); - if (result) - store_gid_sid_cache(psid, *sidtype, *pgid); - return result; - } - - if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) { - DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed.\n", - sid_to_string(sid_str, psid) )); - /* this was probably a foreign sid - assume its a group rid - and continue */ - name_type = SID_NAME_DOM_GRP; - } - - /* - * Ensure this is a group sid. - */ - - if ((name_type != SID_NAME_DOM_GRP) && (name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_WKN_GRP)) { - DEBUG(10,("sid_to_gid: winbind lookup succeeded but SID is not a known group (%u)\n", - (unsigned int)name_type )); - - return False; - } - - *sidtype = name_type; - - /* - * Get the gid for this SID. - */ - - if (!winbind_sid_to_gid(pgid, psid)) { - DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed.\n", - sid_to_string(sid_str, psid) )); - return False; - } - - DEBUG(10,("sid_to_gid: winbindd %s -> %u\n", - sid_to_string(sid_str, psid), - (unsigned int)*pgid )); - - store_gid_sid_cache(psid, *sidtype, *pgid); - return True; -} - |