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

Karolin Seeger kseeger at samba.org
Wed Jan 27 17:07:01 UTC 2021


The branch, v4-14-test has been updated
       via  99673b77b06 s3:idmap_hash: reliable return ID_TYPE_BOTH
       via  fcc6a32e069 smbd: use fsp->conn->session_info for the initial delete-on-close token
       via  4bfdc4eff93 selftest: add a test that verifies unlink works when "force user" is set
       via  4c9cf755eb2 selftest: add force_user_error_inject share in maptoguest env
       via  d5a696fc886 vfs_error_inject: add unlinkat hook
       via  5041731ca02 s3/auth: implement "winbind:ignore domains"
       via  77f07ddb8ee winbind: check for allowed domains in winbindd_pam_auth_pac_verify()
       via  9b717968bd7 winbind: check for allowed domains in winbindd_dual_pam_chauthtok()
       via  647d1ca5e79 winbind: check for allowed domains in winbindd_dual_pam_chng_pswd_auth_crap()
       via  ccc4efd5211 winbind: check for allowed domains in winbindd_dual_pam_auth_crap()
       via  56076c98dbb winbind: check for allowed domains in winbindd_dual_pam_auth()
       via  4f69adab43c winbind: move "winbind:ignore domain" logic to a seperate function
       via  bee8a1cb9e9 selftest: add a test for "winbind:ignore domains"
       via  115c987aa58 winbind: handle MSG_SMB_CONF_UPDATED in the winbinds children
       via  4df20674da1 winbind: set logfile after reloading config
       via  9e797518fb5 winbind: move config-reloading code to winbindd_dual.c
       via  835fd283fec selftest: use correct DNS domain name for wrapper hosts file
      from  c74fc2ab69a VERSION: Bump version up to 4.14.0rc2...

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


- Log -----------------------------------------------------------------
commit 99673b77b069674a6145552eb870de8829dfa503
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Oct 23 12:21:57 2020 +0200

    s3:idmap_hash: reliable return ID_TYPE_BOTH
    
    idmap_hash used to bounce back the requested type,
    which was ID_TYPE_UID, ID_TYPE_GID or ID_TYPE_NOT_SPECIFIED
    before as the winbindd parent always used a lookupsids.
    When the lookupsids failed because of an unknown domain,
    the idmap child weren't requested at all and the caller
    sees ID_TYPE_NOT_SPECIFIED.
    
    This module should have supported ID_TYPE_BOTH since
    samba-4.1.0, similar to idmap_rid and idmap_autorid.
    
    Now that the winbindd parent will pass ID_TYPE_BOTH in order to
    indicate that the domain exists, it's better to always return
    ID_TYPE_BOTH instead of a random mix of ID_TYPE_UID, ID_TYPE_GID
    or ID_TYPE_BOTH. In order to request a type_hint it will return
    ID_REQUIRE_TYPE for ID_TYPE_NOT_SPECIFIED, which means that
    the parent at least assures that the domain sid exists.
    And the caller still gets ID_TYPE_NOT_SPECIFIED if the
    domain doesn't exist.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14539
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Fri Jan 22 11:32:46 UTC 2021 on sn-devel-184
    
    (cherry picked from commit d8339056eef2845805f573bd8b0f3323370ecc8f)
    Reviewed-by: Ralph Boehme <slow at samba.org>
    
    Autobuild-User(v4-14-test): Karolin Seeger <kseeger at samba.org>
    Autobuild-Date(v4-14-test): Wed Jan 27 17:06:51 UTC 2021 on sn-devel-184

commit fcc6a32e069ed20d1ec141f792481f03b57dbdb0
Author: Ralph Boehme <slow at samba.org>
Date:   Sat Jan 23 18:36:23 2021 +0100

    smbd: use fsp->conn->session_info for the initial delete-on-close token
    
    There's a correctly set up session_info at fsp->conn->session_info, we can just
    use that.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14617
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Tue Jan 26 04:04:14 UTC 2021 on sn-devel-184
    
    (cherry picked from commit e06f86bbd93d024c70016e1adcf833db85742aca)

commit 4bfdc4eff93419a8608f163e6fdade7192be678e
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Jan 25 11:48:32 2021 +0100

    selftest: add a test that verifies unlink works when "force user" is set
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14617
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit aa1f09cda0a097617e34dd0a8b1b0acc7a37bca8)

