diff options
author | Volker Lendecke <vl@samba.org> | 2017-08-06 18:13:10 +0200 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2018-05-24 12:50:13 +0200 |
commit | a92c5dc7800a32c4dc58051c111a43b4749d0854 (patch) | |
tree | abd132c45051688c1a219ee3b7d840e4944010aa | |
parent | ea49628bdc94c960a60d466f963f5d97afa5953e (diff) | |
download | samba-a92c5dc7800a32c4dc58051c111a43b4749d0854.tar.gz |
winbindd: Move name<->sid cache to gencache
The mapping from name to sid and vice versa has nothing to
do with a specific domain. It is publically available. Thus put
it into gencache without referring to the domain this was
retrieved from
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13369
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
-rw-r--r-- | source3/winbindd/winbindd_cache.c | 333 |
1 files changed, 143 insertions, 190 deletions
diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c index 8492f907553..afc688fd5f9 100644 --- a/source3/winbindd/winbindd_cache.c +++ b/source3/winbindd/winbindd_cache.c @@ -35,6 +35,7 @@ #include "passdb/machine_sid.h" #include "util_tdb.h" #include "libsmb/samlogon_cache.h" +#include "lib/namemap_cache.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND @@ -961,59 +962,40 @@ static void wcache_save_name_to_sid(struct winbindd_domain *domain, const char *name, const struct dom_sid *sid, enum lsa_SidType type) { - struct cache_entry *centry; - fstring uname; - - centry = centry_start(domain, status); - if (!centry) - return; + bool ok; - if ((domain_name == NULL) || (domain_name[0] == '\0')) { - struct winbindd_domain *mydomain = - find_domain_from_sid_noinit(sid); - if (mydomain != NULL) { - domain_name = mydomain->name; - } + ok = namemap_cache_set_name2sid(domain_name, name, sid, type, + time(NULL) + lp_winbind_cache_time()); + if (!ok) { + DBG_DEBUG("namemap_cache_set_name2sid failed\n"); } - centry_put_uint32(centry, type); - centry_put_sid(centry, sid); - fstrcpy(uname, name); - (void)strupper_m(uname); - centry_end(centry, "NS/%s/%s", domain_name, uname); - DEBUG(10,("wcache_save_name_to_sid: %s\\%s -> %s (%s)\n", domain_name, - uname, sid_string_dbg(sid), nt_errstr(status))); - centry_free(centry); + /* + * Don't store the reverse mapping. The name came from user + * input, and we might not have the correct capitalization, + * which is important for nsswitch. + */ } static void wcache_save_sid_to_name(struct winbindd_domain *domain, NTSTATUS status, const struct dom_sid *sid, const char *domain_name, const char *name, enum lsa_SidType type) { - struct cache_entry *centry; - fstring sid_string; - - centry = centry_start(domain, status); - if (!centry) - return; + bool ok; - if ((domain_name == NULL) || (domain_name[0] == '\0')) { - struct winbindd_domain *mydomain = - find_domain_from_sid_noinit(sid); - if (mydomain != NULL) { - domain_name = mydomain->name; - } + ok = namemap_cache_set_sid2name(sid, domain_name, name, type, + time(NULL) + lp_winbind_cache_time()); + if (!ok) { + DBG_DEBUG("namemap_cache_set_sid2name failed\n"); } - if (NT_STATUS_IS_OK(status)) { - centry_put_uint32(centry, type); - centry_put_string(centry, domain_name); - centry_put_string(centry, name); + if (type != SID_NAME_UNKNOWN) { + ok = namemap_cache_set_name2sid( + domain_name, name, sid, type, + time(NULL) + lp_winbind_cache_time()); + if (!ok) { + DBG_DEBUG("namemap_cache_set_name2sid failed\n"); + } } - - centry_end(centry, "SN/%s", sid_to_fstring(sid_string, sid)); - DEBUG(10,("wcache_save_sid_to_name: %s -> %s\\%s (%s)\n", sid_string, - domain_name, name, nt_errstr(status))); - centry_free(centry); } static void wcache_save_lockout_policy(struct winbindd_domain *domain, @@ -1769,47 +1751,51 @@ skip_save: return status; } -NTSTATUS wcache_name_to_sid(struct winbindd_domain *domain, - const char *domain_name, - const char *name, - struct dom_sid *sid, - enum lsa_SidType *type) +struct wcache_name_to_sid_state { + struct dom_sid *sid; + enum lsa_SidType *type; + bool offline; + bool found; +}; + +static void wcache_name_to_sid_fn(const struct dom_sid *sid, + enum lsa_SidType type, time_t timeout, + void *private_data) { - struct winbind_cache *cache = get_cache(domain); - struct cache_entry *centry; - NTSTATUS status; - char *uname; + struct wcache_name_to_sid_state *state = private_data; - if (cache->tdb == NULL) { - return NT_STATUS_NOT_FOUND; - } + *state->sid = *sid; + *state->type = type; + state->found = (state->offline || (timeout < time(NULL))); +} - uname = talloc_strdup_upper(talloc_tos(), name); - if (uname == NULL) { - return NT_STATUS_NO_MEMORY; - } +NTSTATUS wcache_name_to_sid(struct winbindd_domain *domain, + const char *domain_name, + const char *name, + struct dom_sid *sid, + enum lsa_SidType *type) +{ + struct wcache_name_to_sid_state state = { + .sid = sid, .type = type, .found = false, + .offline = is_domain_offline(domain), + }; + bool ok; - if ((domain_name == NULL) || (domain_name[0] == '\0')) { - domain_name = domain->name; + ok = namemap_cache_find_name(domain_name, name, wcache_name_to_sid_fn, + &state); + if (!ok) { + DBG_DEBUG("namemap_cache_find_name failed\n"); + return NT_STATUS_NOT_FOUND; } - - centry = wcache_fetch(cache, domain, "NS/%s/%s", domain_name, uname); - TALLOC_FREE(uname); - if (centry == NULL) { + if (!state.found) { + DBG_DEBUG("cache entry not found\n"); return NT_STATUS_NOT_FOUND; } - - status = centry->status; - if (NT_STATUS_IS_OK(status)) { - *type = (enum lsa_SidType)centry_uint32(centry); - centry_sid(centry, sid); + if (*type == SID_NAME_UNKNOWN) { + return NT_STATUS_NONE_MAPPED; } - DEBUG(10,("name_to_sid: [Cached] - cached name for domain %s status: " - "%s\n", domain->name, nt_errstr(status) )); - - centry_free(centry); - return status; + return NT_STATUS_OK; } /* convert a single name to a sid in a domain */ @@ -1847,6 +1833,7 @@ NTSTATUS wb_cache_name_to_sid(struct winbindd_domain *domain, DEBUG(10,("name_to_sid: [Cached] - doing backend query for name for domain %s\n", domain->name )); + winbindd_domain_init_backend(domain); status = domain->backend->name_to_sid(domain, mem_ctx, domain_name, name, flags, sid, type); @@ -1868,7 +1855,14 @@ NTSTATUS wb_cache_name_to_sid(struct winbindd_domain *domain, if (domain->online && (NT_STATUS_IS_OK(status) || NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED))) { - wcache_save_name_to_sid(domain, status, domain_name, name, sid, *type); + enum lsa_SidType save_type = *type; + + if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) { + save_type = SID_NAME_UNKNOWN; + } + + wcache_save_name_to_sid(domain, status, domain_name, name, sid, + save_type); /* Only save the reverse mapping if this was not a UPN */ if (!strchr(name, '@')) { @@ -1876,13 +1870,41 @@ NTSTATUS wb_cache_name_to_sid(struct winbindd_domain *domain, return NT_STATUS_INVALID_PARAMETER; } (void)strlower_m(discard_const_p(char, name)); - wcache_save_sid_to_name(domain, status, sid, domain_name, name, *type); + wcache_save_sid_to_name(domain, status, sid, + domain_name, name, save_type); } } return status; } +struct wcache_sid_to_name_state { + TALLOC_CTX *mem_ctx; + char **domain_name; + char **name; + enum lsa_SidType *type; + bool offline; + bool found; +}; + +static void wcache_sid_to_name_fn(const char *domain, const char *name, + enum lsa_SidType type, time_t timeout, + void *private_data) +{ + struct wcache_sid_to_name_state *state = private_data; + + *state->domain_name = talloc_strdup(state->mem_ctx, domain); + if (*state->domain_name == NULL) { + return; + } + *state->name = talloc_strdup(state->mem_ctx, name); + if (*state->name == NULL) { + return; + } + *state->type = type; + state->found = (state->offline || (timeout < time(NULL))); +} + static NTSTATUS wcache_sid_to_name(struct winbindd_domain *domain, const struct dom_sid *sid, TALLOC_CTX *mem_ctx, @@ -1890,39 +1912,27 @@ static NTSTATUS wcache_sid_to_name(struct winbindd_domain *domain, char **name, enum lsa_SidType *type) { - struct winbind_cache *cache = get_cache(domain); - struct cache_entry *centry; - char *sid_string; - NTSTATUS status; + struct wcache_sid_to_name_state state = { + .mem_ctx = mem_ctx, .found = false, + .domain_name = domain_name, .name = name, .type = type, + .offline = is_domain_offline(domain) + }; + bool ok; - if (cache->tdb == NULL) { + ok = namemap_cache_find_sid(sid, wcache_sid_to_name_fn, &state); + if (!ok) { + DBG_DEBUG("namemap_cache_find_name failed\n"); return NT_STATUS_NOT_FOUND; } - - sid_string = sid_string_tos(sid); - if (sid_string == NULL) { - return NT_STATUS_NO_MEMORY; - } - - centry = wcache_fetch(cache, domain, "SN/%s", sid_string); - TALLOC_FREE(sid_string); - if (centry == NULL) { + if (!state.found) { + DBG_DEBUG("cache entry not found\n"); return NT_STATUS_NOT_FOUND; } - - if (NT_STATUS_IS_OK(centry->status)) { - *type = (enum lsa_SidType)centry_uint32(centry); - *domain_name = centry_string(centry, mem_ctx); - *name = centry_string(centry, mem_ctx); + if (*type == SID_NAME_UNKNOWN) { + return NT_STATUS_NONE_MAPPED; } - status = centry->status; - centry_free(centry); - - DEBUG(10,("sid_to_name: [Cached] - cached name for domain %s status: " - "%s\n", domain->name, nt_errstr(status) )); - - return status; + return NT_STATUS_OK; } /* convert a sid to a user or group name. The sid is guaranteed to be in the domain @@ -1961,6 +1971,8 @@ NTSTATUS wb_cache_sid_to_name(struct winbindd_domain *domain, DEBUG(10,("sid_to_name: [Cached] - doing backend query for name for domain %s\n", domain->name )); + winbindd_domain_init_backend(domain); + status = domain->backend->sid_to_name(domain, mem_ctx, sid, domain_name, name, type); if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) || @@ -2031,49 +2043,45 @@ NTSTATUS wb_cache_rids_to_names(struct winbindd_domain *domain, for (i=0; i<num_rids; i++) { struct dom_sid sid; - struct cache_entry *centry; - fstring tmp; + NTSTATUS status; + enum lsa_SidType type; + char *dom, *name; if (!sid_compose(&sid, domain_sid, rids[i])) { result = NT_STATUS_INTERNAL_ERROR; goto error; } - centry = wcache_fetch(cache, domain, "SN/%s", - sid_to_fstring(tmp, &sid)); - if (!centry) { - goto do_query; - } + status = wcache_sid_to_name(domain, &sid, *names, &dom, + &name, &type); (*types)[i] = SID_NAME_UNKNOWN; (*names)[i] = talloc_strdup(*names, ""); - if (NT_STATUS_IS_OK(centry->status)) { - char *dom; + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { + /* not cached */ + goto do_query; + } + + if (NT_STATUS_IS_OK(status)) { have_mapped = true; - (*types)[i] = (enum lsa_SidType)centry_uint32(centry); + (*types)[i] = type; - dom = centry_string(centry, mem_ctx); if (*domain_name == NULL) { *domain_name = dom; } else { - talloc_free(dom); + TALLOC_FREE(dom); } - (*names)[i] = centry_string(centry, *names); + (*names)[i] = name; - } else if (NT_STATUS_EQUAL(centry->status, NT_STATUS_NONE_MAPPED) - || NT_STATUS_EQUAL(centry->status, STATUS_SOME_UNMAPPED)) { + } else if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) { have_unmapped = true; - } else { /* something's definitely wrong */ - result = centry->status; - centry_free(centry); + result = status; goto error; } - - centry_free(centry); } if (!have_mapped) { @@ -2119,50 +2127,43 @@ NTSTATUS wb_cache_rids_to_names(struct winbindd_domain *domain, for (i=0; i<num_rids; i++) { struct dom_sid sid; - struct cache_entry *centry; - fstring tmp; + NTSTATUS status; + enum lsa_SidType type; + char *dom, *name; if (!sid_compose(&sid, domain_sid, rids[i])) { result = NT_STATUS_INTERNAL_ERROR; goto error; } - centry = wcache_fetch(cache, domain, "SN/%s", - sid_to_fstring(tmp, &sid)); - if (!centry) { - (*types)[i] = SID_NAME_UNKNOWN; - (*names)[i] = talloc_strdup(*names, ""); - continue; - } + status = wcache_sid_to_name(domain, &sid, + *names, &dom, + &name, &type); (*types)[i] = SID_NAME_UNKNOWN; (*names)[i] = talloc_strdup(*names, ""); - if (NT_STATUS_IS_OK(centry->status)) { - char *dom; + if (NT_STATUS_IS_OK(status)) { have_mapped = true; - (*types)[i] = (enum lsa_SidType)centry_uint32(centry); + (*types)[i] = type; - dom = centry_string(centry, mem_ctx); if (*domain_name == NULL) { *domain_name = dom; } else { - talloc_free(dom); + TALLOC_FREE(dom); } - (*names)[i] = centry_string(centry, *names); + (*names)[i] = name; - } else if (NT_STATUS_EQUAL(centry->status, NT_STATUS_NONE_MAPPED)) { + } else if (NT_STATUS_EQUAL( + status, + NT_STATUS_NONE_MAPPED)) { have_unmapped = true; - } else { /* something's definitely wrong */ - result = centry->status; - centry_free(centry); + result = status; goto error; } - - centry_free(centry); } if (!have_mapped) { @@ -3620,52 +3621,6 @@ static int validate_seqnum(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbu return 0; } -static int validate_ns(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf, - struct tdb_validation_status *state) -{ - struct cache_entry *centry = create_centry_validate(keystr, dbuf, state); - if (!centry) { - return 1; - } - - (void)centry_uint32(centry); - if (NT_STATUS_IS_OK(centry->status)) { - struct dom_sid sid; - (void)centry_sid(centry, &sid); - } - - centry_free(centry); - - if (!(state->success)) { - return 1; - } - DEBUG(10,("validate_ns: %s ok\n", keystr)); - return 0; -} - -static int validate_sn(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf, - struct tdb_validation_status *state) -{ - struct cache_entry *centry = create_centry_validate(keystr, dbuf, state); - if (!centry) { - return 1; - } - - if (NT_STATUS_IS_OK(centry->status)) { - (void)centry_uint32(centry); - (void)centry_string(centry, mem_ctx); - (void)centry_string(centry, mem_ctx); - } - - centry_free(centry); - - if (!(state->success)) { - return 1; - } - DEBUG(10,("validate_sn: %s ok\n", keystr)); - return 0; -} - static int validate_u(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf, struct tdb_validation_status *state) { @@ -4040,8 +3995,6 @@ struct key_val_struct { int (*validate_data_fn)(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf, struct tdb_validation_status* state); } key_val[] = { {"SEQNUM/", validate_seqnum}, - {"NS/", validate_ns}, - {"SN/", validate_sn}, {"U/", validate_u}, {"LOC_POL/", validate_loc_pol}, {"PWD_POL/", validate_pwd_pol}, |