[SCM] Samba Shared Repository - branch v4-17-test updated

Jule Anger janger at samba.org
Thu Mar 30 16:11:02 UTC 2023


The branch, v4-17-test has been updated
       via  e2df45934ab dsdb: Avoid ERROR(ldb): uncaught exception - Deleted target CN=NTDS Settings... in join
       via  eaff4ef6162 selftest/drs: Demonstrate ERROR(ldb): uncaught exception - Deleted target CN=NTDS Settings... in join
       via  3ecdec683b6 CVE-2020-25720 pydsdb: Add AD schema GUID constants
       via  b1c7df203d0 tsocket: Increase tcp_user_timeout max_loops
       via  bf5ccd5a140 idmap_hash: remember new domain sids in idmap_hash_sid_to_id()
       via  f27cff23350 idmap_hash: don't return ID_REQUIRE_TYPE if the domain is known in the netsamlogon cache
       via  182410af7de idmap_hash: only return ID_REQUIRE_TYPE if we don't know about the domain yet
       via  13a593254af idmap_hash: return ID_REQUIRE_TYPE only if there's a chance to get a mapping later
       via  e5c9a3597af idmap_hash: split out a idmap_hash_sid_to_id() helper function
       via  da270642918 idmap_hash: split out a idmap_hash_id_to_sid() helper function
       via  61f3e674076 idmap_hash: mirror the NT_STATUS_NONE_MAPPED/STATUS_SOME_UNMAPPED logic from idmap_autorid
       via  a19fe930199 idmap_hash: we don't need to call idmap_hash_initialize() over an over again
       via  5a754810dea idmap_hash: remove unused error checks
       via  1e6eeb8efb2 idmap_hash: fix comments about the algorithm
       via  bac09f85daa idmap_hash: provide ID_TYPE_BOTH mappings also for unixids_to_sids
       via  edc8659b505 idmap_autorid: fix ID_REQUIRE_TYPE for more than one SID for an unknown domain
       via  148d5ad7698 winbindd: don't call set_domain_online_request() in the idmap child
      from  cb204cfc69b VERSION: Bump version up to Samba 4.17.8...

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-17-test


- Log -----------------------------------------------------------------
commit e2df45934ab415732f7f0377601774119b37e7b3
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Mar 9 20:25:06 2023 +1300

    dsdb: Avoid ERROR(ldb): uncaught exception - Deleted target CN=NTDS Settings... in join
    
    "samba-tool domain join" uses the replication API in a strange way, perhaps no longer
    required, except that we often still have folks upgrading from very old Samba versions.
    
    When deferring the writing out to the DB of link replication to the very end, there
    is a greater opportunity for the deletion of an object to have been sent with the
    other objects, and have the link applied later.
    
    This tells the repl_meta_data code to behave as if GET_TGT had been sent at the
    time the link was returned, allowing a link to a deleted object to be silently
    discarded.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15329
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    (cherry picked from commit bfc33b47bb428233e100f75e7a725ac52179f823)
    
    Autobuild-User(v4-17-test): Jule Anger <janger at samba.org>
    Autobuild-Date(v4-17-test): Thu Mar 30 16:10:35 UTC 2023 on sn-devel-184

commit eaff4ef61624276b16dc0dcb11868e2778d2e46f
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Mar 9 17:02:35 2023 +1300

    selftest/drs: Demonstrate ERROR(ldb): uncaught exception - Deleted target CN=NTDS Settings... in join
    
    "samba-tool domain join" uses the replication API in a strange way, perhaps no longer
    required, except that we often still have folks upgrading from very old Samba versions.
    
    By deferring the writing out to the DB of link replication to the very end, we have a
    better chance that all the objects required are present, however the situation may
    have changed during the cycle, and a link could still be sent, pointing to a deleted
    object.
    
    We currently fail in this situation.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15329
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    (cherry picked from commit 2d41bcce83a976b85636c92d6fc38c63fdde5431)

