mirror of
https://github.com/samba-team/samba.git
synced 2025-02-23 09:57:40 +03:00
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 Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Ralph Boehme <slow@samba.org>
This commit is contained in:
parent
650f29e2f3
commit
80506136cc
@ -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
|
||||
@ -945,59 +946,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;
|
||||
bool ok;
|
||||
|
||||
centry = centry_start(domain, status);
|
||||
if (!centry)
|
||||
return;
|
||||
|
||||
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;
|
||||
bool ok;
|
||||
|
||||
centry = centry_start(domain, status);
|
||||
if (!centry)
|
||||
return;
|
||||
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 ((domain_name == NULL) || (domain_name[0] == '\0')) {
|
||||
struct winbindd_domain *mydomain =
|
||||
find_domain_from_sid_noinit(sid);
|
||||
if (mydomain != NULL) {
|
||||
domain_name = mydomain->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");
|
||||
}
|
||||
}
|
||||
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
centry_put_uint32(centry, type);
|
||||
centry_put_string(centry, domain_name);
|
||||
centry_put_string(centry, name);
|
||||
}
|
||||
|
||||
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,
|
||||
@ -1752,47 +1734,51 @@ skip_save:
|
||||
return status;
|
||||
}
|
||||
|
||||
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 wcache_name_to_sid_state *state = private_data;
|
||||
|
||||
*state->sid = *sid;
|
||||
*state->type = type;
|
||||
state->found = (state->offline || (timeout < time(NULL)));
|
||||
}
|
||||
|
||||
static 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 winbind_cache *cache = get_cache(domain);
|
||||
struct cache_entry *centry;
|
||||
NTSTATUS status;
|
||||
char *uname;
|
||||
struct wcache_name_to_sid_state state = {
|
||||
.sid = sid, .type = type, .found = false,
|
||||
.offline = is_domain_offline(domain),
|
||||
};
|
||||
bool ok;
|
||||
|
||||
if (cache->tdb == NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
uname = talloc_strdup_upper(talloc_tos(), name);
|
||||
if (uname == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
if ((domain_name == NULL) || (domain_name[0] == '\0')) {
|
||||
domain_name = domain->name;
|
||||
}
|
||||
|
||||
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 */
|
||||
@ -1830,6 +1816,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);
|
||||
|
||||
@ -1851,7 +1838,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, '@')) {
|
||||
@ -1859,13 +1853,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,
|
||||
@ -1873,39 +1895,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
|
||||
@ -1944,6 +1954,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) ||
|
||||
@ -2014,49 +2026,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;
|
||||
have_mapped = true;
|
||||
(*types)[i] = (enum lsa_SidType)centry_uint32(centry);
|
||||
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] = 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) {
|
||||
@ -2102,50 +2110,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) {
|
||||
@ -3604,52 +3605,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)
|
||||
{
|
||||
@ -4024,8 +3979,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},
|
||||
|
Loading…
x
Reference in New Issue
Block a user