The branch, v4-7-test has been updated via eb299c6 s4-drsuapi: Avoid segfault when replicating as a non-admin with GUID_DRS_GET_CHANGES via 7364965 tests/fake_snap: sanitize paths from 8619bd1 VERSION: Bump version up to 4.7.0rc6...
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-7-test - Log ----------------------------------------------------------------- commit eb299c63f15c42bf65393f26cf3c7ab6b05470fd Author: Andrew Bartlett <abart...@samba.org> Date: Fri Aug 4 11:44:19 2017 +1200 s4-drsuapi: Avoid segfault when replicating as a non-admin with GUID_DRS_GET_CHANGES Users who are not administrator do not get b_state->sam_ctx_system filled in. We should probably use the 'sam_ctx' variable in all cases (instead of b_state->sam_ctx*), but I'll make this change in a separate patch, so that the bug fix remains independent from other tidy-ups. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12946 Signed-off-by: Andrew Bartlett <abart...@samba.org> Signed-off-by: Tim Beale <timbe...@catalyst.net.nz> Reviewed-by: Garming Sam <garm...@catalyst.net.nz> (cherry picked from commit dd863b604984c1504895f376ec64f58e27e53efa) Autobuild-User(v4-7-test): Karolin Seeger <ksee...@samba.org> Autobuild-Date(v4-7-test): Thu Aug 31 14:02:51 CEST 2017 on sn-devel-144 commit 7364965ac09b799a25f95ab475819b389dcad174 Author: David Disseldorp via samba-technical <samba-techni...@lists.samba.org> Date: Sat Aug 26 23:40:37 2017 +0200 tests/fake_snap: sanitize paths Ensure fake_snap.pl can be run in taint mode (-T), by sanitizing paths and the PATH env. This fixes the following samba3.rpc.fsrvp selftest failures: Insecure dependency in mkdir while running setgid at (eval 2) line 4. snap create failed: NT_STATUS_UNSUCCESSFUL snap create failed for shadow copy of /home/ddiss/isms/samba/st/nt4_dc/share Bug: https://bugzilla.samba.org/show_bug.cgi?id=12988 Signed-off-by: David Disseldorp <dd...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Tue Aug 29 04:54:51 CEST 2017 on sn-devel-144 (cherry picked from commit f9d4158f0b002b482df0a919d4cb337cce81f9f8) ----------------------------------------------------------------------- Summary of changes: source3/script/tests/fake_snap.pl | 19 ++++- source4/rpc_server/drsuapi/getncchanges.c | 2 +- source4/selftest/tests.py | 5 ++ source4/torture/drs/python/getnc_unpriv.py | 116 +++++++++++++++++++++++++++++ 4 files changed, 138 insertions(+), 4 deletions(-) create mode 100644 source4/torture/drs/python/getnc_unpriv.py Changeset truncated at 500 lines: diff --git a/source3/script/tests/fake_snap.pl b/source3/script/tests/fake_snap.pl index d1233f3..18bbcb7 100755 --- a/source3/script/tests/fake_snap.pl +++ b/source3/script/tests/fake_snap.pl @@ -5,14 +5,25 @@ use strict; use File::Path qw(rmtree); use POSIX (); +sub _untaint_path +{ + my ($path) = @_; + + if ($path =~ /^(.*)$/) { + return $1; + } + die "bad path"; +} + sub _create_snapshot { - my ($base_path) = @_; + my ($base_path) = _untaint_path(shift); my $time_str = POSIX::strftime("%Y.%m.%d-%H.%M.%S" , localtime()); my $snap_path = $base_path . "/.snapshots/\@GMT-" . $time_str; my $ret; - POSIX::mkdir($base_path . "/.snapshots", 0777); + $ENV{'PATH'} = '/bin:/usr/bin'; # untaint PATH + POSIX::mkdir($base_path . "/.snapshots", 0755); # add trailing slash to src path to ensure that only contents is copied $ret = system("rsync", "-a", "--exclude=.snapshots/", "${base_path}/", @@ -28,7 +39,8 @@ sub _create_snapshot sub _delete_snapshot { - my ($base_path, $snap_path) = @_; + my $base_path = _untaint_path(shift); + my $snap_path = _untaint_path(shift); # we're doing a recursive delete, so do some sanity checks if ((index($snap_path, $base_path) != 0) || (index($snap_path, ".snapshots") == -1)) { @@ -36,6 +48,7 @@ sub _delete_snapshot return -1; } + $ENV{'PATH'} = '/bin:/usr/bin'; # untaint PATH rmtree($snap_path, {error => \my $err}); if (@$err) { for my $diag (@$err) { diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c index da294a6..32580bd 100644 --- a/source4/rpc_server/drsuapi/getncchanges.c +++ b/source4/rpc_server/drsuapi/getncchanges.c @@ -2250,7 +2250,7 @@ allowed: return WERR_NOT_ENOUGH_MEMORY; } - ret = dsdb_find_guid_by_dn(b_state->sam_ctx_system, + ret = dsdb_find_guid_by_dn(b_state->sam_ctx, getnc_state->ncRoot_dn, &getnc_state->ncRoot_guid); if (ret != LDB_SUCCESS) { diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index c13af0c..4bcbdc6 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -835,6 +835,11 @@ for env in ['vampire_dc', 'promoted_dc']: name="samba4.drs.getnc_exop.python(%s)" % env, environ={'DC1': "$DC_SERVER", 'DC2': '$%s_SERVER' % env.upper()}, extra_args=['-U$DOMAIN/$DC_USERNAME%$DC_PASSWORD']) + planoldpythontestsuite(env, "getnc_unpriv", + extra_path=[os.path.join(samba4srcdir, 'torture/drs/python')], + name="samba4.drs.getnc_unpriv.python(%s)" % env, + environ={'DC1': "$DC_SERVER", 'DC2': '$%s_SERVER' % env.upper()}, + extra_args=['-U$DOMAIN/$DC_USERNAME%$DC_PASSWORD']) planoldpythontestsuite(env, "linked_attributes_drs", extra_path=[os.path.join(samba4srcdir, 'torture/drs/python')], name="samba4.drs.linked_attributes_drs.python(%s)" % env, diff --git a/source4/torture/drs/python/getnc_unpriv.py b/source4/torture/drs/python/getnc_unpriv.py new file mode 100644 index 0000000..61ecefa --- /dev/null +++ b/source4/torture/drs/python/getnc_unpriv.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Tests replication scenarios with different user privileges +# +# Copyright (C) Kamen Mazdrashki <kame...@samba.org> 2011 +# Copyright (C) Andrew Bartlett <abart...@samba.org> 2017 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +# +# Usage: +# export DC1=dc1_dns_name +# export DC2=dc2_dns_name +# export SUBUNITRUN=$samba4srcdir/scripting/bin/subunitrun +# PYTHONPATH="$PYTHONPATH:$samba4srcdir/torture/drs/python" $SUBUNITRUN getnc_unpriv -U"$DOMAIN/$DC_USERNAME"%"$DC_PASSWORD" +# + +import drs_base +import samba.tests + +from samba import sd_utils +import ldb +from ldb import SCOPE_BASE + +from samba.dcerpc import drsuapi +from samba.credentials import DONT_USE_KERBEROS + +class DrsReplicaSyncUnprivTestCase(drs_base.DrsBaseTestCase): + """Confirm the behaviour of DsGetNCChanges for unprivileged users""" + + def setUp(self): + super(DrsReplicaSyncUnprivTestCase, self).setUp() + self.get_changes_user = "get-changes-user" + self.base_dn = self.ldb_dc1.get_default_basedn() + self.ou = "OU=test_getncchanges,%s" % self.base_dn + self.user_pass = samba.generate_random_password(12, 16) + self.ldb_dc1.add({ + "dn": self.ou, + "objectclass": "organizationalUnit"}) + self.ldb_dc1.newuser(self.get_changes_user, self.user_pass, + userou="OU=test_getncchanges") + (self.drs, self.drs_handle) = self._ds_bind(self.dnsname_dc1) + + self.sd_utils = sd_utils.SDUtils(self.ldb_dc1) + user_dn = "cn=%s,%s" % (self.get_changes_user, self.ou) + user_sid = self.sd_utils.get_object_sid(user_dn) + mod = "(A;;CR;1131f6aa-9c07-11d1-f79f-00c04fc2dcd2;;%s)" % str(user_sid) + self.sd_utils.dacl_add_ace(self.base_dn, mod) + + # We set DONT_USE_KERBEROS to avoid a race with getting the + # user replicated to our selected KDC + self.user_creds = self.insta_creds(template=self.get_credentials(), + username=self.get_changes_user, + userpass=self.user_pass, + kerberos_state=DONT_USE_KERBEROS) + (self.user_drs, self.user_drs_handle) = self._ds_bind(self.dnsname_dc1, + self.user_creds) + + def tearDown(self): + try: + self.ldb_dc1.delete(self.ou, ["tree_delete:1"]) + except ldb.LdbError as (enum, string): + if enum == ldb.ERR_NO_SUCH_OBJECT: + pass + super(DrsReplicaSyncUnprivTestCase, self).tearDown() + + def test_do_single_repl(self): + """ + Make sure that DRSU_EXOP_REPL_OBJ works as a less-privileged + user with the correct GET_CHANGES rights + """ + + ou1 = "OU=single_obj,%s" % self.ou + self.ldb_dc1.add({ + "dn": ou1, + "objectclass": "organizationalUnit" + }) + req8 = self._exop_req8(dest_dsa=None, + invocation_id=self.ldb_dc1.get_invocation_id(), + nc_dn_str=ou1, + exop=drsuapi.DRSUAPI_EXOP_REPL_OBJ, + replica_flags=drsuapi.DRSUAPI_DRS_WRIT_REP) + (level, ctr) = self.user_drs.DsGetNCChanges(self.user_drs_handle, 8, req8) + self._check_ctr6(ctr, [ou1]) + + def test_do_full_repl(self): + """ + Make sure that full replication works as a less-privileged + user with the correct GET_CHANGES rights + """ + + ou1 = "OU=single_obj,%s" % self.ou + self.ldb_dc1.add({ + "dn": ou1, + "objectclass": "organizationalUnit" + }) + req8 = self._exop_req8(dest_dsa=None, + invocation_id=self.ldb_dc1.get_invocation_id(), + nc_dn_str=ou1, + exop=drsuapi.DRSUAPI_EXOP_NONE, + replica_flags=drsuapi.DRSUAPI_DRS_WRIT_REP) + (level, ctr) = self.user_drs.DsGetNCChanges(self.user_drs_handle, 8, req8) + self.assertEqual(ctr.extended_ret, drsuapi.DRSUAPI_EXOP_ERR_NONE) -- Samba Shared Repository