commit 4c9cf755eb2a9e9e257265c5bbef6113e7b2e8e3
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Jan 25 11:47:45 2021 +0100

    selftest: add force_user_error_inject share in maptoguest env
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14617
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit f3f8fdfbf10f690bc8d972a13d6f74f1fb0fb375)

commit d5a696fc8869b9ce65f063ce93b04d07b01c2b2a
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Jan 25 11:46:30 2021 +0100

    vfs_error_inject: add unlinkat hook
    
    Note that a failure is only injected if the owner of the parent directory is not
    the same as the current user.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14617
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit c44dad3ac2eb36fc5eb5a9f80a9ef97183be26ef)

commit 5041731ca022c1f4edd11d8abd0642072e3088f9
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Jan 15 12:56:25 2021 +0100

    s3/auth: implement "winbind:ignore domains"
    
    Under the following conditions a user from an ignored domain might be able to
    authenticate:
    
    - using Kerberos
    
    - successfully previous authentication so the idmap and name caches are filled
    
    - winbind not running (fwiw, winbindd is mandatory on a domain member)
    
    - nscd running with a cached getpwnam for the ignored user (otherwise auth fails
      because getpwnam fails)
    
    - lookup_name() function being modified to look into the name cache before
      contacting winbindd. Currently it talks directly to winbindd and that will
      check the cache.
    
    Currently, authentication will only fail because creating the local token for
    the user fails because an LSA lookupname RPC call fails (because winbindd is not
    running).
    
    All of this makes a successfull authentication unlikelly, but that is more by
    accident then by design.
    
    To ensures that if winbindd is not running and as such winbindd itself can not
    enforce the restriction, also implement the ignored domains check in the auth
    system as a last line of defense.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14602
    RN: "winbind:ignore domains" doesn't prevent user login from trusted domain
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit df5fe2d835169161d3930acf1e9c750dd2bc64b6)

commit 77f07ddb8ee1e5134bc873262165bf693dd01aaf
Author: Ralph Boehme <slow at samba.org>
Date:   Thu Jan 14 10:42:53 2021 +0100

    winbind: check for allowed domains in winbindd_pam_auth_pac_verify()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14602
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit da474ddd13d84f07f5da81c843e651844f33a003)

commit 9b717968bd75d04800cbd39d680962d6ddf9c01f
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Jan 11 17:59:48 2021 +0100

    winbind: check for allowed domains in winbindd_dual_pam_chauthtok()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14602
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 88e92faace7ec17810903166fa3433aa4842a4e3)

commit 647d1ca5e79786053c250e1e2c84f0e36a8242a5
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Jan 11 17:19:05 2021 +0100

    winbind: check for allowed domains in winbindd_dual_pam_chng_pswd_auth_crap()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14602
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 4bc17600bc50fbc0e54d9d019d8db67001fc3eef)

commit ccc4efd52112c8a0c26748faab178ac7c26fda9d
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Jan 11 17:10:19 2021 +0100

    winbind: check for allowed domains in winbindd_dual_pam_auth_crap()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14602
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit c17bc9c6115e4e92132f3cb912547eac78227938)

commit 56076c98dbbef59aba182ab2c57aeca989cc68b3
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Jan 11 16:50:31 2021 +0100

    winbind: check for allowed domains in winbindd_dual_pam_auth()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14602
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 4cefdf03fec91cdcf700922b1a5ceca02407e259)

commit 4f69adab43c8f8844a5060e040dcf6e5f79c8d8b
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Jan 11 16:15:15 2021 +0100

    winbind: move "winbind:ignore domain" logic to a seperate function
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14602
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 894caca79476d25a0268d89b2ad8a5758b7e31f3)

commit bee8a1cb9e9ff6ace3894aef26a37370fae240a1
Author: Ralph Boehme <slow at samba.org>
Date:   Wed Jan 13 11:54:40 2021 +0100

    selftest: add a test for "winbind:ignore domains"
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14602
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 32197d21dabecaee9bc1d6cd557578892220fe4c)

commit 115c987aa58a2cdd5430dc0809c1a8ee94e3261e
Author: Ralph Boehme <slow at samba.org>
Date:   Wed Jan 20 12:00:16 2021 +0100

    winbind: handle MSG_SMB_CONF_UPDATED in the winbinds children
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14602
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 072ef48001710ed8326c83295f2d3cc301d27cfe)