commit 3ecdec683b60cf100b1c031841b709c91191c8f2
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Wed Sep 14 13:21:34 2022 +1200

    CVE-2020-25720 pydsdb: Add AD schema GUID constants
    
    This helps reduce the profusion of magic constant values in Python
    tests.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14810
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15329
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit 2563f85237bd4260b7b527f3695f27da4cc61a74)
    
    [abartlet at samba.org Required context for backport of bug 15329 to
     Samba 4.17]

commit b1c7df203d02410d829381f7b7fcfbc7c8d4bfd1
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Mar 9 10:06:26 2023 +1300

    tsocket: Increase tcp_user_timeout max_loops
    
    Often, on rackspace GitLab CI runners, we get:
    
    UNEXPECTED(failure): samba.unittests.tsocket_tstream.test_tstream_more_tcp_user_timeout_spin(none)
    REASON: Exception: Exception: 0xf == 0xf
    ../../lib/tsocket/tests/test_tstream.c:405: error: Failure!
    
    This allows us more spins before we fail the test.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15328
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    (cherry picked from commit 5a7a28cc45870949fc11d30586a06c309aa517dc)

commit bf5ccd5a14062dc31c09e167dadff9782ba1caba
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Mar 21 16:54:31 2019 +0100

    idmap_hash: remember new domain sids in idmap_hash_sid_to_id()
    
    This change means that idmap_hash_id_to_sid() can return mappings
    for new domains learned in idmap_hash_sid_to_id().
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15319
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Fri Mar 10 11:35:06 UTC 2023 on atb-devel-224
    
    (cherry picked from commit 7ee725f2860d835e9619fa594a2ee6faedbc6d21)

commit f27cff23350dc332515a66d98335418d20e94a0e
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Mar 21 16:54:31 2019 +0100

    idmap_hash: don't return ID_REQUIRE_TYPE if the domain is known in the netsamlogon cache
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15319
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit ee820553fd2c6ada966a0160cbb0240049f9d9f7)

commit 182410af7de4fdfb8100cc83e53d0371e59d6a81
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Mar 21 16:54:31 2019 +0100

    idmap_hash: only return ID_REQUIRE_TYPE if we don't know about the domain yet
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15319
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit ede88d9f83fb77fa8eff226fb6a85ac71e415098)

commit 13a593254afa9cfdfbcefb51da88b1a8309ef723
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Mar 21 16:54:31 2019 +0100

    idmap_hash: return ID_REQUIRE_TYPE only if there's a chance to get a mapping later
    
    If we are going to return ID_UNMAPPED later anyway, there's no need to
    defer that decision by returning ID_REQUIRE_TYPE first.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15319
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 42dcb3db05530179a991fe58e7b96b52bbbcc607)

commit e5c9a3597af05da7236e284422adca5294ff31c4
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Mar 21 14:05:13 2019 +0100

    idmap_hash: split out a idmap_hash_sid_to_id() helper function
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15319
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit c158b075b0b5035615fa8848f1f3d8ef27696861)

commit da2706429185ec6724d91f409f78ffbf10f7208c
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Mar 21 14:05:13 2019 +0100

    idmap_hash: split out a idmap_hash_id_to_sid() helper function
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15319
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 57150b463fb8e27c048670f7b4902bd091ee3ae9)

commit 61f3e6740765c92cd84c28ee69fe410c18b548fc
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Mar 21 14:00:16 2019 +0100

    idmap_hash: mirror the NT_STATUS_NONE_MAPPED/STATUS_SOME_UNMAPPED logic from idmap_autorid
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15319
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 14102b05f3744c67178bd719d41e67fc3e049ee4)

commit a19fe9301999a0ce308f06643ff3be1bbac7beb7
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Mar 21 10:54:49 2019 +0100

    idmap_hash: we don't need to call idmap_hash_initialize() over an over again
    
    It's always the first function that's called from idmap_methods.
    
    This also demonstrates that we currently always return NT_STATUS_OK,
    even if we haven't mapped all map entries.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15319
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 0da13ab3ad7278eafdcd988f39e891242eb46d37)

