[SCM] Samba Shared Repository - branch master updated

Ralph Böhme slow at samba.org
Wed Nov 29 19:58:03 UTC 2017


The branch, master has been updated
       via  926b8be winbindd: Name<->SID cache is not sequence number based anymore
       via  8050613 winbindd: Move name<->sid cache to gencache
       via  650f29e winbindd: Factor out winbindd_domain_init_backend from get_cache()
       via  9789dbd torture3: Test namemap_cache
       via  19afcd0 net: Parse namemap_cache in "net cache list"
       via  3e556bf lib: Add namemap_cache
       via  089cb9e lib: Pass blob instead of &blob to gencache_set_data_blob
       via  71e255f lib: Allow parsing a strv from a non-talloc const buf
       via  8e824ad lib: Only call strlen if necessary in strv
       via  805ae8a lib: Pass in "strv_len" to strv_valid_entry
       via  2f8055f dbwrap_watch: Remove the "prec" parameter from watch_recv
       via  4e86c32 smbd: Avoid using dbwrap_watched_watch_recv's prec argument
       via  1ce165a winbindd: let normalize_name_map() call find_domain_from_name_noinit()
       via  96b44e9 s3/cli_netlogon: remove SEC_CHAN_NULL fallback from rpccli_connect_netlogon()
       via  a8e0bdc winbindd: restore SEC_CHAN_NULL fallback in cm_connect_netlogon_transport
      from  3e43f80 Replace tabs with spaces to comply with PEP8, reorder list of manpages in the alphanumeric sort order.

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 926b8be2cdee06cd25d567403d9fdd07b67ac5b5
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Aug 8 14:24:27 2017 +0200

    winbindd: Name<->SID cache is not sequence number based anymore
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>
    
    Autobuild-User(master): Ralph Böhme <slow at samba.org>
    Autobuild-Date(master): Wed Nov 29 20:57:25 CET 2017 on sn-devel-144

