[SCM] Samba Shared Repository - branch master updated

Karolin Seeger kseeger at samba.org
Tue Dec 10 10:45:02 UTC 2019


The branch, master has been updated
       via  73f43626062 CVE-2019-14870: mit-kdc: enforce delegation_not_allowed flag
       via  84de46f5347 CVE-2019-14870: heimdal: enforce delegation_not_allowed in S4U2Self
       via  df72956adee CVE-2019-14870: heimdal: add S4U test for delegation_not_allowed
       via  aa17d5fcaf7 samba-tool: add user-sensitive command to set not-delegated flag
       via  aaf037dfb34 CVE-2019-14861: Test to demonstrate the bug
       via  defb2373251 CVE-2019-14861: s4-rpc/dnsserver: Avoid crash in ldb_qsort() via dcesrv_DnssrvEnumRecords)
       via  4333e41c224 CVE-2019-14861: s4-rpc_server: Remove special case for @ in dns_build_tree()
       via  a25a2e4513e CVE-2019-14861: s4-rpc/dnsserver: Confirm sort behaviour in dcesrv_DnssrvEnumRecords
      from  8b06cabc7d7 bootstrap: Add chrpath as a required package

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


- Log -----------------------------------------------------------------
commit 73f436260620a97e307110ec45311e9e5dd321ce
Author: Isaac Boukris <iboukris at gmail.com>
Date:   Thu Nov 21 11:12:48 2019 +0100

    CVE-2019-14870: mit-kdc: enforce delegation_not_allowed flag
    
    Signed-off-by: Isaac Boukris <iboukris at samba.org>
    
    Autobuild-User(master): Karolin Seeger <kseeger at samba.org>
    Autobuild-Date(master): Tue Dec 10 10:44:01 UTC 2019 on sn-devel-184

commit 84de46f5347288a3683ba083f529137efa8028e9
Author: Isaac Boukris <iboukris at gmail.com>
Date:   Mon Oct 28 02:54:09 2019 +0200

    CVE-2019-14870: heimdal: enforce delegation_not_allowed in S4U2Self
    
    Signed-off-by: Isaac Boukris <iboukris at gmail.com>

commit df72956adee55fbe60d49bd9d58d9df53d4f2198
Author: Isaac Boukris <iboukris at gmail.com>
Date:   Wed Oct 30 15:59:16 2019 +0100

    CVE-2019-14870: heimdal: add S4U test for delegation_not_allowed
    
    Signed-off-by: Isaac Boukris <iboukris at gmail.com>

commit aa17d5fcaf7fe0f628856cda902cbd8be7e6ecb4
Author: Isaac Boukris <iboukris at gmail.com>
Date:   Sun Oct 27 14:02:00 2019 +0200

    samba-tool: add user-sensitive command to set not-delegated flag
    
    Signed-off-by: Isaac Boukris <iboukris at gmail.com>

commit aaf037dfb3454cea048489b23ad96c415096dddf
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Oct 30 11:50:57 2019 +1300

    CVE-2019-14861: Test to demonstrate the bug
    
    This test does not fail every time, but when it does it casues a segfault which
    takes out the rpc_server master process, as this hosts the dnsserver pipe.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14138
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit defb23732515e3c638d0081f5e4043fbb35d303c
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Oct 29 14:15:36 2019 +1300

    CVE-2019-14861: s4-rpc/dnsserver: Avoid crash in ldb_qsort() via dcesrv_DnssrvEnumRecords)
    
    dns_name_compare() had logic to put @ and the top record in the tree being
    enumerated first, but if a domain had both then this would break the
    older qsort() implementation in ldb_qsort() and cause a read of memory
    before the base pointer.
    
    By removing this special case (not required as the base pointer
    is already seperatly located, no matter were it is in the
    returned records) the crash is avoided.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14138
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit 4333e41c2243781ae788db8ee7fa6897b0a7e334
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Oct 21 12:12:10 2019 +1300

    CVE-2019-14861: s4-rpc_server: Remove special case for @ in dns_build_tree()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14138
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

commit a25a2e4513e48d0408b1f5e78ada0b3569d3426d
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Oct 29 17:25:28 2019 +1300

    CVE-2019-14861: s4-rpc/dnsserver: Confirm sort behaviour in dcesrv_DnssrvEnumRecords
    
    The sort behaviour for child records is not correct in Samba so
    we add a flapping entry.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14138
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>

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

