[SCM] Samba Shared Repository - branch master updated

Volker Lendecke vlendec at samba.org
Fri Dec 16 20:31:05 UTC 2016


The branch, master has been updated
       via  1227065 idmap_autorid: Simplify idmap_autorid_loadconfig
       via  4cef6d2 idmap_autorid: Fix a small memleak
       via  9c6c2ad idmap_autorid: Fix a race condition when acquiring ranges
       via  a04cec5 idmap_autorid: Use acquire_range directly
       via  ba02936 idmap_autorid: Make idmap_autorid_acquire_range public
       via  ba231d2 idmap_autorid: Fix checks for valid domains to allocate ranges for
       via  55daaf1 idmap_autorid: Add ntstatus to a debug message
       via  9fe42eb idmap_autorid: Only look at the tdc cache when allocating ranges
       via  4cfd824 idmap_autorid: Do a readonly attempt before looking at the tdc cache
       via  941d235 idmap_autorid: idmap_autorid_sid_to_id_rid only uses rangesize from "global"
       via  3ae832d idmap_autorid: idmap_autorid_sid_to_id_rid only uses low_id from "range"
       via  f5c9f27 idmap_autorid: Tighten idmap_autorid_id_to_sid a bit
       via  751f598 idmap_autorid: Fix a comment
       via  f1c126c idmap_autorid: Protect against dsize==0
       via  b64835a idmap_tdb: Harden idmap_tdb_common_unixid_to_sid
       via  5ee846f idmap_autorid: Slightly simplify idmap_autorid_unixids_to_sids
       via  321dca7 samlogon_cache: Rename "user_sid" to "sid"
       via  bedc5c0 samlogon_cache: Add the user's domain sid into the samlogon_cache
       via  f4ca27f samlogon_cache: Simplify netsamlogon_cache_have
      from  e7ab2ad pam_winbind: Fix compiler warnings

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


- Log -----------------------------------------------------------------
commit 122706550c67ef778fd4634508bec9e0507a1fe0
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Dec 5 15:31:56 2016 +0000

    idmap_autorid: Simplify idmap_autorid_loadconfig
    
    autorid_global_config is a fixed small structure that can be stack-allocated.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    
    Autobuild-User(master): Volker Lendecke <vl at samba.org>
    Autobuild-Date(master): Fri Dec 16 21:30:28 CET 2016 on sn-devel-144

