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

Jule Anger janger at samba.org
Wed Nov 17 16:13:01 UTC 2021


The branch, v4-15-test has been updated
       via  9bcba58e4d4 CVE-2020-25717: s3:auth: Fallback to a SID/UID based mapping if the named based lookup fails
       via  5d5e5a1f355 CVE-2020-25717: tests/krb5: Add a test for idmap_nss mapping users to SIDs
       via  ae21fe9c01b CVE-2020-25717: selftest: turn ad_member_no_nss_wb into ad_member_idmap_nss
       via  3f009a620a3 CVE-2020-25717: nsswitch/nsstest.c: Lower 'non existent uid' to make room for new accounts
       via  ebe18e23ba6 CVE-2020-25717: tests/krb5: Add method to automatically obtain server credentials
       via  38ddd41e9c6 CVE-2020-25727: idmap_nss: verify that the name of the sid belongs to the configured domain
       via  ad6af1bb831 s3: smbd: Ensure in the directory scanning loops inside rmdir_internals() we don't overwrite the 'ret' variable.
       via  728c9b83564 s3: smbtorture3: Add test for setting delete on close on a directory, then creating a file within to see if delete succeeds.
       via  89903ed1e32 s3: smbd: dirfsp is being used uninitialized inside rmdir_internals().
       via  6aae2575b38 smbd: get rid of get_file_handle_for_metadata()
      from  c357c1b2024 lib/cmdline: setup default file logging for servers

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


