From 6b289970a6f3c92dd78461938f93e20c6b0238e0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 2 Aug 2017 17:22:34 +0200 Subject: [PATCH 01/14] lib: Pass in "strv_len" to strv_valid_entry Preparation for a later commit BUG: https://bugzilla.samba.org/show_bug.cgi?id=13369 Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme --- lib/util/strv.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/lib/util/strv.c b/lib/util/strv.c index 99ce76f54fd..864a3e5cf8b 100644 --- a/lib/util/strv.c +++ b/lib/util/strv.c @@ -62,27 +62,23 @@ int strv_append(TALLOC_CTX *mem_ctx, char **strv, const char *src) return _strv_append(mem_ctx, strv, src, talloc_array_length(src)); } -static bool strv_valid_entry(const char *strv, const char *entry, - size_t *strv_len, size_t *entry_len) +static bool strv_valid_entry(const char *strv, size_t strv_len, + const char *entry, size_t *entry_len) { - size_t len; - - len = talloc_array_length(strv); - if (len == 0) { + if (strv_len == 0) { return false; } - if (strv[len-1] != '\0') { + if (strv[strv_len-1] != '\0') { return false; } if (entry < strv) { return false; } - if (entry >= (strv+len)) { + if (entry >= (strv+strv_len)) { return false; } - *strv_len = len; *entry_len = strlen(entry); return true; @@ -90,17 +86,18 @@ static bool strv_valid_entry(const char *strv, const char *entry, char *strv_next(char *strv, const char *entry) { - size_t len, entry_len; + size_t len = talloc_array_length(strv); + size_t entry_len; char *result; if (entry == NULL) { - if (strv_valid_entry(strv, strv, &len, &entry_len)) { + if (strv_valid_entry(strv, len, strv, &entry_len)) { return strv; } return NULL; } - if (!strv_valid_entry(strv, entry, &len, &entry_len)) { + if (!strv_valid_entry(strv, len, entry, &entry_len)) { return NULL; } result = &strv[entry - strv]; /* avoid const problems with this stmt */ @@ -139,13 +136,14 @@ char *strv_find(char *strv, const char *entry) void strv_delete(char **strv, char *entry) { - size_t len, entry_len; + size_t len = talloc_array_length(*strv); + size_t entry_len; if (entry == NULL) { return; } - if (!strv_valid_entry(*strv, entry, &len, &entry_len)) { + if (!strv_valid_entry(*strv, len, entry, &entry_len)) { return; } entry_len += 1; -- 2.16.3 From 49195af79d4691a1429e94846bce24da67e20979 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 2 Aug 2017 17:32:50 +0200 Subject: [PATCH 02/14] lib: Only call strlen if necessary in strv BUG: https://bugzilla.samba.org/show_bug.cgi?id=13369 Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme --- lib/util/strv.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/util/strv.c b/lib/util/strv.c index 864a3e5cf8b..328f561722b 100644 --- a/lib/util/strv.c +++ b/lib/util/strv.c @@ -79,7 +79,9 @@ static bool strv_valid_entry(const char *strv, size_t strv_len, return false; } - *entry_len = strlen(entry); + if (entry_len != NULL) { + *entry_len = strlen(entry); + } return true; } @@ -91,7 +93,7 @@ char *strv_next(char *strv, const char *entry) char *result; if (entry == NULL) { - if (strv_valid_entry(strv, len, strv, &entry_len)) { + if (strv_valid_entry(strv, len, strv, NULL)) { return strv; } return NULL; -- 2.16.3 From f572b059e96d3bf2f267184b12f0292962476237 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 2 Aug 2017 17:34:25 +0200 Subject: [PATCH 03/14] lib: Allow parsing a strv from a non-talloc const buf This will allow parsing a tdb record without having to talloc_memdup it BUG: https://bugzilla.samba.org/show_bug.cgi?id=13369 Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme --- lib/util/strv.c | 26 +++++++++++++++++--------- lib/util/strv.h | 2 ++ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/lib/util/strv.c b/lib/util/strv.c index 328f561722b..83d84d92528 100644 --- a/lib/util/strv.c +++ b/lib/util/strv.c @@ -86,29 +86,37 @@ static bool strv_valid_entry(const char *strv, size_t strv_len, return true; } -char *strv_next(char *strv, const char *entry) +const char *strv_len_next(const char *strv, size_t strv_len, + const char *entry) { - size_t len = talloc_array_length(strv); size_t entry_len; - char *result; if (entry == NULL) { - if (strv_valid_entry(strv, len, strv, NULL)) { + if (strv_valid_entry(strv, strv_len, strv, NULL)) { return strv; } return NULL; } - if (!strv_valid_entry(strv, len, entry, &entry_len)) { + if (!strv_valid_entry(strv, strv_len, entry, &entry_len)) { return NULL; } - result = &strv[entry - strv]; /* avoid const problems with this stmt */ - result += entry_len + 1; - if (result >= (strv + len)) { + entry += entry_len+1; + + if (entry >= (strv + strv_len)) { return NULL; } - return result; + return entry; +} + +char *strv_next(char *strv, const char *entry) +{ + size_t len = talloc_array_length(strv); + const char *result; + + result = strv_len_next(strv, len, entry); + return discard_const_p(char, result); } size_t strv_count(char *strv) diff --git a/lib/util/strv.h b/lib/util/strv.h index 398e8ead171..89f04023e44 100644 --- a/lib/util/strv.h +++ b/lib/util/strv.h @@ -26,6 +26,8 @@ int strv_add(TALLOC_CTX *mem_ctx, char **strv, const char *string); int strv_addn(TALLOC_CTX *mem_ctx, char **strv, const char *src, size_t srclen); int strv_append(TALLOC_CTX *mem_ctx, char **strv, const char *src); char *strv_next(char *strv, const char *entry); +const char *strv_len_next(const char *strv, size_t strv_len, + const char *entry); char *strv_find(char *strv, const char *entry); size_t strv_count(char *strv); void strv_delete(char **strv, char *entry); -- 2.16.3 From 70c4e00d8efba17c7bcd877d445ed32c5e633d6d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 2 Aug 2017 17:52:40 +0200 Subject: [PATCH 04/14] lib: Pass blob instead of &blob to gencache_set_data_blob Passing a whole DATA_BLOB is cheap enough to simplify the callers: A caller does not have to create a separate variable. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13369 Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme --- source3/lib/gencache.c | 12 ++++++------ source3/lib/gencache.h | 2 +- source3/libsmb/dsgetdcname.c | 7 ++++--- source3/torture/torture.c | 4 ++-- source3/winbindd/wb_dsgetdcname.c | 2 +- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c index 1572825f605..83fa67c5700 100644 --- a/source3/lib/gencache.c +++ b/source3/lib/gencache.c @@ -275,7 +275,7 @@ static int last_stabilize_parser(TDB_DATA key, TDB_DATA data, * @retval false on failure **/ -bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, +bool gencache_set_data_blob(const char *keystr, DATA_BLOB blob, time_t timeout) { int ret; @@ -291,7 +291,7 @@ bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, return false; } - if ((keystr == NULL) || (blob == NULL)) { + if ((keystr == NULL) || (blob.data == NULL)) { return false; } @@ -299,7 +299,7 @@ bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, return false; } - if ((timeout != 0) && gencache_have_val(keystr, blob, timeout)) { + if ((timeout != 0) && gencache_have_val(keystr, &blob, timeout)) { DEBUG(10, ("Did not store value for %s, we already got it\n", keystr)); return true; @@ -310,12 +310,12 @@ bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, if (hdr_len == -1) { return false; } - if ((blob->length + (size_t)hdr_len) < blob->length) { + if ((blob.length + (size_t)hdr_len) < blob.length) { return false; } dbufs[0] = (TDB_DATA) { .dptr = (uint8_t *)hdr, .dsize = hdr_len }; - dbufs[1] = (TDB_DATA) { .dptr = blob->data, .dsize = blob->length }; + dbufs[1] = (TDB_DATA) { .dptr = blob.data, .dsize = blob.length }; DEBUG(10, ("Adding cache entry with key=[%s] and timeout=" "[%s] (%d seconds %s)\n", keystr, @@ -842,7 +842,7 @@ bool gencache_get(const char *keystr, TALLOC_CTX *mem_ctx, char **value, bool gencache_set(const char *keystr, const char *value, time_t timeout) { DATA_BLOB blob = data_blob_const(value, strlen(value)+1); - return gencache_set_data_blob(keystr, &blob, timeout); + return gencache_set_data_blob(keystr, blob, timeout); } struct gencache_iterate_blobs_state { diff --git a/source3/lib/gencache.h b/source3/lib/gencache.h index 4371835599d..fa72a4aa466 100644 --- a/source3/lib/gencache.h +++ b/source3/lib/gencache.h @@ -40,7 +40,7 @@ bool gencache_get_data_blob(const char *keystr, TALLOC_CTX *mem_ctx, DATA_BLOB *blob, time_t *timeout, bool *was_expired); bool gencache_stabilize(void); -bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, +bool gencache_set_data_blob(const char *keystr, DATA_BLOB blob, time_t timeout); void gencache_iterate_blobs(void (*fn)(const char *key, DATA_BLOB value, time_t timeout, void *private_data), diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 92fc312c6a4..ce0cc89899c 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -154,7 +154,7 @@ static NTSTATUS dsgetdcname_cache_delete(TALLOC_CTX *mem_ctx, static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx, const char *domain_name, - const DATA_BLOB *blob) + DATA_BLOB blob) { time_t expire_time; char *key; @@ -200,7 +200,8 @@ static NTSTATUS store_cldap_reply(TALLOC_CTX *mem_ctx, } if (r->domain_name) { - status = dsgetdcname_cache_store(mem_ctx, r->domain_name, &blob); + status = dsgetdcname_cache_store(mem_ctx, r->domain_name, + blob); if (!NT_STATUS_IS_OK(status)) { goto done; } @@ -209,7 +210,7 @@ static NTSTATUS store_cldap_reply(TALLOC_CTX *mem_ctx, } } if (r->dns_domain) { - status = dsgetdcname_cache_store(mem_ctx, r->dns_domain, &blob); + status = dsgetdcname_cache_store(mem_ctx, r->dns_domain, blob); if (!NT_STATUS_IS_OK(status)) { goto done; } diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 1709e94289c..3bc4f9cca45 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -10034,7 +10034,7 @@ static bool run_local_gencache(int dummy) blob = data_blob_string_const_null("bar"); tm = time(NULL) + 60; - if (!gencache_set_data_blob("foo", &blob, tm)) { + if (!gencache_set_data_blob("foo", blob, tm)) { d_printf("%s: gencache_set_data_blob() failed\n", __location__); return False; } @@ -10073,7 +10073,7 @@ static bool run_local_gencache(int dummy) blob.data = (uint8_t *)&v; blob.length = sizeof(v); - if (!gencache_set_data_blob("blob", &blob, tm)) { + if (!gencache_set_data_blob("blob", blob, tm)) { d_printf("%s: gencache_set_data_blob() failed\n", __location__); return false; diff --git a/source3/winbindd/wb_dsgetdcname.c b/source3/winbindd/wb_dsgetdcname.c index bfc6aa11058..2f450c7a2b4 100644 --- a/source3/winbindd/wb_dsgetdcname.c +++ b/source3/winbindd/wb_dsgetdcname.c @@ -153,7 +153,7 @@ NTSTATUS wb_dsgetdcname_gencache_set(const char *domname, return status; } - ok = gencache_set_data_blob(key, &blob, time(NULL)+3600); + ok = gencache_set_data_blob(key, blob, time(NULL)+3600); if (!ok) { DBG_WARNING("gencache_set_data_blob for key %s failed\n", key); -- 2.16.3 From 095c442850e2852305399ed825a293ab91854cfc Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 2 Aug 2017 18:11:49 +0200 Subject: [PATCH 05/14] lib: Add namemap_cache A few functions to maintain lookupname and lookupsid cache in gencache. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13369 Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme --- source3/lib/namemap_cache.c | 323 ++++++++++++++++++++++++++++++++++++++++++++ source3/lib/namemap_cache.h | 45 ++++++ source3/wscript_build | 1 + 3 files changed, 369 insertions(+) create mode 100644 source3/lib/namemap_cache.c create mode 100644 source3/lib/namemap_cache.h diff --git a/source3/lib/namemap_cache.c b/source3/lib/namemap_cache.c new file mode 100644 index 00000000000..0d6ed32abc5 --- /dev/null +++ b/source3/lib/namemap_cache.c @@ -0,0 +1,323 @@ +/* + * Unix SMB/CIFS implementation. + * Utils for caching sid2name and name2sid + * Copyright (C) Volker Lendecke 2017 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "replace.h" +#include "namemap_cache.h" +#include "source3/lib/gencache.h" +#include "lib/util/debug.h" +#include "lib/util/strv.h" +#include "lib/util/talloc_stack.h" +#include "lib/util/charset/charset.h" +#include "libcli/security/dom_sid.h" + +bool namemap_cache_set_sid2name(const struct dom_sid *sid, + const char *domain, const char *name, + enum lsa_SidType type, time_t timeout) +{ + char typebuf[16]; + char sidbuf[DOM_SID_STR_BUFLEN]; + char keybuf[DOM_SID_STR_BUFLEN+10]; + char *val = NULL; + DATA_BLOB data; + int ret; + bool ok = false; + + if ((sid == NULL) || is_null_sid(sid)) { + return true; + } + if (domain == NULL) { + domain = ""; + } + if (name == NULL) { + name = ""; + } + if (type == SID_NAME_UNKNOWN) { + domain = ""; + name = ""; + } + + snprintf(typebuf, sizeof(typebuf), "%d", (int)type); + snprintf(keybuf, sizeof(keybuf), "SID2NAME/%s", sidbuf); + + ret = strv_add(talloc_tos(), &val, domain); + if (ret != 0) { + DBG_DEBUG("strv_add failed: %s\n", strerror(ret)); + goto fail; + } + ret = strv_add(NULL, &val, name); + if (ret != 0) { + DBG_DEBUG("strv_add failed: %s\n", strerror(ret)); + goto fail; + } + ret = strv_add(NULL, &val, typebuf); + if (ret != 0) { + DBG_DEBUG("strv_add failed: %s\n", strerror(ret)); + goto fail; + } + + dom_sid_string_buf(sid, sidbuf, sizeof(sidbuf)); + snprintf(keybuf, sizeof(keybuf), "SID2NAME/%s", sidbuf); + + data = data_blob_const(val, talloc_get_size(val)); + + ok = gencache_set_data_blob(keybuf, data, timeout); + if (!ok) { + DBG_DEBUG("gencache_set_data_blob failed\n"); + } +fail: + TALLOC_FREE(val); + return ok; +} + +struct namemap_cache_find_sid_state { + void (*fn)(const char *domain, const char *name, + enum lsa_SidType type, time_t timeout, + void *private_data); + void *private_data; + bool ok; +}; + +static void namemap_cache_find_sid_parser(time_t timeout, DATA_BLOB blob, + void *private_data) +{ + struct namemap_cache_find_sid_state *state = private_data; + const char *strv = (const char *)blob.data; + size_t strv_len = blob.length; + const char *domain; + const char *name; + const char *typebuf; + char *endptr; + unsigned long type; + + state->ok = false; + + domain = strv_len_next(strv, strv_len, NULL); + if (domain == NULL) { + return; + } + name = strv_len_next(strv, strv_len, domain); + if (name == NULL) { + return; + } + typebuf = strv_len_next(strv, strv_len, name); + if (typebuf == NULL) { + return; + } + + type = strtoul(typebuf, &endptr, 10); + if (*endptr != '\0') { + return; + } + if ((type == ULONG_MAX) && (errno == ERANGE)) { + return; + } + + state->fn(domain, name, (enum lsa_SidType)type, timeout, + state->private_data); + + state->ok = true; +} + +bool namemap_cache_find_sid(const struct dom_sid *sid, + void (*fn)(const char *domain, const char *name, + enum lsa_SidType type, time_t timeout, + void *private_data), + void *private_data) +{ + struct namemap_cache_find_sid_state state = { + .fn = fn, .private_data = private_data + }; + char sidbuf[DOM_SID_STR_BUFLEN]; + char keybuf[DOM_SID_STR_BUFLEN+10]; + bool ok; + + dom_sid_string_buf(sid, sidbuf, sizeof(sidbuf)); + snprintf(keybuf, sizeof(keybuf), "SID2NAME/%s", sidbuf); + + ok = gencache_parse(keybuf, namemap_cache_find_sid_parser, &state); + if (!ok) { + DBG_DEBUG("gencache_parse(%s) failed\n", keybuf); + return false; + } + + if (!state.ok) { + DBG_DEBUG("Could not parse %s, deleting\n", keybuf); + gencache_del(keybuf); + return false; + } + + return true; +} + +bool namemap_cache_set_name2sid(const char *domain, const char *name, + const struct dom_sid *sid, + enum lsa_SidType type, + time_t timeout) +{ + char typebuf[16]; + char sidbuf[DOM_SID_STR_BUFLEN]; + char *key; + char *key_upper; + char *val = NULL; + DATA_BLOB data; + int ret; + bool ok = false; + + if (domain == NULL) { + domain = ""; + } + if (name == NULL) { + name = ""; + } + if (type == SID_NAME_UNKNOWN) { + sidbuf[0] = '\0'; + } else { + dom_sid_string_buf(sid, sidbuf, sizeof(sidbuf)); + } + + snprintf(typebuf, sizeof(typebuf), "%d", (int)type); + + key = talloc_asprintf(talloc_tos(), "NAME2SID/%s\\%s", domain, name); + if (key == NULL) { + DBG_DEBUG("talloc_asprintf failed\n"); + goto fail; + } + key_upper = strupper_talloc(key, key); + if (key_upper == NULL) { + DBG_DEBUG("strupper_talloc failed\n"); + goto fail; + } + + ret = strv_add(key, &val, sidbuf); + if (ret != 0) { + DBG_DEBUG("strv_add failed: %s\n", strerror(ret)); + goto fail; + } + ret = strv_add(NULL, &val, typebuf); + if (ret != 0) { + DBG_DEBUG("strv_add failed: %s\n", strerror(ret)); + goto fail; + } + + data = data_blob_const(val, talloc_get_size(val)); + + ok = gencache_set_data_blob(key_upper, data, timeout); + if (!ok) { + DBG_DEBUG("gencache_set_data_blob failed\n"); + } +fail: + TALLOC_FREE(key); + return ok; +} + +struct namemap_cache_find_name_state { + void (*fn)(const struct dom_sid *sid, + enum lsa_SidType type, time_t timeout, + void *private_data); + void *private_data; + bool ok; +}; + +static void namemap_cache_find_name_parser(time_t timeout, DATA_BLOB blob, + void *private_data) +{ + struct namemap_cache_find_name_state *state = private_data; + const char *strv = (const char *)blob.data; + size_t strv_len = blob.length; + const char *sidbuf; + const char *sid_endptr; + const char *typebuf; + char *endptr; + struct dom_sid sid; + unsigned long type; + bool ok; + + state->ok = false; + + sidbuf = strv_len_next(strv, strv_len, NULL); + if (sidbuf == NULL) { + return; + } + typebuf = strv_len_next(strv, strv_len, sidbuf); + if (typebuf == NULL) { + return; + } + + ok = dom_sid_parse_endp(sidbuf, &sid, &sid_endptr); + if (!ok) { + return; + } + if (*sid_endptr != '\0') { + return; + } + + type = strtoul(typebuf, &endptr, 10); + if (*endptr != '\0') { + return; + } + if ((type == ULONG_MAX) && (errno == ERANGE)) { + return; + } + + state->fn(&sid, (enum lsa_SidType)type, timeout, state->private_data); + + state->ok = true; +} + +bool namemap_cache_find_name(const char *domain, const char *name, + void (*fn)(const struct dom_sid *sid, + enum lsa_SidType type, time_t timeout, + void *private_data), + void *private_data) +{ + struct namemap_cache_find_name_state state = { + .fn = fn, .private_data = private_data + }; + char *key; + char *key_upper; + bool ret = false; + bool ok; + + key = talloc_asprintf(talloc_tos(), "NAME2SID/%s\\%s", domain, name); + if (key == NULL) { + DBG_DEBUG("talloc_asprintf failed\n"); + return false; + } + key_upper = strupper_talloc(key, key); + if (key_upper == NULL) { + DBG_DEBUG("strupper_talloc failed\n"); + goto fail; + } + + ok = gencache_parse(key_upper, namemap_cache_find_name_parser, &state); + if (!ok) { + DBG_DEBUG("gencache_parse(%s) failed\n", key_upper); + goto fail; + } + + if (!state.ok) { + DBG_DEBUG("Could not parse %s, deleting\n", key_upper); + goto fail; + } + + ret = true; +fail: + TALLOC_FREE(key); + return ret; +} diff --git a/source3/lib/namemap_cache.h b/source3/lib/namemap_cache.h new file mode 100644 index 00000000000..a70de34b885 --- /dev/null +++ b/source3/lib/namemap_cache.h @@ -0,0 +1,45 @@ +/* + * Unix SMB/CIFS implementation. + * Utils for caching sid2name and name2sid + * Copyright (C) Volker Lendecke 2017 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __LIB_NAMEMAP_CACHE_H__ +#define __LIB_NAMEMAP_CACHE_H__ + +#include "lib/util/time.h" +#include "lib/util/data_blob.h" +#include "librpc/gen_ndr/lsa.h" + +bool namemap_cache_set_sid2name(const struct dom_sid *sid, + const char *domain, const char *name, + enum lsa_SidType type, time_t timeout); +bool namemap_cache_set_name2sid(const char *domain, const char *name, + const struct dom_sid *sid, + enum lsa_SidType type, + time_t timeout); +bool namemap_cache_find_sid(const struct dom_sid *sid, + void (*fn)(const char *domain, const char *name, + enum lsa_SidType type, time_t timeout, + void *private_data), + void *private_data); +bool namemap_cache_find_name(const char *domain, const char *name, + void (*fn)(const struct dom_sid *sid, + enum lsa_SidType type, time_t timeout, + void *private_data), + void *private_data); + +#endif diff --git a/source3/wscript_build b/source3/wscript_build index 8b119a824c3..cc511c376d8 100644 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -410,6 +410,7 @@ bld.SAMBA3_SUBSYSTEM('samba3core', lib/audit.c lib/tevent_wait.c lib/idmap_cache.c + lib/namemap_cache.c lib/util_ea.c lib/background.c lib/cleanupdb.c -- 2.16.3 From d6c3097a3db30b6e074cc866f310f335d67c2ff8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 3 Aug 2017 16:26:04 +0200 Subject: [PATCH 06/14] net: Parse namemap_cache in "net cache list" namemap_cache.c saves these as strv lists: An array of 0-terminated strings. "net cache list" only printfs the values, so they would be cut off. We might want to do this with other gencache values too in the future. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13369 Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme --- source3/utils/net_cache.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/source3/utils/net_cache.c b/source3/utils/net_cache.c index f43eb0e88c6..8f9f69f8659 100644 --- a/source3/utils/net_cache.c +++ b/source3/utils/net_cache.c @@ -23,6 +23,7 @@ #include "../librpc/gen_ndr/netlogon.h" #include "../librpc/gen_ndr/ndr_netlogon.h" #include "libcli/security/dom_sid.h" +#include "lib/util/strv.h" /** * @file net_cache.c @@ -77,6 +78,24 @@ static void print_cache_entry(const char* keystr, DATA_BLOB value, datastr = (char *)value.data; + if (strnequal(keystr, "NAME2SID/", strlen("NAME2SID/"))) { + const char *strv = (char *)value.data; + size_t strv_len = value.length; + const char *sid = strv_len_next(strv, strv_len, NULL); + const char *type = strv_len_next(strv, strv_len, sid); + datastr = talloc_asprintf(talloc_tos(), "%s (%s)", sid, type); + } + + if (strnequal(keystr, "SID2NAME/", strlen("SID2NAME/"))) { + const char *strv = (char *)value.data; + size_t strv_len = value.length; + const char *domain = strv_len_next(strv, strv_len, NULL); + const char *name = strv_len_next(strv, strv_len, domain); + const char *type = strv_len_next(strv, strv_len, name); + datastr = talloc_asprintf(talloc_tos(), "%s\\%s (%s)", + domain, name, type); + } + if ((value.length > 0) && (value.data[value.length-1] != '\0')) { datastr_free = talloc_asprintf( talloc_tos(), "", -- 2.16.3 From 7a470a12659c71907667a2908ad2db4ea8904242 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 6 Aug 2017 18:11:02 +0200 Subject: [PATCH 07/14] winbindd: Factor out winbindd_domain_init_backend from get_cache() BUG: https://bugzilla.samba.org/show_bug.cgi?id=13369 Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme --- source3/winbindd/winbindd_cache.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c index 98c69f8b231..8492f907553 100644 --- a/source3/winbindd/winbindd_cache.c +++ b/source3/winbindd/winbindd_cache.c @@ -119,12 +119,11 @@ static char *wcache_path(void) return state_path("winbindd_cache.tdb"); } -/* get the winbind_cache structure */ -static struct winbind_cache *get_cache(struct winbindd_domain *domain) +static void winbindd_domain_init_backend(struct winbindd_domain *domain) { - struct winbind_cache *ret = wcache; - - /* We have to know what type of domain we are dealing with first. */ + if (domain->backend != NULL) { + return; + } if (domain->internal) { domain->backend = &builtin_passdb_methods; @@ -189,6 +188,14 @@ static struct winbind_cache *get_cache(struct winbindd_domain *domain) DBG_INFO("Setting MS-RPC methods for domain %s\n", domain->name); domain->backend = &reconnect_methods; } +} + +/* get the winbind_cache structure */ +static struct winbind_cache *get_cache(struct winbindd_domain *domain) +{ + struct winbind_cache *ret = wcache; + + winbindd_domain_init_backend(domain); if (ret != NULL) { return ret; -- 2.16.3 From f4c5998bd7b7beb6b3687ca273f7608f879c3df2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 6 Aug 2017 18:13:10 +0200 Subject: [PATCH 08/14] 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 Reviewed-by: Ralph Boehme --- source3/winbindd/winbindd_cache.c | 333 ++++++++++++++++---------------------- 1 file 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; istatus)) { - 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; istatus)) { - 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}, -- 2.16.3 From 2215c3359a301b0ab14c86da09e024e19df54954 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 8 Aug 2017 14:24:27 +0200 Subject: [PATCH 09/14] winbindd: Name<->SID cache is not sequence number based anymore BUG: https://bugzilla.samba.org/show_bug.cgi?id=13369 Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme --- source3/winbindd/winbindd_cache.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c index afc688fd5f9..a100ed77f2a 100644 --- a/source3/winbindd/winbindd_cache.c +++ b/source3/winbindd/winbindd_cache.c @@ -1851,7 +1851,6 @@ NTSTATUS wb_cache_name_to_sid(struct winbindd_domain *domain, } } /* and save it */ - refresh_sequence_number(domain); if (domain->online && (NT_STATUS_IS_OK(status) || NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED))) { @@ -1990,7 +1989,6 @@ NTSTATUS wb_cache_sid_to_name(struct winbindd_domain *domain, } } /* and save it */ - refresh_sequence_number(domain); if (!NT_STATUS_IS_OK(status)) { return status; } -- 2.16.3 From 226ce092b772607de87c904ad7af78899b853a65 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 20 Apr 2018 11:24:30 +0200 Subject: [PATCH 10/14] nsswitch: Add a test looking up the user using the upn BUG: https://bugzilla.samba.org/show_bug.cgi?id=13369 Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher (cherry picked from commit 0d2f743d826b87b369e25fc6bb9ff61f2b0896aa) --- nsswitch/tests/test_wbinfo_name_lookup.sh | 9 +++++++-- source3/selftest/tests.py | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/nsswitch/tests/test_wbinfo_name_lookup.sh b/nsswitch/tests/test_wbinfo_name_lookup.sh index 696e25b3a2a..a8fd5ec4d99 100755 --- a/nsswitch/tests/test_wbinfo_name_lookup.sh +++ b/nsswitch/tests/test_wbinfo_name_lookup.sh @@ -8,8 +8,9 @@ exit 1; fi DOMAIN=$1 -DC_USERNAME=$2 -shift 2 +REALM=$2 +DC_USERNAME=$3 +shift 3 failed=0 sambabindir="$BINDIR" @@ -22,6 +23,10 @@ testit "name-to-sid.single-separator" \ $wbinfo -n $DOMAIN/$DC_USERNAME || \ failed=$(expr $failed + 1) +testit "name-to-sid.upn" \ + $wbinfo -n $DC_USERNAME@$REALM || \ + failed=$(expr $failed + 1) + # Two separator characters should fail testit_expect_failure "name-to-sid.double-separator" \ $wbinfo -n $DOMAIN//$DC_USERNAME || \ diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index 20e1c03fa66..24ebd7fd98f 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -201,7 +201,7 @@ plantestsuite("samba3.wbinfo_simple.(%s:local).%s" % (env, t), "%s:local" % env, plantestsuite("samba3.wbinfo_name_lookup", env, [ os.path.join(srcdir(), "nsswitch/tests/test_wbinfo_name_lookup.sh"), - '$DOMAIN', '$DC_USERNAME' ]) + '$DOMAIN', '$REALM', '$DC_USERNAME' ]) t = "WBCLIENT-MULTI-PING" plantestsuite("samba3.smbtorture_s3.%s" % t, env, [os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, '//foo/bar', '""', '""', smbtorture3, ""]) plantestsuite("samba3.substitutions", env, [os.path.join(samba3srcdir, "script/tests/test_substitutions.sh"), "$SERVER", "alice", "Secret007", "$PREFIX"]) -- 2.16.3 From 94174949908037697bbd4ab0ab74df6e36294b35 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 4 May 2018 12:43:05 +0200 Subject: [PATCH 11/14] nsswitch: Add a test looking up domain sid BUG: https://bugzilla.samba.org/show_bug.cgi?id=13369 Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher (cherry picked from commit 0aceca6a94e868f9c01a66f79624ca10d80560ab) --- nsswitch/tests/test_wbinfo_name_lookup.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nsswitch/tests/test_wbinfo_name_lookup.sh b/nsswitch/tests/test_wbinfo_name_lookup.sh index a8fd5ec4d99..c1d39c1a602 100755 --- a/nsswitch/tests/test_wbinfo_name_lookup.sh +++ b/nsswitch/tests/test_wbinfo_name_lookup.sh @@ -23,6 +23,10 @@ testit "name-to-sid.single-separator" \ $wbinfo -n $DOMAIN/$DC_USERNAME || \ failed=$(expr $failed + 1) +testit "name-to-sid.at_domain" \ + $wbinfo -n $DOMAIN/ || \ + failed=$(expr $failed + 1) + testit "name-to-sid.upn" \ $wbinfo -n $DC_USERNAME@$REALM || \ failed=$(expr $failed + 1) -- 2.16.3 From 536456dc4c617c99039db53c91dd2f61fb4dff47 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Mon, 7 May 2018 13:23:42 +0200 Subject: [PATCH 12/14] nsswitch: Lookup the domain in tests with the wb seperator Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher (cherry picked from commit 4fa811ec7bc301e96f5e40ba281e8d4e8709b94f) --- nsswitch/tests/test_idmap_nss.sh | 4 ++-- nsswitch/tests/test_idmap_rid.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/nsswitch/tests/test_idmap_nss.sh b/nsswitch/tests/test_idmap_nss.sh index 5072a0df72c..1bbc177774d 100755 --- a/nsswitch/tests/test_idmap_nss.sh +++ b/nsswitch/tests/test_idmap_nss.sh @@ -13,8 +13,8 @@ failed=0 . `dirname $0`/../../testprogs/blackbox/subunit.sh -testit "wbinfo returns domain SID" $wbinfo -n "@$DOMAIN" || exit 1 -DOMAIN_SID=$($wbinfo -n "@$DOMAIN" | cut -f 1 -d " ") +testit "wbinfo returns domain SID" $wbinfo -n "$DOMAIN/" || exit 1 +DOMAIN_SID=$($wbinfo -n "$DOMAIN/" | cut -f 1 -d " ") echo "Domain $DOMAIN has SID $DOMAIN_SID" # Find an unused uid and SID diff --git a/nsswitch/tests/test_idmap_rid.sh b/nsswitch/tests/test_idmap_rid.sh index 7fb59852cf5..8209a50a4fc 100755 --- a/nsswitch/tests/test_idmap_rid.sh +++ b/nsswitch/tests/test_idmap_rid.sh @@ -16,7 +16,7 @@ failed=0 . `dirname $0`/../../testprogs/blackbox/subunit.sh -DOMAIN_SID=$($wbinfo -n "@$DOMAIN" | cut -f 1 -d " ") +DOMAIN_SID=$($wbinfo -n "$DOMAIN/" | cut -f 1 -d " ") if [ $? -ne 0 ] ; then echo "Could not find domain SID" | subunit_fail_test "test_idmap_rid" exit 1 -- 2.16.3 From 9486648604bb431e34f4d3cc5dc4da4dc910efea Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 20 Apr 2018 09:38:24 +0200 Subject: [PATCH 13/14] selftest: Add a user with a different userPrincipalName BUG: https://bugzilla.samba.org/show_bug.cgi?id=13369 Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher (cherry picked from commit 5319cae00096dcecc29aa9fa675a983352ad64d8) --- selftest/target/Samba4.pm | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index 6a1856ef642..7da68c44776 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -840,7 +840,7 @@ userPrincipalName: testdenied_upn\@$ctx->{realm}.upn } # Create to users alice and bob! - my $user_account_array = ["alice", "bob"]; + my $user_account_array = ["alice", "bob", "jane"]; foreach my $user_account (@{$user_account_array}) { my $samba_tool_cmd = ""; @@ -855,6 +855,23 @@ userPrincipalName: testdenied_upn\@$ctx->{realm}.upn } } + my $ldbmodify = ""; + $ldbmodify .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" "; + $ldbmodify .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" "; + $ldbmodify .= Samba::bindir_path($self, "ldbmodify"); + + my $base_dn = "DC=".join(",DC=", split(/\./, $ctx->{realm})); + my $user_dn = "cn=jane,cn=users,$base_dn"; + + open(LDIF, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb"); + print LDIF "dn: $user_dn +changetype: modify +replace: userPrincipalName +userPrincipalName: jane.doe\@$ctx->{realm} +- +"; + close(LDIF); + return $ret; } -- 2.16.3 From 7b81c03ac927d3913c1100138f5193e62168a897 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 20 Apr 2018 11:20:44 +0200 Subject: [PATCH 14/14] nsswitch:tests: Add test for wbinfo --user-info BUG: https://bugzilla.samba.org/show_bug.cgi?id=13369 Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher (cherry picked from commit 2715f52f54e66a73131a92d752a8c2447da1fd33) --- nsswitch/tests/test_wbinfo_user_info.sh | 83 +++++++++++++++++++++++++++++++++ selftest/knownfail.d/upn_handling | 11 +++++ source3/selftest/tests.py | 14 ++++++ 3 files changed, 108 insertions(+) create mode 100755 nsswitch/tests/test_wbinfo_user_info.sh create mode 100644 selftest/knownfail.d/upn_handling diff --git a/nsswitch/tests/test_wbinfo_user_info.sh b/nsswitch/tests/test_wbinfo_user_info.sh new file mode 100755 index 00000000000..2803ac1408b --- /dev/null +++ b/nsswitch/tests/test_wbinfo_user_info.sh @@ -0,0 +1,83 @@ +#!/bin/sh +# Blackbox test for wbinfo lookup for account name and upn +# Copyright (c) 2018 Andreas Schneider + +if [ $# -lt 5 ]; then +cat <