commit 4cef6d29ffa23158ebcbf7da390daf0d12c7d9fd
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Dec 5 15:29:06 2016 +0000

    idmap_autorid: Fix a small memleak
    
    Not long-term, all callers free our "mem_ctx" immediately
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 9c6c2ad26d1936f8a731b18198b47e35e4938d96
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 2 15:37:49 2016 +0000

    idmap_autorid: Fix a race condition when acquiring ranges
    
    Here we are in a transaction to create a range, but we already found
    one to exist. We need to return the information about this range to the
    caller, just as we do when actually allocating the range. This does not
    hit us with current code, as we just have one idmap child. However, if
    we parallelize that, two children might have found a domain to not exist
    and call idmap_autorid_acquire_range simultaneously. One will create
    the range, the other one will find it to already exist. The second child
    will also have to pass the info up.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit a04cec5c624e4486b5ff56b064443ec3dbdfd181
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 2 15:25:10 2016 +0000

    idmap_autorid: Use acquire_range directly
    
    idmap_autorid_get_domainrange is reading again for an existing mapping. We
    know we need to allocate here, so avoid passing down that r/o boolean :-)
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit ba02936032216d8cd774907b1de852e5a0b0ed9d
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 2 15:11:24 2016 +0000

    idmap_autorid: Make idmap_autorid_acquire_range public
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit ba231d250a2a40339ab74891d9b529a7013a0921
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 2 14:10:34 2016 +0000

    idmap_autorid: Fix checks for valid domains to allocate ranges for
    
    The tdc cache is not reliable. The main dynamic check is
    netsamlogon_cache_have: The only reliable way to see a domain as valid
    for allocating a range for is a successful login. With a recent addition
    to netsamlogon_cache_store, we can now reliably tell from there whether
    a domain is trusted.
    
    This also adds a few heuristic checks, such as allocation for the local
    domains and additional ranges where we already have a mapping for range
    index 0 for.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 55daaf10ddc564cd155b3369c6a6eddb8e1fbf90
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 2 14:10:00 2016 +0000

    idmap_autorid: Add ntstatus to a debug message
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 9fe42eb58e55ecf64d0081a804ee8ff169529977
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 2 12:18:06 2016 +0000

    idmap_autorid: Only look at the tdc cache when allocating ranges
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 4cfd824fd3f4d4deb65b291e6e98bb4044317c52
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 2 12:14:17 2016 +0000

    idmap_autorid: Do a readonly attempt before looking at the tdc cache
    
    If autorid.tdb already has a mapping for a domain range, we can just
    return that. Even if the volatile tdc cache at this point does not have
    the domain, we should return a correct mapping.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 941d235f70b7b1c7d9a887a3325ccf9a681dba80
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 2 10:58:35 2016 +0000

    idmap_autorid: idmap_autorid_sid_to_id_rid only uses rangesize from "global"
    
    Simplification -- from the callers perspective looks like a complex
    routine which it is not
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 3ae832de472c8c3285005eba188ff99b3c525114
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Dec 2 10:58:35 2016 +0000

    idmap_autorid: idmap_autorid_sid_to_id_rid only uses low_id from "range"
    
    Simplification -- from the callers perspective looks like a complex
    routine which it is not
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit f5c9f27e62d4094b076a0f18024956d7fe5ee52b
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Dec 1 16:24:51 2016 +0000

    idmap_autorid: Tighten idmap_autorid_id_to_sid a bit
    
    We should only allow '#' as a sid/range-number separator in autorid.tdb.
    
    The logic might be a bit clumsy. But the switch statement with failure
    fall thru was the clearest I could come up with.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>

commit 751f598043188e96a0f11abf5cb065d93df83d1f
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Dec 1 13:29:29 2016 +0000

    idmap_autorid: Fix a comment
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit f1c126c2f6e402524272308821542bf28d29de5e
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Dec 1 13:28:01 2016 +0000

    idmap_autorid: Protect against dsize==0
    
    Not sure it can happen, but you never know...
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit b64835a109b112543cc82a50c2dbb4ece5149ec6
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Nov 30 18:43:44 2016 +0100

    idmap_tdb: Harden idmap_tdb_common_unixid_to_sid
    
    A non-null terminated record would make string_to_sid read beyond the
    end of allocated data.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 5ee846fabf809b1b0070d53bef56f3735ac1e9bb
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Nov 30 18:35:55 2016 +0100

    idmap_autorid: Slightly simplify idmap_autorid_unixids_to_sids
    
    Avoid an else branch where it's not necessary
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 321dca7820df2fc2ad8e1cf0d0c2778036329bb2
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Dec 5 14:38:14 2016 +0000

    samlogon_cache: Rename "user_sid" to "sid"
    
    This is no longer just a user, we can also check for domains
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit bedc5c056833bff4cf0287ef00b8d38bf3b53d2c
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Dec 1 20:46:47 2016 +0000

    samlogon_cache: Add the user's domain sid into the samlogon_cache
    
    This will be used by autorid and possibly others instead of the tdc
    cache. The only reliable way to find a domain to be trusted is via a
    successful login. We indicate successful login via a netsamlogon_cache.tdb
    entry. This patch also adds the user's domain sid with an entry, so we
    can check for that existence without traversing the cache.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit f4ca27f17313abf332cdb32a975a5cd4189c9c6d
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Dec 1 20:45:35 2016 +0000

    samlogon_cache: Simplify netsamlogon_cache_have
    
    We're interested in existence only, we should be able to trust the data
    format consistency for this type of query.
    
    netsamlogon_cache_get calls netsamlogon_cache_init for us, now we have
    to do it directly.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

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

