[prev in list] [next in list] [prev in thread] [next in thread] 

List:       samba-cvs
Subject:    [SCM] Samba Shared Repository - branch master updated
From:       Ralph_Böhme <slow () samba ! org>
Date:       2021-11-15 19:02:01
Message-ID: E1mmhEv-0039XA-E6 () hrx0 ! samba ! org
[Download RAW message or body]

The branch, master has been updated
       via  0a546be0529 CVE-2020-25717: s3:auth: Fallback to a SID/UID based mapping \
                if the named based lookup fails
       via  494bf7de6ff CVE-2020-25717: tests/krb5: Add a test for idmap_nss mapping \
                users to SIDs
       via  8a9f2aa2c1c CVE-2020-25717: selftest: turn ad_member_no_nss_wb into \
                ad_member_idmap_nss
       via  fdbee5e074e CVE-2020-25717: nsswitch/nsstest.c: Lower 'non existent uid' \
                to make room for new accounts
       via  5ea347d3673 CVE-2020-25717: tests/krb5: Add method to automatically \
                obtain server credentials
       via  bfd093648b4 CVE-2020-25727: idmap_nss: verify that the name of the sid \
belongs to the configured domain  from  c69b66f649c IPA DC: add missing checks

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


- Log -----------------------------------------------------------------
commit 0a546be05295a7e4a552f9f4f0c74aeb2e9a0d6e
Author: Andrew Bartlett <abartlet@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@samba.org>
    
    Signed-off-by: Andrew Bartlett <abartlet@samba.org>
    Signed-off-by: Stefan Metzmacher <metze@samba.org>
    
    [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 <slow@samba.org>
    
    Autobuild-User(master): Ralph Böhme <slow@samba.org>
    Autobuild-Date(master): Mon Nov 15 19:01:56 UTC 2021 on sn-devel-184

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

commit 8a9f2aa2c1cdfa72ad50d7c4f879220fe37654cd
Author: Joseph Sutton <josephsutton@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@samba.org>
    
    Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
    Signed-off-by: Stefan Metzmacher <metze@samba.org>
    
    [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 <slow@samba.org>

commit fdbee5e074ebd76d659613b8b7114d70f938c38a
Author: Joseph Sutton <josephsutton@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@catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze@samba.org>
    Reviewed-by: Ralph Boehme <slow@samba.org>

commit 5ea347d3673e35891613c90ca837d1ce4833c1b0
Author: Joseph Sutton <josephsutton@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@catalyst.net.nz>
    Reviewed-by: Stefan Metzmacher <metze@samba.org>
    Reviewed-by: Ralph Boehme <slow@samba.org>

commit bfd093648b4af51d104096c0cb3535e8706671e5
Author: Stefan Metzmacher <metze@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@samba.org>
    Reviewed-by: Ralph Boehme <slow@samba.org>

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

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/winbindd/idmap_nss.c              |  26 +++-
 source4/selftest/tests.py                 |  18 ++-
 9 files changed, 368 insertions(+), 13 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 42aa1afc998..cf66e0afe71 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 69e6dcee591..c4f8eb5d4f9 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/winbindd/idmap_nss.c b/source3/winbindd/idmap_nss.c
index da50e2b4aa7..2729a0de3f3 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,


-- 
Samba Shared Repository


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic