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

Jule Anger janger at samba.org
Wed Apr 5 11:42:02 UTC 2023


The branch, v4-18-test has been updated
       via  4022ee96aef python:netcmd: Decode return value of find_netbios() from bytes into string
       via  50f68094f68 dsdb: Avoid ERROR(ldb): uncaught exception - Deleted target CN=NTDS Settings... in join
       via  e804b5b7808 selftest/drs: Demonstrate ERROR(ldb): uncaught exception - Deleted target CN=NTDS Settings... in join
       via  1a119c757df tsocket: Increase tcp_user_timeout max_loops
       via  f968514c4d4 idmap_hash: remember new domain sids in idmap_hash_sid_to_id()
       via  750865aca3a idmap_hash: don't return ID_REQUIRE_TYPE if the domain is known in the netsamlogon cache
       via  eb4129d3cc7 idmap_hash: only return ID_REQUIRE_TYPE if we don't know about the domain yet
       via  e79be5ed069 idmap_hash: return ID_REQUIRE_TYPE only if there's a chance to get a mapping later
       via  da963496278 idmap_hash: split out a idmap_hash_sid_to_id() helper function
       via  31cedf58e69 idmap_hash: split out a idmap_hash_id_to_sid() helper function
       via  54e872cdf05 idmap_hash: mirror the NT_STATUS_NONE_MAPPED/STATUS_SOME_UNMAPPED logic from idmap_autorid
       via  678c66f1327 idmap_hash: we don't need to call idmap_hash_initialize() over an over again
       via  bbd1f56b78c idmap_hash: remove unused error checks
       via  00909630b0d idmap_hash: fix comments about the algorithm
       via  e804feaf76d idmap_hash: provide ID_TYPE_BOTH mappings also for unixids_to_sids
       via  fd7e0aaa196 idmap_autorid: fix ID_REQUIRE_TYPE for more than one SID for an unknown domain
       via  5c68985b278 winbindd: don't call set_domain_online_request() in the idmap child
      from  5db0223764d VERSION: Bump version up to Samba 4.18.2...

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


- Log -----------------------------------------------------------------
commit 4022ee96aef8184f7d1a4686e06113cda7e29ac3
Author: Andreas Schneider <asn at samba.org>
Date:   Fri Mar 10 09:08:48 2023 +0100

    python:netcmd: Decode return value of find_netbios() from bytes into string
    
    ERROR(<class 'TypeError'>): uncaught exception - replace() argument 1 must be
    str, not bytes
      File "bin/python/samba/netcmd/__init__.py", line 230, in _run
        return self.run(*args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^
      File "bin/python/samba/netcmd/ldapcmp.py", line 966, in run
        if b1.diff(b2):
           ^^^^^^^^^^^
      File "bin/python/samba/netcmd/ldapcmp.py", line 790, in diff
        if object1 == object2:
           ^^^^^^^^^^^^^^^^^^
      File "bin/python/samba/netcmd/ldapcmp.py", line 557, in __eq__
        return self.cmp_attrs(other)
               ^^^^^^^^^^^^^^^^^^^^^
      File "bin/python/samba/netcmd/ldapcmp.py", line 656, in cmp_attrs
        p = [self.fix_domain_netbios(j) for j in m]
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "bin/python/samba/netcmd/ldapcmp.py", line 656, in <listcomp>
        p = [self.fix_domain_netbios(j) for j in m]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "bin/python/samba/netcmd/ldapcmp.py", line 542, in fix_domain_netbios
        res = res.replace(self.con.domain_netbios.lower(), self.con.domain_netbios.upper())
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    
    BUGS: https://bugzilla.samba.org/show_bug.cgi?id=15330
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    (cherry picked from commit 4fa0242b9d34decd8dbd813be40655a593df3db9)
    
    Autobuild-User(v4-18-test): Jule Anger <janger at samba.org>
    Autobuild-Date(v4-18-test): Wed Apr  5 11:41:32 UTC 2023 on atb-devel-224

commit 50f68094f68078072510d9193e72eef56c70c6d5
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)

commit e804b5b7808f5fafaf61c19476cee98c475fab8a
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 1a119c757df4a41407738206e96f6834dd3ae6ff
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 f968514c4d45cd89ea94196ef1b9487447262915
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 750865aca3ae44c8b949babb4c77175d8917543c
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 eb4129d3cc75833554f26f31ef91b164d9a3b2e8
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 e79be5ed069cb4efda859792b43fe7d4c044c2a7
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 da9634962783ddb3fcd7daca8cf1631b012189bf
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 31cedf58e695128509215e5e5e5e0bec53531832
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 54e872cdf051e718b6ba186ab80b4e7974cd13cf
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 678c66f1327988fe4ad0def6a3a43d789ae42387
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 bbd1f56b78cfd0a644016db88ee0eb2a4b2dbc3d
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 00909630b0d609f694ee078562d59dd43cdbdd60
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 e804feaf76d3609e0f69a4bb1cc9d42934c221d3
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 fd7e0aaa196c83f28d76a0309d09c27e5eedae59
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 5c68985b2788330026df687d5439f4e86f90a77c
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 +-
 python/samba/join.py                            |  19 ++
 python/samba/netcmd/ldapcmp.py                  |   2 +-
 source3/winbindd/idmap_autorid.c                |  15 +-
 source3/winbindd/idmap_hash/idmap_hash.c        | 302 +++++++++++++++---------
 source3/winbindd/winbindd_dual.c                |   7 -
 source4/dsdb/pydsdb.c                           |   2 +
 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, 380 insertions(+), 119 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/python/samba/join.py b/python/samba/join.py
index 70b3c9729b0..6c1ab3be7b4 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/python/samba/netcmd/ldapcmp.py b/python/samba/netcmd/ldapcmp.py
index fb49cbe1ae5..ff26e96332d 100644
--- a/python/samba/netcmd/ldapcmp.py
+++ b/python/samba/netcmd/ldapcmp.py
@@ -121,7 +121,7 @@ class LDAPBase(object):
 
         for x in res:
             if "nETBIOSName" in x:
-                return x["nETBIOSName"][0]
+                return x["nETBIOSName"][0].decode()
 
     def object_exists(self, object_dn):
         res = None
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;
+	}
+
+	return STATUS_SOME_UNMAPPED;
 }
 
 /*********************************************************************
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index 8cb59b2f752..d053977033f 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -1811,13 +1811,6 @@ static bool fork_domain_child(struct winbindd_child *child)
 		}
 	}
 


-- 
Samba Shared Repository



More information about the samba-cvs mailing list