Summary of changes:
 python/samba/netcmd/user.py                     |  58 ++++++++++
 python/samba/tests/dcerpc/dnsserver.py          | 148 ++++++++++++++++++++++++
 selftest/flapping.d/dnsserver                   |   2 +
 source4/heimdal/kdc/krb5tgs.c                   |  58 ++++++----
 source4/kdc/mit_samba.c                         |   5 +
 source4/kdc/sdb_to_kdb.c                        |  17 +--
 source4/rpc_server/dnsserver/dcerpc_dnsserver.c |  21 ++--
 source4/rpc_server/dnsserver/dnsdata.c          |  28 ++---
 source4/rpc_server/dnsserver/dnsserver.h        |   4 +-
 source4/selftest/tests.py                       |   1 +
 testprogs/blackbox/test_s4u_heimdal.sh          |  73 ++++++++++++
 11 files changed, 351 insertions(+), 64 deletions(-)
 create mode 100644 selftest/flapping.d/dnsserver
 create mode 100755 testprogs/blackbox/test_s4u_heimdal.sh


Changeset truncated at 500 lines:

diff --git a/python/samba/netcmd/user.py b/python/samba/netcmd/user.py
index fb8da3d3d51..86a7a45b24e 100644
--- a/python/samba/netcmd/user.py
+++ b/python/samba/netcmd/user.py
@@ -2825,6 +2825,63 @@ unixHomeDirectory: {6}
                             .format(username))
 
 
+class cmd_user_sensitive(Command):
+    """Set/unset or show UF_NOT_DELEGATED for an account."""
+
+    synopsis = "%prog <accountname> [(show|on|off)] [options]"
+
+    takes_optiongroups = {
+        "sambaopts": options.SambaOptions,
+        "credopts": options.CredentialsOptions,
+        "versionopts": options.VersionOptions,
+    }
+
+    takes_options = [
+        Option("-H", "--URL", help="LDB URL for database or target server", type=str,
+               metavar="URL", dest="H"),
+    ]
+
+    takes_args = ["accountname", "cmd"]
+
+    def run(self, accountname, cmd, H=None, credopts=None, sambaopts=None,
+            versionopts=None):
+
+        if cmd not in ("show", "on", "off"):
+            raise CommandError("invalid argument: '%s' (choose from 'show', 'on', 'off')" % cmd)
+
+        lp = sambaopts.get_loadparm()
+        creds = credopts.get_credentials(lp, fallback_machine=True)
+        sam = SamDB(url=H, session_info=system_session(),
+                    credentials=creds, lp=lp)
+
+        search_filter = "sAMAccountName=%s" % ldb.binary_encode(accountname)
+        flag = dsdb.UF_NOT_DELEGATED;
+
+        if cmd == "show":
+            res = sam.search(scope=ldb.SCOPE_SUBTREE, expression=search_filter,
+                             attrs=["userAccountControl"])
+            if len(res) == 0:
+                raise Exception("Unable to find account where '%s'" % search_filter)
+
+            uac = int(res[0].get("userAccountControl")[0])
+
+            self.outf.write("Account-DN: %s\n" % str(res[0].dn))
+            self.outf.write("UF_NOT_DELEGATED: %s\n" % bool(uac & flag))
+
+            return
+
+        if cmd == "on":
+            on = True
+        elif cmd == "off":
+            on = False
+
+        try:
+            sam.toggle_userAccountFlags(search_filter, flag, flags_str="Not-Delegated",
+                                        on=on, strict=True)
+        except Exception as err:
+            raise CommandError(err)
+
+
 class cmd_user(SuperCommand):
     """User management."""
 
@@ -2844,3 +2901,4 @@ class cmd_user(SuperCommand):
     subcommands["show"] = cmd_user_show()
     subcommands["move"] = cmd_user_move()
     subcommands["addunixattrs"] = cmd_user_add_unix_attrs()