Summary of changes:
 source3/include/idmap_autorid_tdb.h  |   6 +-
 source3/libsmb/samlogon_cache.c      |  40 ++++++---
 source3/libsmb/samlogon_cache.h      |   2 +-
 source3/winbindd/idmap_autorid.c     | 152 ++++++++++++++++++++++++++---------
 source3/winbindd/idmap_autorid_tdb.c |  73 +++++++++--------
 source3/winbindd/idmap_tdb_common.c  |   6 ++
 6 files changed, 193 insertions(+), 86 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/idmap_autorid_tdb.h b/source3/include/idmap_autorid_tdb.h
index 52bee56..36a595f 100644
--- a/source3/include/idmap_autorid_tdb.h
+++ b/source3/include/idmap_autorid_tdb.h
@@ -82,6 +82,9 @@ NTSTATUS idmap_autorid_setrange(struct db_context *db,
 				uint32_t domain_range_index,
 				uint32_t rangenum);
 
+NTSTATUS idmap_autorid_acquire_range(struct db_context *db,
+				     struct autorid_range_config *range);
+
 /**
  * Delete a domain#index <-> range maping from the database.
  * The mapping is specified by the sid and index.
@@ -135,8 +138,7 @@ NTSTATUS idmap_autorid_db_init(const char *path,
  * Load the configuration stored in the autorid database.
  */
 NTSTATUS idmap_autorid_loadconfig(struct db_context *db,
-				  TALLOC_CTX *ctx,
-				  struct autorid_global_config **result);
+				  struct autorid_global_config *result);
 
 /**
  * Save the global autorid configuration into the autorid database.
diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c
index 8131b2b..5a16686 100644
--- a/source3/libsmb/samlogon_cache.c
+++ b/source3/libsmb/samlogon_cache.c
@@ -122,7 +122,8 @@ void netsamlogon_clear_cached_user(const struct dom_sid *user_sid)
 
 bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3)
 {
-	TDB_DATA data;
+	uint8_t dummy = 0;
+	TDB_DATA data = { .dptr = &dummy, .dsize = sizeof(dummy) };
 	char keystr[DOM_SID_STR_BUFLEN];
 	bool result = false;
 	struct dom_sid	user_sid;
@@ -130,6 +131,7 @@ bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3)
 	DATA_BLOB blob;
 	enum ndr_err_code ndr_err;
 	struct netsamlogoncache_entry r;
+	int ret;
 
 	if (!info3) {
 		return false;
@@ -141,6 +143,23 @@ bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3)
 		return false;
 	}
 
+	/*
+	 * First write a record with just the domain sid for
+	 * netsamlogon_cache_domain_known. Use TDB_INSERT to avoid
+	 * overwriting potentially other data. We're just interested
+	 * in the existence of that record.
+	 */
+	dom_sid_string_buf(info3->base.domain_sid, keystr, sizeof(keystr));
+
+	ret = tdb_store_bystring(netsamlogon_tdb, keystr, data, TDB_INSERT);
+
+	if ((ret == -1) && (tdb_error(netsamlogon_tdb) != TDB_ERR_EXISTS)) {
+		DBG_WARNING("Could not store domain marker for %s: %s\n",
+			    keystr, tdb_errorstr(netsamlogon_tdb));
+		TALLOC_FREE(tmp_ctx);
+		return false;
+	}
+
 	sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid);
 
 	/* Prepare key as DOMAIN-SID/USER-RID string */
@@ -257,21 +276,18 @@ struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const struct do
 	return info3;
 }
 
-bool netsamlogon_cache_have(const struct dom_sid *user_sid)
+bool netsamlogon_cache_have(const struct dom_sid *sid)
 {
-	TALLOC_CTX *mem_ctx = talloc_init("netsamlogon_cache_have");
-	struct netr_SamInfo3 *info3 = NULL;
-	bool result;
+	char keystr[DOM_SID_STR_BUFLEN];
+	bool ok;
 
-	if (mem_ctx == NULL) {
+	if (!netsamlogon_cache_init()) {
+		DBG_WARNING("Cannot open %s\n", NETSAMLOGON_TDB);
 		return false;
 	}
 
-	info3 = netsamlogon_cache_get(mem_ctx, user_sid);
+	dom_sid_string_buf(sid, keystr, sizeof(keystr));
 
-	result = (info3 != NULL);
-
-	TALLOC_FREE(mem_ctx);
-
-	return result;
+	ok = tdb_exists(netsamlogon_tdb, string_term_tdb_data(keystr));
+	return ok;
 }
diff --git a/source3/libsmb/samlogon_cache.h b/source3/libsmb/samlogon_cache.h
index 0a2fd14..221e67b 100644
--- a/source3/libsmb/samlogon_cache.h
+++ b/source3/libsmb/samlogon_cache.h
@@ -36,6 +36,6 @@ bool netsamlogon_cache_store(const char *username,
 			     struct netr_SamInfo3 *info3);
 struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx,
 					    const struct dom_sid *user_sid);
