From d5884d3f180669db62e44ff031ce9723b9325c3e Mon Sep 17 00:00:00 2001 From: Samuel Cabrero Date: Tue, 28 Sep 2021 10:43:40 +0200 Subject: [PATCH 01/34] loadparm: Add new parameter "min domain uid" --- docs-xml/smbdotconf/security/mindomainuid.xml | 13 +++++++++++++ lib/param/loadparm.c | 4 ++++ source3/param/loadparm.c | 2 ++ 3 files changed, 19 insertions(+) create mode 100644 docs-xml/smbdotconf/security/mindomainuid.xml diff --git a/docs-xml/smbdotconf/security/mindomainuid.xml b/docs-xml/smbdotconf/security/mindomainuid.xml new file mode 100644 index 000000000000..81e57111c82e --- /dev/null +++ b/docs-xml/smbdotconf/security/mindomainuid.xml @@ -0,0 +1,13 @@ + + + + The integer parameter specifies the minimum uid allowed when mapping a + local account to an AD account. + + + +1000 + diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 2eac1ba7c388..953734976959 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -2994,6 +2994,10 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) "server smb3 encryption algorithms", DEFAULT_SMB3_ENCRYPTION_ALGORITHMS); + lpcfg_do_global_parameter(lp_ctx, + "min domain uid", + "1000"); + for (i = 0; parm_table[i].label; i++) { if (!(lp_ctx->flags[i] & FLAG_CMDLINE)) { lp_ctx->flags[i] |= FLAG_DEFAULT; diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 6c9830563c3b..e98d1738bb44 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -976,6 +976,8 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.server_smb3_encryption_algorithms = str_list_make_v3_const(NULL, DEFAULT_SMB3_ENCRYPTION_ALGORITHMS, NULL); + Globals.min_domain_uid = 1000; + /* Now put back the settings that were set with lp_set_cmdline() */ apply_lp_set_cmdline(); } -- 2.25.1 From 048573ea4d57ffac514d1c3e0a1cf162df7a9d00 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Oct 2021 18:04:55 +0200 Subject: [PATCH 02/34] selftest/Samba3: remove unused close(USERMAP); calls Signed-off-by: Stefan Metzmacher --- selftest/target/Samba3.pm | 5 ----- 1 file changed, 5 deletions(-) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 3fe6c194ed88..804b19aa7467 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -782,7 +782,6 @@ sub provision_ad_member mkdir($_, 0777) foreach(@dirs); - close(USERMAP); $ret->{DOMAIN} = $dcvars->{DOMAIN}; $ret->{REALM} = $dcvars->{REALM}; $ret->{DOMSID} = $dcvars->{DOMSID}; @@ -1044,7 +1043,6 @@ sub setup_ad_member_rfc2307 $ret or return undef; - close(USERMAP); $ret->{DOMAIN} = $dcvars->{DOMAIN}; $ret->{REALM} = $dcvars->{REALM}; $ret->{DOMSID} = $dcvars->{DOMSID}; @@ -1142,7 +1140,6 @@ sub setup_ad_member_idmap_rid $ret or return undef; - close(USERMAP); $ret->{DOMAIN} = $dcvars->{DOMAIN}; $ret->{REALM} = $dcvars->{REALM}; $ret->{DOMSID} = $dcvars->{DOMSID}; @@ -1242,7 +1239,6 @@ sub setup_ad_member_idmap_ad $ret or return undef; - close(USERMAP); $ret->{DOMAIN} = $dcvars->{DOMAIN}; $ret->{REALM} = $dcvars->{REALM}; $ret->{DOMSID} = $dcvars->{DOMSID}; @@ -1342,7 +1338,6 @@ sub setup_ad_member_oneway $ret or return undef; - close(USERMAP); $ret->{DOMAIN} = $dcvars->{DOMAIN}; $ret->{REALM} = $dcvars->{REALM}; $ret->{DOMSID} = $dcvars->{DOMSID}; -- 2.25.1 From 239ee3f307a3fc94373802ca63c2817c2661ac92 Mon Sep 17 00:00:00 2001 From: Samuel Cabrero Date: Tue, 5 Oct 2021 12:31:29 +0200 Subject: [PATCH 03/34] selftest: Add ad_member_no_nss_wb environment This environment creates an AD member without running NSS winbind neither winbind daemon. It also enables SMB1 to be able to get the security token using posix extensions. Signed-off-by: Samuel Cabrero --- selftest/target/Samba.pm | 1 + selftest/target/Samba3.pm | 62 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm index 10353008b888..69e6dcee5910 100644 --- a/selftest/target/Samba.pm +++ b/selftest/target/Samba.pm @@ -610,6 +610,7 @@ sub get_interface($) fipsadmember => 57, offlineadmem => 58, s2kmember => 59, + admemnonsswb => 60, rootdnsforwarder => 64, diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 804b19aa7467..b6251df5e48a 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -240,6 +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"], clusteredmember => ["nt4_dc"], ); @@ -653,8 +654,15 @@ sub provision_ad_member $dcvars, $trustvars_f, $trustvars_e, + $extra_member_options, $force_fips_mode, - $offline_logon) = @_; + $offline_logon, + $no_nss_winbind) = @_; + + if (defined($offline_logon) && defined($no_nss_winbind)) { + warn ("Offline logon incompatible with no nss winbind\n"); + return undef; + } my $prefix_abs = abs_path($prefix); my @dirs = (); @@ -696,6 +704,10 @@ sub provision_ad_member $netbios_aliases = "netbios aliases = foo bar"; } + unless (defined($extra_member_options)) { + $extra_member_options = ""; + } + my $member_options = " security = ads workgroup = $dcvars->{DOMAIN} @@ -719,6 +731,10 @@ sub provision_ad_member rpc_daemon:epmd = fork rpc_daemon:lsasd = fork + # Begin extra member options + $extra_member_options + # End extra member options + [sub_dug] path = $share_dir/D_%D/U_%U/G_%G writeable = yes @@ -941,10 +957,17 @@ sub provision_ad_member return undef; } } else { + my $run_wb = 1; + if (defined($no_nss_winbind)) { + $ret->{NSS_WRAPPER_MODULE_SO_PATH} = ""; + $ret->{NSS_WRAPPER_MODULE_FN_PREFIX} = ""; + $run_wb = 0; + } + if (not $self->check_or_start( env_vars => $ret, nmbd => "yes", - winbindd => "yes", + winbindd => $run_wb ? "yes" : "no", smbd => "yes")) { return undef; } @@ -1419,6 +1442,7 @@ sub setup_ad_member_fips $dcvars, $trustvars_f, $trustvars_e, + undef, 1); } @@ -1443,9 +1467,43 @@ sub setup_ad_member_offlogon $trustvars_f, $trustvars_e, undef, + undef, 1); } +sub setup_ad_member_no_nss_wb +{ + my ($self, + $prefix, + $dcvars, + $trustvars_f, + $trustvars_e) = @_; + + # If we didn't build with ADS, pretend this env was never available + if (not $self->have_ads()) { + return "UNKNOWN"; + } + + print "PROVISIONING AD MEMBER WITHOUT NSS WINBIND..."; + + my $extra_member_options = " + client min protocol = CORE + server min protocol = LANMAN1 +"; + + my $ret = $self->provision_ad_member($prefix, + "ADMEMNONSSWB", + $dcvars, + $trustvars_f, + $trustvars_e, + $extra_member_options, + undef, + undef, + 1); + + return $ret; +} + sub setup_simpleserver { my ($self, $path) = @_; -- 2.25.1 From cf175cd1c5a606fc72702cb339e74dec8ff29d12 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Oct 2021 12:37:57 +0200 Subject: [PATCH 04/34] sq setup_ad_member_no_nss_wb map to local root --- selftest/target/Samba3.pm | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index b6251df5e48a..56d73a9b5819 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -957,17 +957,15 @@ sub provision_ad_member return undef; } } else { - my $run_wb = 1; if (defined($no_nss_winbind)) { $ret->{NSS_WRAPPER_MODULE_SO_PATH} = ""; $ret->{NSS_WRAPPER_MODULE_FN_PREFIX} = ""; - $run_wb = 0; } if (not $self->check_or_start( env_vars => $ret, nmbd => "yes", - winbindd => $run_wb ? "yes" : "no", + winbindd => "yes", smbd => "yes")) { return undef; } @@ -1487,8 +1485,11 @@ sub setup_ad_member_no_nss_wb print "PROVISIONING AD MEMBER WITHOUT NSS WINBIND..."; my $extra_member_options = " + client min protocol = CORE server min protocol = LANMAN1 + + username map = $prefix/lib/username.map "; my $ret = $self->provision_ad_member($prefix, @@ -1501,6 +1502,12 @@ sub setup_ad_member_no_nss_wb undef, 1); + open(USERMAP, ">$prefix/lib/username.map") or die("Unable to open $prefix/lib/username.map"); + print USERMAP " +root = $dcvars->{DOMAIN}/root +"; + close(USERMAP); + return $ret; } -- 2.25.1 From d7d0c447c4a17a2c01ee38dd8a6fa7717ea8d669 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Oct 2021 19:03:52 +0200 Subject: [PATCH 05/34] sq setup_ad_member_no_nss_wb --- selftest/target/Samba3.pm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 56d73a9b5819..dde687168d93 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -1485,10 +1485,6 @@ sub setup_ad_member_no_nss_wb print "PROVISIONING AD MEMBER WITHOUT NSS WINBIND..."; my $extra_member_options = " - - client min protocol = CORE - server min protocol = LANMAN1 - username map = $prefix/lib/username.map "; -- 2.25.1 From 78bcdde9018cb934acd73cc3134b2a342c86d2e6 Mon Sep 17 00:00:00 2001 From: Samuel Cabrero Date: Tue, 5 Oct 2021 16:56:06 +0200 Subject: [PATCH 06/34] selftest: Add a test for the new 'min domain uid' parameter Signed-off-by: Samuel Cabrero --- python/samba/tests/krb5/test_smb_no_nss_wb.py | 153 ++++++++++++++++++ selftest/knownfail | 2 + source4/selftest/tests.py | 7 + 3 files changed, 162 insertions(+) create mode 100755 python/samba/tests/krb5/test_smb_no_nss_wb.py diff --git a/python/samba/tests/krb5/test_smb_no_nss_wb.py b/python/samba/tests/krb5/test_smb_no_nss_wb.py new file mode 100755 index 000000000000..7d85c0fe7aa2 --- /dev/null +++ b/python/samba/tests/krb5/test_smb_no_nss_wb.py @@ -0,0 +1,153 @@ +#!/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 . +# + +import sys +import os +import pwd +import ctypes + +from ldb import SCOPE_SUBTREE +from samba.tests import delete_force, env_get_var_value +from samba.dcerpc import security +from samba.ndr import ndr_unpack +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 + +sys.path.insert(0, "bin/python") +os.environ["PYTHONUNBUFFERED"] = "1" + +global_asn1_print = False +global_hexdump = False + +class SmbNoNssWbTests(KDCBaseTest): + """Test for SMB authorization based on Kerberos ticket names without NSS + winbind and without running winbind daemon. In this scenario smbd will + try to match the name in the kerberos ticket to a local unix account. + """ + + 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) + + # 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. + (self.creds, self.cachefile) = self.create_ccache_with_user( + self.user_creds, self.mach_name, self.service) + + # Set the Kerberos 5 credentials cache environment variable. This is + # required because the codepath that gets run (gse_krb5) looks for it + # in here and not in the credentials object. + krb5_ccname = os.environ.get("KRB5CCNAME", "") + self.addCleanup(os.environ.__setitem__, "KRB5CCNAME", krb5_ccname) + os.environ["KRB5CCNAME"] = "FILE:" + self.cachefile.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): + # Retrieve the user account's SID. + ldb_res = self.samdb.search( + scope=SCOPE_SUBTREE, + expression="(sAMAccountName=%s)" % self.user_name, + attrs=["objectSid"]) + self.assertEqual(1, len(ldb_res)) + sid = ndr_unpack(security.dom_sid, ldb_res[0]["objectSid"][0]) + + # 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) + + # Connect to a share and retrieve the mapped user SID + 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") + + conn = libsmb.Conn(self.mach_name, self.share, lp=s3_lp, creds=self.creds) + + (uid, gid, gids, sids, guest) = conn.posix_whoami() + + # Ensure no guest + self.assertFalse(guest) + + # Ensure SIDs do not match + self.assertNotEqual(sid, sids[0]) + + # Ensure mapped to unix root + self.assertEqual(uid, unix_root_pw.pw_uid) + self.assertEqual(gid, unix_root_pw.pw_gid) + + # Disconnect + conn = None + + # Restrict access to local unix accounts setting min domain uid + with open(self.global_inject, 'w') as f: + f.write("min domain uid = %s\n" % domain_range_low) + + with self.assertRaises(NTSTATUSError) as cm: + conn = libsmb.Conn(self.mach_name, + self.share, + lp=s3_lp, + creds=self.creds) + code = ctypes.c_uint32(cm.exception.args[0]).value + self.assertEqual(code, ntstatus.NT_STATUS_ACCESS_DENIED) + + with open(self.global_inject, 'w') as f: + f.truncate() + + def tearDown(self): + # Ensure no leftovers in global inject file + with open(self.global_inject, 'w') as f: + f.truncate() + + # Remove the cached credentials file. + os.remove(self.cachefile.name) + super(KDCBaseTest, self).tearDown() + +if __name__ == "__main__": + global_asn1_print = True + global_hexdump = True + import unittest + unittest.main() diff --git a/selftest/knownfail b/selftest/knownfail index 94af250d4eb5..2c23bd724346 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -394,3 +394,5 @@ ^samba.tests.ntlmdisabled.python\(ktest\).ntlmdisabled.NtlmDisabledTests.test_samr_change_password\(ktest\) ^samba.tests.ntlmdisabled.python\(ad_dc_no_ntlm\).ntlmdisabled.NtlmDisabledTests.test_ntlm_connection\(ad_dc_no_ntlm\) +^samba.tests.krb5.test_smb_no_nss_wb.samba.*.SmbNoNssWbTests.test_min_uid\(ad_member_no_nss_wb:local\) + diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 2ed72fda2651..b4740207f5cb 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -948,6 +948,13 @@ planoldpythontestsuite("ad_dc_smb1", "samba.tests.krb5.test_smb", 'ADMIN_PASSWORD': '$PASSWORD', 'STRICT_CHECKING': '0' }) +planoldpythontestsuite("ad_member_no_nss_wb:local", + "samba.tests.krb5.test_smb_no_nss_wb", + 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"']) -- 2.25.1 From bb32ce8af9776c9880889286c1d6c5cd723f804a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Oct 2021 19:22:31 +0200 Subject: [PATCH 07/34] samba.tests.krb5.test_min_domain_uid --- ...mb_no_nss_wb.py => test_min_domain_uid.py} | 44 +++++-------------- source4/selftest/tests.py | 2 +- 2 files changed, 12 insertions(+), 34 deletions(-) rename python/samba/tests/krb5/{test_smb_no_nss_wb.py => test_min_domain_uid.py} (78%) diff --git a/python/samba/tests/krb5/test_smb_no_nss_wb.py b/python/samba/tests/krb5/test_min_domain_uid.py similarity index 78% rename from python/samba/tests/krb5/test_smb_no_nss_wb.py rename to python/samba/tests/krb5/test_min_domain_uid.py index 7d85c0fe7aa2..830b5a30e0a7 100755 --- a/python/samba/tests/krb5/test_smb_no_nss_wb.py +++ b/python/samba/tests/krb5/test_min_domain_uid.py @@ -37,7 +37,7 @@ os.environ["PYTHONUNBUFFERED"] = "1" global_asn1_print = False global_hexdump = False -class SmbNoNssWbTests(KDCBaseTest): +class SmbMinDomainUid(KDCBaseTest): """Test for SMB authorization based on Kerberos ticket names without NSS winbind and without running winbind daemon. In this scenario smbd will try to match the name in the kerberos ticket to a local unix account. @@ -78,14 +78,6 @@ class SmbNoNssWbTests(KDCBaseTest): self.global_inject = os.path.join(server_conf_dir, "global_inject.conf") def test_min_uid(self): - # Retrieve the user account's SID. - ldb_res = self.samdb.search( - scope=SCOPE_SUBTREE, - expression="(sAMAccountName=%s)" % self.user_name, - attrs=["objectSid"]) - self.assertEqual(1, len(ldb_res)) - sid = ndr_unpack(security.dom_sid, ldb_res[0]["objectSid"][0]) - # Assert unix root uid is less than 'idmap config ADDOMAIN' minimum s3_lp = s3param.get_context() s3_lp.load(self.get_lp().configfile) @@ -96,35 +88,13 @@ class SmbNoNssWbTests(KDCBaseTest): self.assertLess(unix_root_pw.pw_uid, domain_range_low) self.assertLess(unix_root_pw.pw_gid, domain_range_low) - # Connect to a share and retrieve the mapped user SID - 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") - conn = libsmb.Conn(self.mach_name, self.share, lp=s3_lp, creds=self.creds) - - (uid, gid, gids, sids, guest) = conn.posix_whoami() - - # Ensure no guest - self.assertFalse(guest) - - # Ensure SIDs do not match - self.assertNotEqual(sid, sids[0]) - - # Ensure mapped to unix root - self.assertEqual(uid, unix_root_pw.pw_uid) - self.assertEqual(gid, unix_root_pw.pw_gid) - # Disconnect conn = None - # Restrict access to local unix accounts setting min domain uid + # Restrict access to local root account uid with open(self.global_inject, 'w') as f: - f.write("min domain uid = %s\n" % domain_range_low) + 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, @@ -134,6 +104,14 @@ class SmbNoNssWbTests(KDCBaseTest): code = ctypes.c_uint32(cm.exception.args[0]).value self.assertEqual(code, ntstatus.NT_STATUS_ACCESS_DENIED) + # 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=self.creds) + # Disconnect + conn = None + with open(self.global_inject, 'w') as f: f.truncate() diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index b4740207f5cb..36c1b8527c24 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -949,7 +949,7 @@ planoldpythontestsuite("ad_dc_smb1", "samba.tests.krb5.test_smb", 'STRICT_CHECKING': '0' }) planoldpythontestsuite("ad_member_no_nss_wb:local", - "samba.tests.krb5.test_smb_no_nss_wb", + "samba.tests.krb5.test_min_domain_uid", environ={ 'ADMIN_USERNAME': '$DC_USERNAME', 'ADMIN_PASSWORD': '$DC_PASSWORD', -- 2.25.1 From 801cedae324ee289c9b04d16cbca7009ced3838b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Oct 2021 19:56:07 +0200 Subject: [PATCH 08/34] sq python/samba/tests/krb5/test_min_domain_uid.py --- .../samba/tests/krb5/test_min_domain_uid.py | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/python/samba/tests/krb5/test_min_domain_uid.py b/python/samba/tests/krb5/test_min_domain_uid.py index 830b5a30e0a7..5f5298961029 100755 --- a/python/samba/tests/krb5/test_min_domain_uid.py +++ b/python/samba/tests/krb5/test_min_domain_uid.py @@ -30,6 +30,9 @@ 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 +from samba.credentials import DONT_USE_KERBEROS +from samba.credentials import AUTO_USE_KERBEROS sys.path.insert(0, "bin/python") os.environ["PYTHONUNBUFFERED"] = "1" @@ -58,26 +61,12 @@ class SmbMinDomainUid(KDCBaseTest): # Create the user account. (self.user_creds, _) = self.create_account(self.samdb, self.user_name) - # 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. - (self.creds, self.cachefile) = self.create_ccache_with_user( - self.user_creds, self.mach_name, self.service) - - # Set the Kerberos 5 credentials cache environment variable. This is - # required because the codepath that gets run (gse_krb5) looks for it - # in here and not in the credentials object. - krb5_ccname = os.environ.get("KRB5CCNAME", "") - self.addCleanup(os.environ.__setitem__, "KRB5CCNAME", krb5_ccname) - os.environ["KRB5CCNAME"] = "FILE:" + self.cachefile.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): + 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) @@ -88,7 +77,7 @@ class SmbMinDomainUid(KDCBaseTest): 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=self.creds) + conn = libsmb.Conn(self.mach_name, self.share, lp=s3_lp, creds=creds) # Disconnect conn = None @@ -100,28 +89,38 @@ class SmbMinDomainUid(KDCBaseTest): conn = libsmb.Conn(self.mach_name, self.share, lp=s3_lp, - creds=self.creds) + creds=creds) code = ctypes.c_uint32(cm.exception.args[0]).value - self.assertEqual(code, ntstatus.NT_STATUS_ACCESS_DENIED) + self.assertEqual(code, ntstatus.NT_STATUS_AUTHENTICATION_FIREWALL_FAILED) # 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=self.creds) + 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): + self.user_creds.set_kerberos_state(MUST_USE_KERBEROS) + ret = self._test_min_uid(self.user_creds) + self.user_creds.set_kerberos_state(AUTO_USE_KERBEROS) + return ret + + def _test_min_domain_uid_ntlmssp(self): + self.user_creds.set_kerberos_state(DONT_USE_KERBEROS) + ret = self._test_min_uid(self.user_creds) + self.user_creds.set_kerberos_state(AUTO_USE_KERBEROS) + return ret + def tearDown(self): # Ensure no leftovers in global inject file with open(self.global_inject, 'w') as f: f.truncate() - # Remove the cached credentials file. - os.remove(self.cachefile.name) super(KDCBaseTest, self).tearDown() if __name__ == "__main__": -- 2.25.1 From 83dcef0bdb8cf6389f40f3c54a40795527c5a666 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Oct 2021 20:10:16 +0200 Subject: [PATCH 09/34] sq python/samba/tests/krb5/test_min_domain_uid.py --- python/samba/tests/krb5/test_min_domain_uid.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samba/tests/krb5/test_min_domain_uid.py b/python/samba/tests/krb5/test_min_domain_uid.py index 5f5298961029..cf0a9a275b7c 100755 --- a/python/samba/tests/krb5/test_min_domain_uid.py +++ b/python/samba/tests/krb5/test_min_domain_uid.py @@ -91,7 +91,7 @@ class SmbMinDomainUid(KDCBaseTest): lp=s3_lp, creds=creds) code = ctypes.c_uint32(cm.exception.args[0]).value - self.assertEqual(code, ntstatus.NT_STATUS_AUTHENTICATION_FIREWALL_FAILED) + 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: -- 2.25.1 From 5c407f2901a2f39cfc35c3d0edb4515ba016b97b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 11 Oct 2021 08:40:24 +0200 Subject: [PATCH 10/34] sq python/samba/tests/krb5/test_min_domain_uid.py python/samba/tests/usage.py --- python/samba/tests/usage.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py index e97be071a5d0..e3d4c26a88a4 100644 --- a/python/samba/tests/usage.py +++ b/python/samba/tests/usage.py @@ -103,6 +103,7 @@ EXCLUDE_USAGE = { 'python/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py', 'python/samba/tests/krb5/as_req_tests.py', 'python/samba/tests/krb5/fast_tests.py', + 'python/samba/tests/krb5/test_min_domain_uid.py', } EXCLUDE_HELP = { -- 2.25.1 From 267eed51c41207c6ae2c269ae11f908aba5460e1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Oct 2021 19:57:18 +0200 Subject: [PATCH 11/34] auth3_generate_session_info_pac status = nt_status_squash(status) --- source3/auth/auth_generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c index 0e9245fc23dc..41c53cee391e 100644 --- a/source3/auth/auth_generic.c +++ b/source3/auth/auth_generic.c @@ -166,7 +166,7 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n", nt_errstr(status))); - status = NT_STATUS_ACCESS_DENIED; + status = nt_status_squash(status); goto done; } -- 2.25.1 From 8781d43bbc537e5bb4c144931c77a30b72d42fd8 Mon Sep 17 00:00:00 2001 From: Samuel Cabrero Date: Tue, 28 Sep 2021 10:45:11 +0200 Subject: [PATCH 12/34] s3: auth: Check minimum domain uid Signed-off-by: Samuel Cabrero --- selftest/knownfail | 2 -- source3/auth/auth_util.c | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/selftest/knownfail b/selftest/knownfail index 2c23bd724346..94af250d4eb5 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -394,5 +394,3 @@ ^samba.tests.ntlmdisabled.python\(ktest\).ntlmdisabled.NtlmDisabledTests.test_samr_change_password\(ktest\) ^samba.tests.ntlmdisabled.python\(ad_dc_no_ntlm\).ntlmdisabled.NtlmDisabledTests.test_ntlm_connection\(ad_dc_no_ntlm\) -^samba.tests.krb5.test_smb_no_nss_wb.samba.*.SmbNoNssWbTests.test_min_uid\(ad_member_no_nss_wb:local\) - diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 0a1cf4803e4e..a0c31124b96d 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -2117,6 +2117,21 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, } } goto out; + } else if ((lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) && + !is_myname(domain) && pwd->pw_uid < lp_min_domain_uid()) { + /* + * !is_myname(domain) because when smbd starts tries to setup + * the guest user info, calling this function with nobody + * username. Nobody is usually uid 65535 but it can be changed + * to a regular user with 'guest account' parameter + */ + DBG_NOTICE("Username '%s%s%s' is invalid on this system, " + "it does not meet 'min domain uid' " + "restriction (%u < %u)\n", + nt_domain, lp_winbind_separator(), nt_username, + pwd->pw_uid, lp_min_domain_uid()); + nt_status = NT_STATUS_LOGON_FAILURE; + goto out; } result = make_server_info(tmp_ctx); -- 2.25.1 From cd910cb8315c65a2e6c1a45274d706e2823e65b6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Oct 2021 19:56:48 +0200 Subject: [PATCH 13/34] make_server_info_info3 min domain uid --- source3/auth/auth_util.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index a0c31124b96d..c2949a57acdb 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -2125,12 +2125,13 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, * username. Nobody is usually uid 65535 but it can be changed * to a regular user with 'guest account' parameter */ + nt_status = NT_STATUS_AUTHENTICATION_FIREWALL_FAILED; DBG_NOTICE("Username '%s%s%s' is invalid on this system, " "it does not meet 'min domain uid' " - "restriction (%u < %u)\n", + "restriction (%u < %u): %s\n", nt_domain, lp_winbind_separator(), nt_username, - pwd->pw_uid, lp_min_domain_uid()); - nt_status = NT_STATUS_LOGON_FAILURE; + pwd->pw_uid, lp_min_domain_uid(), + nt_errstr(nt_status)); goto out; } -- 2.25.1 From 93a9576ba91f546584845183806e865c52e90282 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Oct 2021 20:10:32 +0200 Subject: [PATCH 14/34] make_server_info_info3 NT_STATUS_INVALID_TOKEN --- source3/auth/auth_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index c2949a57acdb..9ff7256bbed7 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -2125,7 +2125,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, * username. Nobody is usually uid 65535 but it can be changed * to a regular user with 'guest account' parameter */ - nt_status = NT_STATUS_AUTHENTICATION_FIREWALL_FAILED; + nt_status = NT_STATUS_INVALID_TOKEN; DBG_NOTICE("Username '%s%s%s' is invalid on this system, " "it does not meet 'min domain uid' " "restriction (%u < %u): %s\n", -- 2.25.1 From 4906704e09b1018a35277e0fc48d1ae9c73884a7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 5 Oct 2021 16:42:00 +0200 Subject: [PATCH 15/34] selftest/Samba3: replace (winbindd => "yes", skip_wait => 1) with (winbindd => "offline") This is much more flexible and concentrates the logic in a single place. We'll use winbindd => "offline" in other places soon. Signed-off-by: Stefan Metzmacher --- selftest/target/Samba3.pm | 38 ++++++++------------------------------ 1 file changed, 8 insertions(+), 30 deletions(-) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index dde687168d93..fb84e4de5b97 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -928,34 +928,13 @@ sub provision_ad_member # Start winbindd in offline mode if (not $self->check_or_start( env_vars => $ret, - winbindd => "yes", - skip_wait => 1)) { + winbindd => "offline")) { return undef; } # Set socket dir again $ENV{SOCKET_WRAPPER_DIR} = $swrap_env; - print "checking for winbindd\n"; - my $count = 0; - my $rc = 0; - $cmd = "NSS_WRAPPER_PASSWD='$ret->{NSS_WRAPPER_PASSWD}' "; - $cmd .= "NSS_WRAPPER_GROUP='$ret->{NSS_WRAPPER_GROUP}' "; - $cmd .= "SELFTEST_WINBINDD_SOCKET_DIR=\"$ret->{SELFTEST_WINBINDD_SOCKET_DIR}\" "; - $cmd .= "$wbinfo --ping"; - - do { - $rc = system($cmd); - if ($rc != 0) { - sleep(1); - } - $count++; - } while ($rc != 0 && $count < 20); - if ($count == 20) { - print "WINBINDD not reachable after 20 seconds\n"; - teardown_env($self, $ret); - return undef; - } } else { if (defined($no_nss_winbind)) { $ret->{NSS_WRAPPER_MODULE_SO_PATH} = ""; @@ -2171,7 +2150,6 @@ sub check_or_start($$) { my $winbindd = $args{winbindd} // "no"; my $smbd = $args{smbd} // "no"; my $child_cleanup = $args{child_cleanup}; - my $skip_wait = $args{skip_wait} // 0; my $STDIN_READER; @@ -2220,7 +2198,7 @@ sub check_or_start($$) { LOG_FILE => $env_vars->{WINBINDD_TEST_LOG}, PCAP_FILE => "env-$ENV{ENVNAME}-winbindd", }; - if ($winbindd ne "yes") { + if ($winbindd ne "yes" and $winbindd ne "offline") { $daemon_ctx->{SKIP_DAEMON} = 1; } @@ -2256,10 +2234,6 @@ sub check_or_start($$) { # close the parent's read-end of the pipe close($STDIN_READER); - if ($skip_wait) { - return 1; - } - return $self->wait_for_start($env_vars, $nmbd, $winbindd, $smbd); } @@ -3456,13 +3430,17 @@ sub wait_for_start($$$$$) } } - if ($winbindd eq "yes") { + if ($winbindd eq "yes" or $winbindd eq "offline") { print "checking for winbindd\n"; my $count = 0; $cmd = "SELFTEST_WINBINDD_SOCKET_DIR='$envvars->{SELFTEST_WINBINDD_SOCKET_DIR}' "; $cmd .= "NSS_WRAPPER_PASSWD='$envvars->{NSS_WRAPPER_PASSWD}' "; $cmd .= "NSS_WRAPPER_GROUP='$envvars->{NSS_WRAPPER_GROUP}' "; - $cmd .= Samba::bindir_path($self, "wbinfo") . " --ping-dc"; + if ($winbindd eq "yes") { + $cmd .= Samba::bindir_path($self, "wbinfo") . " --ping-dc"; + } elsif ($winbindd eq "offline") { + $cmd .= Samba::bindir_path($self, "wbinfo") . " --ping"; + } do { $ret = system($cmd); -- 2.25.1 From 9ffae7bad0277ccef15f1f563ec10791ac661b2a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 5 Oct 2021 17:14:01 +0200 Subject: [PATCH 16/34] ktest autorid winbindd = offline --- selftest/target/Samba3.pm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index fb84e4de5b97..afefc47bae18 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -1962,6 +1962,10 @@ sub setup_ktest # This disables NTLM auth against the local SAM, which # we use can then test this setting by. ntlm auth = disabled + + idmap config * : backend = autorid + idmap config * : range = 1000000-1999999 + idmap config * : rangesize = 100000 "; my $ret = $self->provision( @@ -2044,6 +2048,7 @@ $ret->{USERNAME} = KTEST\\Administrator if (not $self->check_or_start( env_vars => $ret, nmbd => "yes", + winbindd => "offline", smbd => "yes")) { return undef; } -- 2.25.1 From b080af1d6e200ac1b98617db342c5954c7a5de88 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 5 Oct 2021 18:12:24 +0200 Subject: [PATCH 17/34] ktest #username map script = /bin/echo --- selftest/target/Samba3.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index afefc47bae18..62bb57f270b3 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -1955,6 +1955,7 @@ sub setup_ktest realm = ktest.samba.example.com security = ads username map = $prefix/lib/username.map + #username map script = /bin/echo server signing = required server min protocol = SMB3_00 client max protocol = SMB3 -- 2.25.1 From f7ed65408d306db04e61fb66f443ce735b1ecf27 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Oct 2021 20:29:07 +0200 Subject: [PATCH 18/34] Revert "ktest #username map script = /bin/echo" This reverts commit 75cd8b01a3727c940d0fa416f033ab5931d8110c. --- selftest/target/Samba3.pm | 1 - 1 file changed, 1 deletion(-) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 62bb57f270b3..afefc47bae18 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -1955,7 +1955,6 @@ sub setup_ktest realm = ktest.samba.example.com security = ads username map = $prefix/lib/username.map - #username map script = /bin/echo server signing = required server min protocol = SMB3_00 client max protocol = SMB3 -- 2.25.1 From 936199787c8cbcf74c57c7dedd8f3d978c6262db Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 5 Oct 2021 17:14:38 +0200 Subject: [PATCH 19/34] ktest no username map --- selftest/target/Samba3.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index afefc47bae18..6dc5bfa9a6b5 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -1954,7 +1954,7 @@ sub setup_ktest workgroup = KTEST realm = ktest.samba.example.com security = ads - username map = $prefix/lib/username.map + #username map = $prefix/lib/username.map server signing = required server min protocol = SMB3_00 client max protocol = SMB3 -- 2.25.1 From 2001403505e80781ec2adff562adab1e050240c0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Oct 2021 17:40:30 +0200 Subject: [PATCH 20/34] s3:auth: we should not try to autocreate the guest account Signed-off-by: Stefan Metzmacher --- source3/auth/user_krb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/auth/user_krb5.c b/source3/auth/user_krb5.c index 8998f9c8f8ae..074e8c7eb711 100644 --- a/source3/auth/user_krb5.c +++ b/source3/auth/user_krb5.c @@ -155,7 +155,7 @@ NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx, if (!fuser) { return NT_STATUS_NO_MEMORY; } - pw = smb_getpwnam(mem_ctx, fuser, &unixuser, true); + pw = smb_getpwnam(mem_ctx, fuser, &unixuser, false); } /* extra sanity check that the guest account is valid */ -- 2.25.1 From 63f11eb239e270fa226efab11aee812f341783c8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Oct 2021 18:08:20 +0200 Subject: [PATCH 21/34] check_account don't autocreate local users --- source3/auth/auth_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 9ff7256bbed7..af76eaad5fe1 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -1912,7 +1912,7 @@ static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain, return NT_STATUS_NO_MEMORY; } - passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, true ); + passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, false ); if (!passwd) { DEBUG(3, ("Failed to find authenticated user %s via " "getpwnam(), denying access.\n", dom_user)); -- 2.25.1 From cbe8323384680bd3101c26308a9439a9de4759db Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 8 Oct 2021 12:33:16 +0200 Subject: [PATCH 22/34] smb_getpwnam() no fallback for domain users WIP --- source3/auth/auth_util.c | 69 ++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index af76eaad5fe1..3c3444707979 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -1947,7 +1947,7 @@ struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser, { struct passwd *pw = NULL; char *p = NULL; - char *username = NULL; + const char *username = NULL; /* we only save a copy of the username it has been mangled by winbindd use default domain */ @@ -1966,48 +1966,47 @@ struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser, /* code for a DOMAIN\user string */ if ( p ) { - pw = Get_Pwnam_alloc( mem_ctx, domuser ); - if ( pw ) { - /* make sure we get the case of the username correct */ - /* work around 'winbind use default domain = yes' */ - - if ( lp_winbind_use_default_domain() && - !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) { - char *domain; - - /* split the domain and username into 2 strings */ - *p = '\0'; - domain = username; - - *p_save_username = talloc_asprintf(mem_ctx, - "%s%c%s", - domain, - *lp_winbind_separator(), - pw->pw_name); - if (!*p_save_username) { - TALLOC_FREE(pw); - return NULL; - } - } else { - *p_save_username = talloc_strdup(mem_ctx, pw->pw_name); - } + const char *domain = NULL; - /* whew -- done! */ - return pw; - } + /* split the domain and username into 2 strings */ + *p = '\0'; + domain = username; + p++; + username = p; - /* setup for lookup of just the username */ - /* remember that p and username are overlapping memory */ + if (strequal(domain, get_global_sam_name())) { + goto username_only; + } - p++; - username = talloc_strdup(mem_ctx, p); - if (!username) { + pw = Get_Pwnam_alloc( mem_ctx, domuser ); + if (pw == NULL) { return NULL; } + /* make sure we get the case of the username correct */ + /* work around 'winbind use default domain = yes' */ + + if ( lp_winbind_use_default_domain() && + !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) { + *p_save_username = talloc_asprintf(mem_ctx, + "%s%c%s", + domain, + *lp_winbind_separator(), + pw->pw_name); + if (!*p_save_username) { + TALLOC_FREE(pw); + return NULL; + } + } else { + *p_save_username = talloc_strdup(mem_ctx, pw->pw_name); + } + + /* whew -- done! */ + return pw; + } /* just lookup a plain username */ - +username_only: pw = Get_Pwnam_alloc(mem_ctx, username); /* Create local user if requested but only if winbindd -- 2.25.1 From d728b764433a21921dac419645c58ab009de0ef6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 21 Sep 2021 12:27:28 +0200 Subject: [PATCH 23/34] s3:ntlm_auth: fix memory leaks in ntlm_auth_generate_session_info_pac() Signed-off-by: Stefan Metzmacher --- source3/utils/ntlm_auth.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index f887d6814d0d..89662e82f567 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -818,23 +818,27 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c if (!p) { DEBUG(3, ("[%s] Doesn't look like a valid principal\n", princ_name)); - return NT_STATUS_LOGON_FAILURE; + status = NT_STATUS_LOGON_FAILURE; + goto done; } user = talloc_strndup(mem_ctx, princ_name, p - princ_name); if (!user) { - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto done; } realm = talloc_strdup(talloc_tos(), p + 1); if (!realm) { - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto done; } if (!strequal(realm, lp_realm())) { DEBUG(3, ("Ticket for foreign realm %s@%s\n", user, realm)); if (!lp_allow_trusted_domains()) { - return NT_STATUS_LOGON_FAILURE; + status = NT_STATUS_LOGON_FAILURE; + goto done; } } @@ -842,7 +846,8 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c domain = talloc_strdup(mem_ctx, logon_info->info3.base.logon_domain.string); if (!domain) { - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto done; } DEBUG(10, ("Domain is [%s] (using PAC)\n", domain)); } else { @@ -872,7 +877,8 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c domain = talloc_strdup(mem_ctx, realm); } if (!domain) { - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto done; } DEBUG(10, ("Domain is [%s] (using Winbind)\n", domain)); } -- 2.25.1 From 67810f7bb135c0980eabcd780baa300f3a076065 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 21 Sep 2021 12:44:01 +0200 Subject: [PATCH 24/34] s3:ntlm_auth: let ntlm_auth_generate_session_info_pac() base the name on the PAC LOGON_INFO only Signed-off-by: Stefan Metzmacher --- source3/utils/ntlm_auth.c | 91 ++++++++++++--------------------------- 1 file changed, 28 insertions(+), 63 deletions(-) diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 89662e82f567..1d0922d4eb3d 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -790,10 +790,8 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c struct PAC_LOGON_INFO *logon_info = NULL; char *unixuser; NTSTATUS status; - char *domain = NULL; - char *realm = NULL; - char *user = NULL; - char *p; + const char *domain = ""; + const char *user = ""; tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) { @@ -810,79 +808,46 @@ static NTSTATUS ntlm_auth_generate_session_info_pac(struct auth4_context *auth_c if (!NT_STATUS_IS_OK(status)) { goto done; } - } - - DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name)); - - p = strchr_m(princ_name, '@'); - if (!p) { - DEBUG(3, ("[%s] Doesn't look like a valid principal\n", - princ_name)); - status = NT_STATUS_LOGON_FAILURE; + } else { + status = NT_STATUS_ACCESS_DENIED; + DBG_WARNING("Kerberos ticket for[%s] has no PAC: %s\n", + princ_name, nt_errstr(status)); goto done; } - user = talloc_strndup(mem_ctx, princ_name, p - princ_name); - if (!user) { - status = NT_STATUS_NO_MEMORY; - goto done; + if (logon_info->info3.base.account_name.string != NULL) { + user = logon_info->info3.base.account_name.string; + } else { + user = ""; + } + if (logon_info->info3.base.logon_domain.string != NULL) { + domain = logon_info->info3.base.logon_domain.string; + } else { + domain = ""; } - realm = talloc_strdup(talloc_tos(), p + 1); - if (!realm) { - status = NT_STATUS_NO_MEMORY; + if (strlen(user) == 0 || strlen(domain) == 0) { + status = NT_STATUS_ACCESS_DENIED; + DBG_WARNING("Kerberos ticket for[%s] has invalid " + "account_name[%s]/logon_domain[%s]: %s\n", + princ_name, + logon_info->info3.base.account_name.string, + logon_info->info3.base.logon_domain.string, + nt_errstr(status)); goto done; } - if (!strequal(realm, lp_realm())) { - DEBUG(3, ("Ticket for foreign realm %s@%s\n", user, realm)); + DBG_NOTICE("Kerberos ticket principal name is [%s] " + "account_name[%s]/logon_domain[%s]\n", + princ_name, user, domain); + + if (!strequal(domain, lp_workgroup())) { if (!lp_allow_trusted_domains()) { status = NT_STATUS_LOGON_FAILURE; goto done; } } - if (logon_info && logon_info->info3.base.logon_domain.string) { - domain = talloc_strdup(mem_ctx, - logon_info->info3.base.logon_domain.string); - if (!domain) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - DEBUG(10, ("Domain is [%s] (using PAC)\n", domain)); - } else { - - /* If we have winbind running, we can (and must) shorten the - username by using the short netbios name. Otherwise we will - have inconsistent user names. With Kerberos, we get the - fully qualified realm, with ntlmssp we get the short - name. And even w2k3 does use ntlmssp if you for example - connect to an ip address. */ - - wbcErr wbc_status; - struct wbcDomainInfo *info = NULL; - - DEBUG(10, ("Mapping [%s] to short name using winbindd\n", - realm)); - - wbc_status = wbcDomainInfo(realm, &info); - - if (WBC_ERROR_IS_OK(wbc_status)) { - domain = talloc_strdup(mem_ctx, - info->short_name); - wbcFreeMemory(info); - } else { - DEBUG(3, ("Could not find short name: %s\n", - wbcErrorString(wbc_status))); - domain = talloc_strdup(mem_ctx, realm); - } - if (!domain) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - DEBUG(10, ("Domain is [%s] (using Winbind)\n", domain)); - } - unixuser = talloc_asprintf(tmp_ctx, "%s%c%s", domain, winbind_separator(), user); if (!unixuser) { status = NT_STATUS_NO_MEMORY; -- 2.25.1 From cedbf14b8d5b7d85f452796a7d8b5484ae784874 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 21 Sep 2021 13:13:52 +0200 Subject: [PATCH 25/34] s3:lib: add lp_allow_trusted_domains() logic to is_allowed_domain() is_allowed_domain() is a central place we already use to trigger NT_STATUS_AUTHENTICATION_FIREWALL_FAILED, so we can add additional logic there. Signed-off-by: Stefan Metzmacher --- source3/lib/util_names.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/source3/lib/util_names.c b/source3/lib/util_names.c index f0e9f699f29f..b62ddb302c6d 100644 --- a/source3/lib/util_names.c +++ b/source3/lib/util_names.c @@ -69,5 +69,18 @@ bool is_allowed_domain(const char *domain_name) } } - return true; + if (lp_allow_trusted_domains()) { + return true; + } + + if (strequal(lp_workgroup(), domain_name)) { + return true; + } + + if (is_myname(domain_name)) { + return true; + } + + DBG_NOTICE("Not trusted domain '%s'\n", domain_name); + return false; } -- 2.25.1 From 45a6c9eb2330fc78ccb271e2b3304d4badd0772d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 4 Oct 2021 17:29:34 +0200 Subject: [PATCH 26/34] s3:winbindd: make sure winbind_SamLogon() defaults to r->out.authoritative = true --- source3/winbindd/winbindd_dual_srv.c | 7 +++++++ source3/winbindd/winbindd_irpc.c | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index 32d11e1fa57d..0be5ae5554bd 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -941,6 +941,13 @@ NTSTATUS _winbind_SamLogon(struct pipes_struct *p, union netr_Validation *validation = NULL; bool interactive = false; + /* + * Make sure we start with authoritative=true, + * it will only set to false if we don't know the + * domain. + */ + r->out.authoritative = true; + domain = wb_child_domain(); if (domain == NULL) { return NT_STATUS_REQUEST_NOT_ACCEPTED; diff --git a/source3/winbindd/winbindd_irpc.c b/source3/winbindd/winbindd_irpc.c index e419736010b8..918393c08277 100644 --- a/source3/winbindd/winbindd_irpc.c +++ b/source3/winbindd/winbindd_irpc.c @@ -142,6 +142,13 @@ static NTSTATUS wb_irpc_SamLogon(struct irpc_message *msg, const char *target_domain_name = NULL; const char *account_name = NULL; + /* + * Make sure we start with authoritative=true, + * it will only set to false if we don't know the + * domain. + */ + req->out.authoritative = true; + switch (req->in.logon_level) { case NetlogonInteractiveInformation: case NetlogonServiceInformation: -- 2.25.1 From 9cacfbad0adcf178f058645a0f1c2e67fb87f859 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 4 Oct 2021 18:03:55 +0200 Subject: [PATCH 27/34] create_local_token no !winbind_ping() --- source3/auth/auth_util.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 3c3444707979..88737c705ea6 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -570,13 +570,11 @@ NTSTATUS create_local_token(TALLOC_CTX *mem_ctx, } /* - * If winbind is not around, we can not make much use of the SIDs the - * domain controller provided us with. Likewise if the user name was - * mapped to some local unix user. + * If the user name was mapped to some local unix user, + * we can not make much use of the SIDs the + * domain controller provided us with. */ - - if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) || - (server_info->nss_token)) { + if (server_info->nss_token) { char *found_username = NULL; status = create_token_from_username(session_info, server_info->unix_name, -- 2.25.1 From 3f6de610f2a7b6bad53ddccc184c4cbf182912da Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 5 Oct 2021 18:11:57 +0200 Subject: [PATCH 28/34] gensec:require_pac = true --- auth/gensec/gensec_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auth/gensec/gensec_util.c b/auth/gensec/gensec_util.c index e411751c3af2..aa03472603c8 100644 --- a/auth/gensec/gensec_util.c +++ b/auth/gensec/gensec_util.c @@ -48,7 +48,7 @@ NTSTATUS gensec_generate_session_info_pac(TALLOC_CTX *mem_ctx, session_info_flags |= AUTH_SESSION_INFO_DEFAULT_GROUPS; if (!pac_blob) { - if (gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", false)) { + if (gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", true)) { DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access\n", principal_string)); return NT_STATUS_ACCESS_DENIED; -- 2.25.1 From 2bd2c0cdb9ac0edf5405a5136660ac25367b2fd1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 4 Oct 2021 19:42:20 +0200 Subject: [PATCH 29/34] auth3_generate_session_info_pac make_server_info_wbcAuthUserInfo --- source3/auth/auth_generic.c | 109 +++++++++++++++++++++++++++++------- 1 file changed, 89 insertions(+), 20 deletions(-) diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c index 41c53cee391e..dc7ac81c0f1b 100644 --- a/source3/auth/auth_generic.c +++ b/source3/auth/auth_generic.c @@ -54,21 +54,33 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, char *ntuser; char *ntdomain; char *username; - char *rhost; + const char *rhost; struct passwd *pw; NTSTATUS status; - int rc; tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) { return NT_STATUS_NO_MEMORY; } + if (tsocket_address_is_inet(remote_address, "ip")) { + rhost = tsocket_address_inet_addr_string( + remote_address, tmp_ctx); + if (rhost == NULL) { + status = NT_STATUS_NO_MEMORY; + goto done; + } + } else { + rhost = "127.0.0.1"; + } + if (pac_blob) { -#ifdef HAVE_KRB5 struct wbcAuthUserParams params = { 0 }; struct wbcAuthUserInfo *info = NULL; struct wbcAuthErrorInfo *err = NULL; + struct auth_serversupplied_info *server_info = NULL; + char *original_user_name = NULL; + char *p = NULL; wbcErr wbc_err; /* @@ -87,6 +99,7 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, params.password.pac.data = pac_blob->data; params.password.pac.length = pac_blob->length; + /* we are contacting the privileged pipe */ become_root(); wbc_err = wbcAuthenticateUserEx(¶ms, &info, &err); unbecome_root(); @@ -99,18 +112,90 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, */ switch (wbc_err) { - case WBC_ERR_WINBIND_NOT_AVAILABLE: case WBC_ERR_SUCCESS: break; + case WBC_ERR_WINBIND_NOT_AVAILABLE: + if (lp_server_role() == ROLE_DOMAIN_MEMBER) { + status = NT_STATUS_NO_LOGON_SERVERS; + DBG_ERR("winbindd not running - " + "but required as domain member: %s\n", + nt_errstr(status)); + goto done; + } + goto legacy; case WBC_ERR_AUTH_ERROR: status = NT_STATUS(err->nt_status); wbcFreeMemory(err); goto done; + case WBC_ERR_NO_MEMORY: + status = NT_STATUS_NO_MEMORY; + goto done; default: status = NT_STATUS_LOGON_FAILURE; goto done; } + status = make_server_info_wbcAuthUserInfo(mem_ctx, + info->account_name, + info->domain_name, + info, &server_info); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("make_server_info_wbcAuthUserInfo failed: %s\n", + nt_errstr(status))); + goto done; + } + + /* We skip doing this step if the caller asked us not to */ + if (!(server_info->guest)) { + const char *unix_username = server_info->unix_name; + + /* We might not be root if we are an RPC call */ + become_root(); + status = smb_pam_accountcheck(unix_username, rhost); + unbecome_root(); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("check_ntlm_password: PAM Account for user [%s] " + "FAILED with error %s\n", + unix_username, nt_errstr(status))); + goto done; + } + + DEBUG(5, ("check_ntlm_password: PAM Account for user [%s] " + "succeeded\n", unix_username)); + } + + DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name)); + + p = strchr_m(princ_name, '@'); + if (!p) { + DEBUG(3, ("[%s] Doesn't look like a valid principal\n", + princ_name)); + status = NT_STATUS_LOGON_FAILURE; + goto done; + } + + original_user_name = talloc_strndup(tmp_ctx, princ_name, p - princ_name); + if (original_user_name == NULL) { + status = NT_STATUS_NO_MEMORY; + goto done; + } + + status = create_local_token(mem_ctx, + server_info, + NULL, + original_user_name, + session_info); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("create_local_token failed: %s\n", + nt_errstr(status))); + goto done; + } + + status = NT_STATUS_OK; + goto done; +legacy: +#ifdef HAVE_KRB5 status = kerberos_pac_logon_info(tmp_ctx, *pac_blob, NULL, NULL, NULL, NULL, 0, &logon_info); #else @@ -121,22 +206,6 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, } } - rc = get_remote_hostname(remote_address, - &rhost, - tmp_ctx); - if (rc < 0) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - if (strequal(rhost, "UNKNOWN")) { - rhost = tsocket_address_inet_addr_string(remote_address, - tmp_ctx); - if (rhost == NULL) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - } - status = get_user_from_kerberos_info(tmp_ctx, rhost, princ_name, logon_info, &is_mapped, &is_guest, -- 2.25.1 From 9247285f515d39ab2789107d930fb557d4291a43 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 5 Oct 2021 18:12:49 +0200 Subject: [PATCH 30/34] auth3_generate_session_info_pac remove legacy --- source3/auth/auth_generic.c | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c index dc7ac81c0f1b..dbed3f19f66c 100644 --- a/source3/auth/auth_generic.c +++ b/source3/auth/auth_generic.c @@ -47,8 +47,6 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, struct auth_session_info **session_info) { TALLOC_CTX *tmp_ctx; - struct PAC_LOGON_INFO *logon_info = NULL; - struct netr_SamInfo3 *info3_copy = NULL; bool is_mapped; bool is_guest; char *ntuser; @@ -122,7 +120,8 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, nt_errstr(status)); goto done; } - goto legacy; + status = NT_STATUS_ACCESS_DENIED; + goto done; case WBC_ERR_AUTH_ERROR: status = NT_STATUS(err->nt_status); wbcFreeMemory(err); @@ -194,20 +193,18 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, status = NT_STATUS_OK; goto done; -legacy: -#ifdef HAVE_KRB5 - status = kerberos_pac_logon_info(tmp_ctx, *pac_blob, NULL, NULL, - NULL, NULL, 0, &logon_info); -#else - status = NT_STATUS_ACCESS_DENIED; -#endif - if (!NT_STATUS_IS_OK(status)) { - goto done; - } } + if (lp_server_role() != ROLE_STANDALONE) { + status = NT_STATUS_NO_LOGON_SERVERS; + DBG_ERR("winbindd not running - " + "but required as domain member: %s\n", + nt_errstr(status)); + goto done; + } + status = get_user_from_kerberos_info(tmp_ctx, rhost, - princ_name, logon_info, + princ_name, NULL, &is_mapped, &is_guest, &ntuser, &ntdomain, &username, &pw); @@ -218,19 +215,9 @@ legacy: goto done; } - /* Get the info3 from the PAC data if we have it */ - if (logon_info) { - status = create_info3_from_pac_logon_info(tmp_ctx, - logon_info, - &info3_copy); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - } - status = make_session_info_krb5(mem_ctx, ntuser, ntdomain, username, pw, - info3_copy, is_guest, is_mapped, NULL /* No session key for now, caller will sort it out */, + NULL, is_guest, is_mapped, NULL /* No session key for now, caller will sort it out */, session_info); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n", -- 2.25.1 From 7a942772456d928eb1f6a1a8b3cec4353f319b06 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Oct 2021 17:59:59 +0200 Subject: [PATCH 31/34] get_user_from_kerberos_info no logon_info no winbind --- source3/auth/auth_generic.c | 2 +- source3/auth/proto.h | 1 - source3/auth/user_krb5.c | 57 +++++++------------------------------ 3 files changed, 11 insertions(+), 49 deletions(-) diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c index dbed3f19f66c..d800c786ce1f 100644 --- a/source3/auth/auth_generic.c +++ b/source3/auth/auth_generic.c @@ -204,7 +204,7 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, } status = get_user_from_kerberos_info(tmp_ctx, rhost, - princ_name, NULL, + princ_name, &is_mapped, &is_guest, &ntuser, &ntdomain, &username, &pw); diff --git a/source3/auth/proto.h b/source3/auth/proto.h index 036d4004c382..596cbd68a7f5 100644 --- a/source3/auth/proto.h +++ b/source3/auth/proto.h @@ -417,7 +417,6 @@ struct PAC_LOGON_INFO; NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx, const char *cli_name, const char *princ_name, - struct PAC_LOGON_INFO *logon_info, bool *is_mapped, bool *mapped_to_guest, char **ntuser, diff --git a/source3/auth/user_krb5.c b/source3/auth/user_krb5.c index 074e8c7eb711..7b69ca6c222e 100644 --- a/source3/auth/user_krb5.c +++ b/source3/auth/user_krb5.c @@ -31,7 +31,6 @@ NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx, const char *cli_name, const char *princ_name, - struct PAC_LOGON_INFO *logon_info, bool *is_mapped, bool *mapped_to_guest, char **ntuser, @@ -40,8 +39,8 @@ NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx, struct passwd **_pw) { NTSTATUS status; - char *domain = NULL; - char *realm = NULL; + const char *domain = NULL; + const char *realm = NULL; char *user = NULL; char *p; char *fuser = NULL; @@ -62,55 +61,16 @@ NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } - realm = talloc_strdup(talloc_tos(), p + 1); - if (!realm) { - return NT_STATUS_NO_MEMORY; - } + realm = p + 1; if (!strequal(realm, lp_realm())) { DEBUG(3, ("Ticket for foreign realm %s@%s\n", user, realm)); if (!lp_allow_trusted_domains()) { return NT_STATUS_LOGON_FAILURE; } - } - - if (logon_info && logon_info->info3.base.logon_domain.string) { - domain = talloc_strdup(mem_ctx, - logon_info->info3.base.logon_domain.string); - if (!domain) { - return NT_STATUS_NO_MEMORY; - } - DEBUG(10, ("Domain is [%s] (using PAC)\n", domain)); + domain = realm; } else { - - /* If we have winbind running, we can (and must) shorten the - username by using the short netbios name. Otherwise we will - have inconsistent user names. With Kerberos, we get the - fully qualified realm, with ntlmssp we get the short - name. And even w2k3 does use ntlmssp if you for example - connect to an ip address. */ - - wbcErr wbc_status; - struct wbcDomainInfo *info = NULL; - - DEBUG(10, ("Mapping [%s] to short name using winbindd\n", - realm)); - - wbc_status = wbcDomainInfo(realm, &info); - - if (WBC_ERROR_IS_OK(wbc_status)) { - domain = talloc_strdup(mem_ctx, - info->short_name); - wbcFreeMemory(info); - } else { - DEBUG(3, ("Could not find short name: %s\n", - wbcErrorString(wbc_status))); - domain = talloc_strdup(mem_ctx, realm); - } - if (!domain) { - return NT_STATUS_NO_MEMORY; - } - DEBUG(10, ("Domain is [%s] (using Winbind)\n", domain)); + domain = lp_workgroup(); } fuser = talloc_asprintf(mem_ctx, @@ -175,7 +135,11 @@ NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } *ntuser = user; - *ntdomain = domain; + *ntdomain = talloc_strdup(mem_ctx, domain); + if (*ntdomain == NULL) { + return NT_STATUS_NO_MEMORY; + } + *_pw = pw; return NT_STATUS_OK; @@ -282,7 +246,6 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx, NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx, const char *cli_name, const char *princ_name, - struct PAC_LOGON_INFO *logon_info, bool *is_mapped, bool *mapped_to_guest, char **ntuser, -- 2.25.1 From a61399690348b84874c6d55338588625833bfddf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 8 Oct 2021 18:03:04 +0200 Subject: [PATCH 32/34] make_session_info_krb5 no info3 no session key --- source3/auth/auth_generic.c | 2 +- source3/auth/proto.h | 2 -- source3/auth/user_krb5.c | 20 +------------------- 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c index d800c786ce1f..41c1a71bcdcf 100644 --- a/source3/auth/auth_generic.c +++ b/source3/auth/auth_generic.c @@ -217,7 +217,7 @@ static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, status = make_session_info_krb5(mem_ctx, ntuser, ntdomain, username, pw, - NULL, is_guest, is_mapped, NULL /* No session key for now, caller will sort it out */, + is_guest, is_mapped, session_info); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n", diff --git a/source3/auth/proto.h b/source3/auth/proto.h index 596cbd68a7f5..9bffce7a8088 100644 --- a/source3/auth/proto.h +++ b/source3/auth/proto.h @@ -428,9 +428,7 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx, char *ntdomain, char *username, struct passwd *pw, - const struct netr_SamInfo3 *info3, bool mapped_to_guest, bool username_was_mapped, - DATA_BLOB *session_key, struct auth_session_info **session_info); /* The following definitions come from auth/auth_samba4.c */ diff --git a/source3/auth/user_krb5.c b/source3/auth/user_krb5.c index 7b69ca6c222e..b8f37cbeee05 100644 --- a/source3/auth/user_krb5.c +++ b/source3/auth/user_krb5.c @@ -150,9 +150,7 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx, char *ntdomain, char *username, struct passwd *pw, - const struct netr_SamInfo3 *info3, bool mapped_to_guest, bool username_was_mapped, - DATA_BLOB *session_key, struct auth_session_info **session_info) { NTSTATUS status; @@ -166,20 +164,6 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx, return status; } - } else if (info3) { - /* pass the unmapped username here since map_username() - will be called again in make_server_info_info3() */ - - status = make_server_info_info3(mem_ctx, - ntuser, ntdomain, - &server_info, - info3); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("make_server_info_info3 failed: %s!\n", - nt_errstr(status))); - return status; - } - } else { /* * We didn't get a PAC, we have to make up the user @@ -231,7 +215,7 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx, server_info->nss_token |= username_was_mapped; - status = create_local_token(mem_ctx, server_info, session_key, ntuser, session_info); + status = create_local_token(mem_ctx, server_info, NULL, ntuser, session_info); talloc_free(server_info); if (!NT_STATUS_IS_OK(status)) { DEBUG(10,("failed to create local token: %s\n", @@ -261,9 +245,7 @@ NTSTATUS make_session_info_krb5(TALLOC_CTX *mem_ctx, char *ntdomain, char *username, struct passwd *pw, - const struct netr_SamInfo3 *info3, bool mapped_to_guest, bool username_was_mapped, - DATA_BLOB *session_key, struct auth_session_info **session_info) { return NT_STATUS_NOT_IMPLEMENTED; -- 2.25.1 From 947df52883e8be15565b684754311a86edf75911 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 11 Oct 2021 23:17:19 +0200 Subject: [PATCH 33/34] auth_generate_session_info_principal NT_STATUS_NO_IMPERSONATION_TOKEN --- source4/auth/auth.h | 8 ------- source4/auth/ntlm/auth.c | 45 +----------------------------------- source4/auth/ntlm/auth_sam.c | 12 ---------- 3 files changed, 1 insertion(+), 64 deletions(-) diff --git a/source4/auth/auth.h b/source4/auth/auth.h index 3f9fb1ae3cbc..6b7db99cbe2d 100644 --- a/source4/auth/auth.h +++ b/source4/auth/auth.h @@ -69,14 +69,6 @@ struct auth_operations { TALLOC_CTX *mem_ctx, struct auth_user_info_dc **interim_info, bool *authoritative); - - /* Lookup a 'session info interim' return based only on the principal or DN */ - NTSTATUS (*get_user_info_dc_principal)(TALLOC_CTX *mem_ctx, - struct auth4_context *auth_context, - const char *principal, - struct ldb_dn *user_dn, - struct auth_user_info_dc **interim_info); - uint32_t flags; }; struct auth_method_context { diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c index e54eb7719f57..25d5b5f5a76d 100644 --- a/source4/auth/ntlm/auth.c +++ b/source4/auth/ntlm/auth.c @@ -86,48 +86,6 @@ _PUBLIC_ NTSTATUS auth_get_challenge(struct auth4_context *auth_ctx, uint8_t cha return NT_STATUS_OK; } -/**************************************************************************** -Used in the gensec_gssapi and gensec_krb5 server-side code, where the -PAC isn't available, and for tokenGroups in the DSDB stack. - - Supply either a principal or a DN -****************************************************************************/ -static NTSTATUS auth_generate_session_info_principal(struct auth4_context *auth_ctx, - TALLOC_CTX *mem_ctx, - const char *principal, - struct ldb_dn *user_dn, - uint32_t session_info_flags, - struct auth_session_info **session_info) -{ - NTSTATUS nt_status; - struct auth_method_context *method; - struct auth_user_info_dc *user_info_dc; - - for (method = auth_ctx->methods; method; method = method->next) { - if (!method->ops->get_user_info_dc_principal) { - continue; - } - - nt_status = method->ops->get_user_info_dc_principal(mem_ctx, auth_ctx, principal, user_dn, &user_info_dc); - if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) { - continue; - } - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - nt_status = auth_generate_session_info_wrapper(auth_ctx, mem_ctx, - user_info_dc, - user_info_dc->info->account_name, - session_info_flags, session_info); - talloc_free(user_info_dc); - - return nt_status; - } - - return NT_STATUS_NOT_IMPLEMENTED; -} - /** * Check a user's Plaintext, LM or NTLM password. * (sync version) @@ -622,8 +580,7 @@ static NTSTATUS auth_generate_session_info_pac(struct auth4_context *auth_ctx, TALLOC_CTX *tmp_ctx; if (!pac_blob) { - return auth_generate_session_info_principal(auth_ctx, mem_ctx, principal_name, - NULL, session_info_flags, session_info); + return NT_STATUS_NO_IMPERSONATION_TOKEN; } tmp_ctx = talloc_named(mem_ctx, 0, "gensec_gssapi_session_info context"); diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c index a521bc94bc4a..dbbf97665db3 100644 --- a/source4/auth/ntlm/auth_sam.c +++ b/source4/auth/ntlm/auth_sam.c @@ -938,22 +938,11 @@ static NTSTATUS authsam_want_check(struct auth_method_context *ctx, return NT_STATUS_OK; } -/* Wrapper for the auth subsystem pointer */ -static NTSTATUS authsam_get_user_info_dc_principal_wrapper(TALLOC_CTX *mem_ctx, - struct auth4_context *auth_context, - const char *principal, - struct ldb_dn *user_dn, - struct auth_user_info_dc **user_info_dc) -{ - return authsam_get_user_info_dc_principal(mem_ctx, auth_context->lp_ctx, auth_context->sam_ctx, - principal, user_dn, user_info_dc); -} static const struct auth_operations sam_ignoredomain_ops = { .name = "sam_ignoredomain", .want_check = authsam_ignoredomain_want_check, .check_password_send = authsam_check_password_send, .check_password_recv = authsam_check_password_recv, - .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper, }; static const struct auth_operations sam_ops = { @@ -961,7 +950,6 @@ static const struct auth_operations sam_ops = { .want_check = authsam_want_check, .check_password_send = authsam_check_password_send, .check_password_recv = authsam_check_password_recv, - .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper, }; _PUBLIC_ NTSTATUS auth4_sam_init(TALLOC_CTX *); -- 2.25.1 From fd882960d1285becde6fadc8ef09acfdff0f6d4e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 11 Oct 2021 23:18:41 +0200 Subject: [PATCH 34/34] gensec:require_pac=yes NT_STATUS_NO_IMPERSONATION_TOKEN --- auth/gensec/gensec_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auth/gensec/gensec_util.c b/auth/gensec/gensec_util.c index aa03472603c8..c67091fe96a7 100644 --- a/auth/gensec/gensec_util.c +++ b/auth/gensec/gensec_util.c @@ -51,7 +51,7 @@ NTSTATUS gensec_generate_session_info_pac(TALLOC_CTX *mem_ctx, if (gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", true)) { DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access\n", principal_string)); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_NO_IMPERSONATION_TOKEN; } DBG_NOTICE("Unable to find PAC for %s, resorting to local " "user lookup\n", principal_string); -- 2.25.1