commit 5a754810dead1225554b5a9c5c5265079ae5c0a9
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Mar 21 13:54:10 2019 +0100

    idmap_hash: remove unused error checks
    
    id_map_ptrs_init() is used in the callers in order to
    set everything up as expected.
    
    Other backends also just trust the caller.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15319
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 2cfcff3101fce94b365eccde114432dfa980bbd0)

commit 1e6eeb8efb21a836c08d203d379817598d6ea447
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Mar 21 13:37:16 2019 +0100

    idmap_hash: fix comments about the algorithm
    
    Only support ~ 50k users per domain.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15319
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>
    (cherry picked from commit 0f96c4b419a59ea884e68a460910e5c8a45bfcec)

commit bac09f85daa6f610347fd467c27d1b5197b3a662
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Mar 21 16:38:35 2019 +0100

    idmap_hash: provide ID_TYPE_BOTH mappings also for unixids_to_sids
    
    While sids_to_unixids returns ID_TYPE_BOTH mappings,
    unixids_to_sids() returns the callers asked for, which
    fills gencache with the non ID_TYPE_BOTH mappings.
    As a result also the sids_to_unixids fast path via
    gencache won't return ID_TYPE_BOTH mappings.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15319
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 9a24570d3d69f51b6d50bb04b739815ec67c1a3d)

commit edc8659b5055e3b8adec83417846a76147ee1408
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Feb 17 16:51:42 2023 +0100

    idmap_autorid: fix ID_REQUIRE_TYPE for more than one SID for an unknown domain
    
    When we see a trusted domain SID for the first time,
    idmap_autorid returns ID_REQUIRE_TYPE only for the first sid
    and leaves the others with ID_TYPE_NOT_SPECIFIED.
    It means the winbindd parent only retries the first sid.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15318
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit a9583b5f96fe3fbf9c1ee545fa868fd705aef3e0)

commit 148d5ad7698d154731dfa092b0c6314c71f38086
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Feb 16 16:31:34 2023 +0100

    winbindd: don't call set_domain_online_request() in the idmap child
    
    Most idmap backends don't need access to the domain controllers.
    And the related code is not needed for the backends.
    
    Commit 17c86a2c5a5a5e2b194362e5f36f0f99910222c5 changed
    the logic of set_domain_online_request() completely!
    Instead of triggering a dc probe in the background,
    it is now doing a blocking connection.
    And doing this in the idmap child is completely useless.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=15317
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit ad242a20643c930eb00a8b700f7bd9638f8821a8)

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

Summary of changes:
 lib/tsocket/tests/test_tstream.c                |   2 +-
 libds/common/flags.h                            |  14 ++
 python/samba/join.py                            |  19 ++
 source3/winbindd/idmap_autorid.c                |  15 +-
 source3/winbindd/idmap_hash/idmap_hash.c        | 302 +++++++++++++++---------
 source3/winbindd/winbindd_dual.c                |   7 -
 source4/dsdb/pydsdb.c                           |  15 ++
 source4/dsdb/samdb/ldb_modules/repl_meta_data.c |  13 +-
 source4/dsdb/samdb/samdb.h                      |   2 +
 source4/torture/drs/python/ridalloc_exop.py     | 135 +++++++++++
 10 files changed, 406 insertions(+), 118 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/tsocket/tests/test_tstream.c b/lib/tsocket/tests/test_tstream.c