commit 4df20674da1942425cb64fac25bf876b2778d164
Author: Ralph Boehme <slow at samba.org>
Date:   Wed Jan 20 12:27:23 2021 +0100

    winbind: set logfile after reloading config
    
    lp_load_global() will overwrite whatever we've set with lp_set_logfile().
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14602
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 0c4497f8c66d0ea7c68d42c19e859932ebc3e2ac)

commit 9e797518fb53e66e52209b27dab0851f8c9b002b
Author: Ralph Boehme <slow at samba.org>
Date:   Wed Jan 20 11:17:22 2021 +0100

    winbind: move config-reloading code to winbindd_dual.c
    
    In preperation of forwarding MSG_SMB_CONF_UPDATED to all childs.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14602
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit 81edc65e79aba121db800ec53aadd766e61a0001)

commit 835fd283fec6965ce17f7d2c538312be474903c6
Author: Ralph Boehme <slow at samba.org>
Date:   Thu Jan 14 08:14:46 2021 +0100

    selftest: use correct DNS domain name for wrapper hosts file
    
    For some reason the join fails to register the DNS records when provisioning the
    member env:
    
       Using short domain name -- SAMBA2008R2
       Joined 'IDMAPADMEMBER' to dns domain 'samba2008r2.example.com'
       DNS Update for idmapadmember.samba.example.com failed: ERROR_DNS_UPDATE_FAILED
    
    At the same time the hosts file used by the wrappers contains the wrong fqdn. As
    a result the test that the next commit is going do add fails due do the broken
    DNS resolution:
    
    ...
    UNEXPECTED(failure): samba3.blackbox.winbind_ignore_domain.test_winbind_ignore_domains_ok_krb5(ad_member_idmap_ad:local)
    REASON: Exception: Exception: do_connect: Connection to idmapadmember.samba2008r2.example.com failed (Error NT_STATUS_UNSUCCESSFUL)
    ...
    
    Checking DNS in the testenv, first the working record for the main DC:
    
    testenv$ dig @10.53.57.64 dc7.samba2008r2.example.com +short
    10.53.57.27
    
    testenv$ bin/samba-tool dns query dc7 samba2008r2.example.com dc7 A -U Administrator%locDCpass7
      Name=, Records=1, Children=0
        A: 10.53.57.27 (flags=f0, serial=1, ttl=900)
    
    Now the failing idmapadmember:
    
    testenv$ dig @10.53.57.64 idmapadmember.samba2008r2.example.com +short
    
    testenv$ bin/samba-tool dns query dc7 samba2008r2.example.com idmapadmember A -U Administrator%locDCpass7
    ERROR: Record or zone does not exist.
    
    Fixing the hosts file lets the tests work, fixing the broken DNS record
    registration is a task for another day.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14602
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    (cherry picked from commit e1fc84138ca118c4187d87b7be4a7e6dd771dc4f)

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

Summary of changes:
 selftest/target/Samba3.pm                          |  25 ++++-
 source3/auth/auth_util.c                           |   8 ++
 source3/include/proto.h                            |   1 +
 source3/lib/util_names.c                           |  20 ++++
 source3/modules/vfs_error_inject.c                 |  44 +++++++++
 source3/script/tests/test_force_user_unlink.sh     |  40 ++++++++
 .../script/tests/test_winbind_ignore_domains.sh    | 104 +++++++++++++++++++++
 source3/selftest/tests.py                          |   8 ++
 source3/smbd/close.c                               |  25 +----
 source3/winbindd/idmap_hash/idmap_hash.c           |  35 +++++++
 source3/winbindd/winbindd.c                        |  29 ++----
 source3/winbindd/winbindd_dual.c                   |  37 ++++++++
 source3/winbindd/winbindd_pam.c                    |  44 +++++++++
 source3/winbindd/winbindd_proto.h                  |   7 ++
 source3/winbindd/winbindd_util.c                   |  10 +-
 15 files changed, 386 insertions(+), 51 deletions(-)
 create mode 100755 source3/script/tests/test_force_user_unlink.sh
 create mode 100755 source3/script/tests/test_winbind_ignore_domains.sh


Changeset truncated at 500 lines:

diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index ee20528a325..b0910433940 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -761,6 +761,7 @@ sub provision_ad_member
 	my $ret = $self->provision(
 	    prefix => $prefix,
 	    domain => $dcvars->{DOMAIN},
+	    realm => $dcvars->{REALM},
 	    server => "LOCALADMEMBER",
 	    password => "loCalMemberPass",
 	    extra_options => $member_options,
@@ -911,6 +912,7 @@ sub setup_ad_member_rfc2307
 	my $ret = $self->provision(
 	    prefix => $prefix,
 	    domain => $dcvars->{DOMAIN},
+	    realm => $dcvars->{REALM},
 	    server => "RFC2307MEMBER",
 	    password => "loCalMemberPass",
 	    extra_options => $member_options,
@@ -1008,6 +1010,7 @@ sub setup_ad_member_idmap_rid
 	my $ret = $self->provision(
 	    prefix => $prefix,
 	    domain => $dcvars->{DOMAIN},
+	    realm => $dcvars->{REALM},
 	    server => "IDMAPRIDMEMBER",
 	    password => "loCalMemberPass",
 	    extra_options => $member_options,
@@ -1107,6 +1110,7 @@ sub setup_ad_member_idmap_ad
 	my $ret = $self->provision(
 	    prefix => $prefix,
 	    domain => $dcvars->{DOMAIN},
+	    realm => $dcvars->{REALM},
 	    server => "IDMAPADMEMBER",
 	    password => "loCalMemberPass",
 	    extra_options => $member_options,
@@ -1762,12 +1766,22 @@ $ret->{USERNAME} = KTEST\\Administrator
 sub setup_maptoguest
 {
 	my ($self, $path) = @_;
+	my $prefix_abs = abs_path($path);
+	my $libdir="$prefix_abs/lib";
+	my $share_dir="$prefix_abs/share";
+	my $errorinjectconf="$libdir/error_inject.conf";
 
 	print "PROVISIONING maptoguest...";
 
 	my $options = "
 map to guest = bad user
 ntlm auth = yes
+
+[force_user_error_inject]
+	path = $share_dir
+	vfs objects = acl_xattr fake_acls xattr_tdb error_inject
+	force user = user1
+	include = $errorinjectconf
 ";
 
 	my $vars = $self->provision(
@@ -1965,6 +1979,7 @@ sub provision($$)
 
 	my $prefix = $args{prefix};
 	my $domain = $args{domain};
+	my $realm = $args{realm};
 	my $server = $args{server};
 	my $password = $args{password};
 	my $extra_options = $args{extra_options};
@@ -1982,6 +1997,12 @@ sub provision($$)
 	my %createuser_env = ();
 	my $server_ip = Samba::get_ipv4_addr($server);
 	my $server_ipv6 = Samba::get_ipv6_addr($server);
+	my $dns_domain;
+	if (defined($realm)) {
+	    $dns_domain = lc($realm);
+	} else {
+	    $dns_domain = "samba.example.com";
+	}
 
 	my $unix_name = ($ENV{USER} or $ENV{LOGNAME} or `PATH=/usr/ucb:$ENV{PATH} whoami`);
 	chomp $unix_name;
@@ -2987,8 +3008,8 @@ force_user:x:$gid_force_user:
 		warn("Unable to open $nss_wrapper_hosts");
 		return undef;
 	}
-	print HOSTS "${server_ip} ${hostname}.samba.example.com ${hostname}\n";
-	print HOSTS "${server_ipv6} ${hostname}.samba.example.com ${hostname}\n";
+	print HOSTS "${server_ip} ${hostname}.${dns_domain} ${hostname}\n";
+	print HOSTS "${server_ipv6} ${hostname}.${dns_domain} ${hostname}\n";
 	close(HOSTS);
 
 	$resolv_conf = "$privatedir/no_resolv.conf" unless defined($resolv_conf);
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 9427c05f573..4686b29111e 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -485,6 +485,14 @@ NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
 		return NT_STATUS_LOGON_FAILURE;
 	}
 
+	if (!is_allowed_domain(server_info->info3->base.logon_domain.string)) {
+		DBG_NOTICE("Authentication failed for user [%s] "
+			   "from firewalled domain [%s]\n",
+			   server_info->info3->base.account_name.string,
+			   server_info->info3->base.logon_domain.string);
+		return NT_STATUS_AUTHENTICATION_FIREWALL_FAILED;
+	}
+
 	if (server_info->cached_session_info != NULL) {
 		session_info = copy_session_info(mem_ctx,
 				server_info->cached_session_info);
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 6c9cf130d04..16cd587ed30 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -304,6 +304,7 @@ struct passwd *Get_Pwnam_alloc(TALLOC_CTX *mem_ctx, const char *user);
 /* The following definitions come from lib/util_names.c  */
 const char *get_global_sam_name(void);
 const char *my_sam_name(void);
+bool is_allowed_domain(const char *domain_name);
 
 /* The following definitions come from lib/util.c  */
 
diff --git a/source3/lib/util_names.c b/source3/lib/util_names.c
index 15236c913df..630a25875c7 100644
--- a/source3/lib/util_names.c
+++ b/source3/lib/util_names.c
@@ -182,3 +182,23 @@ const char *my_sam_name(void)
 
 	return lp_workgroup();
 }
+
+bool is_allowed_domain(const char *domain_name)
+{
+	const char **ignored_domains = NULL;
+	const char **dom = NULL;
+
+	ignored_domains = lp_parm_string_list(-1,
+					      "winbind",
+					      "ignore domains",
+					      NULL);
+
+	for (dom = ignored_domains; dom != NULL && *dom != NULL; dom++) {
+		if (gen_fnmatch(*dom, domain_name) == 0) {
+			DBG_NOTICE("Ignoring domain '%s'\n", domain_name);
+			return false;
+		}
+	}
+
+	return true;
+}
diff --git a/source3/modules/vfs_error_inject.c b/source3/modules/vfs_error_inject.c
index 2230b8a2991..31257cc1d00 100644
--- a/source3/modules/vfs_error_inject.c
+++ b/source3/modules/vfs_error_inject.c
@@ -30,6 +30,7 @@ struct unix_error_map {
 	{	"ESTALE",	ESTALE	},
 	{	"EBADF",	EBADF	},
 	{	"EINTR",	EINTR	},
+	{	"EACCES",	EACCES	},
 };
 
 static int find_unix_error_from_string(const char *err_str)
@@ -123,10 +124,53 @@ static int vfs_error_inject_openat(struct vfs_handle_struct *handle,
 	return SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, flags, mode);
 }
 
+static int vfs_error_inject_unlinkat(struct vfs_handle_struct *handle,
+				     struct files_struct *dirfsp,
+				     const struct smb_filename *smb_fname,
+				     int flags)
+{
+	struct smb_filename *full_fname = NULL;
+	struct smb_filename *parent_fname = NULL;
+	int error = inject_unix_error("unlinkat", handle);
+	int ret;
+	bool ok;
+
+	if (error == 0) {
+		return SMB_VFS_NEXT_UNLINKAT(handle, dirfsp, smb_fname, flags);
+	}
+
+	full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+						  dirfsp,
+						  smb_fname);
+	if (full_fname == NULL) {
+		return -1;
+	}
+
+	ok = parent_smb_fname(full_fname, full_fname, &parent_fname, NULL);
+	if (!ok) {
+		TALLOC_FREE(full_fname);
+		return -1;
+	}
+
+	ret = SMB_VFS_STAT(handle->conn, parent_fname);
+	if (ret != 0) {
+		TALLOC_FREE(full_fname);
+		return -1;
+	}
+
+	if (parent_fname->st.st_ex_uid == get_current_uid(dirfsp->conn)) {
+		return SMB_VFS_NEXT_UNLINKAT(handle, dirfsp, smb_fname, flags);
+	}
+
+	errno = error;
+	return -1;
+}
+
 static struct vfs_fn_pointers vfs_error_inject_fns = {
 	.chdir_fn = vfs_error_inject_chdir,
 	.pwrite_fn = vfs_error_inject_pwrite,
 	.openat_fn = vfs_error_inject_openat,
+	.unlinkat_fn = vfs_error_inject_unlinkat,
 };
 
 static_decl_vfs;
diff --git a/source3/script/tests/test_force_user_unlink.sh b/source3/script/tests/test_force_user_unlink.sh
new file mode 100755
index 00000000000..86076535497
--- /dev/null
+++ b/source3/script/tests/test_force_user_unlink.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+# Test unlink on share with "force user"
+#
+# Copyright (C) 2021 Ralph Boehme
+
+incdir=$(dirname $0)/../../../testprogs/blackbox
+. $incdir/subunit.sh
+. $incdir/common_test_fns.inc
+
+smbclient="$BINDIR/smbclient"
+error_inject_conf=$(dirname ${SMB_CONF_PATH})/error_inject.conf
+failed=0
+
+test_forced_user_can_delete() {
+    out=$($smbclient -U $DOMAIN/$USERNAME%$PASSWORD //$SERVER_IP/force_user_error_inject -c "rm dir/file")
+    if [ $? -ne 0 ] ; then
+	echo $out
+	return 1
+    fi
+    tmp=$(echo $out | grep NT_STATUS_ )
+    if [ $? -eq 0 ] ; then
+	return 1
+    fi
+    return 0
+}
+
+echo "error_inject:unlinkat = EACCES" > ${error_inject_conf}
+
+$smbclient -U $DOMAIN/$USERNAME%$PASSWORD //$SERVER_IP/force_user_error_inject -c "mkdir dir" || failed=`expr $failed + 1`
+$smbclient -U $DOMAIN/$USERNAME%$PASSWORD //$SERVER_IP/force_user_error_inject -c "put WHATSNEW.txt dir/file" || failed=`expr $failed + 1`
+
+testit "test_forced_user_can_delete" test_forced_user_can_delete || failed=`expr $failed + 1`
+
+rm ${error_inject_conf}
+
+# Clean up after ourselves.
+$smbclient -U $DOMAIN/$USERNAME%$PASSWORD //$SERVER_IP/force_user_error_inject -c "del dir/file; rmdir dir"
+
+testok $0 $failed
diff --git a/source3/script/tests/test_winbind_ignore_domains.sh b/source3/script/tests/test_winbind_ignore_domains.sh
new file mode 100755
index 00000000000..adce8abb09c
--- /dev/null
+++ b/source3/script/tests/test_winbind_ignore_domains.sh
@@ -0,0 +1,104 @@
+#!/bin/sh
+
+incdir=`dirname $0`/../../../testprogs/blackbox
+. $incdir/subunit.sh
+. $incdir/common_test_fns.inc
+
+failed=0
+
+smbclient="$BINDIR/smbclient"
+smbcontrol="$BINDIR/smbcontrol"
+ldbmodify="$BINDIR/ldbmodify"
+ldbsearch="$BINDIR/ldbsearch"
+wbinfo="$BINDIR/wbinfo"
+global_inject_conf=$(dirname $SMB_CONF_PATH)/global_inject.conf
+SERVER_FQDN=$(echo "$SERVER.$REALM" | awk '{print tolower($0)}')
+
+TRUST_BASE_DN=$($ldbsearch -H ldap://$TRUST_SERVER -b "" -s base defaultNamingContext | awk '/^defaultNamingContext/ {print $2}')
+if [ $? -ne 0 ] ; then
+    echo "Could not find trusted base DN" | subunit_fail_test "test_idmap_ad"
+    exit 1
+fi
+
+#
+# Add POSIX ids to trusted domain
+#
+add_posix_ids() {
+cat <<EOF | $ldbmodify -H ldap://$TRUST_SERVER \
+       -U "$TRUST_DOMAIN\Administrator%$TRUST_PASSWORD"
+dn: CN=Administrator,CN=Users,$TRUST_BASE_DN
+changetype: modify
+add: uidNumber
+uidNumber: 2500000
+EOF
+
+cat <<EOF | $ldbmodify -H ldap://$TRUST_SERVER \
+       -U "$TRUST_DOMAIN\Administrator%$TRUST_PASSWORD"
+dn: CN=Domain Users,CN=Users,$TRUST_BASE_DN
+changetype: modify
+add: gidNumber
+gidNumber: 2500001
+EOF
+
+cat <<EOF | $ldbmodify -H ldap://$TRUST_SERVER \
+       -U "$TRUST_DOMAIN\Administrator%$TRUST_PASSWORD"
+dn: CN=Domain Admins,CN=Users,$TRUST_BASE_DN
+changetype: modify
+add: gidNumber
+gidNumber: 2500002
+EOF
+}
+
+#
+# Remove POSIX ids from trusted domain
+#
+remove_posix_ids() {
+cat <<EOF | $ldbmodify -H ldap://$TRUST_SERVER \
+       -U "$TRUST_DOMAIN\Administrator%$TRUST_PASSWORD"
+dn: CN=Administrator,CN=Users,$TRUST_BASE_DN
+changetype: modify
+delete: uidNumber
+uidNumber: 2500000
+EOF
+
+cat <<EOF | $ldbmodify -H ldap://$TRUST_SERVER \
+       -U "$TRUST_DOMAIN\Administrator%$TRUST_PASSWORD"
+dn: CN=Domain Users,CN=Users,$TRUST_BASE_DN
+changetype: modify
+delete: gidNumber
+gidNumber: 2500001
+EOF
+
+cat <<EOF | $ldbmodify -H ldap://$TRUST_SERVER \
+       -U "$TRUST_DOMAIN\Administrator%$TRUST_PASSWORD"
+dn: CN=Domain Admins,CN=Users,$TRUST_BASE_DN
+changetype: modify
+delete: gidNumber
+gidNumber: 2500002
+EOF
+}
+
+add_posix_ids
+
+echo "" > $global_inject_conf
+$smbcontrol winbindd reload-config
+$wbinfo -p
+
+test_smbclient "test_winbind_ignore_domains_ok_ntlm_ip" "ls" "//$SERVER_IP/tmp" -U $TRUST_DOMAIN/$TRUST_USERNAME%$TRUST_PASSWORD || failed=`expr $failed + 1`
+test_smbclient "test_winbind_ignore_domains_ok_ntlm_fqdn" "ls" "//$SERVER_FQDN/tmp" -U $TRUST_DOMAIN/$TRUST_USERNAME%$TRUST_PASSWORD || failed=`expr $failed + 1`
+test_smbclient "test_winbind_ignore_domains_ok_krb5" "ls" "//$SERVER_FQDN/tmp" -U $TRUST_USERNAME@$TRUST_REALM%$TRUST_PASSWORD -k || failed=`expr $failed + 1`
+
+echo "winbind:ignore domains = $TRUST_DOMAIN" > $global_inject_conf
+$smbcontrol winbindd reload-config
+$wbinfo -p
+
+test_smbclient_expect_failure "test_winbind_ignore_domains_fail_ntlm_ip" "ls" "//$SERVER_IP/tmp" -U $TRUST_DOMAIN/$TRUST_USERNAME%$TRUST_PASSWORD || failed=`expr $failed + 1`
+test_smbclient_expect_failure "test_winbind_ignore_domains_fail_ntlm_fqdn" "ls" "//$SERVER_FQDN/tmp" -U $TRUST_DOMAIN/$TRUST_USERNAME%$TRUST_PASSWORD || failed=`expr $failed + 1`
+test_smbclient_expect_failure "test_winbind_ignore_domains_fail_krb5" "ls" "//$SERVER_FQDN/tmp" -U $TRUST_USERNAME@$TRUST_REALM%$TRUST_PASSWORD -k || failed=`expr $failed + 1`
+
+echo "" > $global_inject_conf
+$smbcontrol winbindd reload-config
+$wbinfo -p
+remove_posix_ids
+
+testok $0 $failed
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index c7280c630dc..6f65bf5ef9d 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -1037,6 +1037,9 @@ plantestsuite("samba3.blackbox.smbd_no_krb5", "ad_member:local",
               [os.path.join(samba3srcdir, "script/tests/test_smbd_no_krb5.sh"),
                smbclient3, '$SERVER', "$DC_USERNAME", "$DC_PASSWORD", "$PREFIX"])
 
+plantestsuite("samba3.blackbox.winbind_ignore_domain", "ad_member_idmap_ad:local",
+              [os.path.join(samba3srcdir, "script/tests/test_winbind_ignore_domains.sh")])
+
 plantestsuite("samba3.blackbox.durable_v2_delay", "simpleserver:local",
               [os.path.join(samba3srcdir, "script/tests/test_durable_handle_reconnect.sh")])
 
@@ -1186,6 +1189,11 @@ plantestsuite(
      "bin/samba-tool",
      '$DNSNAME'])
 
+plantestsuite("samba3.blackbox.force-user-unlink",
+              "maptoguest:local",
+              [os.path.join(samba3srcdir,
+                            "script/tests/test_force_user_unlink.sh")])
+
 def planclusteredmembertestsuite(tname, prefix):
     '''Define a clustered test for the clusteredmember environment'''
 
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index 97d13473082..f05619d1886 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -342,21 +342,13 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
 
 	if (fsp->fsp_flags.initial_delete_on_close &&
 			!is_delete_on_close_set(lck, fsp->name_hash)) {
-		struct auth_session_info *session_info = NULL;
-
 		/* Initial delete on close was set and no one else
 		 * wrote a real delete on close. */
 
-		status = smbXsrv_session_info_lookup(conn->sconn->client,
-						     fsp->vuid,
-						     &session_info);
-		if (!NT_STATUS_IS_OK(status)) {
-			return NT_STATUS_INTERNAL_ERROR;
-		}
 		fsp->fsp_flags.delete_on_close = true;
 		set_delete_on_close_lck(fsp, lck,
-					session_info->security_token,
-					session_info->unix_token);
+					fsp->conn->session_info->security_token,
+					fsp->conn->session_info->unix_token);
 	}
 
 	delete_file = is_delete_on_close_set(lck, fsp->name_hash) &&
@@ -1175,24 +1167,15 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
 	}
 
 	if (fsp->fsp_flags.initial_delete_on_close) {
-		struct auth_session_info *session_info = NULL;
-
 		/* Initial delete on close was set - for
 		 * directories we don't care if anyone else
 		 * wrote a real delete on close. */
 
-		status = smbXsrv_session_info_lookup(fsp->conn->sconn->client,
-						     fsp->vuid,
-						     &session_info);
-		if (!NT_STATUS_IS_OK(status)) {
-			return NT_STATUS_INTERNAL_ERROR;
-		}
-
 		send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
 					       fsp->fsp_name->base_name);
 		set_delete_on_close_lck(fsp, lck,
-					session_info->security_token,
-					session_info->unix_token);
+					fsp->conn->session_info->security_token,
+					fsp->conn->session_info->unix_token);
 		fsp->fsp_flags.delete_on_close = true;
 	}
 