commit 80506136cc41b81ff166a108d087e9aede4e5d97
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Aug 6 18:13:10 2017 +0200

    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 at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 650f29e2f35bdfa5f96cf13462528e933e8ecf35
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Aug 6 18:11:02 2017 +0200

    winbindd: Factor out winbindd_domain_init_backend from get_cache()
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 9789dbd75c874b404a74c51fd0d82d5623a0f869
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Aug 3 16:26:25 2017 +0200

    torture3: Test namemap_cache
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 19afcd0e816f096fd17cf624f21d2d6f9c5f8d05
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Aug 3 16:26:04 2017 +0200

    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.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 3e556bf3703504625f0707f7f87a478c41bafede
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Aug 2 18:11:49 2017 +0200

    lib: Add namemap_cache
    
    A few functions to maintain lookupname and lookupsid cache in gencache.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 089cb9e24c47ccff492865bae9f7b895b78c5d02
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Aug 2 17:52:40 2017 +0200

    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.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 71e255fd3d2beb0a2fcb2ff39014a668dd724c13
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Aug 2 17:34:25 2017 +0200

    lib: Allow parsing a strv from a non-talloc const buf
    
    This will allow parsing a tdb record without having to talloc_memdup it
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 8e824ad69700412cedeb758029fdad4d1b5c6bbe
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Aug 2 17:32:50 2017 +0200

    lib: Only call strlen if necessary in strv
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 805ae8a4f1fe61cb44000c2967f61e3bffa08eca
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Aug 2 17:22:34 2017 +0200

    lib: Pass in "strv_len" to strv_valid_entry
    
    Preparation for a later commit
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 2f8055f676a52b01a609611bbc3361442bb81a9b
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Jul 1 08:27:57 2017 +0200

    dbwrap_watch: Remove the "prec" parameter from watch_recv
    
    The initial idea was to have some "atomicity" in this API. Every
    caller interested in a record would have to do something with
    it once it changes. However, only one caller really used this
    feature, and that is easily changed to not use it. So
    remove the complexity.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 4e86c322147ccf6e741b19ffb14fdd0d22bf927b
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Jul 1 08:20:23 2017 +0200

    smbd: Avoid using dbwrap_watched_watch_recv's prec argument
    
    This is the only user of the "prec" argument of
    dbwrap_watched_watch_recv. The next patch will remove this
    functionality, as it's easily replaced here.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 1ce165a73350e802500c32435dbefe3639340435
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Nov 27 12:42:44 2017 +0100

    winbindd: let normalize_name_map() call find_domain_from_name_noinit()
    
    Let normalize_name_map fetch the domain itself with
    find_domain_from_name_noinit().
    
    This removes two calls to find_domain_from_name_noinit() in the default
    configuration of "winbind normalize names = no". The domain is only need
    in normalize_name_map if "winbind normalize names" is enabled.
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 96b44e9da572cfee5429affe0dc86ee5e2275847
Author: Ralph Boehme <slow at samba.org>
Date:   Sun Nov 26 19:04:19 2017 +0100

    s3/cli_netlogon: remove SEC_CHAN_NULL fallback from rpccli_connect_netlogon()
    
    The caller should handle secure-channel-type SEC_CHAN_NULL. The previous
    commit already added handling of SEC_CHAN_NULL to
    cm_connect_netlogon_transport.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13167
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit a8e0bdc97100578d85f58633bcdf64b7cfb4c216
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Nov 27 15:28:38 2017 +0100

    winbindd: restore SEC_CHAN_NULL fallback in cm_connect_netlogon_transport
    
    This partially reverts commit d7e31d9f4d9ce7395e458ac341dd83ac06255a20
    "winbindd: Use rpccli_connect_netlogon" and restores handling of SEC_CHAN_NULL.
    
    Without this we fail to enumerate domains in trusted forests so users
    from any child-domain (or tree-root) in the trusted forest can't login
    via eg SMB.
    
    This is a temporary hack that will go away once we get rid of the trusted domain
    list.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=13167
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 lib/util/strv.c                      |  50 ++---
 lib/util/strv.h                      |   2 +
 source3/lib/dbwrap/dbwrap_watch.c    |  37 +---
 source3/lib/dbwrap/dbwrap_watch.h    |   2 -
 source3/lib/g_lock.c                 |   2 +-
 source3/lib/gencache.c               |  12 +-
 source3/lib/gencache.h               |   2 +-
 source3/lib/namemap_cache.c          | 323 ++++++++++++++++++++++++++++++++
 source3/lib/namemap_cache.h          |  45 +++++
 source3/libsmb/dsgetdcname.c         |   7 +-
 source3/rpc_client/cli_netlogon.c    |  38 +---
 source3/selftest/tests.py            |   1 +
 source3/smbd/open.c                  |   3 +-
 source3/smbd/smb2_setinfo.c          |   3 +-
 source3/smbd/smbXsrv_session.c       |  12 +-
 source3/torture/proto.h              |   1 +
 source3/torture/test_dbwrap_watch.c  |   3 +-
 source3/torture/test_namemap_cache.c | 262 ++++++++++++++++++++++++++
 source3/torture/torture.c            |   5 +-
 source3/utils/net_cache.c            |  19 ++
 source3/winbindd/wb_dsgetdcname.c    |   2 +-
 source3/winbindd/wb_getpwsid.c       |   8 +-
 source3/winbindd/winbindd_cache.c    | 344 +++++++++++++++--------------------
 source3/winbindd/winbindd_cm.c       |  36 ++++
 source3/winbindd/winbindd_group.c    |  11 +-
 source3/winbindd/winbindd_msrpc.c    |   4 +-
 source3/winbindd/winbindd_proto.h    |   2 +-
 source3/winbindd/winbindd_rpc.c      |   4 +-
 source3/winbindd/winbindd_util.c     |   9 +-
 source3/wscript_build                |   2 +
 30 files changed, 924 insertions(+), 327 deletions(-)
 create mode 100644 source3/lib/namemap_cache.c
 create mode 100644 source3/lib/namemap_cache.h
 create mode 100644 source3/torture/test_namemap_cache.c


Changeset truncated at 500 lines:

diff --git a/lib/util/strv.c b/lib/util/strv.c
index 99ce76f..83d84d9 100644
--- a/lib/util/strv.c
+++ b/lib/util/strv.c
@@ -62,54 +62,61 @@ 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);
+	if (entry_len != NULL) {
+		*entry_len = strlen(entry);
+	}
 
 	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, entry_len;