index a920e671cda..47008bb8bf8 100644
--- a/lib/tsocket/tests/test_tstream.c
+++ b/lib/tsocket/tests/test_tstream.c
@@ -322,7 +322,7 @@ static void test_tstream_server_spin_client_tcp_user_timeout(struct socket_pair
 	rc = write(sp->socket_client, TEST_STRING, sizeof(TEST_STRING));
 	assert_return_code(rc, errno);
 	sp->expected_errno = ETIMEDOUT;
-	sp->max_loops = 15;
+	sp->max_loops = 30;
 }
 
 static void test_tstream_server_spin_client_both_timer(struct tevent_context *ev,
diff --git a/libds/common/flags.h b/libds/common/flags.h
index bee1016b294..c013d2f0f25 100644
--- a/libds/common/flags.h
+++ b/libds/common/flags.h
@@ -237,6 +237,20 @@
 /* wellknown GUIDs for optional directory features */
 #define DS_GUID_FEATURE_RECYCLE_BIN		      "766ddcd8-acd0-445e-f3b9-a7f9b6744f2a"
 
+/* GUIDs for AD schema attributes and classes */
+#define DS_GUID_SCHEMA_ATTR_DEPARTMENT                "bf96794f-0de6-11d0-a285-00aa003049e2"
+#define DS_GUID_SCHEMA_ATTR_DNS_HOST_NAME             "72e39547-7b18-11d1-adef-00c04fd8d5cd"
+#define DS_GUID_SCHEMA_ATTR_INSTANCE_TYPE             "bf96798c-0de6-11d0-a285-00aa003049e2"
+#define DS_GUID_SCHEMA_ATTR_MS_SFU_30                 "16c5d1d3-35c2-4061-a870-a5cefda804f0"
+#define DS_GUID_SCHEMA_ATTR_NT_SECURITY_DESCRIPTOR    "bf9679e3-0de6-11d0-a285-00aa003049e2"
+#define DS_GUID_SCHEMA_ATTR_PRIMARY_GROUP_ID          "bf967a00-0de6-11d0-a285-00aa003049e2"
+#define DS_GUID_SCHEMA_ATTR_SERVICE_PRINCIPAL_NAME    "f3a64788-5306-11d1-a9c5-0000f80367c1"
+#define DS_GUID_SCHEMA_ATTR_USER_ACCOUNT_CONTROL      "bf967a68-0de6-11d0-a285-00aa003049e2"
+#define DS_GUID_SCHEMA_ATTR_USER_PASSWORD             "bf967a6e-0de6-11d0-a285-00aa003049e2"
+#define DS_GUID_SCHEMA_CLASS_COMPUTER                 "bf967a86-0de6-11d0-a285-00aa003049e2"
+#define DS_GUID_SCHEMA_CLASS_MANAGED_SERVICE_ACCOUNT  "ce206244-5827-4a86-ba1c-1c0c386c1b64"
+#define DS_GUID_SCHEMA_CLASS_USER                     "bf967aba-0de6-11d0-a285-00aa003049e2"
+
 /* dsHeuristics character indexes see MS-ADTS 7.1.1.2.4.1.2 */
 
 #define DS_HR_SUPFIRSTLASTANR                     0x00000001
diff --git a/python/samba/join.py b/python/samba/join.py
index 650bb5a08ae..30d33d43f11 100644
--- a/python/samba/join.py
+++ b/python/samba/join.py
@@ -50,6 +50,7 @@ import tempfile
 from collections import OrderedDict
 from samba.common import get_string
 from samba.netcmd import CommandError
+from samba import dsdb
 
 
 class DCJoinException(Exception):
@@ -937,6 +938,10 @@ class DCJoinContext(object):
         """Replicate the SAM."""
 
         ctx.logger.info("Starting replication")
+
+        # A global transaction is started so that linked attributes
+        # are applied at the very end, once all partitions are
+        # replicated.  This helps get all cross-partition links.
         ctx.local_samdb.transaction_start()
         try:
             source_dsa_invocation_id = misc.GUID(ctx.samdb.get_invocation_id())
@@ -1057,7 +1062,21 @@ class DCJoinContext(object):
             ctx.local_samdb.transaction_cancel()
             raise
         else:
+
+            # This is a special case, we have completed a full
+            # replication so if a link comes to us that points to a
+            # deleted object, and we asked for all objects already, we
+            # just have to ignore it, the chance to re-try the
+            # replication with GET_TGT has long gone.  This can happen
+            # if the object is deleted and sent to us after the link
+            # was sent, as we are processing all links in the
+            # transaction_commit().
+            if not ctx.domain_replica_flags & drsuapi.DRSUAPI_DRS_CRITICAL_ONLY:
+                ctx.local_samdb.set_opaque_integer(dsdb.DSDB_FULL_JOIN_REPLICATION_COMPLETED_OPAQUE_NAME,
+                                                   1)
             ctx.local_samdb.transaction_commit()
+            ctx.local_samdb.set_opaque_integer(dsdb.DSDB_FULL_JOIN_REPLICATION_COMPLETED_OPAQUE_NAME,
+                                               0)
             ctx.logger.info("Committed SAM database")
 
         # A large replication may have caused our LDB connection to the
diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c
index c7d56a37684..bf5947a9b43 100644
--- a/source3/winbindd/idmap_autorid.c
+++ b/source3/winbindd/idmap_autorid.c
@@ -697,9 +697,10 @@ static NTSTATUS idmap_autorid_sids_to_unixids(struct idmap_domain *dom,
 {
 	struct idmap_tdb_common_context *commoncfg;
 	NTSTATUS ret;
-	int i;
-	int num_tomap = 0;
-	int num_mapped = 0;
+	size_t i;
+	size_t num_tomap = 0;
+	size_t num_mapped = 0;
+	size_t num_required = 0;
 
 	/* initialize the status to avoid surprise */
 	for (i = 0; ids[i]; i++) {
@@ -713,6 +714,12 @@ static NTSTATUS idmap_autorid_sids_to_unixids(struct idmap_domain *dom,
 
 	for (i = 0; ids[i]; i++) {
 		ret = idmap_autorid_sid_to_id(commoncfg, dom, ids[i]);
+		if (NT_STATUS_EQUAL(ret, NT_STATUS_SOME_NOT_MAPPED) &&
+		    ids[i]->status == ID_REQUIRE_TYPE)
+		{
+			num_required++;
+			continue;
+		}
 		if ((!NT_STATUS_IS_OK(ret)) &&
 		    (!NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED))) {
 			struct dom_sid_buf buf;
@@ -729,6 +736,8 @@ static NTSTATUS idmap_autorid_sids_to_unixids(struct idmap_domain *dom,
 
 	if (num_tomap == num_mapped) {
 		return NT_STATUS_OK;
+	} else if (num_required > 0) {
+		return STATUS_SOME_UNMAPPED;
 	} else if (num_mapped == 0) {
 		return NT_STATUS_NONE_MAPPED;
 	}
diff --git a/source3/winbindd/idmap_hash/idmap_hash.c b/source3/winbindd/idmap_hash/idmap_hash.c
index d0bed7631a6..e9d90e3d02b 100644
--- a/source3/winbindd/idmap_hash/idmap_hash.c
+++ b/source3/winbindd/idmap_hash/idmap_hash.c
@@ -25,6 +25,7 @@
 #include "ads.h"
 #include "nss_info.h"
 #include "../libcli/security/dom_sid.h"
+#include "libsmb/samlogon_cache.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_IDMAP
@@ -60,13 +61,16 @@ static uint32_t hash_domain_sid(const struct dom_sid *sid)
 }
 
 /*********************************************************************
- Hash a Relative ID to a 20 bit number
+ Hash a Relative ID to a 19 bit number
  ********************************************************************/
 
 static uint32_t hash_rid(uint32_t rid)
 {
-	/* 20 bits for the rid which allows us to support
-	   the first 100K users/groups in a domain */
+	/*
+	 * 19 bits for the rid which allows us to support
+	 * the first 50K users/groups in a domain
+	 *
+	 */
 
 	return (rid & 0x0007FFFF);
 }
@@ -79,8 +83,13 @@ static uint32_t combine_hashes(uint32_t h_domain,
 {
 	uint32_t return_id = 0;
 
-	/* shift the hash_domain 19 bits to the left and OR with the
-	   hash_rid */
+	/*
+	 * shift the hash_domain 19 bits to the left and OR with the
+	 * hash_rid
+	 *
+	 * This will generate a 31 bit number out of
+	 * 12 bit domain and 19 bit rid.
+	 */
 
 	return_id = ((h_domain<<19) | h_rid);
 
@@ -123,14 +132,6 @@ static NTSTATUS idmap_hash_initialize(struct idmap_domain *dom)
 		return NT_STATUS_INVALID_PARAMETER;
 	}
 
-	/* If the domain SID hash table has been initialized, assume
-	   that we completed this function previously */
-
-	if (dom->private_data != NULL) {
-		nt_status = NT_STATUS_OK;
-		goto done;
-	}
-
 	if (!wcache_tdc_fetch_list(&dom_list, &num_domains)) {
 		nt_status = NT_STATUS_TRUSTED_DOMAIN_FAILURE;
 		BAIL_ON_NTSTATUS_ERROR(nt_status);
@@ -183,135 +184,224 @@ done:
 /*********************************************************************
  ********************************************************************/
 
+static NTSTATUS idmap_hash_id_to_sid(struct sid_hash_table *hashed_domains,
+				     struct idmap_domain *dom,
+				     struct id_map *id)
+{
+	uint32_t h_domain = 0, h_rid = 0;
+
+	id->status = ID_UNMAPPED;
+
+	separate_hashes(id->xid.id, &h_domain, &h_rid);
+
+	/*
+	 * If the domain hash doesn't find a SID in the table,
+	 * skip it
+	 */
+	if (hashed_domains[h_domain].sid == NULL) {
+		/* keep ID_UNMAPPED */
+		return NT_STATUS_OK;
+	}
+
+	id->xid.type = ID_TYPE_BOTH;
+	sid_compose(id->sid, hashed_domains[h_domain].sid, h_rid);
+	id->status = ID_MAPPED;
+
+	return NT_STATUS_OK;
+}
+
 static NTSTATUS unixids_to_sids(struct idmap_domain *dom,
 				struct id_map **ids)
 {
 	struct sid_hash_table *hashed_domains = talloc_get_type_abort(
 		dom->private_data, struct sid_hash_table);
-	NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-	int i;
-
-	if (!ids) {
-		nt_status = NT_STATUS_INVALID_PARAMETER;
-		BAIL_ON_NTSTATUS_ERROR(nt_status);
-	}
+	size_t i;
+	size_t num_tomap = 0;
+	size_t num_mapped = 0;
 
-	/* initialize the status to avoid suprise */
+	/* initialize the status to avoid surprise */
 	for (i = 0; ids[i]; i++) {
 		ids[i]->status = ID_UNKNOWN;
+		num_tomap++;
 	}
 
-	nt_status = idmap_hash_initialize(dom);
-	BAIL_ON_NTSTATUS_ERROR(nt_status);
-
 	for (i=0; ids[i]; i++) {
-		uint32_t h_domain, h_rid;
+		NTSTATUS ret;
+
+		ret = idmap_hash_id_to_sid(hashed_domains, dom, ids[i]);
+		if (!NT_STATUS_IS_OK(ret)) {
+			/* some fatal error occurred, log it */
+			DBG_NOTICE("Unexpected error resolving an ID "
+				   "(%d): %s\n", ids[i]->xid.id,
+				   nt_errstr(ret));
+			return ret;
+		}
 
-		ids[i]->status = ID_UNMAPPED;
+		if (ids[i]->status == ID_MAPPED) {
+			num_mapped++;
+		}
+	}
 
-		separate_hashes(ids[i]->xid.id, &h_domain, &h_rid);
+	if (num_tomap == num_mapped) {
+		return NT_STATUS_OK;
+	} else if (num_mapped == 0) {
+		return NT_STATUS_NONE_MAPPED;
+	}
 
-		/* Make sure the caller allocated memor for us */
+	return STATUS_SOME_UNMAPPED;
+}
 
-		if (!ids[i]->sid) {
-			nt_status = NT_STATUS_INVALID_PARAMETER;
-			BAIL_ON_NTSTATUS_ERROR(nt_status);
-		}
+/*********************************************************************
+ ********************************************************************/
 
-		/* If the domain hash doesn't find a SID in the table,
-		   skip it */
+static NTSTATUS idmap_hash_sid_to_id(struct sid_hash_table *hashed_domains,
+				     struct idmap_domain *dom,
+				     struct id_map *id)
+{
+	struct dom_sid sid;
+	uint32_t rid;
+	uint32_t h_domain, h_rid;
 
-		if (!hashed_domains[h_domain].sid)
-			continue;
+	id->status = ID_UNMAPPED;
 
-		sid_compose(ids[i]->sid, hashed_domains[h_domain].sid, h_rid);
-		ids[i]->status = ID_MAPPED;
+	sid_copy(&sid, id->sid);
+	sid_split_rid(&sid, &rid);
+
+	h_domain = hash_domain_sid(&sid);
+	h_rid = hash_rid(rid);
+
+	/* Check that both hashes are non-zero*/
+	if (h_domain == 0) {
+		/* keep ID_UNMAPPED */
+		return NT_STATUS_OK;
+	}
+	if (h_rid == 0) {
+		/* keep ID_UNMAPPED */
+		return NT_STATUS_OK;
 	}
 
-done:
-	return nt_status;
-}
+	/*
+	 * If the domain hash already exists find a SID in the table,
+	 * just return the mapping.
+	 */
+	if (hashed_domains[h_domain].sid != NULL) {
+		goto return_mapping;
+	}
 
-/*********************************************************************
- ********************************************************************/
+	/*
+	 * 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.
+	 */
+	if (netsamlogon_cache_have(&sid)) {
+		/*
+		 * The domain is valid, so we'll
+		 * remember it in order to
+		 * allow reverse mappings to work.
+		 */
+		goto remember_domain;
+	}
+
+	if (id->xid.type == ID_TYPE_NOT_SPECIFIED) {
+		/*
+		 * idmap_hash used to bounce back the requested type,
+		 * which was ID_TYPE_UID, ID_TYPE_GID or
+		 * ID_TYPE_NOT_SPECIFIED before as the winbindd parent
+		 * always used a lookupsids.  When the lookupsids
+		 * failed because of an unknown domain, the idmap child
+		 * weren't requested at all and the caller sees
+		 * ID_TYPE_NOT_SPECIFIED.
+		 *
+		 * Now that the winbindd parent will pass ID_TYPE_BOTH
+		 * in order to indicate that the domain exists.
+		 * We should ask the parent to fallback to lookupsids
+		 * if the domain is not known yet.
+		 */
+		id->status = ID_REQUIRE_TYPE;
+		return NT_STATUS_OK;
+	}
+
+	/*
+	 * Now we're sure the domain exist, remember
+	 * the domain in order to return reverse mappings
+	 * in future.
+	 */
+remember_domain:
+	hashed_domains[h_domain].sid = dom_sid_dup(hashed_domains, &sid);
+	if (hashed_domains[h_domain].sid == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	/*
+	 * idmap_hash used to bounce back the requested type,
+	 * which was ID_TYPE_UID, ID_TYPE_GID or
+	 * ID_TYPE_NOT_SPECIFIED before as the winbindd parent
+	 * always used a lookupsids.
+	 *
+	 * This module should have supported ID_TYPE_BOTH since
+	 * samba-4.1.0, similar to idmap_rid and idmap_autorid.
+	 *
+	 * Now that the winbindd parent will pass ID_TYPE_BOTH
+	 * in order to indicate that the domain exists, it's
+	 * better to always return ID_TYPE_BOTH instead of a
+	 * random mix of ID_TYPE_UID, ID_TYPE_GID or
+	 * ID_TYPE_BOTH.
+	 */
+return_mapping:
+	id->xid.type = ID_TYPE_BOTH;
+	id->xid.id = combine_hashes(h_domain, h_rid);
+	id->status = ID_MAPPED;
+
+	return NT_STATUS_OK;
+}
 
 static NTSTATUS sids_to_unixids(struct idmap_domain *dom,
 				struct id_map **ids)
 {
-	NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
-	int i;
-
-	if (!ids) {
-		nt_status = NT_STATUS_INVALID_PARAMETER;
-		BAIL_ON_NTSTATUS_ERROR(nt_status);
-	}
+	struct sid_hash_table *hashed_domains = talloc_get_type_abort(
+		dom->private_data, struct sid_hash_table);
+	size_t i;
+	size_t num_tomap = 0;
+	size_t num_mapped = 0;
+	size_t num_required = 0;
 
-	/* initialize the status to avoid suprise */
+	/* initialize the status to avoid surprise */
 	for (i = 0; ids[i]; i++) {
 		ids[i]->status = ID_UNKNOWN;
+		num_tomap++;
 	}
 
-	nt_status = idmap_hash_initialize(dom);
-	BAIL_ON_NTSTATUS_ERROR(nt_status);
-
 	for (i=0; ids[i]; i++) {
-		struct dom_sid sid;
-		uint32_t rid;
-		uint32_t h_domain, h_rid;
-
-		ids[i]->status = ID_UNMAPPED;
-
-		if (ids[i]->xid.type == ID_TYPE_NOT_SPECIFIED) {
-			/*
-			 * idmap_hash used to bounce back the requested type,
-			 * which was ID_TYPE_UID, ID_TYPE_GID or
-			 * ID_TYPE_NOT_SPECIFIED before as the winbindd parent
-			 * always used a lookupsids.  When the lookupsids
-			 * failed because of an unknown domain, the idmap child
-			 * weren't requested at all and the caller sees
-			 * ID_TYPE_NOT_SPECIFIED.
-			 *
-			 * Now that the winbindd parent will pass ID_TYPE_BOTH
-			 * in order to indicate that the domain exists.
-			 * We should ask the parent to fallback to lookupsids
-			 * if the domain is not known yet.
-			 */
-			ids[i]->status = ID_REQUIRE_TYPE;
-			continue;
+		NTSTATUS ret;
+
+		ret = idmap_hash_sid_to_id(hashed_domains, dom, ids[i]);
+		if (!NT_STATUS_IS_OK(ret)) {
+			struct dom_sid_buf buf;
+			/* some fatal error occurred, log it */
+			DBG_NOTICE("Unexpected error resolving a SID "
+				   "(%s): %s\n",
+				   dom_sid_str_buf(ids[i]->sid, &buf),
+				   nt_errstr(ret));
+			return ret;
 		}
 
-		sid_copy(&sid, ids[i]->sid);
-		sid_split_rid(&sid, &rid);
-
-		h_domain = hash_domain_sid(&sid);
-		h_rid = hash_rid(rid);
-
-		/* Check that both hashes are non-zero*/
-
-		if (h_domain && h_rid) {
-			/*
-			 * idmap_hash used to bounce back the requested type,
-			 * which was ID_TYPE_UID, ID_TYPE_GID or
-			 * ID_TYPE_NOT_SPECIFIED before as the winbindd parent
-			 * always used a lookupsids.
-			 *
-			 * This module should have supported ID_TYPE_BOTH since
-			 * samba-4.1.0, similar to idmap_rid and idmap_autorid.
-			 *
-			 * Now that the winbindd parent will pass ID_TYPE_BOTH
-			 * in order to indicate that the domain exists, it's
-			 * better to always return ID_TYPE_BOTH instead of a
-			 * random mix of ID_TYPE_UID, ID_TYPE_GID or
-			 * ID_TYPE_BOTH.
-			 */
-			ids[i]->xid.type = ID_TYPE_BOTH;
-			ids[i]->xid.id = combine_hashes(h_domain, h_rid);
-			ids[i]->status = ID_MAPPED;
+		if (ids[i]->status == ID_MAPPED) {
+			num_mapped++;
+		}
+		if (ids[i]->status == ID_REQUIRE_TYPE) {
+			num_required++;
 		}
 	}
 
-done:
-	return nt_status;
+	if (num_tomap == num_mapped) {
+		return NT_STATUS_OK;
+	} else if (num_required > 0) {
+		return STATUS_SOME_UNMAPPED;
+	} else if (num_mapped == 0) {
+		return NT_STATUS_NONE_MAPPED;
+	}
+


-- 
Samba Shared Repository



More information about the samba-cvs mailing list