diff --git a/source3/winbindd/idmap_hash/idmap_hash.c b/source3/winbindd/idmap_hash/idmap_hash.c
index be0ba45a044..d0bed7631a6 100644
--- a/source3/winbindd/idmap_hash/idmap_hash.c
+++ b/source3/winbindd/idmap_hash/idmap_hash.c
@@ -261,6 +261,25 @@ static NTSTATUS sids_to_unixids(struct idmap_domain *dom,
 
 		ids[i]->status = ID_UNMAPPED;
 
+		if (ids[i]->xid.type == ID_TYPE_NOT_SPECIFIED) {
+			/*
+			 * idmap_hash used to bounce back the requested type,
+			 * which was ID_TYPE_UID, ID_TYPE_GID or
+			 * ID_TYPE_NOT_SPECIFIED before as the winbindd parent
+			 * always used a lookupsids.  When the lookupsids
+			 * failed because of an unknown domain, the idmap child
+			 * weren't requested at all and the caller sees
+			 * ID_TYPE_NOT_SPECIFIED.
+			 *
+			 * Now that the winbindd parent will pass ID_TYPE_BOTH
+			 * in order to indicate that the domain exists.
+			 * We should ask the parent to fallback to lookupsids
+			 * if the domain is not known yet.
+			 */
+			ids[i]->status = ID_REQUIRE_TYPE;
+			continue;
+		}
+
 		sid_copy(&sid, ids[i]->sid);
 		sid_split_rid(&sid, &rid);
 
@@ -270,6 +289,22 @@ static NTSTATUS sids_to_unixids(struct idmap_domain *dom,
 		/* Check that both hashes are non-zero*/
 
 		if (h_domain && h_rid) {
+			/*
+			 * idmap_hash used to bounce back the requested type,
+			 * which was ID_TYPE_UID, ID_TYPE_GID or
+			 * ID_TYPE_NOT_SPECIFIED before as the winbindd parent
+			 * always used a lookupsids.
+			 *
+			 * This module should have supported ID_TYPE_BOTH since
+			 * samba-4.1.0, similar to idmap_rid and idmap_autorid.
+			 *
+			 * Now that the winbindd parent will pass ID_TYPE_BOTH
+			 * in order to indicate that the domain exists, it's
+			 * better to always return ID_TYPE_BOTH instead of a
+			 * random mix of ID_TYPE_UID, ID_TYPE_GID or


-- 
Samba Shared Repository



More information about the samba-cvs mailing list