diff options
author | Gerald Carter <jerry@samba.org> | 2003-09-09 04:07:32 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2003-09-09 04:07:32 +0000 |
commit | 4093bf7ff8c8861cf7b941945ede53a8ec5bb6c8 (patch) | |
tree | dd0a9f32d9933e1f75d919b5083e007d7453f9c4 /source3/smbd/uid.c | |
parent | 3d7cb49747a9a7f5cdec0ee05c6270ec3604202f (diff) | |
download | samba-4093bf7ff8c8861cf7b941945ede53a8ec5bb6c8.tar.gz samba-4093bf7ff8c8861cf7b941945ede53a8ec5bb6c8.tar.bz2 samba-4093bf7ff8c8861cf7b941945ede53a8ec5bb6c8.zip |
sync 3.0 into HEAD for the last time
(This used to be commit c17a7dc9a190156a069da3e861c18fd3f81224ad)
Diffstat (limited to 'source3/smbd/uid.c')
-rw-r--r-- | source3/smbd/uid.c | 465 |
1 files changed, 1 insertions, 464 deletions
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 8d3e7cd9be..7979ffe854 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -370,7 +370,7 @@ BOOL unbecome_user(void) } /***************************************************************** - Convert the suplimentary SIDs returned in a netlogon into UNIX + Convert the supplementary SIDs returned in a netlogon into UNIX group gid_t's. Add to the total group array. *****************************************************************/ @@ -437,467 +437,4 @@ void add_supplementary_nt_login_groups(int *n_groups, gid_t **pp_groups, NT_USER *pptok = new_tok; } -/***************************************************************** - *THE CANONICAL* convert name to SID function. - Tries local lookup first - for local domains - then uses winbind. -*****************************************************************/ - -BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type) -{ - fstring sid; - BOOL local_lookup = False; - - *name_type = SID_NAME_UNKNOWN; - - /* If we are looking up a domain user, make sure it is - for the local machine only */ - - if (strequal(global_myname(), domain)) { - local_lookup = True; - } else if (lp_server_role() == ROLE_DOMAIN_PDC || - lp_server_role() == ROLE_DOMAIN_BDC) { - if (strequal(domain, lp_workgroup())) { - local_lookup = True; - } - } - - if (local_lookup) { - if (local_lookup_name(name, psid, name_type)) { - DEBUG(10, - ("lookup_name: (local) [%s]\\[%s] -> SID %s (type %s: %u)\n", - domain, name, sid_to_string(sid,psid), - sid_type_lookup(*name_type), (unsigned int)*name_type)); - return True; - } - } else { - /* Remote */ - if (winbind_lookup_name(domain, name, psid, name_type)) { - - DEBUG(10,("lookup_name (winbindd): [%s]\\[%s] -> SID %s (type %u)\n", - domain, name, sid_to_string(sid, psid), - (unsigned int)*name_type)); - return True; - } - } - - DEBUG(10, ("lookup_name: %s lookup for [%s]\\[%s] failed\n", - local_lookup ? "local" : "winbind", domain, name)); - - return False; -} - -/***************************************************************** - *THE CANONICAL* convert SID to name function. - Tries local lookup first - for local sids, then tries winbind. -*****************************************************************/ - -BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type) -{ - if (!name_type) - return False; - - *name_type = SID_NAME_UNKNOWN; - - /* Check if this is our own sid. This should perhaps be done by - winbind? For the moment handle it here. */ - - if (sid->num_auths == 5) { - DOM_SID tmp_sid; - uint32 rid; - - sid_copy(&tmp_sid, sid); - sid_split_rid(&tmp_sid, &rid); - - if (sid_equal(get_global_sam_sid(), &tmp_sid)) { - - return map_domain_sid_to_name(&tmp_sid, dom_name) && - local_lookup_sid(sid, name, name_type); - } - } - - if (!winbind_lookup_sid(sid, dom_name, name, name_type)) { - fstring sid_str; - DOM_SID tmp_sid; - uint32 rid; - - DEBUG(10,("lookup_sid: winbind lookup for SID %s failed - trying local.\n", sid_to_string(sid_str, sid) )); - - sid_copy(&tmp_sid, sid); - sid_split_rid(&tmp_sid, &rid); - return map_domain_sid_to_name(&tmp_sid, dom_name) && - lookup_known_rid(&tmp_sid, rid, name, name_type); - } - 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, 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; - 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 ) -{ - 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, 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); - 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, 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; - 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) -{ - 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, 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); - DLIST_ADD(gid_sid_cache_head, pc); - n_gid_sid_cache++; -} - -/***************************************************************** - *THE CANONICAL* convert uid_t to SID function. -*****************************************************************/ - -NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid) -{ - uid_t low, high; - fstring sid; - - ZERO_STRUCTP(psid); - - if (fetch_sid_from_uid_cache(psid, uid)) - return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); - - if (lp_idmap_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, uid); - return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); - } - } - - if (!local_uid_to_sid(psid, uid)) { - DEBUG(10,("uid_to_sid: local %u failed to map to sid\n", (unsigned int)uid )); - return NT_STATUS_UNSUCCESSFUL; - } - - DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid))); - - store_uid_sid_cache(psid, uid); - return NT_STATUS_OK; -} - -/***************************************************************** - *THE CANONICAL* convert gid_t to SID function. -*****************************************************************/ - -NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid) -{ - gid_t low, high; - fstring sid; - - ZERO_STRUCTP(psid); - - if (fetch_sid_from_gid_cache(psid, gid)) - return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); - - if (lp_idmap_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, gid); - return ( psid ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL ); - } - } - - if (!local_gid_to_sid(psid, gid)) { - DEBUG(10,("gid_to_sid: local %u failed to map to sid\n", (unsigned int)gid )); - return NT_STATUS_UNSUCCESSFUL; - } - - DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid))); - - store_gid_sid_cache(psid, gid); - return NT_STATUS_OK; -} - -/***************************************************************** - *THE CANONICAL* convert SID to uid function. -*****************************************************************/ - -NTSTATUS sid_to_uid(const DOM_SID *psid, uid_t *puid) -{ - fstring dom_name, name, sid_str; - enum SID_NAME_USE name_type; - - if (fetch_uid_from_cache(puid, psid)) - return NT_STATUS_OK; - - /* if this is our SID then go straight to a local lookup */ - - if ( sid_compare_domain(get_global_sam_sid(), psid) == 0 ) { - DEBUG(10,("sid_to_uid: my domain (%s) - trying local.\n", - sid_string_static(psid) )); - - if ( local_sid_to_uid(puid, psid, &name_type) ) - goto success; - - DEBUG(10,("sid_to_uid: local lookup failed\n")); - - return NT_STATUS_UNSUCCESSFUL; - } - - /* If it is not our local domain, only hope is winbindd */ - - if ( !winbind_lookup_sid(psid, dom_name, name, &name_type) ) { - DEBUG(10,("sid_to_uid: winbind lookup for non-local sid %s failed\n", - sid_string_static(psid) )); - - return NT_STATUS_UNSUCCESSFUL; - } - - /* If winbindd does know the SID, ensure this is a user */ - - if (name_type != SID_NAME_USER) { - DEBUG(10,("sid_to_uid: winbind lookup succeeded but SID is not a user (%u)\n", - (unsigned int)name_type )); - return NT_STATUS_INVALID_PARAMETER; - } - - /* get the uid. Has to work or else we are dead in the water */ - - if ( !winbind_sid_to_uid(puid, psid) ) { - DEBUG(10,("sid_to_uid: winbind failed to allocate a new uid for sid %s\n", - sid_to_string(sid_str, psid) )); - return NT_STATUS_UNSUCCESSFUL; - } - -success: - DEBUG(10,("sid_to_uid: %s -> %u\n", sid_to_string(sid_str, psid), - (unsigned int)*puid )); - - store_uid_sid_cache(psid, *puid); - - return NT_STATUS_OK; -} -/***************************************************************** - *THE CANONICAL* convert SID to gid function. - Group mapping is used for gids that maps to Wellknown SIDs -*****************************************************************/ - -NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid) -{ - fstring dom_name, name, sid_str; - enum SID_NAME_USE name_type; - - if (fetch_gid_from_cache(pgid, psid)) - return NT_STATUS_OK; - - /* - * First we must look up the name and decide if this is a group sid. - * Group mapping can deal with foreign SIDs - */ - - if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) { - DEBUG(10,("sid_to_gid: winbind lookup for sid %s failed - trying local.\n", - sid_to_string(sid_str, psid) )); - - if ( local_sid_to_gid(pgid, psid, &name_type) ) - goto success; - - DEBUG(10,("sid_to_gid: no one knows this SID\n")); - - return NT_STATUS_UNSUCCESSFUL; - } - - /* winbindd knows it; 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 )); - - /* winbindd is running and knows about this SID. Just the wrong type. - Don't fallback to a local lookup here */ - - return NT_STATUS_INVALID_PARAMETER; - } - - /* winbindd knows it and it is a type of group; sid_to_gid must succeed - or we are dead in the water */ - - if ( !winbind_sid_to_gid(pgid, psid) ) { - DEBUG(10,("sid_to_uid: winbind failed to allocate a new gid for sid %s\n", - sid_to_string(sid_str, psid) )); - return NT_STATUS_UNSUCCESSFUL; - } - -success: - DEBUG(10,("sid_to_gid: %s -> %u\n", sid_to_string(sid_str, psid), - (unsigned int)*pgid )); - - store_gid_sid_cache(psid, *pgid); - - return NT_STATUS_OK; -} |