diff options
-rw-r--r-- | source3/winbindd/idmap.c | 434 | ||||
-rw-r--r-- | source3/winbindd/idmap_cache.c | 498 | ||||
-rw-r--r-- | source3/winbindd/winbindd.c | 3 | ||||
-rw-r--r-- | source3/winbindd/winbindd_idmap.c | 108 | ||||
-rw-r--r-- | source3/winbindd/winbindd_sid.c | 26 |
5 files changed, 0 insertions, 1069 deletions
diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c index f0d2c03e0b..2c18164f8c 100644 --- a/source3/winbindd/idmap.c +++ b/source3/winbindd/idmap.c @@ -269,10 +269,6 @@ NTSTATUS idmap_init_cache(void) return NT_STATUS_NO_MEMORY; } - if ( (idmap_cache = idmap_cache_init(idmap_ctx)) == NULL ) { - return NT_STATUS_UNSUCCESSFUL; - } - return NT_STATUS_OK; } @@ -1092,196 +1088,6 @@ static NTSTATUS idmap_backends_set_mapping(const struct id_map *map) return dom->methods->set_mapping(dom, map); } -static NTSTATUS idmap_backends_unixids_to_sids(struct id_map **ids) -{ - struct idmap_domain *dom; - struct id_map **unmapped; - struct id_map **_ids; - TALLOC_CTX *ctx; - NTSTATUS ret; - int i, u, n; - - if (!ids || !*ids) { - DEBUG(1, ("Invalid list of maps\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - ctx = talloc_named_const(NULL, 0, "idmap_backends_unixids_to_sids ctx"); - if ( ! ctx) { - DEBUG(0, ("Out of memory!\n")); - return NT_STATUS_NO_MEMORY; - } - - DEBUG(10, ("Query backends to map ids->sids\n")); - - /* start from the default (the last one) and then if there are still - * unmapped entries cycle through the others */ - - _ids = ids; - - unmapped = NULL; - for (n = num_domains-1; n >= 0; n--) { /* cycle backwards */ - - dom = idmap_domains[n]; - - DEBUG(10, ("Query sids from domain %s\n", dom->name)); - - ret = dom->methods->unixids_to_sids(dom, _ids); - IDMAP_REPORT_RET(ret); - - unmapped = NULL; - - for (i = 0, u = 0; _ids[i]; i++) { - if (_ids[i]->status != ID_MAPPED) { - unmapped = talloc_realloc(ctx, unmapped, - struct id_map *, u + 2); - IDMAP_CHECK_ALLOC(unmapped); - unmapped[u] = _ids[i]; - u++; - } - } - if (unmapped) { - /* terminate the unmapped list */ - unmapped[u] = NULL; - } else { /* no more entries, get out */ - break; - } - - _ids = unmapped; - - } - - if (unmapped) { - /* there are still unmapped ids, - * map them to the unix users/groups domains */ - /* except for expired entries, - * these will be returned as valid (offline mode) */ - for (i = 0; unmapped[i]; i++) { - if (unmapped[i]->status == ID_EXPIRED) continue; - switch (unmapped[i]->xid.type) { - case ID_TYPE_UID: - uid_to_unix_users_sid( - (uid_t)unmapped[i]->xid.id, - unmapped[i]->sid); - unmapped[i]->status = ID_MAPPED; - break; - case ID_TYPE_GID: - gid_to_unix_groups_sid( - (gid_t)unmapped[i]->xid.id, - unmapped[i]->sid); - unmapped[i]->status = ID_MAPPED; - break; - default: /* what?! */ - unmapped[i]->status = ID_UNKNOWN; - break; - } - } - } - - ret = NT_STATUS_OK; - -done: - talloc_free(ctx); - return ret; -} - -static NTSTATUS idmap_backends_sids_to_unixids(struct id_map **ids) -{ - struct id_map ***dom_ids; - struct idmap_domain *dom; - TALLOC_CTX *ctx; - NTSTATUS ret; - int i, *counters; - - if ( (ctx = talloc_named_const(NULL, 0, "be_sids_to_ids")) == NULL ) { - DEBUG(1, ("failed to allocate talloc context, OOM?\n")); - return NT_STATUS_NO_MEMORY; - } - - DEBUG(10, ("Query backends to map sids->ids\n")); - - /* split list per domain */ - if (num_domains == 0) { - DEBUG(1, ("No domains available?\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - dom_ids = TALLOC_ZERO_ARRAY(ctx, struct id_map **, num_domains); - IDMAP_CHECK_ALLOC(dom_ids); - counters = TALLOC_ZERO_ARRAY(ctx, int, num_domains); - IDMAP_CHECK_ALLOC(counters); - - /* partition the requests by domain */ - - for (i = 0; ids[i]; i++) { - uint32 idx; - - if ((dom = find_idmap_domain_from_sid(ids[i]->sid)) == NULL) { - /* no available idmap_domain. Move on */ - continue; - } - - DEBUG(10,("SID %s is being handled by %s\n", - sid_string_dbg(ids[i]->sid), - dom ? dom->name : "none" )); - - idx = find_idmap_domain_index( dom ); - SMB_ASSERT( idx != -1 ); - - dom_ids[idx] = talloc_realloc(ctx, dom_ids[idx], - struct id_map *, - counters[idx] + 2); - IDMAP_CHECK_ALLOC(dom_ids[idx]); - - dom_ids[idx][counters[idx]] = ids[i]; - counters[idx]++; - dom_ids[idx][counters[idx]] = NULL; - } - - /* All the ids have been dispatched in the right queues. - Let's cycle through the filled ones */ - - for (i = 0; i < num_domains; i++) { - if (dom_ids[i]) { - dom = idmap_domains[i]; - DEBUG(10, ("Query ids from domain %s\n", dom->name)); - ret = dom->methods->sids_to_unixids(dom, dom_ids[i]); - IDMAP_REPORT_RET(ret); - } - } - - /* ok all the backends have been contacted at this point */ - /* let's see if we have any unmapped SID left and act accordingly */ - - for (i = 0; ids[i]; i++) { - /* NOTE: this will NOT touch ID_EXPIRED entries that the backend - * was not able to confirm/deny (offline mode) */ - if (ids[i]->status == ID_UNKNOWN || - ids[i]->status == ID_UNMAPPED) { - /* ok this is an unmapped one, see if we can map it */ - ret = idmap_new_mapping(ctx, ids[i]); - if (NT_STATUS_IS_OK(ret)) { - /* successfully mapped */ - ids[i]->status = ID_MAPPED; - } else - if (NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) { - /* could not map it */ - ids[i]->status = ID_UNMAPPED; - } else { - /* Something very bad happened down there - * OR we are offline */ - ids[i]->status = ID_UNKNOWN; - } - } - } - - ret = NT_STATUS_OK; - -done: - talloc_free(ctx); - return ret; -} - NTSTATUS idmap_backends_unixid_to_sid(struct id_map *id) { struct id_map *maps[2]; @@ -1321,242 +1127,6 @@ NTSTATUS idmap_backends_sid_to_unixid(struct id_map *id) return dom->methods->sids_to_unixids(dom, maps); } -/************************************************************************** - idmap interface functions -**************************************************************************/ - -NTSTATUS idmap_unixids_to_sids(struct id_map **ids) -{ - TALLOC_CTX *ctx; - NTSTATUS ret; - struct id_map **bids; - int i, bi; - int bn = 0; - struct winbindd_domain *our_domain = find_our_domain(); - - if (! NT_STATUS_IS_OK(ret = idmap_init())) { - return ret; - } - - if (!ids || !*ids) { - DEBUG(1, ("Invalid list of maps\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - ctx = talloc_named_const(NULL, 0, "idmap_unixids_to_sids ctx"); - if ( ! ctx) { - DEBUG(1, ("failed to allocate talloc context, OOM?\n")); - return NT_STATUS_NO_MEMORY; - } - - /* no ids to be asked to the backends by default */ - bids = NULL; - bi = 0; - - for (i = 0; ids[i]; i++) { - - if ( ! ids[i]->sid) { - DEBUG(1, ("invalid null SID in id_map array")); - talloc_free(ctx); - return NT_STATUS_INVALID_PARAMETER; - } - - ret = idmap_cache_map_id(idmap_cache, ids[i]); - - if (NT_STATUS_IS_OK(ret)) continue; - - if ( ! bids) { - /* alloc space for ids to be resolved by - * backends (realloc ten by ten) */ - bids = TALLOC_ARRAY(ctx, struct id_map *, 10); - if ( ! bids) { - DEBUG(1, ("Out of memory!\n")); - talloc_free(ctx); - return NT_STATUS_NO_MEMORY; - } - bn = 10; - } - - /* add this id to the ones to be retrieved - * from the backends */ - bids[bi] = ids[i]; - bi++; - - /* check if we need to allocate new space - * on the rids array */ - if (bi == bn) { - bn += 10; - bids = talloc_realloc(ctx, bids, struct id_map *, bn); - if ( ! bids) { - DEBUG(1, ("Out of memory!\n")); - talloc_free(ctx); - return NT_STATUS_NO_MEMORY; - } - } - - /* make sure the last element is NULL */ - bids[bi] = NULL; - } - - /* let's see if there is any id mapping to be retrieved - * from the backends */ - if (bids) { - bool online; - - /* Only do query if we are online */ - online = !IS_DOMAIN_OFFLINE(our_domain); - if (online) { - ret = idmap_backends_unixids_to_sids(bids); - IDMAP_CHECK_RET(ret); - } - - /* update the cache */ - for (i = 0; i < bi; i++) { - if (bids[i]->status == ID_MAPPED) { - ret = idmap_cache_set(idmap_cache, bids[i]); - } else if (bids[i]->status == ID_EXPIRED) { - /* the cache returned an expired entry and the - * backend was not able to clear the situation - * (offline). This handles a previous - * NT_STATUS_SYNCHRONIZATION_REQUIRED - * for disconnected mode, */ - bids[i]->status = ID_MAPPED; - } else if (bids[i]->status == ID_UNKNOWN) { - /* something bad here. We were not able to - * handle this for some reason, mark it as - * unmapped and hope next time things will - * settle down. */ - bids[i]->status = ID_UNMAPPED; - } else if (online) { /* unmapped */ - ret = idmap_cache_set_negative_id(idmap_cache, - bids[i]); - } - IDMAP_CHECK_RET(ret); - } - } - - ret = NT_STATUS_OK; -done: - talloc_free(ctx); - return ret; -} - -NTSTATUS idmap_sids_to_unixids(struct id_map **ids) -{ - TALLOC_CTX *ctx; - NTSTATUS ret; - struct id_map **bids; - int i, bi; - int bn = 0; - struct winbindd_domain *our_domain = find_our_domain(); - - if (! NT_STATUS_IS_OK(ret = idmap_init())) { - return ret; - } - - if (!ids || !*ids) { - DEBUG(1, ("Invalid list of maps\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - ctx = talloc_named_const(NULL, 0, "idmap_sids_to_unixids ctx"); - if ( ! ctx) { - DEBUG(1, ("failed to allocate talloc context, OOM?\n")); - return NT_STATUS_NO_MEMORY; - } - - /* no ids to be asked to the backends by default */ - bids = NULL; - bi = 0; - - for (i = 0; ids[i]; i++) { - - if ( ! ids[i]->sid) { - DEBUG(1, ("invalid null SID in id_map array\n")); - talloc_free(ctx); - return NT_STATUS_INVALID_PARAMETER; - } - - ret = idmap_cache_map_sid(idmap_cache, ids[i]); - - if (NT_STATUS_IS_OK(ret)) continue; - - if ( ! bids) { - /* alloc space for ids to be resolved - by backends (realloc ten by ten) */ - bids = TALLOC_ARRAY(ctx, struct id_map *, 10); - if ( ! bids) { - DEBUG(1, ("Out of memory!\n")); - talloc_free(ctx); - return NT_STATUS_NO_MEMORY; - } - bn = 10; - } - - /* add this id to the ones to be retrieved - * from the backends */ - bids[bi] = ids[i]; - bi++; - - /* check if we need to allocate new space - * on the ids array */ - if (bi == bn) { - bn += 10; - bids = talloc_realloc(ctx, bids, struct id_map *, bn); - if ( ! bids) { - DEBUG(1, ("Out of memory!\n")); - talloc_free(ctx); - return NT_STATUS_NO_MEMORY; - } - } - - /* make sure the last element is NULL */ - bids[bi] = NULL; - } - - /* let's see if there is any id mapping to be retrieved - * from the backends */ - if (bids) { - bool online; - - /* Only do query if we are online */ - online = !IS_DOMAIN_OFFLINE(our_domain); - if (online) { - ret = idmap_backends_sids_to_unixids(bids); - IDMAP_CHECK_RET(ret); - } - - /* update the cache */ - for (i = 0; bids[i]; i++) { - if (bids[i]->status == ID_MAPPED) { - ret = idmap_cache_set(idmap_cache, bids[i]); - } else if (bids[i]->status == ID_EXPIRED) { - /* the cache returned an expired entry and the - * backend was not able to clear the situation - * (offline). This handles a previous - * NT_STATUS_SYNCHRONIZATION_REQUIRED - * for disconnected mode, */ - bids[i]->status = ID_MAPPED; - } else if (bids[i]->status == ID_UNKNOWN) { - /* something bad here. We were not able to - * handle this for some reason, mark it as - * unmapped and hope next time things will - * settle down. */ - bids[i]->status = ID_UNMAPPED; - } else if (online) { /* unmapped */ - ret = idmap_cache_set_negative_sid(idmap_cache, - bids[i]); - } - IDMAP_CHECK_RET(ret); - } - } - - ret = NT_STATUS_OK; -done: - talloc_free(ctx); - return ret; -} - NTSTATUS idmap_set_mapping(const struct id_map *id) { TALLOC_CTX *ctx; @@ -1584,10 +1154,6 @@ NTSTATUS idmap_set_mapping(const struct id_map *id) ret = idmap_backends_set_mapping(id); IDMAP_CHECK_RET(ret); - /* set the mapping in the cache */ - ret = idmap_cache_set(idmap_cache, id); - IDMAP_CHECK_RET(ret); - done: talloc_free(ctx); return ret; diff --git a/source3/winbindd/idmap_cache.c b/source3/winbindd/idmap_cache.c index e54d02784f..1e82314440 100644 --- a/source3/winbindd/idmap_cache.c +++ b/source3/winbindd/idmap_cache.c @@ -23,504 +23,6 @@ #include "includes.h" #include "winbindd.h" -#define TIMEOUT_LEN 12 -#define IDMAP_CACHE_DATA_FMT "%12u/%s" -#define IDMAP_READ_CACHE_DATA_FMT_TEMPLATE "%%12u/%%%us" - -struct idmap_cache_ctx { - TDB_CONTEXT *tdb; -}; - -static int idmap_cache_destructor(struct idmap_cache_ctx *cache) -{ - int ret = 0; - - if (cache && cache->tdb) { - ret = tdb_close(cache->tdb); - cache->tdb = NULL; - } - - return ret; -} - -struct idmap_cache_ctx *idmap_cache_init(TALLOC_CTX *memctx) -{ - struct idmap_cache_ctx *cache; - char* cache_fname = NULL; - - cache = talloc(memctx, struct idmap_cache_ctx); - if ( ! cache) { - DEBUG(0, ("Out of memory!\n")); - return NULL; - } - - cache_fname = lock_path("idmap_cache.tdb"); - - DEBUG(10, ("Opening cache file at %s\n", cache_fname)); - - cache->tdb = tdb_open_log(cache_fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); - - if (!cache->tdb) { - DEBUG(5, ("Attempt to open %s has failed.\n", cache_fname)); - return NULL; - } - - talloc_set_destructor(cache, idmap_cache_destructor); - - return cache; -} - -static NTSTATUS idmap_cache_build_sidkey(TALLOC_CTX *ctx, char **sidkey, - const struct id_map *id) -{ - fstring sidstr; - - *sidkey = talloc_asprintf(ctx, "IDMAP/SID/%s", - sid_to_fstring(sidstr, id->sid)); - if ( ! *sidkey) { - DEBUG(1, ("failed to build sidkey, OOM?\n")); - return NT_STATUS_NO_MEMORY; - } - - return NT_STATUS_OK; -} - -static NTSTATUS idmap_cache_build_idkey(TALLOC_CTX *ctx, char **idkey, - const struct id_map *id) -{ - *idkey = talloc_asprintf(ctx, "IDMAP/%s/%lu", - (id->xid.type==ID_TYPE_UID)?"UID":"GID", - (unsigned long)id->xid.id); - if ( ! *idkey) { - DEBUG(1, ("failed to build idkey, OOM?\n")); - return NT_STATUS_NO_MEMORY; - } - - return NT_STATUS_OK; -} - -NTSTATUS idmap_cache_set(struct idmap_cache_ctx *cache, const struct id_map *id) -{ - NTSTATUS ret; - time_t timeout = time(NULL) + lp_idmap_cache_time(); - TDB_DATA databuf; - char *sidkey; - char *idkey; - char *valstr; - - /* Don't cache lookups in the S-1-22-{1,2} domain */ - if ( (id->xid.type == ID_TYPE_UID) && - sid_check_is_in_unix_users(id->sid) ) - { - return NT_STATUS_OK; - } - if ( (id->xid.type == ID_TYPE_GID) && - sid_check_is_in_unix_groups(id->sid) ) - { - return NT_STATUS_OK; - } - - - ret = idmap_cache_build_sidkey(cache, &sidkey, id); - if (!NT_STATUS_IS_OK(ret)) return ret; - - /* use sidkey as the local memory ctx */ - ret = idmap_cache_build_idkey(sidkey, &idkey, id); - if (!NT_STATUS_IS_OK(ret)) { - goto done; - } - - /* save SID -> ID */ - - /* use sidkey as the local memory ctx */ - valstr = talloc_asprintf(sidkey, IDMAP_CACHE_DATA_FMT, (int)timeout, idkey); - if (!valstr) { - DEBUG(0, ("Out of memory!\n")); - ret = NT_STATUS_NO_MEMORY; - goto done; - } - - databuf = string_term_tdb_data(valstr); - DEBUG(10, ("Adding cache entry with key = %s; value = %s and timeout =" - " %s (%d seconds %s)\n", sidkey, valstr , ctime(&timeout), - (int)(timeout - time(NULL)), - timeout > time(NULL) ? "ahead" : "in the past")); - - if (tdb_store_bystring(cache->tdb, sidkey, databuf, TDB_REPLACE) != 0) { - DEBUG(3, ("Failed to store cache entry!\n")); - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* save ID -> SID */ - - /* use sidkey as the local memory ctx */ - valstr = talloc_asprintf(sidkey, IDMAP_CACHE_DATA_FMT, (int)timeout, sidkey); - if (!valstr) { - DEBUG(0, ("Out of memory!\n")); - ret = NT_STATUS_NO_MEMORY; - goto done; - } - - databuf = string_term_tdb_data(valstr); - DEBUG(10, ("Adding cache entry with key = %s; value = %s and timeout =" - " %s (%d seconds %s)\n", idkey, valstr, ctime(&timeout), - (int)(timeout - time(NULL)), - timeout > time(NULL) ? "ahead" : "in the past")); - - if (tdb_store_bystring(cache->tdb, idkey, databuf, TDB_REPLACE) != 0) { - DEBUG(3, ("Failed to store cache entry!\n")); - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - ret = NT_STATUS_OK; - -done: - talloc_free(sidkey); - return ret; -} - -NTSTATUS idmap_cache_set_negative_sid(struct idmap_cache_ctx *cache, const struct id_map *id) -{ - NTSTATUS ret; - time_t timeout = time(NULL) + lp_idmap_negative_cache_time(); - TDB_DATA databuf; - char *sidkey; - char *valstr; - - ret = idmap_cache_build_sidkey(cache, &sidkey, id); - if (!NT_STATUS_IS_OK(ret)) return ret; - - /* use sidkey as the local memory ctx */ - valstr = talloc_asprintf(sidkey, IDMAP_CACHE_DATA_FMT, (int)timeout, "IDMAP/NEGATIVE"); - if (!valstr) { - DEBUG(0, ("Out of memory!\n")); - ret = NT_STATUS_NO_MEMORY; - goto done; - } - - databuf = string_term_tdb_data(valstr); - DEBUG(10, ("Adding cache entry with key = %s; value = %s and timeout =" - " %s (%d seconds %s)\n", sidkey, valstr, ctime(&timeout), - (int)(timeout - time(NULL)), - timeout > time(NULL) ? "ahead" : "in the past")); - - if (tdb_store_bystring(cache->tdb, sidkey, databuf, TDB_REPLACE) != 0) { - DEBUG(3, ("Failed to store cache entry!\n")); - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } - -done: - talloc_free(sidkey); - return ret; -} - -NTSTATUS idmap_cache_set_negative_id(struct idmap_cache_ctx *cache, const struct id_map *id) -{ - NTSTATUS ret; - time_t timeout = time(NULL) + lp_idmap_negative_cache_time(); - TDB_DATA databuf; - char *idkey; - char *valstr; - - ret = idmap_cache_build_idkey(cache, &idkey, id); - if (!NT_STATUS_IS_OK(ret)) return ret; - - /* use idkey as the local memory ctx */ - valstr = talloc_asprintf(idkey, IDMAP_CACHE_DATA_FMT, (int)timeout, "IDMAP/NEGATIVE"); - if (!valstr) { - DEBUG(0, ("Out of memory!\n")); - ret = NT_STATUS_NO_MEMORY; - goto done; - } - - databuf = string_term_tdb_data(valstr); - DEBUG(10, ("Adding cache entry with key = %s; value = %s and timeout =" - " %s (%d seconds %s)\n", idkey, valstr, ctime(&timeout), - (int)(timeout - time(NULL)), - timeout > time(NULL) ? "ahead" : "in the past")); - - if (tdb_store_bystring(cache->tdb, idkey, databuf, TDB_REPLACE) != 0) { - DEBUG(3, ("Failed to store cache entry!\n")); - ret = NT_STATUS_UNSUCCESSFUL; - goto done; - } - -done: - talloc_free(idkey); - return ret; -} - -static NTSTATUS idmap_cache_fill_map(struct id_map *id, const char *value) -{ - char *rem; - - /* see if it is a sid */ - if ( ! strncmp("IDMAP/SID/", value, 10)) { - - if ( ! string_to_sid(id->sid, &value[10])) { - goto failed; - } - - id->status = ID_MAPPED; - - return NT_STATUS_OK; - } - - /* not a SID see if it is an UID or a GID */ - if ( ! strncmp("IDMAP/UID/", value, 10)) { - - /* a uid */ - id->xid.type = ID_TYPE_UID; - - } else if ( ! strncmp("IDMAP/GID/", value, 10)) { - - /* a gid */ - id->xid.type = ID_TYPE_GID; - - } else { - - /* a completely bogus value bail out */ - goto failed; - } - - id->xid.id = strtol(&value[10], &rem, 0); - if (*rem != '\0') { - goto failed; - } - - id->status = ID_MAPPED; - - return NT_STATUS_OK; - -failed: - DEBUG(1, ("invalid value: %s\n", value)); - id->status = ID_UNKNOWN; - return NT_STATUS_INTERNAL_DB_CORRUPTION; -} - -/* search the cahce for the SID an return a mapping if found * - * - * 4 cases are possible - * - * 1 map found - * in this case id->status = ID_MAPPED and NT_STATUS_OK is returned - * 2 map not found - * in this case id->status = ID_UNKNOWN and NT_STATUS_NONE_MAPPED is returned - * 3 negative cache found - * in this case id->status = ID_UNMAPPED and NT_STATUS_OK is returned - * 4 map found but timer expired - * in this case id->status = ID_EXPIRED and NT_STATUS_SYNCHRONIZATION_REQUIRED - * is returned. In this case revalidation of the cache is needed. - */ - -NTSTATUS idmap_cache_map_sid(struct idmap_cache_ctx *cache, struct id_map *id) -{ - NTSTATUS ret; - TDB_DATA databuf; - time_t t; - char *sidkey; - char *endptr; - struct winbindd_domain *our_domain = find_our_domain(); - time_t now = time(NULL); - - /* make sure it is marked as not mapped by default */ - id->status = ID_UNKNOWN; - - ret = idmap_cache_build_sidkey(cache, &sidkey, id); - if (!NT_STATUS_IS_OK(ret)) return ret; - - databuf = tdb_fetch_bystring(cache->tdb, sidkey); - - if (databuf.dptr == NULL) { - DEBUG(10, ("Cache entry with key = %s couldn't be found\n", sidkey)); - ret = NT_STATUS_NONE_MAPPED; - goto done; - } - - t = strtol((const char *)databuf.dptr, &endptr, 10); - - if ((endptr == NULL) || (*endptr != '/')) { - DEBUG(2, ("Invalid gencache data format: %s\n", (const char *)databuf.dptr)); - /* remove the entry */ - tdb_delete_bystring(cache->tdb, sidkey); - ret = NT_STATUS_NONE_MAPPED; - goto done; - } - - /* check it is not negative */ - if (strcmp("IDMAP/NEGATIVE", endptr+1) != 0) { - - DEBUG(10, ("Returning %s cache entry: key = %s, value = %s, " - "timeout = %s", t > now ? "valid" : - "expired", sidkey, endptr+1, ctime(&t))); - - /* this call if successful will also mark the entry as mapped */ - ret = idmap_cache_fill_map(id, endptr+1); - if ( ! NT_STATUS_IS_OK(ret)) { - /* if not valid form delete the entry */ - tdb_delete_bystring(cache->tdb, sidkey); - ret = NT_STATUS_NONE_MAPPED; - goto done; - } - - /* here ret == NT_STATUS_OK and id->status = ID_MAPPED */ - - if (t <= now) { - /* If we've been told to be offline - stay in - that state... */ - if ( IS_DOMAIN_OFFLINE(our_domain) ) { - DEBUG(10,("idmap_cache_map_sid: idmap is offline\n")); - goto done; - } - - /* We're expired, set an error code - for upper layer */ - ret = NT_STATUS_SYNCHRONIZATION_REQUIRED; - } - - goto done; - } - - /* Was a negative cache hit */ - - /* Ignore the negative cache when offline */ - - if ( IS_DOMAIN_OFFLINE(our_domain) ) { - DEBUG(10,("idmap_cache_map_sid: idmap is offline\n")); - goto done; - } - - - /* Check for valid or expired cache hits */ - if (t <= now) { - /* We're expired. Return not mapped */ - ret = NT_STATUS_NONE_MAPPED; - } else { - /* this is not mapped as it was a negative cache hit */ - id->status = ID_UNMAPPED; - ret = NT_STATUS_OK; - } - -done: - SAFE_FREE(databuf.dptr); - talloc_free(sidkey); - return ret; -} - -/* search the cahce for the ID an return a mapping if found * - * - * 4 cases are possible - * - * 1 map found - * in this case id->status = ID_MAPPED and NT_STATUS_OK is returned - * 2 map not found - * in this case id->status = ID_UNKNOWN and NT_STATUS_NONE_MAPPED is returned - * 3 negative cache found - * in this case id->status = ID_UNMAPPED and NT_STATUS_OK is returned - * 4 map found but timer expired - * in this case id->status = ID_EXPIRED and NT_STATUS_SYNCHRONIZATION_REQUIRED - * is returned. In this case revalidation of the cache is needed. - */ - -NTSTATUS idmap_cache_map_id(struct idmap_cache_ctx *cache, struct id_map *id) -{ - NTSTATUS ret; - TDB_DATA databuf; - time_t t; - char *idkey; - char *endptr; - struct winbindd_domain *our_domain = find_our_domain(); - time_t now = time(NULL); - - /* make sure it is marked as unknown by default */ - id->status = ID_UNKNOWN; - - ret = idmap_cache_build_idkey(cache, &idkey, id); - if (!NT_STATUS_IS_OK(ret)) return ret; - - databuf = tdb_fetch_bystring(cache->tdb, idkey); - - if (databuf.dptr == NULL) { - DEBUG(10, ("Cache entry with key = %s couldn't be found\n", idkey)); - ret = NT_STATUS_NONE_MAPPED; - goto done; - } - - t = strtol((const char *)databuf.dptr, &endptr, 10); - - if ((endptr == NULL) || (*endptr != '/')) { - DEBUG(2, ("Invalid gencache data format: %s\n", (const char *)databuf.dptr)); - /* remove the entry */ - tdb_delete_bystring(cache->tdb, idkey); - ret = NT_STATUS_NONE_MAPPED; - goto done; - } - - /* check it is not negative */ - if (strcmp("IDMAP/NEGATIVE", endptr+1) != 0) { - - DEBUG(10, ("Returning %s cache entry: key = %s, value = %s, " - "timeout = %s", t > now ? "valid" : - "expired", idkey, endptr+1, ctime(&t))); - - /* this call if successful will also mark the entry as mapped */ - ret = idmap_cache_fill_map(id, endptr+1); - if ( ! NT_STATUS_IS_OK(ret)) { - /* if not valid form delete the entry */ - tdb_delete_bystring(cache->tdb, idkey); - ret = NT_STATUS_NONE_MAPPED; - goto done; - } - - /* here ret == NT_STATUS_OK and id->mapped = ID_MAPPED */ - - if (t <= now) { - /* If we've been told to be offline - stay in - that state... */ - if ( IS_DOMAIN_OFFLINE(our_domain) ) { - DEBUG(10,("idmap_cache_map_sid: idmap is offline\n")); - goto done; - } - - /* We're expired, set an error code - for upper layer */ - ret = NT_STATUS_SYNCHRONIZATION_REQUIRED; - } - - goto done; - } - - /* Was a negative cache hit */ - - /* Ignore the negative cache when offline */ - - if ( IS_DOMAIN_OFFLINE(our_domain) ) { - DEBUG(10,("idmap_cache_map_sid: idmap is offline\n")); - ret = NT_STATUS_NONE_MAPPED; - - goto done; - } - - /* Process the negative cache hit */ - - if (t <= now) { - /* We're expired. Return not mapped */ - ret = NT_STATUS_NONE_MAPPED; - } else { - /* this is not mapped is it was a negative cache hit */ - id->status = ID_UNMAPPED; - ret = NT_STATUS_OK; - } - -done: - SAFE_FREE(databuf.dptr); - talloc_free(idkey); - return ret; -} - bool idmap_cache_find_sid2uid(const struct dom_sid *sid, uid_t *puid, bool *expired) { diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index 13c510d4f9..08cf8ba00a 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -340,9 +340,6 @@ static struct winbindd_dispatch_table { { WINBINDD_SID_TO_GID, winbindd_sid_to_gid, "SID_TO_GID" }, { WINBINDD_UID_TO_SID, winbindd_uid_to_sid, "UID_TO_SID" }, { WINBINDD_GID_TO_SID, winbindd_gid_to_sid, "GID_TO_SID" }, -#if 0 /* DISABLED until we fix the interface in Samba 3.0.26 --jerry */ - { WINBINDD_SIDS_TO_XIDS, winbindd_sids_to_unixids, "SIDS_TO_XIDS" }, -#endif /* end DISABLED */ { WINBINDD_ALLOCATE_UID, winbindd_allocate_uid, "ALLOCATE_UID" }, { WINBINDD_ALLOCATE_GID, winbindd_allocate_gid, "ALLOCATE_GID" }, { WINBINDD_SET_MAPPING, winbindd_set_mapping, "SET_MAPPING" }, diff --git a/source3/winbindd/winbindd_idmap.c b/source3/winbindd/winbindd_idmap.c index 3c7aa2d0c2..41782ff0d1 100644 --- a/source3/winbindd/winbindd_idmap.c +++ b/source3/winbindd/winbindd_idmap.c @@ -170,108 +170,6 @@ enum winbindd_result winbindd_dual_set_hwm(struct winbindd_domain *domain, return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; } -static void winbindd_sids2xids_recv(TALLOC_CTX *mem_ctx, bool success, - struct winbindd_response *response, - void *c, void *private_data) -{ - void (*cont)(void *priv, bool succ, void *, int) = - (void (*)(void *, bool, void *, int))c; - - if (!success) { - DEBUG(5, ("Could not trigger sids2xids\n")); - cont(private_data, False, NULL, 0); - return; - } - - if (response->result != WINBINDD_OK) { - DEBUG(5, ("sids2xids returned an error\n")); - cont(private_data, False, NULL, 0); - return; - } - - cont(private_data, True, response->extra_data.data, response->length - sizeof(response)); -} - -void winbindd_sids2xids_async(TALLOC_CTX *mem_ctx, void *sids, int size, - void (*cont)(void *private_data, bool success, void *data, int len), - void *private_data) -{ - struct winbindd_request request; - ZERO_STRUCT(request); - request.cmd = WINBINDD_DUAL_SIDS2XIDS; - request.extra_data.data = (char *)sids; - request.extra_len = size; - do_async(mem_ctx, idmap_child(), &request, winbindd_sids2xids_recv, - (void *)cont, private_data); -} - -enum winbindd_result winbindd_dual_sids2xids(struct winbindd_domain *domain, - struct winbindd_cli_state *state) -{ - DOM_SID *sids; - struct unixid *xids; - struct id_map **ids; - NTSTATUS result; - int num, i; - - DEBUG(3, ("[%5lu]: sids to unix ids\n", (unsigned long)state->pid)); - - if (state->request.extra_len == 0) { - DEBUG(0, ("Invalid buffer size!\n")); - return WINBINDD_ERROR; - } - - sids = (DOM_SID *)state->request.extra_data.data; - num = state->request.extra_len / sizeof(DOM_SID); - - ids = TALLOC_ZERO_ARRAY(state->mem_ctx, struct id_map *, num + 1); - if ( ! ids) { - DEBUG(0, ("Out of memory!\n")); - return WINBINDD_ERROR; - } - for (i = 0; i < num; i++) { - ids[i] = TALLOC_P(ids, struct id_map); - if ( ! ids[i]) { - DEBUG(0, ("Out of memory!\n")); - talloc_free(ids); - return WINBINDD_ERROR; - } - ids[i]->sid = &sids[i]; - } - - result = idmap_sids_to_unixids(ids); - - if (NT_STATUS_IS_OK(result)) { - - xids = SMB_MALLOC_ARRAY(struct unixid, num); - if ( ! xids) { - DEBUG(0, ("Out of memory!\n")); - talloc_free(ids); - return WINBINDD_ERROR; - } - - for (i = 0; i < num; i++) { - if (ids[i]->status == ID_MAPPED) { - xids[i].type = ids[i]->xid.type; - xids[i].id = ids[i]->xid.id; - } else { - xids[i].type = -1; - } - } - - state->response.length = sizeof(state->response) + (sizeof(struct unixid) * num); - state->response.extra_data.data = xids; - - } else { - DEBUG (2, ("idmap_sids_to_unixids returned an error: 0x%08x\n", NT_STATUS_V(result))); - talloc_free(ids); - return WINBINDD_ERROR; - } - - talloc_free(ids); - return WINBINDD_OK; -} - static void winbindd_sid2uid_recv(TALLOC_CTX *mem_ctx, bool success, struct winbindd_response *response, void *c, void *private_data) @@ -521,12 +419,6 @@ static const struct winbindd_child_dispatch_table idmap_dispatch_table[] = { .name = "DUAL_SID2GID", .struct_cmd = WINBINDD_DUAL_SID2GID, .struct_fn = winbindd_dual_sid2gid, -#if 0 /* DISABLED until we fix the interface in Samba 3.0.26 --jerry */ - },{ - .name = "DUAL_SIDS2XIDS", - .struct_cmd = WINBINDD_DUAL_SIDS2XIDS, - .struct_fn = winbindd_dual_sids2xids, -#endif /* end DISABLED */ },{ .name = "DUAL_UID2SID", .struct_cmd = WINBINDD_DUAL_UID2SID, diff --git a/source3/winbindd/winbindd_sid.c b/source3/winbindd/winbindd_sid.c index 2869c7c8e1..5f5972fb05 100644 --- a/source3/winbindd/winbindd_sid.c +++ b/source3/winbindd/winbindd_sid.c @@ -369,32 +369,6 @@ void winbindd_sid_to_gid(struct winbindd_cli_state *state) winbindd_lookupsid_async( state->mem_ctx, &sid, sid2gid_lookupsid_recv, state ); } -static void sids2xids_recv(void *private_data, bool success, void *data, int len) -{ - struct winbindd_cli_state *state = - talloc_get_type_abort(private_data, struct winbindd_cli_state); - - if (!success) { - DEBUG(5, ("Could not convert sids to xids\n")); - request_error(state); - return; - } - - state->response.extra_data.data = data; - state->response.length = sizeof(state->response) + len; - request_ok(state); -} - -void winbindd_sids_to_unixids(struct winbindd_cli_state *state) -{ - DEBUG(3, ("[%5lu]: sids to xids\n", (unsigned long)state->pid)); - - winbindd_sids2xids_async(state->mem_ctx, - state->request.extra_data.data, - state->request.extra_len, - sids2xids_recv, state); -} - static void set_mapping_recv(void *private_data, bool success) { struct winbindd_cli_state *state = |