+    subcommands["sensitive"] = cmd_user_sensitive()
diff --git a/python/samba/tests/dcerpc/dnsserver.py b/python/samba/tests/dcerpc/dnsserver.py
index 0da9614d066..c6a150c876f 100644
--- a/python/samba/tests/dcerpc/dnsserver.py
+++ b/python/samba/tests/dcerpc/dnsserver.py
@@ -156,6 +156,154 @@ class DnsserverTests(RpcInterfaceTestCase):
                                    None)
         super(DnsserverTests, self).tearDown()
 
+    def test_enum_is_sorted(self):
+        """
+        Confirm the zone is sorted
+        """
+
+        record_str = "192.168.50.50"
+        record_type_str = "A"
+        self.add_record(self.custom_zone, "atestrecord-1", record_type_str, record_str)
+        self.add_record(self.custom_zone, "atestrecord-2", record_type_str, record_str)
+        self.add_record(self.custom_zone, "atestrecord-3", record_type_str, record_str)
+        self.add_record(self.custom_zone, "atestrecord-4", record_type_str, record_str)
+        self.add_record(self.custom_zone, "atestrecord-0", record_type_str, record_str)
+
+        # This becomes an extra A on the zone itself by server-side magic
+        self.add_record(self.custom_zone, self.custom_zone, record_type_str, record_str)
+
+        _, result = self.conn.DnssrvEnumRecords2(dnsserver.DNS_CLIENT_VERSION_LONGHORN,
+                                                 0,
+                                                 self.server,
+                                                 self.custom_zone,
+                                                 "@",
+                                                 None,
+                                                 self.record_type_int(record_type_str),
+                                                 dnsserver.DNS_RPC_VIEW_AUTHORITY_DATA,
+                                                 None,
+                                                 None)
+
+        self.assertEqual(len(result.rec), 6)
+        self.assertEqual(result.rec[0].dnsNodeName.str, "")
+        self.assertEqual(result.rec[1].dnsNodeName.str, "atestrecord-0")
+        self.assertEqual(result.rec[2].dnsNodeName.str, "atestrecord-1")
+        self.assertEqual(result.rec[3].dnsNodeName.str, "atestrecord-2")
+        self.assertEqual(result.rec[4].dnsNodeName.str, "atestrecord-3")
+        self.assertEqual(result.rec[5].dnsNodeName.str, "atestrecord-4")
+
+    def test_enum_is_sorted_with_zone_dup(self):
+        """
+        Confirm the zone is sorted
+        """
+
+        record_str = "192.168.50.50"
+        record_type_str = "A"
+        self.add_record(self.custom_zone, "atestrecord-1", record_type_str, record_str)
+        self.add_record(self.custom_zone, "atestrecord-2", record_type_str, record_str)
+        self.add_record(self.custom_zone, "atestrecord-3", record_type_str, record_str)
+        self.add_record(self.custom_zone, "atestrecord-4", record_type_str, record_str)
+        self.add_record(self.custom_zone, "atestrecord-0", record_type_str, record_str)
+
+        # This triggers a bug in old Samba
+        self.add_record(self.custom_zone, self.custom_zone + "1", record_type_str, record_str)
+
+        dn, record = self.get_record_from_db(self.custom_zone, self.custom_zone + "1")
+
+        new_dn = ldb.Dn(self.samdb, str(dn))
+        new_dn.set_component(0, "dc", self.custom_zone)
+        self.samdb.rename(dn, new_dn)
+
+        _, result = self.conn.DnssrvEnumRecords2(dnsserver.DNS_CLIENT_VERSION_LONGHORN,
+                                                 0,
+                                                 self.server,
+                                                 self.custom_zone,
+                                                 "@",
+                                                 None,
+                                                 self.record_type_int(record_type_str),
+                                                 dnsserver.DNS_RPC_VIEW_AUTHORITY_DATA,
+                                                 None,
+                                                 None)
+
+        self.assertEqual(len(result.rec), 7)
+        self.assertEqual(result.rec[0].dnsNodeName.str, "")
+        self.assertEqual(result.rec[1].dnsNodeName.str, "atestrecord-0")
+        self.assertEqual(result.rec[2].dnsNodeName.str, "atestrecord-1")
+        self.assertEqual(result.rec[3].dnsNodeName.str, "atestrecord-2")
+        self.assertEqual(result.rec[4].dnsNodeName.str, "atestrecord-3")
+        self.assertEqual(result.rec[5].dnsNodeName.str, "atestrecord-4")
+
+        # Windows doesn't reload the zone fast enough, but doesn't
+        # have the bug anyway, it will sort last on both names (where
+        # it should)
+        if result.rec[6].dnsNodeName.str != (self.custom_zone + "1"):
+            self.assertEqual(result.rec[6].dnsNodeName.str, self.custom_zone)
+
+    def test_enum_is_sorted_children_prefix_first(self):
+        """
+        Confirm the zone returns the selected prefix first but no more
+        as Samba is flappy for the full sort
+        """
+
+        record_str = "192.168.50.50"
+        record_type_str = "A"
+        self.add_record(self.custom_zone, "atestrecord-1.a.b", record_type_str, record_str)
+        self.add_record(self.custom_zone, "atestrecord-2.a.b", record_type_str, record_str)
+        self.add_record(self.custom_zone, "atestrecord-3.a.b", record_type_str, record_str)
+        self.add_record(self.custom_zone, "atestrecord-4.a.b", record_type_str, record_str)
+        self.add_record(self.custom_zone, "atestrecord-0.a.b", record_type_str, record_str)
+
+        # Not expected to be returned
+        self.add_record(self.custom_zone, "atestrecord-0.b.b", record_type_str, record_str)
+
+        _, result = self.conn.DnssrvEnumRecords2(dnsserver.DNS_CLIENT_VERSION_LONGHORN,
+                                                 0,
+                                                 self.server,
+                                                 self.custom_zone,
+                                                 "a.b",
+                                                 None,
+                                                 self.record_type_int(record_type_str),
+                                                 dnsserver.DNS_RPC_VIEW_AUTHORITY_DATA,
+                                                 None,
+                                                 None)
+
+        self.assertEqual(len(result.rec), 6)
+        self.assertEqual(result.rec[0].dnsNodeName.str, "")
+
+    def test_enum_is_sorted_children(self):
+        """
+        Confirm the zone is sorted
+        """
+
+        record_str = "192.168.50.50"
+        record_type_str = "A"
+        self.add_record(self.custom_zone, "atestrecord-1.a.b", record_type_str, record_str)
+        self.add_record(self.custom_zone, "atestrecord-2.a.b", record_type_str, record_str)
+        self.add_record(self.custom_zone, "atestrecord-3.a.b", record_type_str, record_str)
+        self.add_record(self.custom_zone, "atestrecord-4.a.b", record_type_str, record_str)
+        self.add_record(self.custom_zone, "atestrecord-0.a.b", record_type_str, record_str)
+
+        # Not expected to be returned
+        self.add_record(self.custom_zone, "atestrecord-0.b.b", record_type_str, record_str)
+
+        _, result = self.conn.DnssrvEnumRecords2(dnsserver.DNS_CLIENT_VERSION_LONGHORN,
+                                                 0,
+                                                 self.server,
+                                                 self.custom_zone,
+                                                 "a.b",
+                                                 None,
+                                                 self.record_type_int(record_type_str),
+                                                 dnsserver.DNS_RPC_VIEW_AUTHORITY_DATA,
+                                                 None,
+                                                 None)
+
+        self.assertEqual(len(result.rec), 6)
+        self.assertEqual(result.rec[0].dnsNodeName.str, "")
+        self.assertEqual(result.rec[1].dnsNodeName.str, "atestrecord-0")
+        self.assertEqual(result.rec[2].dnsNodeName.str, "atestrecord-1")
+        self.assertEqual(result.rec[3].dnsNodeName.str, "atestrecord-2")
+        self.assertEqual(result.rec[4].dnsNodeName.str, "atestrecord-3")
+        self.assertEqual(result.rec[5].dnsNodeName.str, "atestrecord-4")
+
     # This test fails against Samba (but passes against Windows),
     # because Samba does not return the record when we enum records.
     # Records can be given DNS_RANK_NONE when the zone they are in