-bool netsamlogon_cache_have(const struct dom_sid *user_sid);
+bool netsamlogon_cache_have(const struct dom_sid *sid);
 
 #endif
diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c
index 1fd6a76..c27c503 100644
--- a/source3/winbindd/idmap_autorid.c
+++ b/source3/winbindd/idmap_autorid.c
@@ -78,6 +78,8 @@
 #include "idmap.h"
 #include "idmap_rw.h"
 #include "../libcli/security/dom_sid.h"
+#include "libsmb/samlogon_cache.h"
+#include "passdb/machine_sid.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_IDMAP
@@ -142,7 +144,7 @@ static NTSTATUS idmap_autorid_allocate_id(struct idmap_domain *dom,
 }
 
 /*
- * map a SID to xid using the idmap_tdb like pool
+ * map a xid to SID using the idmap_tdb like pool
  */
 static NTSTATUS idmap_autorid_id_to_sid_alloc(struct idmap_domain *dom,
 					      struct id_map *map)
@@ -169,7 +171,7 @@ static NTSTATUS idmap_autorid_id_to_sid(struct autorid_global_config *cfg,
 					struct id_map *map)
 {
 	uint32_t range_number;
-	uint32_t domain_range_index = 0;
+	uint32_t domain_range_index;
 	uint32_t normalized_id;
 	uint32_t reduced_rid;
 	uint32_t rid;
@@ -217,7 +219,7 @@ static NTSTATUS idmap_autorid_id_to_sid(struct autorid_global_config *cfg,
 		return NT_STATUS_OK;
 	}
 
-	if (data.dptr[data.dsize-1] != '\0') {
+	if ((data.dsize == 0) || (data.dptr[data.dsize-1] != '\0')) {
 		DBG_WARNING("Invalid range %"PRIu32"\n", range_number);
 		TALLOC_FREE(data.dptr);
 		map->status = ID_UNKNOWN;
@@ -243,14 +245,28 @@ static NTSTATUS idmap_autorid_id_to_sid(struct autorid_global_config *cfg,
 		map->status = ID_UNKNOWN;
 		return NT_STATUS_OK;
 	}
-	if (*q != '\0') {
-		if (sscanf(q+1, "%"SCNu32, &domain_range_index) != 1) {
-			DEBUG(10, ("Domain range index not found, "
-				   "ignoring mapping request\n"));
-			TALLOC_FREE(data.dptr);
-			map->status = ID_UNKNOWN;
-			return NT_STATUS_OK;
-		}
+
+	/*
+	 * Allow for sid#range_index, just sid is range index 0
+	 */
+
+	switch (*q) {
+	    case '\0':
+		    domain_range_index = 0;
+		    break;
+	    case '#':
+		    if (sscanf(q+1, "%"SCNu32, &domain_range_index) == 1) {
+			    break;
+		    }
+		    /* If we end up here, something weird is in the record. */
+
+		    /* FALL THROUGH */
+	    default:
+		    DBG_DEBUG("SID/domain range: %s\n",
+			      (const char *)data.dptr);
+		    TALLOC_FREE(data.dptr);
+		    map->status = ID_UNKNOWN;
+		    return NT_STATUS_OK;
 	}
 
 	TALLOC_FREE(data.dptr);
@@ -275,8 +291,8 @@ static NTSTATUS idmap_autorid_id_to_sid(struct autorid_global_config *cfg,
 **********************************/
 
 static NTSTATUS idmap_autorid_sid_to_id_rid(
-					struct autorid_global_config *global,
-					struct autorid_range_config *range,
+					uint32_t rangesize,
+					uint32_t low_id,
 					struct id_map *map)
 {
 	uint32_t rid;
@@ -284,9 +300,9 @@ static NTSTATUS idmap_autorid_sid_to_id_rid(
 
 	sid_peek_rid(map->sid, &rid);
 
-	reduced_rid = rid % global->rangesize;
+	reduced_rid = rid % rangesize;
 
-	map->xid.id = reduced_rid + range->low_id;
+	map->xid.id = reduced_rid + low_id;
 	map->xid.type = ID_TYPE_BOTH;
 	map->status = ID_MAPPED;
 
@@ -340,7 +356,8 @@ static NTSTATUS idmap_autorid_unixids_to_sids(struct idmap_domain *dom,
 
 	if (num_tomap == num_mapped) {
 		return NT_STATUS_OK;
-	} else if (num_mapped == 0) {
+	}
+	if (num_mapped == 0) {
 		return NT_STATUS_NONE_MAPPED;
 	}
 
@@ -525,7 +542,6 @@ static NTSTATUS idmap_autorid_sid_to_id(struct idmap_tdb_common_context *common,
 	struct autorid_global_config *global =
 		talloc_get_type_abort(common->private_data,
 				      struct autorid_global_config);
-	struct winbindd_tdc_domain *domain;
 	struct autorid_range_config range;
 	uint32_t rid;
 	struct dom_sid domainsid;
@@ -558,38 +574,98 @@ static NTSTATUS idmap_autorid_sid_to_id(struct idmap_tdb_common_context *common,
 		return NT_STATUS_NONE_MAPPED;
 	}
 
-	/*
-	 * Check if the domain is around
-	 */
-	domain = wcache_tdc_fetch_domainbysid(talloc_tos(),
-					      &domainsid);
-	if (domain == NULL) {
-		DEBUG(10, ("Ignoring unknown domain sid %s\n",
-			   sid_string_dbg(&domainsid)));
-		map->status = ID_UNMAPPED;
-		return NT_STATUS_NONE_MAPPED;
-	}
-	TALLOC_FREE(domain);
-
 	sid_to_fstring(range.domsid, &domainsid);
 
 	range.domain_range_index = rid / (global->rangesize);
 
-	ret = idmap_autorid_get_domainrange(autorid_db, &range, dom->read_only);
-	if (NT_STATUS_EQUAL(ret, NT_STATUS_NOT_FOUND) && dom->read_only) {
-		DEBUG(10, ("read-only is enabled, did not allocate "
-			   "new range for domain %s\n",
-			   sid_string_dbg(&domainsid)));
+	ret = idmap_autorid_getrange(autorid_db, range.domsid,
+				     range.domain_range_index,
+				     &range.rangenum, &range.low_id);
+	if (NT_STATUS_IS_OK(ret)) {
+		return idmap_autorid_sid_to_id_rid(
+			global->rangesize, range.low_id, map);
+	}
+
+	if (dom->read_only) {
+		DBG_DEBUG("read-only is enabled, did not allocate "
+			  "new range for domain %s\n", range.domsid);
 		map->status = ID_UNMAPPED;
 		return NT_STATUS_NONE_MAPPED;
 	}
+
+	/*
+	 * Check if we should allocate a domain range. We need to
+	 * protect against unknown domains to not fill our ranges
+	 * needlessly.
+	 */
+
+	if (sid_check_is_builtin(&domainsid) ||
+	    sid_check_is_our_sam(&domainsid)) {
+		goto allocate;
+	}
+
+	{
+		struct winbindd_domain *domain;
+
+		/*
+		 * Deterministic check for domain members: We can be
+		 * sure that the domain we are member of is worth to
+		 * add a mapping for.
+		 */
+
+		domain = find_our_domain();
+		if ((domain != NULL) &&
+		    dom_sid_equal(&domain->sid, &domainsid)) {
+			goto allocate;
+		}
+	}
+
+	/*
+	 * If we have already allocated range index 0, this domain is
+	 * worth allocating for in higher ranges.
+	 */
+	if (range.domain_range_index != 0) {
+		uint32_t zero_rangenum, zero_low_id;
+
+		ret = idmap_autorid_getrange(autorid_db, range.domsid, 0,
+					     &zero_rangenum, &zero_low_id);
+		if (NT_STATUS_IS_OK(ret)) {
+			goto allocate;
+		}
+	}
+
+	/*
+	 * Check of last resort: A domain is valid if a user from that
+	 * domain has recently logged in. The samlogon_cache these
+	 * days also stores the domain sid.
+	 *
+	 * We used to check the list of trusted domains we received
+	 * from "our" dc, but this is not reliable enough.
+	 */
+	if (netsamlogon_cache_have(&domainsid)) {
+		goto allocate;
+	}
+
+	/*
+	 * Nobody knows this domain, so refuse to allocate a fresh
+	 * range.
+	 */
+
+	DBG_NOTICE("Allocating range for domain %s refused\n", range.domsid);
+	map->status = ID_UNMAPPED;
+	return NT_STATUS_NONE_MAPPED;
+
+allocate:
+	ret = idmap_autorid_acquire_range(autorid_db, &range);
 	if (!NT_STATUS_IS_OK(ret)) {
-		DEBUG(3, ("Could not determine range for domain, "
-			  "check previous messages for reason\n"));
+		DBG_NOTICE("Could not determine range for domain: %s, "
+			   "check previous messages for reason\n",
+			   nt_errstr(ret));
 		return ret;
 	}
 
-	return idmap_autorid_sid_to_id_rid(global, &range, map);
+	return idmap_autorid_sid_to_id_rid(global->rangesize, range.low_id,
+					   map);
 }
 
 /**********************************
diff --git a/source3/winbindd/idmap_autorid_tdb.c b/source3/winbindd/idmap_autorid_tdb.c
index 2f09f6c..a95702e 100644
--- a/source3/winbindd/idmap_autorid_tdb.c
+++ b/source3/winbindd/idmap_autorid_tdb.c
@@ -88,7 +88,7 @@ static NTSTATUS idmap_autorid_addrange_action(struct db_context *db,
 	NTSTATUS ret;
 	uint32_t hwm;
 	char *numstr;
-	struct autorid_global_config *globalcfg;
+	struct autorid_global_config globalcfg = {0};
 	fstring keystr;
 	uint32_t increment;
 	TALLOC_CTX *mem_ctx = NULL;
@@ -127,6 +127,21 @@ static NTSTATUS idmap_autorid_addrange_action(struct db_context *db,
 		if (acquire) {
 			DEBUG(10, ("domain range already allocated - "
 				   "Not adding!\n"));
+
+			ret = idmap_autorid_loadconfig(db, &globalcfg);
+			if (!NT_STATUS_IS_OK(ret)) {
+				DEBUG(1, ("Fatal error while fetching "
+					  "configuration: %s\n",
+					  nt_errstr(ret)));
+				goto error;
+			}
+
+			range->rangenum = stored_rangenum;
+			range->low_id = globalcfg.minvalue
+				+ range->rangenum * globalcfg.rangesize;
+			range->high_id =
+				range->low_id  + globalcfg.rangesize - 1;
+
 			return NT_STATUS_OK;
 		}
 
@@ -152,7 +167,7 @@ static NTSTATUS idmap_autorid_addrange_action(struct db_context *db,
 
 	mem_ctx = talloc_stackframe();
 
-	ret = idmap_autorid_loadconfig(db, mem_ctx, &globalcfg);
+	ret = idmap_autorid_loadconfig(db, &globalcfg);
 	if (!NT_STATUS_IS_OK(ret)) {
 		DEBUG(1, ("Fatal error while fetching configuration: %s\n",
 			  nt_errstr(ret)));
@@ -166,11 +181,11 @@ static NTSTATUS idmap_autorid_addrange_action(struct db_context *db,
 		requested_rangenum = hwm;
 	}
 
-	if (requested_rangenum >= globalcfg->maxranges) {
+	if (requested_rangenum >= globalcfg.maxranges) {
 		DEBUG(1, ("Not enough ranges available: New range %u must be "
 			  "smaller than configured maximum number of ranges "
 			  "(%u).\n",
-			  requested_rangenum, globalcfg->maxranges));
+			  requested_rangenum, globalcfg.maxranges));
 		ret = NT_STATUS_NO_MEMORY;
 		goto error;
 	}
@@ -256,9 +271,9 @@ static NTSTATUS idmap_autorid_addrange_action(struct db_context *db,
 
 	range->rangenum = requested_rangenum;
 
-	range->low_id = globalcfg->minvalue
-		      + range->rangenum * globalcfg->rangesize;
-	range->high_id = range->low_id  + globalcfg->rangesize - 1;
+	range->low_id = globalcfg.minvalue
+		      + range->rangenum * globalcfg.rangesize;
+	range->high_id = range->low_id  + globalcfg.rangesize - 1;
 
 	ret = NT_STATUS_OK;
 
@@ -298,8 +313,8 @@ NTSTATUS idmap_autorid_setrange(struct db_context *db,
 	return status;
 }
 
-static NTSTATUS idmap_autorid_acquire_range(struct db_context *db,
-					    struct autorid_range_config *range)
+NTSTATUS idmap_autorid_acquire_range(struct db_context *db,
+				     struct autorid_range_config *range)
 {
 	return idmap_autorid_addrange(db, range, true);
 }
@@ -308,7 +323,7 @@ static NTSTATUS idmap_autorid_getrange_int(struct db_context *db,
 					   struct autorid_range_config *range)
 {
 	NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
-	struct autorid_global_config *globalcfg = NULL;
+	struct autorid_global_config globalcfg = {0};
 	fstring keystr;
 
 	if (db == NULL || range == NULL) {
@@ -333,16 +348,14 @@ static NTSTATUS idmap_autorid_getrange_int(struct db_context *db,
 		goto done;
 	}
 
-	status = idmap_autorid_loadconfig(db, talloc_tos(), &globalcfg);
+	status = idmap_autorid_loadconfig(db, &globalcfg);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(1, ("Failed to read global configuration"));
 		goto done;
 	}
-	range->low_id = globalcfg->minvalue
-		      + range->rangenum * globalcfg->rangesize;
-	range->high_id = range->low_id  + globalcfg->rangesize - 1;
-
-	TALLOC_FREE(globalcfg);
+	range->low_id = globalcfg.minvalue
+		      + range->rangenum * globalcfg.rangesize;
+	range->high_id = range->low_id  + globalcfg.rangesize - 1;
 done:
 	return status;
 }
@@ -844,10 +857,9 @@ bool idmap_autorid_parse_configstr(const char *configstr,
 }
 
 NTSTATUS idmap_autorid_loadconfig(struct db_context *db,
-				  TALLOC_CTX *mem_ctx,
-				  struct autorid_global_config **result)
+				  struct autorid_global_config *result)
 {
-	struct autorid_global_config *cfg;
+	struct autorid_global_config cfg = {0};
 	NTSTATUS status;
 	bool ok;
 	char *configstr = NULL;
@@ -856,25 +868,20 @@ NTSTATUS idmap_autorid_loadconfig(struct db_context *db,
 		return NT_STATUS_INVALID_PARAMETER;
 	}
 
-	status = idmap_autorid_getconfigstr(db, mem_ctx, &configstr);
+	status = idmap_autorid_getconfigstr(db, db, &configstr);
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
 	}
 
-	cfg = talloc_zero(mem_ctx, struct autorid_global_config);
-	if (cfg == NULL) {
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	ok = idmap_autorid_parse_configstr(configstr, cfg);
+	ok = idmap_autorid_parse_configstr(configstr, &cfg);
+	TALLOC_FREE(configstr);
 	if (!ok) {
-		talloc_free(cfg);
 		return NT_STATUS_INVALID_PARAMETER;
 	}
 
 	DEBUG(10, ("Loaded previously stored configuration "
 		   "minvalue:%d rangesize:%d\n",


-- 
Samba Shared Repository



More information about the samba-cvs mailing list