summaryrefslogtreecommitdiff
path: root/source3/smbd/uid.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd/uid.c')
-rw-r--r--source3/smbd/uid.c465
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;
-}