Version in base suite: 4.13.13+dfsg-1~deb11u2 Base version: samba_4.13.13+dfsg-1~deb11u2 Target version: samba_4.13.13+dfsg-1~deb11u3 Base file: /srv/ftp-master.debian.org/ftp/pool/main/s/samba/samba_4.13.13+dfsg-1~deb11u2.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/s/samba/samba_4.13.13+dfsg-1~deb11u3.dsc changelog | 32 patches/0001-CVE-2020-25727-idmap_nss-verify-that-the-name-of-the.patch | 79 + patches/0001-CVE-2021-44142-libadouble-add-defines-for-icon-lengt.patch | 31 patches/0001-CVE-2022-0336-pytest-Add-a-test-for-an-SPN-conflict-.patch | 53 + patches/0002-CVE-2020-25717-tests-krb5-Add-method-to-automaticall.patch | 72 + patches/0002-CVE-2021-44142-smbd-add-Netatalk-xattr-used-by-vfs_f.patch | 40 patches/0002-CVE-2022-0336-s4-dsdb-samldb-Don-t-return-early-when.patch | 42 patches/0003-CVE-2020-25717-nsswitch-nsstest.c-Lower-non-existent.patch | 32 patches/0003-CVE-2021-44142-libadouble-harden-ad_unpack_xattrs.patch | 68 + patches/0004-CVE-2020-25717-selftest-turn-ad_member_no_nss_wb-int.patch | 142 +++ patches/0004-CVE-2021-44142-libadouble-add-basic-cmocka-tests.patch | 452 ++++++++++ patches/0005-CVE-2020-25717-tests-krb5-Add-a-test-for-idmap_nss-m.patch | 315 ++++++ patches/0005-CVE-2021-44142-libadouble-harden-parsing-code.patch | 169 +++ patches/0006-CVE-2020-25717-s3-auth-Fallback-to-a-SID-UID-based-m.patch | 127 ++ patches/series | 13 15 files changed, 1667 insertions(+) diff -Nru samba-4.13.13+dfsg/debian/changelog samba-4.13.13+dfsg/debian/changelog --- samba-4.13.13+dfsg/debian/changelog 2021-11-04 22:20:37.000000000 +0000 +++ samba-4.13.13+dfsg/debian/changelog 2022-02-03 20:54:02.000000000 +0000 @@ -1,3 +1,35 @@ +samba (2:4.13.13+dfsg-1~deb11u3) bullseye-security; urgency=high + + * Non-maintainer upload by the Security Team. + * Add patches for CVE-2022-0336 (Closes: #1004694) + - CVE-2022-0336: pytest: Add a test for an SPN conflict with a re-added + SPN. + - CVE-2022-0336: s4/dsdb/samldb: Don't return early when an SPN is + re-added to an object. + * Add patches for CVE-2021-44142 (Closes: #1004693) + - CVE-2021-44142: libadouble: add defines for icon lengths. + - CVE-2021-44142: smbd: add Netatalk xattr used by vfs_fruit to the list + of private Samba xattrs. + - CVE-2021-44142: libadouble: harden ad_unpack_xattrs() + - CVE-2021-44142: libadouble: add basic cmocka tests. + - CVE-2021-44142: libadouble: harden parsing code. + * Add patches to address "The CVE-2020-25717 username map [script] advice + has undesired side effects for the local nt token" (Closes: #1001068) + - CVE-2020-25727: idmap_nss: verify that the name of the sid belongs to + the configured domain + - CVE-2020-25717: tests/krb5: Add method to automatically obtain server + credentials + - CVE-2020-25717: nsswitch/nsstest.c: Lower 'non existent uid' to make + room for new accounts + - CVE-2020-25717: selftest: turn ad_member_no_nss_wb into + ad_member_idmap_nss + - CVE-2020-25717: tests/krb5: Add a test for idmap_nss mapping users to + SIDs + - CVE-2020-25717: s3:auth: Fallback to a SID/UID based mapping if the + named based lookup fails + + -- Salvatore Bonaccorso Thu, 03 Feb 2022 21:54:02 +0100 + samba (2:4.13.13+dfsg-1~deb11u2) bullseye-security; urgency=high * This is a security release in order to address the following defects: diff -Nru samba-4.13.13+dfsg/debian/patches/0001-CVE-2020-25727-idmap_nss-verify-that-the-name-of-the.patch samba-4.13.13+dfsg/debian/patches/0001-CVE-2020-25727-idmap_nss-verify-that-the-name-of-the.patch --- samba-4.13.13+dfsg/debian/patches/0001-CVE-2020-25727-idmap_nss-verify-that-the-name-of-the.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.13.13+dfsg/debian/patches/0001-CVE-2020-25727-idmap_nss-verify-that-the-name-of-the.patch 2022-02-03 20:54:02.000000000 +0000 @@ -0,0 +1,79 @@ +From a6eddc3bd7a032e1fd3921cd7ea213b5c48f2eab Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +Date: Fri, 12 Nov 2021 15:27:58 +0100 +Subject: [PATCH 1/6] CVE-2020-25727: idmap_nss: verify that the name of the + sid belongs to the configured domain + +We already check the sid belongs to the domain, but checking the name +too feels better and make it easier to understand. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14901 + +Signed-off-by: Stefan Metzmacher +Reviewed-by: Ralph Boehme +(cherry picked from commit bfd093648b4af51d104096c0cb3535e8706671e5) +--- + source3/winbindd/idmap_nss.c | 26 +++++++++++++++++++++----- + 1 file changed, 21 insertions(+), 5 deletions(-) + +diff --git a/source3/winbindd/idmap_nss.c b/source3/winbindd/idmap_nss.c +index da50e2b4aa75..2729a0de3f31 100644 +--- a/source3/winbindd/idmap_nss.c ++++ b/source3/winbindd/idmap_nss.c +@@ -139,18 +139,21 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma + for (i = 0; ids[i]; i++) { + struct group *gr; + enum lsa_SidType type; +- const char *p = NULL; ++ const char *_domain = NULL; ++ const char *_name = NULL; ++ char *domain = NULL; + char *name = NULL; + bool ret; + + /* by default calls to winbindd are disabled + the following call will not recurse so this is safe */ + (void)winbind_on(); +- ret = winbind_lookup_sid(talloc_tos(), ids[i]->sid, NULL, +- &p, &type); ++ ret = winbind_lookup_sid(talloc_tos(), ++ ids[i]->sid, ++ &_domain, ++ &_name, ++ &type); + (void)winbind_off(); +- name = discard_const_p(char, p); +- + if (!ret) { + /* TODO: how do we know if the name is really not mapped, + * or something just failed ? */ +@@ -158,6 +161,18 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma + continue; + } + ++ domain = discard_const_p(char, _domain); ++ name = discard_const_p(char, _name); ++ ++ if (!strequal(domain, dom->name)) { ++ struct dom_sid_buf buf; ++ DBG_ERR("DOMAIN[%s] ignoring SID[%s] belongs to %s [%s\\%s]\n", ++ dom->name, dom_sid_str_buf(ids[i]->sid, &buf), ++ sid_type_lookup(type), domain, name); ++ ids[i]->status = ID_UNMAPPED; ++ continue; ++ } ++ + switch (type) { + case SID_NAME_USER: { + struct passwd *pw; +@@ -190,6 +205,7 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma + ids[i]->status = ID_UNKNOWN; + break; + } ++ TALLOC_FREE(domain); + TALLOC_FREE(name); + } + return NT_STATUS_OK; +-- +2.34.1 + diff -Nru samba-4.13.13+dfsg/debian/patches/0001-CVE-2021-44142-libadouble-add-defines-for-icon-lengt.patch samba-4.13.13+dfsg/debian/patches/0001-CVE-2021-44142-libadouble-add-defines-for-icon-lengt.patch --- samba-4.13.13+dfsg/debian/patches/0001-CVE-2021-44142-libadouble-add-defines-for-icon-lengt.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.13.13+dfsg/debian/patches/0001-CVE-2021-44142-libadouble-add-defines-for-icon-lengt.patch 2022-02-03 20:54:02.000000000 +0000 @@ -0,0 +1,31 @@ +From 57d9afe5d71da5360501f43f1c69208bca3b0769 Mon Sep 17 00:00:00 2001 +From: Ralph Boehme +Date: Thu, 13 Jan 2022 16:48:01 +0100 +Subject: [PATCH 1/5] CVE-2021-44142: libadouble: add defines for icon lengths + +From https://www.ietf.org/rfc/rfc1740.txt + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914 + +Signed-off-by: Ralph Boehme +Reviewed-by: Jeremy Allison +--- + source3/lib/adouble.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/source3/lib/adouble.h b/source3/lib/adouble.h +index 90a825c502e0..e3b9263a1f9a 100644 +--- a/source3/lib/adouble.h ++++ b/source3/lib/adouble.h +@@ -101,6 +101,8 @@ typedef enum {ADOUBLE_META, ADOUBLE_RSRC} adouble_type_t; + #define ADEDLEN_MACFILEI 4 + #define ADEDLEN_PRODOSFILEI 8 + #define ADEDLEN_MSDOSFILEI 2 ++#define ADEDLEN_ICONBW 128 ++#define ADEDLEN_ICONCOL 1024 + #define ADEDLEN_DID 4 + #define ADEDLEN_PRIVDEV 8 + #define ADEDLEN_PRIVINO 8 +-- +2.34.1 + diff -Nru samba-4.13.13+dfsg/debian/patches/0001-CVE-2022-0336-pytest-Add-a-test-for-an-SPN-conflict-.patch samba-4.13.13+dfsg/debian/patches/0001-CVE-2022-0336-pytest-Add-a-test-for-an-SPN-conflict-.patch --- samba-4.13.13+dfsg/debian/patches/0001-CVE-2022-0336-pytest-Add-a-test-for-an-SPN-conflict-.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.13.13+dfsg/debian/patches/0001-CVE-2022-0336-pytest-Add-a-test-for-an-SPN-conflict-.patch 2022-02-03 20:54:02.000000000 +0000 @@ -0,0 +1,53 @@ +From 7368e0051a320fce48c1f303914b62985a40beb0 Mon Sep 17 00:00:00 2001 +From: Joseph Sutton +Date: Tue, 18 Jan 2022 11:56:38 +1300 +Subject: [PATCH 1/2] CVE-2022-0336: pytest: Add a test for an SPN conflict + with a re-added SPN + +This test currently fails, as re-adding an SPN means that later checks +do not run. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14950 + +Signed-off-by: Joseph Sutton +Reviewed-by: Douglas Bagnall +--- + python/samba/tests/ldap_spn.py | 7 +++++++ + selftest/knownfail.d/ldap_spn | 1 + + 2 files changed, 8 insertions(+) + +diff --git a/python/samba/tests/ldap_spn.py b/python/samba/tests/ldap_spn.py +index 8a398ffaa491..6ebdf8f9a32d 100644 +--- a/python/samba/tests/ldap_spn.py ++++ b/python/samba/tests/ldap_spn.py +@@ -268,6 +268,8 @@ class LdapSpnTestBase(TestCase): + for k in ('dNSHostName', 'servicePrincipalName'): + if isinstance(m.get(k), str): + m[k] = m[k].format(dnsname=f"x.{REALM}") ++ elif isinstance(m.get(k), list): ++ m[k] = [x.format(dnsname=f"x.{REALM}") for x in m[k]] + + msg = ldb.Message.from_dict(samdb, m, op) + +@@ -727,6 +729,11 @@ class LdapSpnSambaOnlyTest(LdapSpnTestBase): + ('user:C', 'host/{dnsname}', '*', ok), + ('user:D', 'www/{dnsname}', 'D', denied), + ), ++ ("add a conflict, along with a re-added SPN", ++ ('A', 'cifs/{dnsname}', '*', ok), ++ ('B', 'cifs/heeble.example.net', 'B', ok), ++ ('B', ['cifs/heeble.example.net', 'host/{dnsname}'], 'B', constraint), ++ ), + + ("changing dNSHostName after host", + ('A', {'dNSHostName': '{dnsname}'}, '*', ok), +diff --git a/selftest/knownfail.d/ldap_spn b/selftest/knownfail.d/ldap_spn +index 63f9fe02ef7d..16dafa91b665 100644 +--- a/selftest/knownfail.d/ldap_spn ++++ b/selftest/knownfail.d/ldap_spn +@@ -1 +1,2 @@ + samba.tests.ldap_spn.+LdapSpnTest.test_spn_dodgy_spns ++samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_add_a_conflict_along_with_a_re_added_SPN +-- +2.34.1 + diff -Nru samba-4.13.13+dfsg/debian/patches/0002-CVE-2020-25717-tests-krb5-Add-method-to-automaticall.patch samba-4.13.13+dfsg/debian/patches/0002-CVE-2020-25717-tests-krb5-Add-method-to-automaticall.patch --- samba-4.13.13+dfsg/debian/patches/0002-CVE-2020-25717-tests-krb5-Add-method-to-automaticall.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.13.13+dfsg/debian/patches/0002-CVE-2020-25717-tests-krb5-Add-method-to-automaticall.patch 2022-02-03 20:54:02.000000000 +0000 @@ -0,0 +1,72 @@ +From 302bb70ebc9b47d9f1d46212deac17470e64740d Mon Sep 17 00:00:00 2001 +From: Joseph Sutton +Date: Fri, 12 Nov 2021 14:14:55 +1300 +Subject: [PATCH 2/6] CVE-2020-25717: tests/krb5: Add method to automatically + obtain server credentials + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14901 + +Signed-off-by: Joseph Sutton +Reviewed-by: Stefan Metzmacher +Reviewed-by: Ralph Boehme +(cherry picked from commit 5ea347d3673e35891613c90ca837d1ce4833c1b0) +--- + python/samba/tests/krb5/kdc_base_test.py | 42 ++++++++++++++++++++++++ + 1 file changed, 42 insertions(+) + +diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py +index f64bd0b206ef..6e96b982167a 100644 +--- a/python/samba/tests/krb5/kdc_base_test.py ++++ b/python/samba/tests/krb5/kdc_base_test.py +@@ -1063,6 +1063,48 @@ class KDCBaseTest(RawKerberosTest): + fallback_creds_fn=download_dc_creds) + return c + ++ def get_server_creds(self, ++ require_keys=True, ++ require_strongest_key=False): ++ if require_strongest_key: ++ self.assertTrue(require_keys) ++ ++ def download_server_creds(): ++ samdb = self.get_samdb() ++ ++ res = samdb.search(base=samdb.get_default_basedn(), ++ expression=(f'(|(sAMAccountName={self.host}*)' ++ f'(dNSHostName={self.host}))'), ++ scope=ldb.SCOPE_SUBTREE, ++ attrs=['sAMAccountName', ++ 'msDS-KeyVersionNumber']) ++ self.assertEqual(1, len(res)) ++ dn = res[0].dn ++ username = str(res[0]['sAMAccountName']) ++ ++ creds = KerberosCredentials() ++ creds.set_domain(self.env_get_var('DOMAIN', 'SERVER')) ++ creds.set_realm(self.env_get_var('REALM', 'SERVER')) ++ creds.set_username(username) ++ ++ kvno = int(res[0]['msDS-KeyVersionNumber'][0]) ++ creds.set_kvno(kvno) ++ creds.set_dn(dn) ++ ++ keys = self.get_keys(samdb, dn) ++ self.creds_set_keys(creds, keys) ++ ++ self.creds_set_enctypes(creds) ++ ++ return creds ++ ++ c = self._get_krb5_creds(prefix='SERVER', ++ allow_missing_password=True, ++ allow_missing_keys=not require_keys, ++ require_strongest_key=require_strongest_key, ++ fallback_creds_fn=download_server_creds) ++ return c ++ + def as_req(self, cname, sname, realm, etypes, padata=None, kdc_options=0): + '''Send a Kerberos AS_REQ, returns the undecoded response + ''' +-- +2.34.1 + diff -Nru samba-4.13.13+dfsg/debian/patches/0002-CVE-2021-44142-smbd-add-Netatalk-xattr-used-by-vfs_f.patch samba-4.13.13+dfsg/debian/patches/0002-CVE-2021-44142-smbd-add-Netatalk-xattr-used-by-vfs_f.patch --- samba-4.13.13+dfsg/debian/patches/0002-CVE-2021-44142-smbd-add-Netatalk-xattr-used-by-vfs_f.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.13.13+dfsg/debian/patches/0002-CVE-2021-44142-smbd-add-Netatalk-xattr-used-by-vfs_f.patch 2022-02-03 20:54:02.000000000 +0000 @@ -0,0 +1,40 @@ +From 9eba87ce4b47488f1422248b8d4ad9b37ae26899 Mon Sep 17 00:00:00 2001 +From: Ralph Boehme +Date: Sat, 20 Nov 2021 16:36:42 +0100 +Subject: [PATCH 2/5] CVE-2021-44142: smbd: add Netatalk xattr used by + vfs_fruit to the list of private Samba xattrs + +This is an internal xattr that should not be user visible. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914 + +Signed-off-by: Ralph Boehme +Reviewed-by: Jeremy Allison +[slow@samba.org: conflict due to changed includes in source3/smbd/trans2.c] +--- + source3/smbd/trans2.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c +index 7acde285a90d..673d7165c04e 100644 +--- a/source3/smbd/trans2.c ++++ b/source3/smbd/trans2.c +@@ -44,6 +44,7 @@ + #include "messages.h" + #include "smb1_utils.h" + #include "libcli/smb/smb2_posix.h" ++#include "source3/lib/adouble.h" + + #define DIR_ENTRY_SAFETY_MARGIN 4096 + +@@ -240,6 +241,7 @@ bool samba_private_attr_name(const char *unix_ea_name) + SAMBA_XATTR_DOS_ATTRIB, + SAMBA_XATTR_MARKER, + XATTR_NTACL_NAME, ++ AFPINFO_EA_NETATALK, + NULL + }; + +-- +2.34.1 + diff -Nru samba-4.13.13+dfsg/debian/patches/0002-CVE-2022-0336-s4-dsdb-samldb-Don-t-return-early-when.patch samba-4.13.13+dfsg/debian/patches/0002-CVE-2022-0336-s4-dsdb-samldb-Don-t-return-early-when.patch --- samba-4.13.13+dfsg/debian/patches/0002-CVE-2022-0336-s4-dsdb-samldb-Don-t-return-early-when.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.13.13+dfsg/debian/patches/0002-CVE-2022-0336-s4-dsdb-samldb-Don-t-return-early-when.patch 2022-02-03 20:54:02.000000000 +0000 @@ -0,0 +1,42 @@ +From 2802b7d8f3f77a639d0d69bced528f328655750b Mon Sep 17 00:00:00 2001 +From: Joseph Sutton +Date: Tue, 18 Jan 2022 12:02:45 +1300 +Subject: [PATCH 2/2] CVE-2022-0336: s4/dsdb/samldb: Don't return early when an + SPN is re-added to an object + +If an added SPN already exists on an object, we still want to check the +rest of the element values for conflicts. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14950 + +Signed-off-by: Joseph Sutton +Reviewed-by: Douglas Bagnall +--- + selftest/knownfail.d/ldap_spn | 1 - + source4/dsdb/samdb/ldb_modules/samldb.c | 3 +-- + 2 files changed, 1 insertion(+), 3 deletions(-) + +diff --git a/selftest/knownfail.d/ldap_spn b/selftest/knownfail.d/ldap_spn +index 16dafa91b665..63f9fe02ef7d 100644 +--- a/selftest/knownfail.d/ldap_spn ++++ b/selftest/knownfail.d/ldap_spn +@@ -1,2 +1 @@ + samba.tests.ldap_spn.+LdapSpnTest.test_spn_dodgy_spns +-samba.tests.ldap_spn.+LdapSpnSambaOnlyTest.test_spn_add_a_conflict_along_with_a_re_added_SPN +diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c +index f0227411ccd2..a219446bba72 100644 +--- a/source4/dsdb/samdb/ldb_modules/samldb.c ++++ b/source4/dsdb/samdb/ldb_modules/samldb.c +@@ -4001,8 +4001,7 @@ static int samldb_spn_uniqueness_check(struct samldb_ctx *ac, + ac->msg->dn); + if (ret == LDB_ERR_COMPARE_TRUE) { + DBG_INFO("SPN %s re-added to the same object\n", spn); +- talloc_free(tmp_ctx); +- return LDB_SUCCESS; ++ continue; + } + if (ret != LDB_SUCCESS) { + DBG_ERR("SPN %s failed direct uniqueness check\n", spn); +-- +2.34.1 + diff -Nru samba-4.13.13+dfsg/debian/patches/0003-CVE-2020-25717-nsswitch-nsstest.c-Lower-non-existent.patch samba-4.13.13+dfsg/debian/patches/0003-CVE-2020-25717-nsswitch-nsstest.c-Lower-non-existent.patch --- samba-4.13.13+dfsg/debian/patches/0003-CVE-2020-25717-nsswitch-nsstest.c-Lower-non-existent.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.13.13+dfsg/debian/patches/0003-CVE-2020-25717-nsswitch-nsstest.c-Lower-non-existent.patch 2022-02-03 20:54:02.000000000 +0000 @@ -0,0 +1,32 @@ +From 0a56d233bfdb48bb2222891f7abfe054769b2ef2 Mon Sep 17 00:00:00 2001 +From: Joseph Sutton +Date: Fri, 12 Nov 2021 20:53:30 +1300 +Subject: [PATCH 3/6] CVE-2020-25717: nsswitch/nsstest.c: Lower 'non existent + uid' to make room for new accounts + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14901 + +Signed-off-by: Joseph Sutton +Reviewed-by: Stefan Metzmacher +Reviewed-by: Ralph Boehme +(cherry picked from commit fdbee5e074ebd76d659613b8b7114d70f938c38a) +--- + nsswitch/nsstest.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/nsswitch/nsstest.c b/nsswitch/nsstest.c +index e2ee9fbf3af4..45270cdc459e 100644 +--- a/nsswitch/nsstest.c ++++ b/nsswitch/nsstest.c +@@ -466,7 +466,7 @@ static void nss_test_errors(void) + printf("ERROR Non existent user gave error %d\n", last_error); + } + +- pwd = getpwuid(0xFFF0); ++ pwd = getpwuid(0xFF00); + if (pwd || last_error != NSS_STATUS_NOTFOUND) { + total_errors++; + printf("ERROR Non existent uid gave error %d\n", last_error); +-- +2.34.1 + diff -Nru samba-4.13.13+dfsg/debian/patches/0003-CVE-2021-44142-libadouble-harden-ad_unpack_xattrs.patch samba-4.13.13+dfsg/debian/patches/0003-CVE-2021-44142-libadouble-harden-ad_unpack_xattrs.patch --- samba-4.13.13+dfsg/debian/patches/0003-CVE-2021-44142-libadouble-harden-ad_unpack_xattrs.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.13.13+dfsg/debian/patches/0003-CVE-2021-44142-libadouble-harden-ad_unpack_xattrs.patch 2022-02-03 20:54:02.000000000 +0000 @@ -0,0 +1,68 @@ +From b3b76222cfba5d162843b14b55570a02573c8ce8 Mon Sep 17 00:00:00 2001 +From: Ralph Boehme +Date: Fri, 26 Nov 2021 07:19:32 +0100 +Subject: [PATCH 3/5] CVE-2021-44142: libadouble: harden ad_unpack_xattrs() + +This ensures ad_unpack_xattrs() is only called for an ad_type of ADOUBLE_RSRC, +which is used for parsing ._ AppleDouble sidecar files, and the buffer +ad->ad_data is AD_XATTR_MAX_HDR_SIZE bytes large which is a prerequisite for all +buffer out-of-bounds access checks in ad_unpack_xattrs(). + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914 + +Signed-off-by: Ralph Boehme +Reviewed-by: Jeremy Allison +--- + source3/lib/adouble.c | 21 ++++++++++++++++++--- + 1 file changed, 18 insertions(+), 3 deletions(-) + +diff --git a/source3/lib/adouble.c b/source3/lib/adouble.c +index 42b2e808d667..48621feb530d 100644 +--- a/source3/lib/adouble.c ++++ b/source3/lib/adouble.c +@@ -707,14 +707,27 @@ static bool ad_pack(struct vfs_handle_struct *handle, + static bool ad_unpack_xattrs(struct adouble *ad) + { + struct ad_xattr_header *h = &ad->adx_header; ++ size_t bufsize = talloc_get_size(ad->ad_data); + const char *p = ad->ad_data; + uint32_t hoff; + uint32_t i; + ++ if (ad->ad_type != ADOUBLE_RSRC) { ++ return false; ++ } ++ + if (ad_getentrylen(ad, ADEID_FINDERI) <= ADEDLEN_FINDERI) { + return true; + } + ++ /* ++ * Ensure the buffer ad->ad_data was allocated by ad_alloc() for an ++ * ADOUBLE_RSRC type (._ AppleDouble file on-disk). ++ */ ++ if (bufsize != AD_XATTR_MAX_HDR_SIZE) { ++ return false; ++ } ++ + /* 2 bytes padding */ + hoff = ad_getentryoff(ad, ADEID_FINDERI) + ADEDLEN_FINDERI + 2; + +@@ -964,9 +977,11 @@ static bool ad_unpack(struct adouble *ad, const size_t nentries, + ad->ad_eid[eid].ade_len = len; + } + +- ok = ad_unpack_xattrs(ad); +- if (!ok) { +- return false; ++ if (ad->ad_type == ADOUBLE_RSRC) { ++ ok = ad_unpack_xattrs(ad); ++ if (!ok) { ++ return false; ++ } + } + + return true; +-- +2.34.1 + diff -Nru samba-4.13.13+dfsg/debian/patches/0004-CVE-2020-25717-selftest-turn-ad_member_no_nss_wb-int.patch samba-4.13.13+dfsg/debian/patches/0004-CVE-2020-25717-selftest-turn-ad_member_no_nss_wb-int.patch --- samba-4.13.13+dfsg/debian/patches/0004-CVE-2020-25717-selftest-turn-ad_member_no_nss_wb-int.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.13.13+dfsg/debian/patches/0004-CVE-2020-25717-selftest-turn-ad_member_no_nss_wb-int.patch 2022-02-03 20:54:02.000000000 +0000 @@ -0,0 +1,142 @@ +From a40c007fb5574cc781b60ab948477dcd9dd05aab Mon Sep 17 00:00:00 2001 +From: Joseph Sutton +Date: Fri, 12 Nov 2021 14:20:45 +1300 +Subject: [PATCH 4/6] CVE-2020-25717: selftest: turn ad_member_no_nss_wb into + ad_member_idmap_nss + +In reality environments without 'nss_winbind' make use of 'idmap_nss'. + +For testing, DOMAIN/bob is mapped to the local 'bob', +while DOMAIN/jane gets the uid based on the local 'jane' +vis idmap_nss. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14901 + +Pair-Programmed-With: Stefan Metzmacher + +Signed-off-by: Joseph Sutton +Signed-off-by: Stefan Metzmacher + +[metze@samba.org avoid to create a new ad_member_idmap_nss environment +and merge it with ad_member_no_nss_wb instead] +Reviewed-by: Ralph Boehme + +(cherry picked from commit 8a9f2aa2c1cdfa72ad50d7c4f879220fe37654cd) +--- + selftest/target/Samba.pm | 2 +- + selftest/target/Samba3.pm | 24 ++++++++++++++++++++---- + source4/selftest/tests.py | 2 +- + 3 files changed, 22 insertions(+), 6 deletions(-) + +diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm +index 6caeb932e28a..7ed10020aa11 100644 +--- a/selftest/target/Samba.pm ++++ b/selftest/target/Samba.pm +@@ -579,7 +579,7 @@ sub get_interface($) + lclnt4dc2smb1 => 55, + fipsdc => 56, + fipsadmember => 57, +- admemnonsswb => 60, ++ admemidmapnss => 60, + + rootdnsforwarder => 64, + +diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm +index 39327964569f..e726b7a15dfe 100755 +--- a/selftest/target/Samba3.pm ++++ b/selftest/target/Samba3.pm +@@ -238,7 +238,7 @@ sub check_env($$) + ad_member_idmap_rid => ["ad_dc"], + ad_member_idmap_ad => ["fl2008r2dc"], + ad_member_fips => ["ad_dc_fips"], +- ad_member_no_nss_wb => ["ad_dc"], ++ ad_member_idmap_nss => ["ad_dc"], + + clusteredmember_smb1 => ["nt4_dc"], + ); +@@ -1194,7 +1194,7 @@ sub setup_ad_member_fips + 1); + } + +-sub setup_ad_member_no_nss_wb ++sub setup_ad_member_idmap_nss + { + my ($self, + $prefix, +@@ -1207,14 +1207,23 @@ sub setup_ad_member_no_nss_wb + return "UNKNOWN"; + } + +- print "PROVISIONING AD MEMBER WITHOUT NSS WINBIND..."; ++ print "PROVISIONING AD MEMBER WITHOUT NSS WINBIND WITH idmap_nss config..."; + + my $extra_member_options = " ++ # bob:x:65521:65531:localbob gecos:/:/bin/false ++ # jane:x:65520:65531:localjane gecos:/:/bin/false ++ idmap config $dcvars->{DOMAIN} : backend = nss ++ idmap config $dcvars->{DOMAIN} : range = 65520-65521 ++ ++ # Support SMB1 so that we can use posix_whoami(). ++ client min protocol = CORE ++ server min protocol = LANMAN1 ++ + username map = $prefix/lib/username.map + "; + + my $ret = $self->provision_ad_member($prefix, +- "ADMEMNONSSWB", ++ "ADMEMIDMAPNSS", + $dcvars, + $trustvars_f, + $trustvars_e, +@@ -1225,6 +1234,7 @@ sub setup_ad_member_no_nss_wb + open(USERMAP, ">$prefix/lib/username.map") or die("Unable to open $prefix/lib/username.map"); + print USERMAP " + root = $dcvars->{DOMAIN}/root ++bob = $dcvars->{DOMAIN}/bob + "; + close(USERMAP); + +@@ -2246,6 +2256,8 @@ sub provision($$) + my ($uid_gooduser); + my ($uid_eviluser); + my ($uid_slashuser); ++ my ($uid_localbob); ++ my ($uid_localjane); + + if ($unix_uid < 0xffff - 13) { + $max_uid = 0xffff; +@@ -2266,6 +2278,8 @@ sub provision($$) + $uid_gooduser = $max_uid - 11; + $uid_eviluser = $max_uid - 12; + $uid_slashuser = $max_uid - 13; ++ $uid_localbob = $max_uid - 14; ++ $uid_localjane = $max_uid - 15; + + if ($unix_gids[0] < 0xffff - 8) { + $max_gid = 0xffff; +@@ -2974,6 +2988,8 @@ user2:x:$uid_user2:$gid_nogroup:user2 gecos:$prefix_abs:/bin/false + gooduser:x:$uid_gooduser:$gid_domusers:gooduser gecos:$prefix_abs:/bin/false + eviluser:x:$uid_eviluser:$gid_domusers:eviluser gecos::/bin/false + slashuser:x:$uid_slashuser:$gid_domusers:slashuser gecos:/:/bin/false ++bob:x:$uid_localbob:$gid_domusers:localbob gecos:/:/bin/false ++jane:x:$uid_localjane:$gid_domusers:localjane gecos:/:/bin/false + "; + if ($unix_uid != 0) { + print PASSWD "root:x:$uid_root:$gid_root:root gecos:$prefix_abs:/bin/false +diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py +index cdc7bc77c0ae..b7f0976a1eea 100755 +--- a/source4/selftest/tests.py ++++ b/source4/selftest/tests.py +@@ -854,7 +854,7 @@ planoldpythontestsuite("ad_dc_smb1", "samba.tests.krb5.test_smb", + 'TKT_SIG_SUPPORT': tkt_sig_support, + 'EXPECT_PAC': expect_pac + }) +-planoldpythontestsuite("ad_member_no_nss_wb:local", ++planoldpythontestsuite("ad_member_idmap_nss:local", + "samba.tests.krb5.test_min_domain_uid", + environ={ + 'ADMIN_USERNAME': '$DC_USERNAME', +-- +2.34.1 + diff -Nru samba-4.13.13+dfsg/debian/patches/0004-CVE-2021-44142-libadouble-add-basic-cmocka-tests.patch samba-4.13.13+dfsg/debian/patches/0004-CVE-2021-44142-libadouble-add-basic-cmocka-tests.patch --- samba-4.13.13+dfsg/debian/patches/0004-CVE-2021-44142-libadouble-add-basic-cmocka-tests.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.13.13+dfsg/debian/patches/0004-CVE-2021-44142-libadouble-add-basic-cmocka-tests.patch 2022-02-03 20:54:02.000000000 +0000 @@ -0,0 +1,452 @@ +From ffa40d4acb5f2d57443670be31dca05caacb1cfd Mon Sep 17 00:00:00 2001 +From: Ralph Boehme +Date: Thu, 25 Nov 2021 15:04:03 +0100 +Subject: [PATCH 4/5] CVE-2021-44142: libadouble: add basic cmocka tests + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914 + +Signed-off-by: Ralph Boehme +Reviewed-by: Jeremy Allison +[slow@samba.org: conflict due to missing test in selftest/tests.py] +--- + selftest/knownfail.d/samba.unittests.adouble | 3 + + selftest/tests.py | 2 + + source3/lib/test_adouble.c | 389 +++++++++++++++++++ + source3/wscript_build | 5 + + 4 files changed, 399 insertions(+) + create mode 100644 selftest/knownfail.d/samba.unittests.adouble + create mode 100644 source3/lib/test_adouble.c + +diff --git a/selftest/knownfail.d/samba.unittests.adouble b/selftest/knownfail.d/samba.unittests.adouble +new file mode 100644 +index 000000000000..8b0314f2faec +--- /dev/null ++++ b/selftest/knownfail.d/samba.unittests.adouble +@@ -0,0 +1,3 @@ ++^samba.unittests.adouble.parse_abouble_finderinfo2\(none\) ++^samba.unittests.adouble.parse_abouble_finderinfo3\(none\) ++^samba.unittests.adouble.parse_abouble_date2\(none\) +diff --git a/selftest/tests.py b/selftest/tests.py +index a2b8bf5c4d5b..ac5070f7e5b8 100644 +--- a/selftest/tests.py ++++ b/selftest/tests.py +@@ -417,3 +417,5 @@ plantestsuite("samba.unittests.test_oLschema2ldif", "none", + if with_elasticsearch_backend: + plantestsuite("samba.unittests.mdsparser_es", "none", + [os.path.join(bindir(), "default/source3/test_mdsparser_es")] + [configuration]) ++plantestsuite("samba.unittests.adouble", "none", ++ [os.path.join(bindir(), "test_adouble")]) +diff --git a/source3/lib/test_adouble.c b/source3/lib/test_adouble.c +new file mode 100644 +index 000000000000..615c22469c91 +--- /dev/null ++++ b/source3/lib/test_adouble.c +@@ -0,0 +1,389 @@ ++/* ++ * Unix SMB/CIFS implementation. ++ * ++ * Copyright (C) 2021 Ralph Boehme ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++#include "adouble.c" ++#include ++ ++static int setup_talloc_context(void **state) ++{ ++ TALLOC_CTX *frame = talloc_stackframe(); ++ ++ *state = frame; ++ return 0; ++} ++ ++static int teardown_talloc_context(void **state) ++{ ++ TALLOC_CTX *frame = *state; ++ ++ TALLOC_FREE(frame); ++ return 0; ++} ++ ++/* ++ * Basic and sane buffer. ++ */ ++static uint8_t ad_basic[] = { ++ 0x00, 0x05, 0x16, 0x07, /* Magic */ ++ 0x00, 0x02, 0x00, 0x00, /* Version */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x02, /* Count */ ++ /* adentry 1: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x32, /* offset */ ++ 0x00, 0x00, 0x00, 0x20, /* length */ ++ /* adentry 2: Resourcefork */ ++ 0x00, 0x00, 0x00, 0x02, /* eid: Resourcefork */ ++ 0x00, 0x00, 0x00, 0x52, /* offset */ ++ 0xff, 0xff, 0xff, 0x00, /* length */ ++ /* FinderInfo data: 32 bytes */ ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++}; ++ ++/* ++ * An empty FinderInfo entry. ++ */ ++static uint8_t ad_finderinfo1[] = { ++ 0x00, 0x05, 0x16, 0x07, /* Magic */ ++ 0x00, 0x02, 0x00, 0x00, /* Version */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x02, /* Count */ ++ /* adentry 1: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x52, /* off: points at end of buffer */ ++ 0x00, 0x00, 0x00, 0x00, /* len: 0, so off+len don't exceed bufferlen */ ++ /* adentry 2: Resourcefork */ ++ 0x00, 0x00, 0x00, 0x02, /* eid: Resourcefork */ ++ 0x00, 0x00, 0x00, 0x52, /* offset */ ++ 0xff, 0xff, 0xff, 0x00, /* length */ ++ /* FinderInfo data: 32 bytes */ ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++}; ++ ++/* ++ * A dangerous FinderInfo with correct length exceeding buffer by one byte. ++ */ ++static uint8_t ad_finderinfo2[] = { ++ 0x00, 0x05, 0x16, 0x07, /* Magic */ ++ 0x00, 0x02, 0x00, 0x00, /* Version */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x02, /* Count */ ++ /* adentry 1: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x33, /* off: points at beginng of data + 1 */ ++ 0x00, 0x00, 0x00, 0x20, /* len: 32, so off+len exceeds bufferlen by 1 */ ++ /* adentry 2: Resourcefork */ ++ 0x00, 0x00, 0x00, 0x02, /* eid: Resourcefork */ ++ 0x00, 0x00, 0x00, 0x52, /* offset */ ++ 0xff, 0xff, 0xff, 0x00, /* length */ ++ /* FinderInfo data: 32 bytes */ ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++}; ++ ++static uint8_t ad_finderinfo3[] = { ++ 0x00, 0x05, 0x16, 0x07, /* Magic */ ++ 0x00, 0x02, 0x00, 0x00, /* Version */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x02, /* Count */ ++ /* adentry 1: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x33, /* off: points at beginng of data + 1 */ ++ 0x00, 0x00, 0x00, 0x1f, /* len: 31, so off+len don't exceed buf */ ++ /* adentry 2: Resourcefork */ ++ 0x00, 0x00, 0x00, 0x02, /* eid: Resourcefork */ ++ 0x00, 0x00, 0x00, 0x52, /* offset */ ++ 0xff, 0xff, 0xff, 0x00, /* length */ ++ /* FinderInfo data: 32 bytes */ ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++}; ++ ++/* ++ * A dangerous name entry. ++ */ ++static uint8_t ad_name[] = { ++ 0x00, 0x05, 0x16, 0x07, /* Magic */ ++ 0x00, 0x02, 0x00, 0x00, /* Version */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x02, /* Count */ ++ /* adentry 1: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x32, /* offset */ ++ 0x00, 0x00, 0x00, 0x20, /* length */ ++ /* adentry 2: Name */ ++ 0x00, 0x00, 0x00, 0x03, /* eid: Name */ ++ 0x00, 0x00, 0x00, 0x52, /* off: points at end of buffer */ ++ 0x00, 0x00, 0x00, 0x01, /* len: 1, so off+len exceeds bufferlen */ ++ /* FinderInfo data: 32 bytes */ ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++}; ++ ++/* ++ * A empty ADEID_FILEDATESI entry. ++ */ ++static uint8_t ad_date1[] = { ++ 0x00, 0x05, 0x16, 0x07, /* Magic */ ++ 0x00, 0x02, 0x00, 0x00, /* Version */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x02, /* Count */ ++ /* adentry 1: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x32, /* offset */ ++ 0x00, 0x00, 0x00, 0x20, /* length */ ++ /* adentry 2: Dates */ ++ 0x00, 0x00, 0x00, 0x08, /* eid: dates */ ++ 0x00, 0x00, 0x00, 0x52, /* off: end of buffer */ ++ 0x00, 0x00, 0x00, 0x00, /* len: 0, empty entry, valid */ ++ /* FinderInfo data: 32 bytes */ ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++}; ++ ++/* ++ * A dangerous ADEID_FILEDATESI entry, invalid length. ++ */ ++static uint8_t ad_date2[] = { ++ 0x00, 0x05, 0x16, 0x07, /* Magic */ ++ 0x00, 0x02, 0x00, 0x00, /* Version */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x00, 0x00, 0x00, /* Filler */ ++ 0x00, 0x02, /* Count */ ++ /* adentry 1: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x09, /* eid: FinderInfo */ ++ 0x00, 0x00, 0x00, 0x32, /* offset */ ++ 0x00, 0x00, 0x00, 0x20, /* length */ ++ /* adentry 2: Dates */ ++ 0x00, 0x00, 0x00, 0x08, /* eid: dates */ ++ 0x00, 0x00, 0x00, 0x43, /* off: FinderInfo buf but one byte short */ ++ 0x00, 0x00, 0x00, 0x0f, /* len: 15, so off+len don't exceed bufferlen */ ++ /* FinderInfo data: 32 bytes */ ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, ++}; ++ ++static struct adouble *parse_adouble(TALLOC_CTX *mem_ctx, ++ uint8_t *adbuf, ++ size_t adsize, ++ off_t filesize) ++{ ++ struct adouble *ad = NULL; ++ bool ok; ++ ++ ad = talloc_zero(mem_ctx, struct adouble); ++ ad->ad_data = talloc_zero_size(ad, adsize); ++ assert_non_null(ad); ++ ++ memcpy(ad->ad_data, adbuf, adsize); ++ ++ ok = ad_unpack(ad, 2, filesize); ++ if (!ok) { ++ return NULL; ++ } ++ ++ return ad; ++} ++ ++static void parse_abouble_basic(void **state) ++{ ++ TALLOC_CTX *frame = *state; ++ struct adouble *ad = NULL; ++ char *p = NULL; ++ ++ ad = parse_adouble(frame, ad_basic, sizeof(ad_basic), 0xffffff52); ++ assert_non_null(ad); ++ ++ p = ad_get_entry(ad, ADEID_FINDERI); ++ assert_non_null(p); ++ ++ return; ++} ++ ++static void parse_abouble_finderinfo1(void **state) ++{ ++ TALLOC_CTX *frame = *state; ++ struct adouble *ad = NULL; ++ char *p = NULL; ++ ++ ad = parse_adouble(frame, ++ ad_finderinfo1, ++ sizeof(ad_finderinfo1), ++ 0xffffff52); ++ assert_non_null(ad); ++ ++ p = ad_get_entry(ad, ADEID_FINDERI); ++ assert_null(p); ++ ++ return; ++} ++ ++static void parse_abouble_finderinfo2(void **state) ++{ ++ TALLOC_CTX *frame = *state; ++ struct adouble *ad = NULL; ++ ++ ad = parse_adouble(frame, ++ ad_finderinfo2, ++ sizeof(ad_finderinfo2), ++ 0xffffff52); ++ assert_null(ad); ++ ++ return; ++} ++ ++static void parse_abouble_finderinfo3(void **state) ++{ ++ TALLOC_CTX *frame = *state; ++ struct adouble *ad = NULL; ++ ++ ad = parse_adouble(frame, ++ ad_finderinfo3, ++ sizeof(ad_finderinfo3), ++ 0xffffff52); ++ assert_null(ad); ++ ++ return; ++} ++ ++static void parse_abouble_name(void **state) ++{ ++ TALLOC_CTX *frame = *state; ++ struct adouble *ad = NULL; ++ ++ ad = parse_adouble(frame, ad_name, sizeof(ad_name), 0x52); ++ assert_null(ad); ++ ++ return; ++} ++ ++static void parse_abouble_date1(void **state) ++{ ++ TALLOC_CTX *frame = *state; ++ struct adouble *ad = NULL; ++ char *p = NULL; ++ ++ ad = parse_adouble(frame, ad_date1, sizeof(ad_date1), 0x52); ++ assert_non_null(ad); ++ ++ p = ad_get_entry(ad, ADEID_FILEDATESI); ++ assert_null(p); ++ ++ return; ++} ++ ++static void parse_abouble_date2(void **state) ++{ ++ TALLOC_CTX *frame = *state; ++ struct adouble *ad = NULL; ++ ++ ad = parse_adouble(frame, ad_date2, sizeof(ad_date2), 0x52); ++ assert_null(ad); ++ ++ return; ++} ++ ++int main(int argc, char *argv[]) ++{ ++ int rc; ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test(parse_abouble_basic), ++ cmocka_unit_test(parse_abouble_finderinfo1), ++ cmocka_unit_test(parse_abouble_finderinfo2), ++ cmocka_unit_test(parse_abouble_finderinfo3), ++ cmocka_unit_test(parse_abouble_name), ++ cmocka_unit_test(parse_abouble_date1), ++ cmocka_unit_test(parse_abouble_date2), ++ }; ++ ++ if (argc == 2) { ++ cmocka_set_test_filter(argv[1]); ++ } ++ cmocka_set_message_output(CM_OUTPUT_SUBUNIT); ++ ++ rc = cmocka_run_group_tests(tests, ++ setup_talloc_context, ++ teardown_talloc_context); ++ ++ return rc; ++} +diff --git a/source3/wscript_build b/source3/wscript_build +index 46c914c7b224..6ac99e81b7f1 100644 +--- a/source3/wscript_build ++++ b/source3/wscript_build +@@ -1086,6 +1086,11 @@ bld.SAMBA3_SUBSYSTEM('ADOUBLE', + source='lib/adouble.c', + deps='STRING_REPLACE') + ++bld.SAMBA3_BINARY('test_adouble', ++ source='lib/test_adouble.c', ++ deps='smbd_base STRING_REPLACE cmocka', ++ for_selftest=True) ++ + bld.SAMBA3_SUBSYSTEM('STRING_REPLACE', + source='lib/string_replace.c') + +-- +2.34.1 + diff -Nru samba-4.13.13+dfsg/debian/patches/0005-CVE-2020-25717-tests-krb5-Add-a-test-for-idmap_nss-m.patch samba-4.13.13+dfsg/debian/patches/0005-CVE-2020-25717-tests-krb5-Add-a-test-for-idmap_nss-m.patch --- samba-4.13.13+dfsg/debian/patches/0005-CVE-2020-25717-tests-krb5-Add-a-test-for-idmap_nss-m.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.13.13+dfsg/debian/patches/0005-CVE-2020-25717-tests-krb5-Add-a-test-for-idmap_nss-m.patch 2022-02-03 20:54:02.000000000 +0000 @@ -0,0 +1,315 @@ +From 32ba258cd753301504bdb4a00624053f08373b95 Mon Sep 17 00:00:00 2001 +From: Joseph Sutton +Date: Fri, 12 Nov 2021 14:22:47 +1300 +Subject: [PATCH 5/6] CVE-2020-25717: tests/krb5: Add a test for idmap_nss + mapping users to SIDs + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14901 + +Pair-Programmed-With: Stefan Metzmacher + +Signed-off-by: Joseph Sutton +Signed-off-by: Stefan Metzmacher + +[metze@samba.org removed unused tests for a feature that + was removed before merging] +Reviewed-by: Ralph Boehme + +(cherry picked from commit 494bf7de6ff3e9abeb3753df0635737b80ce5bb7) +--- + python/samba/tests/krb5/test_idmap_nss.py | 232 +++++++++++++++++++++ + python/samba/tests/usage.py | 1 + + selftest/knownfail.d/idmap_nss_sid_mapping | 2 + + source4/selftest/tests.py | 16 ++ + 4 files changed, 251 insertions(+) + create mode 100755 python/samba/tests/krb5/test_idmap_nss.py + create mode 100644 selftest/knownfail.d/idmap_nss_sid_mapping + +diff --git a/python/samba/tests/krb5/test_idmap_nss.py b/python/samba/tests/krb5/test_idmap_nss.py +new file mode 100755 +index 000000000000..d3480dbca3f7 +--- /dev/null ++++ b/python/samba/tests/krb5/test_idmap_nss.py +@@ -0,0 +1,232 @@ ++#!/usr/bin/env python3 ++# Unix SMB/CIFS implementation. ++# Copyright (C) Stefan Metzmacher 2020 ++# Copyright (C) 2021 Catalyst.Net Ltd ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++# ++ ++import sys ++import os ++ ++from ldb import SCOPE_SUBTREE ++from samba import NTSTATUSError ++from samba.credentials import DONT_USE_KERBEROS ++from samba.dcerpc import security ++from samba.ndr import ndr_unpack ++from samba.ntstatus import ( ++ NT_STATUS_NO_IMPERSONATION_TOKEN, ++ NT_STATUS_LOGON_FAILURE ++) ++from samba.samba3 import libsmb_samba_internal as libsmb ++from samba.samba3 import param as s3param ++ ++from samba.tests.krb5.kdc_base_test import KDCBaseTest ++ ++sys.path.insert(0, 'bin/python') ++os.environ['PYTHONUNBUFFERED'] = '1' ++ ++global_asn1_print = False ++global_hexdump = False ++ ++ ++class IdmapNssTests(KDCBaseTest): ++ ++ mappeduser_uid = 0xffff - 14 ++ mappeduser_sid = security.dom_sid(f'S-1-22-1-{mappeduser_uid}') ++ unmappeduser_uid = 0xffff - 15 ++ unmappeduser_sid = security.dom_sid(f'S-1-22-1-{unmappeduser_uid}') ++ ++ def get_mapped_creds(self, ++ allow_missing_password=False, ++ allow_missing_keys=True): ++ c = self._get_krb5_creds(prefix='MAPPED', ++ allow_missing_password=allow_missing_password, ++ allow_missing_keys=allow_missing_keys) ++ c.set_workstation('') ++ return c ++ ++ def get_unmapped_creds(self, ++ allow_missing_password=False, ++ allow_missing_keys=True): ++ c = self._get_krb5_creds(prefix='UNMAPPED', ++ allow_missing_password=allow_missing_password, ++ allow_missing_keys=allow_missing_keys) ++ c.set_workstation('') ++ return c ++ ++ def get_invalid_creds(self, ++ allow_missing_password=False, ++ allow_missing_keys=True): ++ c = self._get_krb5_creds(prefix='INVALID', ++ allow_missing_password=allow_missing_password, ++ allow_missing_keys=allow_missing_keys) ++ c.set_workstation('') ++ return c ++ ++ # Expect a mapping to the local user SID. ++ def test_mapped_user_kerberos(self): ++ user_creds = self.get_mapped_creds() ++ self._run_idmap_nss_test(user_creds, use_kerberos=True, ++ expected_first_sid=self.mappeduser_sid, ++ expected_uid=self.mappeduser_uid) ++ ++ # Expect a mapping to the local user SID. ++ def test_mapped_user_ntlm(self): ++ user_creds = self.get_mapped_creds() ++ self._run_idmap_nss_test(user_creds, use_kerberos=False, ++ expected_first_sid=self.mappeduser_sid, ++ expected_uid=self.mappeduser_uid) ++ ++ def test_mapped_user_no_pac_kerberos(self): ++ user_creds = self.get_mapped_creds() ++ self._run_idmap_nss_test( ++ user_creds, use_kerberos=True, remove_pac=True, ++ expected_error=NT_STATUS_NO_IMPERSONATION_TOKEN) ++ ++ def test_unmapped_user_kerberos(self): ++ user_creds = self.get_unmapped_creds() ++ self._run_idmap_nss_test(user_creds, use_kerberos=True, ++ expected_additional_sid=self.unmappeduser_sid, ++ expected_uid=self.unmappeduser_uid) ++ ++ def test_unmapped_user_ntlm(self): ++ user_creds = self.get_unmapped_creds() ++ self._run_idmap_nss_test(user_creds, use_kerberos=False, ++ expected_additional_sid=self.unmappeduser_sid, ++ expected_uid=self.unmappeduser_uid) ++ ++ def test_unmapped_user_no_pac_kerberos(self): ++ user_creds = self.get_unmapped_creds() ++ self._run_idmap_nss_test( ++ user_creds, use_kerberos=True, remove_pac=True, ++ expected_error=NT_STATUS_NO_IMPERSONATION_TOKEN) ++ ++ def test_invalid_user_kerberos(self): ++ user_creds = self.get_invalid_creds() ++ self._run_idmap_nss_test(user_creds, use_kerberos=True, ++ expected_error=NT_STATUS_LOGON_FAILURE) ++ ++ def test_invalid_user_ntlm(self): ++ user_creds = self.get_invalid_creds() ++ self._run_idmap_nss_test(user_creds, use_kerberos=False, ++ expected_error=NT_STATUS_LOGON_FAILURE) ++ ++ def test_invalid_user_no_pac_kerberos(self): ++ user_creds = self.get_invalid_creds() ++ self._run_idmap_nss_test( ++ user_creds, use_kerberos=True, remove_pac=True, ++ expected_error=NT_STATUS_NO_IMPERSONATION_TOKEN) ++ ++ def _run_idmap_nss_test(self, user_creds, ++ use_kerberos, ++ remove_pac=False, ++ expected_error=None, ++ expected_first_sid=None, ++ expected_additional_sid=None, ++ expected_uid=None): ++ if expected_first_sid is not None: ++ self.assertIsNotNone(expected_uid) ++ if expected_additional_sid is not None: ++ self.assertIsNotNone(expected_uid) ++ if expected_uid is not None: ++ self.assertIsNone(expected_error) ++ ++ if not use_kerberos: ++ self.assertFalse(remove_pac) ++ ++ samdb = self.get_samdb() ++ ++ server_name = self.host ++ service = 'cifs' ++ share = 'tmp' ++ ++ server_creds = self.get_server_creds() ++ ++ if expected_first_sid is None: ++ # Retrieve the user account's SID. ++ user_name = user_creds.get_username() ++ res = samdb.search(scope=SCOPE_SUBTREE, ++ expression=f'(sAMAccountName={user_name})', ++ attrs=['objectSid']) ++ self.assertEqual(1, len(res)) ++ ++ expected_first_sid = ndr_unpack(security.dom_sid, ++ res[0].get('objectSid', idx=0)) ++ ++ if use_kerberos: ++ # Talk to the KDC to obtain the service ticket, which gets placed ++ # into the cache. The machine account name has to match the name in ++ # the ticket, to ensure that the krbtgt ticket doesn't also need to ++ # be stored. ++ creds, cachefile = self.create_ccache_with_user( ++ user_creds, ++ server_creds, ++ service, ++ server_name, ++ pac=not remove_pac) ++ ++ # Remove the cached creds file. ++ self.addCleanup(os.remove, cachefile.name) ++ ++ # Set the Kerberos 5 creds cache environment variable. This is ++ # required because the codepath that gets run (gse_krb5) looks for ++ # it in here and not in the creds object. ++ krb5_ccname = os.environ.get('KRB5CCNAME', '') ++ self.addCleanup(os.environ.__setitem__, 'KRB5CCNAME', krb5_ccname) ++ os.environ['KRB5CCNAME'] = 'FILE:' + cachefile.name ++ else: ++ creds = user_creds ++ creds.set_kerberos_state(DONT_USE_KERBEROS) ++ ++ # Connect to a share and retrieve the user SID. ++ s3_lp = s3param.get_context() ++ s3_lp.load(self.get_lp().configfile) ++ ++ min_protocol = s3_lp.get('client min protocol') ++ self.addCleanup(s3_lp.set, 'client min protocol', min_protocol) ++ s3_lp.set('client min protocol', 'NT1') ++ ++ max_protocol = s3_lp.get('client max protocol') ++ self.addCleanup(s3_lp.set, 'client max protocol', max_protocol) ++ s3_lp.set('client max protocol', 'NT1') ++ ++ try: ++ conn = libsmb.Conn(server_name, share, lp=s3_lp, creds=creds) ++ except NTSTATUSError as e: ++ enum, _ = e.args ++ self.assertEqual(expected_error, enum) ++ return ++ else: ++ self.assertIsNone(expected_error) ++ ++ uid, gid, gids, sids, guest = conn.posix_whoami() ++ ++ # Ensure that they match. ++ self.assertEqual(expected_first_sid, sids[0]) ++ self.assertNotIn(expected_first_sid, sids[1:-1]) ++ ++ if expected_additional_sid: ++ self.assertNotEqual(expected_additional_sid, sids[0]) ++ self.assertIn(expected_additional_sid, sids) ++ ++ self.assertIsNotNone(expected_uid) ++ self.assertEqual(expected_uid, uid) ++ ++ ++if __name__ == '__main__': ++ global_asn1_print = False ++ global_hexdump = False ++ import unittest ++ unittest.main() +diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py +index 048bd1c30995..881383d6e392 100644 +--- a/python/samba/tests/usage.py ++++ b/python/samba/tests/usage.py +@@ -107,6 +107,7 @@ EXCLUDE_USAGE = { + 'python/samba/tests/krb5/spn_tests.py', + 'python/samba/tests/krb5/alias_tests.py', + 'python/samba/tests/krb5/test_min_domain_uid.py', ++ 'python/samba/tests/krb5/test_idmap_nss.py', + } + + EXCLUDE_HELP = { +diff --git a/selftest/knownfail.d/idmap_nss_sid_mapping b/selftest/knownfail.d/idmap_nss_sid_mapping +new file mode 100644 +index 000000000000..7e1913f03fce +--- /dev/null ++++ b/selftest/knownfail.d/idmap_nss_sid_mapping +@@ -0,0 +1,2 @@ ++^samba.tests.krb5.test_idmap_nss.samba.tests.krb5.test_idmap_nss.IdmapNssTests.test_unmapped_user_kerberos ++^samba.tests.krb5.test_idmap_nss.samba.tests.krb5.test_idmap_nss.IdmapNssTests.test_unmapped_user_ntlm +diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py +index b7f0976a1eea..5c9490266741 100755 +--- a/source4/selftest/tests.py ++++ b/source4/selftest/tests.py +@@ -861,6 +861,22 @@ planoldpythontestsuite("ad_member_idmap_nss:local", + 'ADMIN_PASSWORD': '$DC_PASSWORD', + 'STRICT_CHECKING': '0' + }) ++planoldpythontestsuite("ad_member_idmap_nss:local", ++ "samba.tests.krb5.test_idmap_nss", ++ environ={ ++ 'ADMIN_USERNAME': '$DC_USERNAME', ++ 'ADMIN_PASSWORD': '$DC_PASSWORD', ++ 'MAPPED_USERNAME': 'bob', ++ 'MAPPED_PASSWORD': 'Secret007', ++ 'UNMAPPED_USERNAME': 'jane', ++ 'UNMAPPED_PASSWORD': 'Secret007', ++ 'INVALID_USERNAME': 'joe', ++ 'INVALID_PASSWORD': 'Secret007', ++ 'STRICT_CHECKING': '0', ++ 'FAST_SUPPORT': have_fast_support, ++ 'TKT_SIG_SUPPORT': tkt_sig_support, ++ 'EXPECT_PAC': expect_pac ++ }) + + for env in ["ad_dc", smbv1_disabled_testenv]: + planoldpythontestsuite(env, "samba.tests.smb", extra_args=['-U"$USERNAME%$PASSWORD"']) +-- +2.34.1 + diff -Nru samba-4.13.13+dfsg/debian/patches/0005-CVE-2021-44142-libadouble-harden-parsing-code.patch samba-4.13.13+dfsg/debian/patches/0005-CVE-2021-44142-libadouble-harden-parsing-code.patch --- samba-4.13.13+dfsg/debian/patches/0005-CVE-2021-44142-libadouble-harden-parsing-code.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.13.13+dfsg/debian/patches/0005-CVE-2021-44142-libadouble-harden-parsing-code.patch 2022-02-03 20:54:02.000000000 +0000 @@ -0,0 +1,169 @@ +From edf661e40b3c17681563613bf58b2e757a6ebc12 Mon Sep 17 00:00:00 2001 +From: Ralph Boehme +Date: Thu, 13 Jan 2022 17:03:02 +0100 +Subject: [PATCH 5/5] CVE-2021-44142: libadouble: harden parsing code + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14914 + +Signed-off-by: Ralph Boehme +Reviewed-by: Jeremy Allison +--- + selftest/knownfail.d/samba.unittests.adouble | 3 - + source3/lib/adouble.c | 115 ++++++++++++++++--- + 2 files changed, 101 insertions(+), 17 deletions(-) + delete mode 100644 selftest/knownfail.d/samba.unittests.adouble + +diff --git a/selftest/knownfail.d/samba.unittests.adouble b/selftest/knownfail.d/samba.unittests.adouble +deleted file mode 100644 +index 8b0314f2faec..000000000000 +--- a/selftest/knownfail.d/samba.unittests.adouble ++++ /dev/null +@@ -1,3 +0,0 @@ +-^samba.unittests.adouble.parse_abouble_finderinfo2\(none\) +-^samba.unittests.adouble.parse_abouble_finderinfo3\(none\) +-^samba.unittests.adouble.parse_abouble_date2\(none\) +diff --git a/source3/lib/adouble.c b/source3/lib/adouble.c +index 48621feb530d..bb94a45e2ded 100644 +--- a/source3/lib/adouble.c ++++ b/source3/lib/adouble.c +@@ -269,6 +269,95 @@ size_t ad_setentryoff(struct adouble *ad, int eid, size_t off) + return ad->ad_eid[eid].ade_off = off; + } + ++/* ++ * All entries besides FinderInfo and resource fork must fit into the ++ * buffer. FinderInfo is special as it may be larger then the default 32 bytes ++ * if it contains marshalled xattrs, which we will fixup that in ++ * ad_convert(). The first 32 bytes however must also be part of the buffer. ++ * ++ * The resource fork is never accessed directly by the ad_data buf. ++ */ ++static bool ad_entry_check_size(uint32_t eid, ++ size_t bufsize, ++ uint32_t off, ++ uint32_t got_len) ++{ ++ struct { ++ off_t expected_len; ++ bool fixed_size; ++ bool minimum_size; ++ } ad_checks[] = { ++ [ADEID_DFORK] = {-1, false, false}, /* not applicable */ ++ [ADEID_RFORK] = {-1, false, false}, /* no limit */ ++ [ADEID_NAME] = {ADEDLEN_NAME, false, false}, ++ [ADEID_COMMENT] = {ADEDLEN_COMMENT, false, false}, ++ [ADEID_ICONBW] = {ADEDLEN_ICONBW, true, false}, ++ [ADEID_ICONCOL] = {ADEDLEN_ICONCOL, false, false}, ++ [ADEID_FILEI] = {ADEDLEN_FILEI, true, false}, ++ [ADEID_FILEDATESI] = {ADEDLEN_FILEDATESI, true, false}, ++ [ADEID_FINDERI] = {ADEDLEN_FINDERI, false, true}, ++ [ADEID_MACFILEI] = {ADEDLEN_MACFILEI, true, false}, ++ [ADEID_PRODOSFILEI] = {ADEDLEN_PRODOSFILEI, true, false}, ++ [ADEID_MSDOSFILEI] = {ADEDLEN_MSDOSFILEI, true, false}, ++ [ADEID_SHORTNAME] = {ADEDLEN_SHORTNAME, false, false}, ++ [ADEID_AFPFILEI] = {ADEDLEN_AFPFILEI, true, false}, ++ [ADEID_DID] = {ADEDLEN_DID, true, false}, ++ [ADEID_PRIVDEV] = {ADEDLEN_PRIVDEV, true, false}, ++ [ADEID_PRIVINO] = {ADEDLEN_PRIVINO, true, false}, ++ [ADEID_PRIVSYN] = {ADEDLEN_PRIVSYN, true, false}, ++ [ADEID_PRIVID] = {ADEDLEN_PRIVID, true, false}, ++ }; ++ ++ if (eid >= ADEID_MAX) { ++ return false; ++ } ++ if (got_len == 0) { ++ /* Entry present, but empty, allow */ ++ return true; ++ } ++ if (ad_checks[eid].expected_len == 0) { ++ /* ++ * Shouldn't happen: implicitly initialized to zero because ++ * explicit initializer missing. ++ */ ++ return false; ++ } ++ if (ad_checks[eid].expected_len == -1) { ++ /* Unused or no limit */ ++ return true; ++ } ++ if (ad_checks[eid].fixed_size) { ++ if (ad_checks[eid].expected_len != got_len) { ++ /* Wrong size fo fixed size entry. */ ++ return false; ++ } ++ } else { ++ if (ad_checks[eid].minimum_size) { ++ if (got_len < ad_checks[eid].expected_len) { ++ /* ++ * Too small for variable sized entry with ++ * minimum size. ++ */ ++ return false; ++ } ++ } else { ++ if (got_len > ad_checks[eid].expected_len) { ++ /* Too big for variable sized entry. */ ++ return false; ++ } ++ } ++ } ++ if (off + got_len < off) { ++ /* wrap around */ ++ return false; ++ } ++ if (off + got_len > bufsize) { ++ /* overflow */ ++ return false; ++ } ++ return true; ++} ++ + /** + * Return a pointer to an AppleDouble entry + * +@@ -276,8 +365,15 @@ size_t ad_setentryoff(struct adouble *ad, int eid, size_t off) + **/ + char *ad_get_entry(const struct adouble *ad, int eid) + { ++ size_t bufsize = talloc_get_size(ad->ad_data); + off_t off = ad_getentryoff(ad, eid); + size_t len = ad_getentrylen(ad, eid); ++ bool valid; ++ ++ valid = ad_entry_check_size(eid, bufsize, off, len); ++ if (!valid) { ++ return NULL; ++ } + + if (off == 0 || len == 0) { + return NULL; +@@ -914,20 +1010,11 @@ static bool ad_unpack(struct adouble *ad, const size_t nentries, + return false; + } + +- /* +- * All entries besides FinderInfo and resource fork +- * must fit into the buffer. FinderInfo is special as +- * it may be larger then the default 32 bytes (if it +- * contains marshalled xattrs), but we will fixup that +- * in ad_convert(). And the resource fork is never +- * accessed directly by the ad_data buf (also see +- * comment above) anyway. +- */ +- if ((eid != ADEID_RFORK) && +- (eid != ADEID_FINDERI) && +- ((off + len) > bufsize)) { +- DEBUG(1, ("bogus eid %d: off: %" PRIu32 ", len: %" PRIu32 "\n", +- eid, off, len)); ++ ok = ad_entry_check_size(eid, bufsize, off, len); ++ if (!ok) { ++ DBG_ERR("bogus eid [%"PRIu32"] bufsize [%zu] " ++ "off [%"PRIu32"] len [%"PRIu32"]\n", ++ eid, bufsize, off, len); + return false; + } + +-- +2.34.1 + diff -Nru samba-4.13.13+dfsg/debian/patches/0006-CVE-2020-25717-s3-auth-Fallback-to-a-SID-UID-based-m.patch samba-4.13.13+dfsg/debian/patches/0006-CVE-2020-25717-s3-auth-Fallback-to-a-SID-UID-based-m.patch --- samba-4.13.13+dfsg/debian/patches/0006-CVE-2020-25717-s3-auth-Fallback-to-a-SID-UID-based-m.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.13.13+dfsg/debian/patches/0006-CVE-2020-25717-s3-auth-Fallback-to-a-SID-UID-based-m.patch 2022-02-03 20:54:02.000000000 +0000 @@ -0,0 +1,127 @@ +From 105c6a15effd118d7cfe9dfa7b1ad4faab9fe224 Mon Sep 17 00:00:00 2001 +From: Andrew Bartlett +Date: Fri, 12 Nov 2021 16:10:31 +1300 +Subject: [PATCH 6/6] CVE-2020-25717: s3:auth: Fallback to a SID/UID based + mapping if the named based lookup fails +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Before the CVE-2020-25717 fixes we had a fallback from +getpwnam('DOMAIN\user') to getpwnam('user') which was very dangerous and +unpredictable. + +Now we do the fallback based on sid_to_uid() followed by +getpwuid() on the returned uid. + +This obsoletes 'username map [script]' based workaround adviced +for CVE-2020-25717, when nss_winbindd is not used or +idmap_nss is actually used. + +In future we may decide to prefer or only do the SID/UID based +lookup, but for now we want to keep this unchanged as much as possible. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14901 + +Pair-Programmed-With: Stefan Metzmacher + +Signed-off-by: Andrew Bartlett +Signed-off-by: Stefan Metzmacher + +[metze@samba.org moved the new logic into the fallback codepath only + in order to avoid behavior changes as much as possible] +Reviewed-by: Ralph Boehme + +Autobuild-User(master): Ralph Böhme +Autobuild-Date(master): Mon Nov 15 19:01:56 UTC 2021 on sn-devel-184 + +(cherry picked from commit 0a546be05295a7e4a552f9f4f0c74aeb2e9a0d6e) + +Autobuild-User(v4-13-test): Jule Anger +Autobuild-Date(v4-13-test): Wed Nov 17 15:50:53 UTC 2021 on sn-devel-184 +--- + selftest/knownfail.d/idmap_nss_sid_mapping | 2 -- + source3/auth/auth_util.c | 34 +++++++++++++++++++++- + 2 files changed, 33 insertions(+), 3 deletions(-) + delete mode 100644 selftest/knownfail.d/idmap_nss_sid_mapping + +diff --git a/selftest/knownfail.d/idmap_nss_sid_mapping b/selftest/knownfail.d/idmap_nss_sid_mapping +deleted file mode 100644 +index 7e1913f03fce..000000000000 +--- a/selftest/knownfail.d/idmap_nss_sid_mapping ++++ /dev/null +@@ -1,2 +0,0 @@ +-^samba.tests.krb5.test_idmap_nss.samba.tests.krb5.test_idmap_nss.IdmapNssTests.test_unmapped_user_kerberos +-^samba.tests.krb5.test_idmap_nss.samba.tests.krb5.test_idmap_nss.IdmapNssTests.test_unmapped_user_ntlm +diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c +index 065b525500f9..7a97dd45f11e 100644 +--- a/source3/auth/auth_util.c ++++ b/source3/auth/auth_util.c +@@ -1862,7 +1862,9 @@ const struct auth_session_info *get_session_info_system(void) + ***************************************************************************/ + + static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain, +- const char *username, char **found_username, ++ const char *username, ++ const struct dom_sid *sid, ++ char **found_username, + struct passwd **pwd, + bool *username_was_mapped) + { +@@ -1897,6 +1899,31 @@ static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain, + } + + passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, false); ++ if (!passwd && !*username_was_mapped) { ++ struct dom_sid_buf buf; ++ uid_t uid; ++ bool ok; ++ ++ DBG_DEBUG("Failed to find authenticated user %s via " ++ "getpwnam(), fallback to sid_to_uid(%s).\n", ++ dom_user, dom_sid_str_buf(sid, &buf)); ++ ++ ok = sid_to_uid(sid, &uid); ++ if (!ok) { ++ DBG_ERR("Failed to convert SID %s to a UID (dom_user[%s])\n", ++ dom_sid_str_buf(sid, &buf), dom_user); ++ return NT_STATUS_NO_SUCH_USER; ++ } ++ passwd = getpwuid_alloc(mem_ctx, uid); ++ if (!passwd) { ++ DBG_ERR("Failed to find local account with UID %lld for SID %s (dom_user[%s])\n", ++ (long long)uid, ++ dom_sid_str_buf(sid, &buf), ++ dom_user); ++ return NT_STATUS_NO_SUCH_USER; ++ } ++ real_username = talloc_strdup(mem_ctx, passwd->pw_name); ++ } + if (!passwd) { + DEBUG(3, ("Failed to find authenticated user %s via " + "getpwnam(), denying access.\n", dom_user)); +@@ -2042,6 +2069,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, + bool username_was_mapped; + struct passwd *pwd; + struct auth_serversupplied_info *result; ++ struct dom_sid sid; + TALLOC_CTX *tmp_ctx = talloc_stackframe(); + + /* +@@ -2088,9 +2116,13 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, + + /* this call will try to create the user if necessary */ + ++ sid_copy(&sid, info3->base.domain_sid); ++ sid_append_rid(&sid, info3->base.rid); ++ + nt_status = check_account(tmp_ctx, + nt_domain, + nt_username, ++ &sid, + &found_username, + &pwd, + &username_was_mapped); +-- +2.34.1 + diff -Nru samba-4.13.13+dfsg/debian/patches/series samba-4.13.13+dfsg/debian/patches/series --- samba-4.13.13+dfsg/debian/patches/series 2021-11-04 20:42:38.000000000 +0000 +++ samba-4.13.13+dfsg/debian/patches/series 2022-02-03 20:54:02.000000000 +0000 @@ -275,3 +275,16 @@ CVE-2021-23192-only-4.13-v2.patch CVE-2021-3738-dsdb-crash-4.13-v03.patch CVE-2016-2124-v4-13-metze02.patches.txt +0001-CVE-2022-0336-pytest-Add-a-test-for-an-SPN-conflict-.patch +0002-CVE-2022-0336-s4-dsdb-samldb-Don-t-return-early-when.patch +0001-CVE-2021-44142-libadouble-add-defines-for-icon-lengt.patch +0002-CVE-2021-44142-smbd-add-Netatalk-xattr-used-by-vfs_f.patch +0003-CVE-2021-44142-libadouble-harden-ad_unpack_xattrs.patch +0004-CVE-2021-44142-libadouble-add-basic-cmocka-tests.patch +0005-CVE-2021-44142-libadouble-harden-parsing-code.patch +0001-CVE-2020-25727-idmap_nss-verify-that-the-name-of-the.patch +0002-CVE-2020-25717-tests-krb5-Add-method-to-automaticall.patch +0003-CVE-2020-25717-nsswitch-nsstest.c-Lower-non-existent.patch +0004-CVE-2020-25717-selftest-turn-ad_member_no_nss_wb-int.patch +0005-CVE-2020-25717-tests-krb5-Add-a-test-for-idmap_nss-m.patch +0006-CVE-2020-25717-s3-auth-Fallback-to-a-SID-UID-based-m.patch