- Log -----------------------------------------------------------------
commit 9bcba58e4d42f6107ad8f9fa3faf892f9426a0ec
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Nov 12 16:10:31 2021 +1300

    CVE-2020-25717: s3:auth: Fallback to a SID/UID based mapping if the named based lookup fails
    
    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 <metze at samba.org>
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    
    [metze at 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 <slow at samba.org>
    
    Autobuild-User(master): Ralph Böhme <slow at samba.org>
    Autobuild-Date(master): Mon Nov 15 19:01:56 UTC 2021 on sn-devel-184
    
    (cherry picked from commit 0a546be05295a7e4a552f9f4f0c74aeb2e9a0d6e)
    
    Autobuild-User(v4-15-test): Jule Anger <janger at samba.org>
    Autobuild-Date(v4-15-test): Wed Nov 17 16:12:28 UTC 2021 on sn-devel-184

commit 5d5e5a1f3558b52776ada0c1fabfa87c0adafd2d
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Fri Nov 12 14:22:47 2021 +1300

    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 <metze at samba.org>
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    
    [metze at samba.org removed unused tests for a feature that
     was removed before merging]
    Reviewed-by: Ralph Boehme <slow at samba.org>
    
    (cherry picked from commit 494bf7de6ff3e9abeb3753df0635737b80ce5bb7)

commit ae21fe9c01b50232ca3223cca0096f8001786395
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Fri Nov 12 14:20:45 2021 +1300

    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 <metze at samba.org>
    
    Signed-off-by: Joseph Sutton <josephsutton at catalyst.net.nz>
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    
    [metze at 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 <slow at samba.org>
    
    (cherry picked from commit 8a9f2aa2c1cdfa72ad50d7c4f879220fe37654cd)

commit 3f009a620a32fc02e26f7056b2c53cb940b7bbd4
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Fri Nov 12 20:53:30 2021 +1300

    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 <josephsutton at catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>
    (cherry picked from commit fdbee5e074ebd76d659613b8b7114d70f938c38a)

commit ebe18e23ba62e99295661584ce72942ce214aa4c
Author: Joseph Sutton <josephsutton at catalyst.net.nz>
Date:   Fri Nov 12 14:14:55 2021 +1300

    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 <josephsutton at catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>
    (cherry picked from commit 5ea347d3673e35891613c90ca837d1ce4833c1b0)

commit 38ddd41e9c6314ab37d727ff20ca09426a6d7e89
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Nov 12 15:27:58 2021 +0100

    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 <metze at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>
    (cherry picked from commit bfd093648b4af51d104096c0cb3535e8706671e5)

commit ad6af1bb8316783a9b31934184863d78fa3eeb27
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Nov 3 19:02:36 2021 -0700

    s3: smbd: Ensure in the directory scanning loops inside rmdir_internals() we don't overwrite the 'ret' variable.
    
    If we overwrite with ret=0, we return NT_STATUS_OK even when we goto err.
    
    This function should be restructured to use NT_STATUS internally,
    and make 'int ret' transitory, but that's a patch for another
    time.
    
    Remove knownfail.
    
    BUG: BUG: https://bugzilla.samba.org/show_bug.cgi?id=14892
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>
    
    Autobuild-User(master): Ralph Böhme <slow at samba.org>
    Autobuild-Date(master): Thu Nov  4 09:10:27 UTC 2021 on sn-devel-184
    
    (cherry picked from commit 141f3f5f9a5ef556cc7864b2afbf8ad48b7ebe77)

commit 728c9b83564cef7e721488855cf352e32a5ca123
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Nov 3 16:50:10 2021 -0700

    s3: smbtorture3: Add test for setting delete on close on a directory, then creating a file within to see if delete succeeds.
    
    Exposes an existing problem where "ret" is overwritten
    in the directory scan.
    
    Add knownfail.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14892
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>
    (cherry picked from commit adfad6390962022277cc6aacaa388af86e46b71c)

commit 89903ed1e3210ebbade1bf325ba16187a3c2e753
Author: Jeremy Allison <jra at samba.org>
Date:   Tue Nov 2 10:44:44 2021 -0700

    s3: smbd: dirfsp is being used uninitialized inside rmdir_internals().
    
    Not caught be the tests in bugs 14878, 14879 as can_delete_directory_fsp()
    doesn't have the same bug.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14892
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>
    
    Autobuild-User(master): Ralph Böhme <slow at samba.org>
    Autobuild-Date(master): Wed Nov  3 14:33:49 UTC 2021 on sn-devel-184
    
    (cherry picked from commit bbdcd66c048fee39629aeff450b50d049806e2f7)

commit 6aae2575b389fb475f70a8fc221e3e685b220ed6
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Nov 15 18:04:30 2021 +0100

    smbd: get rid of get_file_handle_for_metadata()
    
    This also avoids triggering an assert in get_share_mode_lock(). We already have
    a handle, use that one, no need to call get_file_handle_for_metadata().
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14907
    RN: set_ea_dos_attribute() fallback calling get_file_handle_for_metadata() triggers locking.tdb assert
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Tue Nov 16 18:51:15 UTC 2021 on sn-devel-184
    
    (cherry picked from commit a8c0c2c9e3adc94843a236fd9374980e2c0e6bfe)

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

Summary of changes:
 nsswitch/nsstest.c                        |   2 +-
 python/samba/tests/krb5/kdc_base_test.py  |  42 ++++++
 python/samba/tests/krb5/test_idmap_nss.py | 232 ++++++++++++++++++++++++++++++
 python/samba/tests/usage.py               |   1 +
 selftest/target/Samba.pm                  |   2 +-
 selftest/target/Samba3.pm                 |  24 +++-
 source3/auth/auth_util.c                  |  34 ++++-
 source3/selftest/tests.py                 |  15 ++
 source3/smbd/close.c                      |  16 ++-
 source3/smbd/dosmode.c                    | 119 +--------------
 source3/torture/proto.h                   |   1 +
 source3/torture/test_smb2.c               | 136 ++++++++++++++++++
 source3/torture/torture.c                 |   4 +
 source3/winbindd/idmap_nss.c              |  26 +++-
 source4/selftest/tests.py                 |  18 ++-
 15 files changed, 535 insertions(+), 137 deletions(-)
 create mode 100755 python/samba/tests/krb5/test_idmap_nss.py


Changeset truncated at 500 lines:

diff --git a/nsswitch/nsstest.c b/nsswitch/nsstest.c
index e2ee9fbf3af..45270cdc459 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);
diff --git a/python/samba/tests/krb5/kdc_base_test.py b/python/samba/tests/krb5/kdc_base_test.py
index f64bd0b206e..6e96b982167 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
         '''
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 00000000000..d3480dbca3f
--- /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 <http://www.gnu.org/licenses/>.
+#
+
+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 3dd1345d485..6bbd96e7a08 100644
--- a/python/samba/tests/usage.py
+++ b/python/samba/tests/usage.py
@@ -108,6 +108,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/target/Samba.pm b/selftest/target/Samba.pm
index b57edfe8cf9..ec56f0e02ef 100644
--- a/selftest/target/Samba.pm
+++ b/selftest/target/Samba.pm
@@ -610,7 +610,7 @@ sub get_interface($)
 		fipsadmember      => 57,
 		offlineadmem      => 58,
 		s2kmember         => 59,
-		admemnonsswb      => 60,
+		admemidmapnss     => 60,
 
 		rootdnsforwarder  => 64,
 
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index c0ed379bf3f..d1ac5c16c26 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -240,7 +240,7 @@ sub check_env($$)
 	ad_member_fips      => ["ad_dc_fips"],
 	ad_member_offlogon  => ["ad_dc"],
 	ad_member_oneway    => ["fl2000dc"],
-	ad_member_no_nss_wb => ["ad_dc"],
+	ad_member_idmap_nss => ["ad_dc"],
 
 	clusteredmember => ["nt4_dc"],
 );
@@ -1448,7 +1448,7 @@ sub setup_ad_member_offlogon
 					  1);
 }
 
-sub setup_ad_member_no_nss_wb
+sub setup_ad_member_idmap_nss
 {
 	my ($self,
 	    $prefix,
@@ -1461,14 +1461,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,
@@ -1480,6 +1489,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);
 
@@ -2528,6 +2538,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;
@@ -2548,6 +2560,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;
@@ -3289,6 +3303,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/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 4527dedc49d..28850cd8520 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -1877,7 +1877,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)
 {
@@ -1912,6 +1914,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));
@@ -2057,6 +2084,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();
 
 	/* 
@@ -2103,9 +2131,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);
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index c24558d8a8a..10dd5042e46 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -256,6 +256,21 @@ plantestsuite("samba3.smbtorture_s3.plain.%s" % "SMB2-LIST-DIR-ASYNC",
                 smbtorture3,
                 "",
                 "-l $LOCAL_PATH"])
+#
+# SMB2-DEL-ON-CLOSE-NONEMPTY needs to run against a special fileserver share veto_files_delete
+#
+plantestsuite("samba3.smbtorture_s3.plain.%s" % "SMB2-DEL-ON-CLOSE-NONEMPTY",
+                "fileserver",
+                [os.path.join(samba3srcdir,
+                              "script/tests/test_smbtorture_s3.sh"),
+                'SMB2-DEL-ON-CLOSE-NONEMPTY',
+                '//$SERVER_IP/veto_files_delete',
+                '$USERNAME',
+                '$PASSWORD',


-- 
Samba Shared Repository



More information about the samba-cvs mailing list