diff --git a/selftest/flapping.d/dnsserver b/selftest/flapping.d/dnsserver
new file mode 100644
index 00000000000..9b33e8522a3
--- /dev/null
+++ b/selftest/flapping.d/dnsserver
@@ -0,0 +1,2 @@
+# This is not stable in samba due to a bug
+^samba.tests.dcerpc.dnsserver.samba.tests.dcerpc.dnsserver.DnsserverTests.test_enum_is_sorted_children
\ No newline at end of file
diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c
index ff7d93138c0..ee3ac3d8f53 100644
--- a/source4/heimdal/kdc/krb5tgs.c
+++ b/source4/heimdal/kdc/krb5tgs.c
@@ -1975,30 +1975,42 @@ server_lookup:
 	    if (ret)
 		goto out;
 
+	    ret = _kdc_db_fetch(context, config, tp, HDB_F_GET_CLIENT | flags,
+				NULL, &s4u2self_impersonated_clientdb,
+				&s4u2self_impersonated_client);
+	    if (ret) {
+		const char *msg;
+
+		/*
+		 * If the client belongs to the same realm as our krbtgt, it
+		 * should exist in the local database.
+		 *
+		 */
+
+		if (ret == HDB_ERR_NOENTRY)
+		    ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
+		msg = krb5_get_error_message(context, ret);
+		kdc_log(context, config, 1,
+			"S2U4Self principal to impersonate %s not found in database: %s",
+			tpn, msg);
+		krb5_free_error_message(context, msg);
+		goto out;
+	    }
+
+	    /* Ignore pw_end attributes (as Windows does),
+	     * since S4U2Self is not password authentication. */
+	    free(s4u2self_impersonated_client->entry.pw_end);
+	    s4u2self_impersonated_client->entry.pw_end = NULL;
+
+	    ret = kdc_check_flags(context, config, s4u2self_impersonated_client, tpn,
+				  NULL, NULL, FALSE);
+	    if (ret)
+		goto out;
+
 	    /* If we were about to put a PAC into the ticket, we better fix it to be the right PAC */
 	    if(rspac.data) {
 		krb5_pac p = NULL;
 		krb5_data_free(&rspac);
-		ret = _kdc_db_fetch(context, config, tp, HDB_F_GET_CLIENT | flags,
-				    NULL, &s4u2self_impersonated_clientdb, &s4u2self_impersonated_client);
-		if (ret) {
-		    const char *msg;
-
-		    /*
-		     * If the client belongs to the same realm as our krbtgt, it
-		     * should exist in the local database.
-		     *
-		     */
-
-		    if (ret == HDB_ERR_NOENTRY)
-			ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
-		    msg = krb5_get_error_message(context, ret);
-		    kdc_log(context, config, 1,
-			    "S2U4Self principal to impersonate %s not found in database: %s",
-			    tpn, msg);
-		    krb5_free_error_message(context, msg);
-		    goto out;
-		}
 		ret = _kdc_pac_generate(context, s4u2self_impersonated_client, NULL, &p);
 		if (ret) {
 		    kdc_log(context, config, 0, "PAC generation failed for -- %s",
@@ -2034,10 +2046,12 @@ server_lookup:
 
 	    /*
 	     * If the service isn't trusted for authentication to
-	     * delegation, remove the forward flag.
+	     * delegation or if the impersonate client is disallowed
+	     * forwardable, remove the forwardable flag.
 	     */
 
-	    if (client->entry.flags.trusted_for_delegation) {
+	    if (client->entry.flags.trusted_for_delegation &&
+		s4u2self_impersonated_client->entry.flags.forwardable) {
 		str = "[forwardable]";
 	    } else {
 		b->kdc_options.forwardable = 0;
diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c
index 54dcd545ea1..5a4f6e73e97 100644
--- a/source4/kdc/mit_samba.c
+++ b/source4/kdc/mit_samba.c
@@ -304,6 +304,11 @@ fetch_referral_principal:
 
 	sdb_free_entry(&sentry);
 
+	if ((kflags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) == 0) {
+		kentry->attributes &= ~KRB5_KDB_DISALLOW_FORWARDABLE;
+		kentry->attributes &= ~KRB5_KDB_DISALLOW_PROXIABLE;
+	}
+
 done:
 	krb5_free_principal(ctx->context, referral_principal);
 	referral_principal = NULL;
diff --git a/source4/kdc/sdb_to_kdb.c b/source4/kdc/sdb_to_kdb.c
index 1411b0f5f66..2981f180333 100644
--- a/source4/kdc/sdb_to_kdb.c
+++ b/source4/kdc/sdb_to_kdb.c
@@ -36,18 +36,13 @@ static int SDBFlags_to_kflags(const struct SDBFlags *s,
 	if (s->initial) {
 		*k |= KRB5_KDB_DISALLOW_TGT_BASED;
 	}
-	/*
-	 * Do not set any disallow rules for forwardable, proxiable,
-	 * renewable, postdate and server.
-	 *
-	 * The KDC will take care setting the flags based on the incoming
-	 * ticket.
-	 */
-	if (s->forwardable) {
-		;
+	/* The forwardable and proxiable flags are set according to client and
+	 * server attributes. */
+	if (!s->forwardable) {
+		*k |= KRB5_KDB_DISALLOW_FORWARDABLE;
 	}
-	if (s->proxiable) {
-		;
+	if (!s->proxiable) {
+		*k |= KRB5_KDB_DISALLOW_PROXIABLE;
 	}
 	if (s->renewable) {
 		;
diff --git a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
index 993e5dc4e56..b6389f2328a 100644
--- a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
+++ b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c
@@ -1763,6 +1763,7 @@ static WERROR dnsserver_enumerate_records(struct dnsserver_state *dsstate,
 	struct DNS_RPC_RECORDS_ARRAY *recs;
 	char **add_names = NULL;
 	char *rname;
+	const char *preference_name = NULL;
 	int add_count = 0;
 	int i, ret, len;
 	WERROR status;
@@ -1779,6 +1780,7 @@ static WERROR dnsserver_enumerate_records(struct dnsserver_state *dsstate,
 		ret = ldb_search(dsstate->samdb, tmp_ctx, &res, z->zone_dn,
 				 LDB_SCOPE_ONELEVEL, attrs,
 				 "(&(objectClass=dnsNode)(!(dNSTombstoned=TRUE)))");
+		preference_name = "@";
 	} else {
 		char *encoded_name
 			= ldb_binary_encode_string(tmp_ctx, name);
@@ -1786,6 +1788,7 @@ static WERROR dnsserver_enumerate_records(struct dnsserver_state *dsstate,
 				 LDB_SCOPE_ONELEVEL, attrs,
 				 "(&(objectClass=dnsNode)(|(name=%s)(name=*.%s))(!(dNSTombstoned=TRUE)))",
 				 encoded_name, encoded_name);
+		preference_name = name;
 	}
 	if (ret != LDB_SUCCESS) {
 		talloc_free(tmp_ctx);
@@ -1799,16 +1802,18 @@ static WERROR dnsserver_enumerate_records(struct dnsserver_state *dsstate,
 	recs = talloc_zero(mem_ctx, struct DNS_RPC_RECORDS_ARRAY);
 	W_ERROR_HAVE_NO_MEMORY_AND_FREE(recs, tmp_ctx);
 
-	/* Sort the names, so that the first record is the parent record */
-	ldb_qsort(res->msgs, res->count, sizeof(struct ldb_message *), name,
-			(ldb_qsort_cmp_fn_t)dns_name_compare);
+	/*
+	 * Sort the names, so that the records are in order by the child
+	 * component below "name".
+	 *
+	 * A full tree sort is not required, so we pass in "name" so
+	 * we know which level to sort, as only direct children are
+	 * eventually returned
+	 */
+	LDB_TYPESAFE_QSORT(res->msgs, res->count, name, dns_name_compare);
 
 	/* Build a tree of name components from dns name */
-	if (strcasecmp(name, z->name) == 0) {
-		tree = dns_build_tree(tmp_ctx, "@", res);
-	} else {
-		tree = dns_build_tree(tmp_ctx, name, res);
-	}
+	tree = dns_build_tree(tmp_ctx, preference_name, res);
 	W_ERROR_HAVE_NO_MEMORY_AND_FREE(tree, tmp_ctx);
 
 	/* Find the parent record in the tree */
diff --git a/source4/rpc_server/dnsserver/dnsdata.c b/source4/rpc_server/dnsserver/dnsdata.c
index 2dc098a64a0..47d6f5d5c88 100644
--- a/source4/rpc_server/dnsserver/dnsdata.c
+++ b/source4/rpc_server/dnsserver/dnsdata.c
@@ -801,10 +801,11 @@ struct dns_tree *dns_build_tree(TALLOC_CTX *mem_ctx, const char *name, struct ld
 			goto failed;
 		}
 
-		if (strcmp(ptr, "@") == 0) {
-			base->data = res->msgs[i];
-			continue;
-		} else if (strcasecmp(ptr, name) == 0) {
+		/*
+		 * This might be the sub-domain in the zone being
+		 * requested, or @ for the root of the zone
+		 */
+		if (strcasecmp(ptr, name) == 0) {
 			base->data = res->msgs[i];
 			continue;
 		}
@@ -1065,8 +1066,8 @@ WERROR dns_fill_records_array(TALLOC_CTX *mem_ctx,
 }
 
 
-int dns_name_compare(const struct ldb_message **m1, const struct ldb_message **m2,
-				char *search_name)
+int dns_name_compare(struct ldb_message * const *m1, struct ldb_message * const *m2,
+		     const char *search_name)
 {
 	const char *name1, *name2;
 	const char *ptr1, *ptr2;
@@ -1077,21 +1078,6 @@ int dns_name_compare(const struct ldb_message **m1, const struct ldb_message **m
 		return 0;
 	}
 
-	/* '@' record and the search_name record gets preference */
-	if (name1[0] == '@') {
-		return -1;
-	}
-	if (search_name && strcasecmp(name1, search_name) == 0) {
-		return -1;
-	}
-
-	if (name2[0] == '@') {
-		return 1;
-	}
-	if (search_name && strcasecmp(name2, search_name) == 0) {
-		return 1;
-	}
-
 	/* Compare the last components of names.
 	 * If search_name is not NULL, compare the second last components of names */
 	ptr1 = strrchr(name1, '.');
diff --git a/source4/rpc_server/dnsserver/dnsserver.h b/source4/rpc_server/dnsserver/dnsserver.h
index a8307ef836a..2e46e7c66a4 100644
--- a/source4/rpc_server/dnsserver/dnsserver.h
+++ b/source4/rpc_server/dnsserver/dnsserver.h
@@ -188,8 +188,8 @@ struct DNS_ADDR_ARRAY *dns_addr_array_copy(TALLOC_CTX *mem_ctx, struct DNS_ADDR_
 int dns_split_name_components(TALLOC_CTX *mem_ctx, const char *name, char ***components);
 char *dns_split_node_name(TALLOC_CTX *mem_ctx, const char *node_name, const char *zone_name);
 
-int dns_name_compare(const struct ldb_message **m1, const struct ldb_message **m2,
-			char *search_name);
+int dns_name_compare(struct ldb_message * const *m1, struct ldb_message * const *m2,
+		     const char *search_name);
 bool dns_record_match(struct dnsp_DnssrvRpcRecord *rec1, struct dnsp_DnssrvRpcRecord *rec2);
 
 void dnsp_to_dns_copy(TALLOC_CTX *mem_ctx, struct dnsp_DnssrvRpcRecord *dnsp,
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
index 7843d50c952..43fbf0e5f0f 100755
--- a/source4/selftest/tests.py
+++ b/source4/selftest/tests.py
@@ -459,6 +459,7 @@ if have_heimdal_support:
     plantestsuite("samba4.blackbox.kinit_trust", "fl2003dc:local", [os.path.join(bbdir, "test_kinit_trusts_heimdal.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$TRUST_SERVER', '$TRUST_USERNAME', '$TRUST_PASSWORD', '$TRUST_REALM', '$TRUST_DOMAIN', '$PREFIX', "external", "arcfour-hmac-md5"])
     plantestsuite("samba4.blackbox.export.keytab", "ad_dc_ntvfs:local", [os.path.join(bbdir, "test_export_keytab_heimdal.sh"), '$SERVER', '$USERNAME', '$REALM', '$DOMAIN', "$PREFIX", smbclient4])
     plantestsuite("samba4.blackbox.kpasswd", "ad_dc_ntvfs:local", [os.path.join(bbdir, "test_kpasswd_heimdal.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', "$PREFIX/ad_dc_ntvfs"])
+    plantestsuite("samba4.blackbox.krb5.s4u", "fl2008r2dc:local", [os.path.join(bbdir, "test_s4u_heimdal.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$REALM', '$DOMAIN', '$PREFIX', configuration])


-- 
Samba Shared Repository



More information about the samba-cvs mailing list