-	char *result;
+	size_t entry_len;
 
 	if (entry == NULL) {
-		if (strv_valid_entry(strv, strv, &len, &entry_len)) {
+		if (strv_valid_entry(strv, strv_len, strv, NULL)) {
 			return strv;
 		}
 		return NULL;
 	}
 
-	if (!strv_valid_entry(strv, entry, &len, &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)
@@ -139,13 +146,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;
diff --git a/lib/util/strv.h b/lib/util/strv.h
index 398e8ea..89f0402 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);
diff --git a/source3/lib/dbwrap/dbwrap_watch.c b/source3/lib/dbwrap/dbwrap_watch.c
index be0a0d3..3e91f46 100644
--- a/source3/lib/dbwrap/dbwrap_watch.c
+++ b/source3/lib/dbwrap/dbwrap_watch.c
@@ -1003,18 +1003,12 @@ static void dbwrap_watched_watch_done(struct tevent_req *subreq)
 }
 
 NTSTATUS dbwrap_watched_watch_recv(struct tevent_req *req,
-				   TALLOC_CTX *mem_ctx,
-				   struct db_record **prec,
 				   bool *blockerdead,
 				   struct server_id *blocker)
 {
 	struct dbwrap_watched_watch_state *state = tevent_req_data(
 		req, struct dbwrap_watched_watch_state);
-	struct db_watched_subrec *subrec;
 	NTSTATUS status;
-	TDB_DATA key;
-	struct db_record *rec;
-	bool ok;
 
 	if (tevent_req_is_nterror(req, &status)) {
 		return status;
@@ -1025,35 +1019,6 @@ NTSTATUS dbwrap_watched_watch_recv(struct tevent_req *req,
 	if (blocker != NULL) {
 		*blocker = state->blocker;
 	}
-	if (prec == NULL) {
-		return NT_STATUS_OK;
-	}
-
-	ok = dbwrap_record_watchers_key_parse(state->w_key, NULL, NULL, &key);
-	if (!ok) {
-		return NT_STATUS_INTERNAL_DB_ERROR;
-	}
-
-	rec = dbwrap_fetch_locked(state->db, mem_ctx, key);
-	if (rec == NULL) {
-		return NT_STATUS_INTERNAL_DB_ERROR;
-	}
-
-	talloc_set_destructor(state, NULL);
-
-	subrec = talloc_get_type_abort(
-		rec->private_data, struct db_watched_subrec);
-
-	ok = dbwrap_watched_remove_waiter(&subrec->wrec, state->me);
-	if (ok) {
-		status = dbwrap_watched_save(subrec->subrec, &subrec->wrec,
-					     NULL, &subrec->wrec.data, 1, 0);
-		if (!NT_STATUS_IS_OK(status)) {
-			DBG_WARNING("dbwrap_watched_save failed: %s\n",
-				    nt_errstr(status));
-		}
-	}
-
-	*prec = rec;
 	return NT_STATUS_OK;
 }
+
diff --git a/source3/lib/dbwrap/dbwrap_watch.h b/source3/lib/dbwrap/dbwrap_watch.h
index 1849310..e94378f 100644
--- a/source3/lib/dbwrap/dbwrap_watch.h
+++ b/source3/lib/dbwrap/dbwrap_watch.h
@@ -32,8 +32,6 @@ struct tevent_req *dbwrap_watched_watch_send(TALLOC_CTX *mem_ctx,
 					     struct db_record *rec,
 					     struct server_id blocker);
 NTSTATUS dbwrap_watched_watch_recv(struct tevent_req *req,
-				   TALLOC_CTX *mem_ctx,
-				   struct db_record **prec,
 				   bool *blockerdead,
 				   struct server_id *blocker);
 
diff --git a/source3/lib/g_lock.c b/source3/lib/g_lock.c
index 8709052..c5d66e3 100644
--- a/source3/lib/g_lock.c
+++ b/source3/lib/g_lock.c
@@ -385,7 +385,7 @@ static void g_lock_lock_retry(struct tevent_req *subreq)
 	struct g_lock_lock_fn_state fn_state;
 	NTSTATUS status;
 
-	status = dbwrap_watched_watch_recv(subreq, NULL, NULL, NULL, NULL);
+	status = dbwrap_watched_watch_recv(subreq, NULL, NULL);
 	DBG_DEBUG("watch_recv returned %s\n", nt_errstr(status));
 	TALLOC_FREE(subreq);
 
diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c
index e73d1c5..ab12fc1 100644
--- a/source3/lib/gencache.c
+++ b/source3/lib/gencache.c
@@ -252,7 +252,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;
@@ -268,7 +268,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;
 	}
 
@@ -276,7 +276,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;
@@ -287,12 +287,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,
@@ -784,7 +784,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 4371835..fa72a4a 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/lib/namemap_cache.c b/source3/lib/namemap_cache.c
new file mode 100644
index 0000000..0d6ed32
--- /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 <http://www.gnu.org/licenses/>.
+ */
+
+#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);


-- 
Samba Shared Repository



More information about the samba-cvs mailing list