]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
CVE-2020-25717: selftest: Add a test for the new 'min domain uid' parameter
authorSamuel Cabrero <scabrero@samba.org>
Tue, 5 Oct 2021 14:56:06 +0000 (16:56 +0200)
committerJule Anger <janger@samba.org>
Mon, 8 Nov 2021 09:52:10 +0000 (10:52 +0100)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14801
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14556

Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>

Signed-off-by: Samuel Cabrero <scabrero@samba.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
[abartlet@samba.org Fixed knowfail per instruction from metze]

python/samba/tests/krb5/test_min_domain_uid.py [new file with mode: 0755]
python/samba/tests/usage.py
selftest/knownfail.d/min_domain_uid [new file with mode: 0644]
source4/selftest/tests.py

diff --git a/python/samba/tests/krb5/test_min_domain_uid.py b/python/samba/tests/krb5/test_min_domain_uid.py
new file mode 100755 (executable)
index 0000000..77414b2
--- /dev/null
@@ -0,0 +1,121 @@
+#!/usr/bin/env python3
+# Unix SMB/CIFS implementation.
+# Copyright (C) Samuel Cabrero 2021
+#
+# 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 <http://www.gnu.org/licenses/>.
+#
+
+import sys
+import os
+import pwd
+import ctypes
+
+from samba.tests import env_get_var_value
+from samba.samba3 import libsmb_samba_internal as libsmb
+from samba.samba3 import param as s3param
+from samba import NTSTATUSError, ntstatus
+
+from samba.tests.krb5.kdc_base_test import KDCBaseTest
+from samba.credentials import MUST_USE_KERBEROS, DONT_USE_KERBEROS
+
+sys.path.insert(0, "bin/python")
+os.environ["PYTHONUNBUFFERED"] = "1"
+
+class SmbMinDomainUid(KDCBaseTest):
+    """Test for SMB authorization without NSS winbind. In such setup domain
+       accounts are mapped to local accounts using the 'username map' option.
+    """
+
+    def setUp(self):
+        super(KDCBaseTest, self).setUp()
+
+        # Create a user account, along with a Kerberos credentials cache file
+        # where the service ticket authenticating the user are stored.
+        self.samdb = self.get_samdb()
+
+        self.mach_name = env_get_var_value('SERVER')
+        self.user_name = "root"
+        self.service = "cifs"
+        self.share = "tmp"
+
+        # Create the user account.
+        (self.user_creds, _) = self.create_account(self.samdb, self.user_name)
+
+        # Build the global inject file path
+        server_conf = env_get_var_value('SMB_CONF_PATH')
+        server_conf_dir = os.path.dirname(server_conf)
+        self.global_inject = os.path.join(server_conf_dir, "global_inject.conf")
+
+    def _test_min_uid(self, creds):
+        # Assert unix root uid is less than 'idmap config ADDOMAIN' minimum
+        s3_lp = s3param.get_context()
+        s3_lp.load(self.get_lp().configfile)
+
+        domain_range = s3_lp.get("idmap config * : range").split('-')
+        domain_range_low = int(domain_range[0])
+        unix_root_pw = pwd.getpwnam(self.user_name)
+        self.assertLess(unix_root_pw.pw_uid, domain_range_low)
+        self.assertLess(unix_root_pw.pw_gid, domain_range_low)
+
+        conn = libsmb.Conn(self.mach_name, self.share, lp=s3_lp, creds=creds)
+        # Disconnect
+        conn = None
+
+        # Restrict access to local root account uid
+        with open(self.global_inject, 'w') as f:
+            f.write("min domain uid = %s\n" % (unix_root_pw.pw_uid + 1))
+
+        with self.assertRaises(NTSTATUSError) as cm:
+            conn = libsmb.Conn(self.mach_name,
+                               self.share,
+                               lp=s3_lp,
+                               creds=creds)
+        code = ctypes.c_uint32(cm.exception.args[0]).value
+        self.assertEqual(code, ntstatus.NT_STATUS_INVALID_TOKEN)
+
+        # check that the local root account uid is now allowed
+        with open(self.global_inject, 'w') as f:
+            f.write("min domain uid = %s\n" % unix_root_pw.pw_uid)
+
+        conn = libsmb.Conn(self.mach_name, self.share, lp=s3_lp, creds=creds)
+        # Disconnect
+        conn = None
+
+        with open(self.global_inject, 'w') as f:
+            f.truncate()
+
+    def test_min_domain_uid_krb5(self):
+        krb5_state = self.user_creds.get_kerberos_state()
+        self.user_creds.set_kerberos_state(MUST_USE_KERBEROS)
+        ret = self._test_min_uid(self.user_creds)
+        self.user_creds.set_kerberos_state(krb5_state)
+        return ret
+
+    def test_min_domain_uid_ntlmssp(self):
+        krb5_state = self.user_creds.get_kerberos_state()
+        self.user_creds.set_kerberos_state(DONT_USE_KERBEROS)
+        ret = self._test_min_uid(self.user_creds)
+        self.user_creds.set_kerberos_state(krb5_state)
+        return ret
+
+    def tearDown(self):
+        # Ensure no leftovers in global inject file
+        with open(self.global_inject, 'w') as f:
+            f.truncate()
+
+        super(KDCBaseTest, self).tearDown()
+
+if __name__ == "__main__":
+    import unittest
+    unittest.main()
index 5cae74299853cb6c1e1bba9fb64fee2ec38b00e5..048bd1c309950e1e56e910c0cc55906ffb02dd1c 100644 (file)
@@ -106,6 +106,7 @@ EXCLUDE_USAGE = {
     'python/samba/tests/krb5/salt_tests.py',
     'python/samba/tests/krb5/spn_tests.py',
     'python/samba/tests/krb5/alias_tests.py',
+    'python/samba/tests/krb5/test_min_domain_uid.py',
 }
 
 EXCLUDE_HELP = {
diff --git a/selftest/knownfail.d/min_domain_uid b/selftest/knownfail.d/min_domain_uid
new file mode 100644 (file)
index 0000000..00bf75c
--- /dev/null
@@ -0,0 +1 @@
+^samba.tests.krb5.test_min_domain_uid.samba.*.SmbMinDomainUid.test_min_domain_uid_.*\(ad_member_no_nss_wb:local\)
index bd68094436fbbc7cad40522d4a0c9206424752cc..312e7944a0ce6949a3f92314e0c49d7969ba80cc 100755 (executable)
@@ -845,6 +845,13 @@ planoldpythontestsuite("ad_dc_smb1", "samba.tests.krb5.test_smb",
                            'FAST_SUPPORT': have_fast_support,
                            'TKT_SIG_SUPPORT': tkt_sig_support
                        })
+planoldpythontestsuite("ad_member_no_nss_wb:local",
+                       "samba.tests.krb5.test_min_domain_uid",
+                       environ={
+                           'ADMIN_USERNAME': '$DC_USERNAME',
+                           'ADMIN_PASSWORD': '$DC_PASSWORD',
+                           'STRICT_CHECKING': '0'
+                       })
 
 for env in ["ad_dc", smbv1_disabled_testenv]:
     planoldpythontestsuite(env, "samba.tests.smb", extra_args=['-U"$USERNAME%$PASSWORD"'])