The branch, v4-10-stable has been updated via 25f2fe02a61 VERSION: Disable GIT_SNAPSHOT for the 4.10.0 release. via 983bcc352cb VERSION: Bump version up to 4.10.0. via 5da71ca11d4 WHATSNEW: Add release notes for Samba 4.10.0. via 00ea6a7d24e lib:util: Move debug message for mkdir failing to log level 1 via 6d901af0f1c lib/winbind_util: Add winbind_xid_to_sid for --without-winbind via 3c32774b925 lib/winbind_util: Move include out of ifdef via 545914afefa passdb: Update ABI to 0.27.2 via 2021080a41d passdb: Make [ug]id_to_sid use xid_to_sid via 8c0268a5fec passdb: Introduce xid_to_sid via 10a0d77f17c lib: Introduce winbind_xid_to_sid via ba6dd781d4a winbind: Use idmap_cache_find_xid2sid via a20e68bcc63 torture: Add tests for idmap cache via f6f0994a597 idmap_cache: Introduce idmap_cache_find_xid2sid via 6434de2b76d winbind: Now we explicitly track if we got ids from cache via 465bd07ff70 winbind: Initialize "expired" parameter to idmap_cache_xid2sid via 1df6720d74b idmap_cache: Only touch "sid" on success in find_xid_to_sid via 41c1870a8c2 lib: Make idmap_cache return negative mappings via 5c2a243d3e7 CI: don't use swap via 7bd135d25d6 s4/scripting/bin: open unicode files with utf8 encoding and write unicode string via 5d0e2bf8190 libcli/security: fix handling of deny type ACEs in access_check_max_allowed() via cc7629a20e9 s4:torture: Add test_deny1(). via c9b6b7ed4be s4:torture: Add test_owner_rights_deny1(). via 1dc2e296f17 libcli/security: correct access check and maximum access calculation for Owner Rights ACEs via 3026c1a36c3 s4:torture: Add test_owner_rights_deny(). via 63f0db77204 s4:torture: Fix the test_owner_rights() test to show permissions are additive. via 7e95499d39a libcli/security: add "Owner Rights" calculation to access_check_max_allowed() via ac08949dcdf s4:torture: add a Maximum Access check with an Owner Rights ACE via 3b52cba505a s4:libcli: remember return code from maximum access via 49bac77e789 autobuild: Add -py2 tests for new split backup/restore testenvs via 9f85efa76d3 autobuild: Split backup/restore testenvs out into separate job via ea33a7b0911 sambaundoguididx: use the right escaped oder unescaped sam ldb files via 2f4d8214601 s4-server: Open and close a transaction on sam.ldb at startup via 0e80b245bf4 WHATSNEW: mention new vfs_glusterfs_fuse module via 9169e9722d6 VERSION: Bump version up to 4.10.0rc5... from e399a0209f4 VERSION: Disable GIT_SNAPSHOT for the 4.10.0rc4 release.
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-10-stable - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: .gitlab-ci.yml | 17 +- VERSION | 2 +- WHATSNEW.txt | 58 ++- lib/util/util.c | 6 +- libcli/security/access_check.c | 127 +++-- script/autobuild.py | 13 + source3/lib/idmap_cache.c | 48 +- source3/lib/idmap_cache.h | 2 + source3/lib/winbind_util.c | 41 +- source3/lib/winbind_util.h | 2 + ...passdb-0.27.1.sigs => samba-passdb-0.27.2.sigs} | 2 + source3/passdb/lookup_sid.c | 235 +++------ source3/passdb/lookup_sid.h | 1 + source3/selftest/tests.py | 1 + source3/torture/proto.h | 1 + source3/torture/test_idmap_cache.c | 122 +++++ source3/torture/torture.c | 1 + source3/winbindd/wb_xids2sids.c | 33 +- source3/wscript_build | 3 +- source4/libcli/raw/interfaces.h | 1 + source4/libcli/smb2/create.c | 4 +- source4/scripting/bin/gen_ntstatus.py | 11 +- source4/scripting/bin/gen_werror.py | 11 +- source4/scripting/bin/sambaundoguididx | 3 +- source4/smbd/server.c | 42 ++ source4/torture/smb2/acls.c | 558 +++++++++++++++++++++ 26 files changed, 1066 insertions(+), 279 deletions(-) copy source3/passdb/ABI/{samba-passdb-0.27.1.sigs => samba-passdb-0.27.2.sigs} (99%) create mode 100644 source3/torture/test_idmap_cache.c Changeset truncated at 500 lines: diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 04d57cb0491..4249f5296b3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,12 +7,7 @@ variables: GIT_DEPTH: "3" before_script: - - echo "Build starting (preparing swap)..." - - if [ $(df -m / --output=avail | tail -n1) -gt 10240 ]; then - sudo dd if=/dev/zero of=/samba-swap bs=1M count=6144; - sudo mkswap /samba-swap; - sudo swapon /samba-swap; - fi + - echo "Build starting..." after_script: - tar -xf logs.tar.gz system-info.txt -O @@ -61,6 +56,16 @@ build_samba_ad_dc_2: # this one takes about 1 hours to finish - script/autobuild.py samba-ad-dc-2 --verbose --nocleanup --keeplogs --tail --testbase /tmp/samba-testbase +build_samba_ad_dc_backup: + <<: *shared_template + script: + - script/autobuild.py samba-ad-dc-backup --verbose --nocleanup --keeplogs --tail --testbase /tmp/samba-testbase + +build_samba_ad_dc_backup_py2: + <<: *shared_template + script: + - script/autobuild.py samba-ad-dc-backup-py2 --verbose --nocleanup --keeplogs --tail --testbase /tmp/samba-testbase + build_samba_ad_dc_2_py2: <<: *shared_template script: diff --git a/VERSION b/VERSION index a07b000b709..48820391c4f 100644 --- a/VERSION +++ b/VERSION @@ -87,7 +87,7 @@ SAMBA_VERSION_PRE_RELEASE= # e.g. SAMBA_VERSION_RC_RELEASE=1 # # -> "3.0.0rc1" # ######################################################## -SAMBA_VERSION_RC_RELEASE=4 +SAMBA_VERSION_RC_RELEASE= ######################################################## # To mark SVN snapshots this should be set to 'yes' # diff --git a/WHATSNEW.txt b/WHATSNEW.txt index 875d168e749..5d3d23ab9da 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -1,16 +1,11 @@ -Release Announcements -===================== + ============================== + Release Notes for Samba 4.10.0 + March 19, 2019 + ============================== -This is the fourth release candidate of Samba 4.10. This is *not* -intended for production environments and is designed for testing -purposes only. Please report any defects via the Samba bug reporting -system at https://bugzilla.samba.org/. -Samba 4.10 will be the next version of the Samba suite. - - -UPGRADING -========= +This is the first stable release of the Samba 4.10 release series. +Please read the release notes carefully before upgrading. NEW FEATURES/CHANGES @@ -194,6 +189,19 @@ DC that had SMBv1 disabled. SMBv2 support has now been added for samba-tool. The affected commands are 'samba-tool domain backup|rename' and the 'samba-tool gpo' set of commands. Refer also bug #13676. +New glusterfs_fuse VFS module +----------------------------- + +The new vfs_glusterfs_fuse module improves performance when Samba +accesses a glusterfs volume mounted via FUSE (Filesystem in Userspace +as part of the Linux kernel). It achieves that by leveraging a +mechanism to retrieve the appropriate case of filenames by querying a +specific extended attribute in the filesystem. No extra configuration +is required to use this module, only glusterfs_fuse needs to be set in +the "vfs objects" parameter. Further details can be found in the +vfs_glusterfs_fuse(8) manpage. This new vfs_glusterfs_fuse module does +not replace the existing vfs_glusterfs module, it just provides an +additional, alternative mechanism to access a Gluster volume. REMOVED FEATURES ================ @@ -242,6 +250,34 @@ smb.conf changes sharemode" but for SMB getinfo +CHANGES SINCE 4.10.0rc4 +======================= + +o Andrew Bartlett <abart...@samba.org> + * BUG 13760: s4-server: Open and close a transaction on sam.ldb at startup. + +o Ralph Boehme <s...@samba.org> + * BUG 13812: access_check_max_allowed() doesn't process "Owner Rights" ACEs. + +o Joe Guo <j...@catalyst.net.nz> + * s4/scripting/bin: Open unicode files with utf8 encoding and write + * unicode string. + +o Björn Jacke <b...@sernet.de> + * BUG 13759: sambaundoguididx: Use the right escaped oder unescaped sam ldb + files. + +o Volker Lendecke <v...@samba.org> + * BUG 13813: Fix idmap cache pollution with S-1-22- IDs on winbind hickup. + +o Christof Schmitt <c...@samba.org> + * passdb: Update ABI to 0.27.2. + * BUG 13813: lib/winbind_util: Add winbind_xid_to_sid for --without-winbind. + +o Andreas Schneider <a...@samba.org> + * BUG 13823: lib:util: Move debug message for mkdir failing to log level 1. + + CHANGES SINCE 4.10.0rc3 ======================= diff --git a/lib/util/util.c b/lib/util/util.c index f52f69c6ef0..dc1772c839e 100644 --- a/lib/util/util.c +++ b/lib/util/util.c @@ -200,9 +200,9 @@ _PUBLIC_ bool directory_create_or_exist(const char *dname, old_umask = umask(0); ret = mkdir(dname, dir_perms); if (ret == -1 && errno != EEXIST) { - DEBUG(0, ("mkdir failed on directory " - "%s: %s\n", dname, - strerror(errno))); + DBG_WARNING("mkdir failed on directory %s: %s\n", + dname, + strerror(errno)); umask(old_umask); return false; } diff --git a/libcli/security/access_check.c b/libcli/security/access_check.c index 03a7dca4adf..322f4fdb0c6 100644 --- a/libcli/security/access_check.c +++ b/libcli/security/access_check.c @@ -109,24 +109,61 @@ static uint32_t access_check_max_allowed(const struct security_descriptor *sd, const struct security_token *token) { uint32_t denied = 0, granted = 0; + bool am_owner = false; + bool have_owner_rights_ace = false; unsigned i; + if (sd->dacl == NULL) { + if (security_token_has_sid(token, sd->owner_sid)) { + granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL; + } + return granted; + } + if (security_token_has_sid(token, sd->owner_sid)) { - granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL; + /* + * Check for explicit owner rights: if there are none, we remove + * the default owner right SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL + * from remaining_access. Otherwise we just process the + * explicitly granted rights when processing the ACEs. + */ + am_owner = true; + + for (i=0; i < sd->dacl->num_aces; i++) { + struct security_ace *ace = &sd->dacl->aces[i]; + + if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) { + continue; + } + + have_owner_rights_ace = dom_sid_equal( + &ace->trustee, &global_sid_Owner_Rights); + if (have_owner_rights_ace) { + break; + } + } } - if (sd->dacl == NULL) { - return granted & ~denied; + if (am_owner && !have_owner_rights_ace) { + granted |= SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL; } for (i = 0;i<sd->dacl->num_aces; i++) { struct security_ace *ace = &sd->dacl->aces[i]; + bool is_owner_rights_ace = false; if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) { continue; } - if (!security_token_has_sid(token, &ace->trustee)) { + if (am_owner) { + is_owner_rights_ace = dom_sid_equal( + &ace->trustee, &global_sid_Owner_Rights); + } + + if (!is_owner_rights_ace && + !security_token_has_sid(token, &ace->trustee)) + { continue; } @@ -136,7 +173,7 @@ static uint32_t access_check_max_allowed(const struct security_descriptor *sd, break; case SEC_ACE_TYPE_ACCESS_DENIED: case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: - denied |= ace->access_mask; + denied |= ~granted & ace->access_mask; break; default: /* Other ACE types not handled/supported */ break; @@ -159,16 +196,8 @@ NTSTATUS se_access_check(const struct security_descriptor *sd, uint32_t i; uint32_t bits_remaining; uint32_t explicitly_denied_bits = 0; - /* - * Up until Windows Server 2008, owner always had these rights. Now - * we have to use Owner Rights perms if they are on the file. - * - * In addition we have to accumulate these bits and apply them - * correctly. See bug #8795 - */ - uint32_t owner_rights_allowed = 0; - uint32_t owner_rights_denied = 0; - bool owner_rights_default = true; + bool am_owner = false; + bool have_owner_rights_ace = false; *access_granted = access_desired; bits_remaining = access_desired; @@ -198,35 +227,50 @@ NTSTATUS se_access_check(const struct security_descriptor *sd, goto done; } + if (security_token_has_sid(token, sd->owner_sid)) { + /* + * Check for explicit owner rights: if there are none, we remove + * the default owner right SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL + * from remaining_access. Otherwise we just process the + * explicitly granted rights when processing the ACEs. + */ + am_owner = true; + + for (i=0; i < sd->dacl->num_aces; i++) { + struct security_ace *ace = &sd->dacl->aces[i]; + + if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) { + continue; + } + + have_owner_rights_ace = dom_sid_equal( + &ace->trustee, &global_sid_Owner_Rights); + if (have_owner_rights_ace) { + break; + } + } + } + if (am_owner && !have_owner_rights_ace) { + bits_remaining &= ~(SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL); + } + /* check each ace in turn. */ for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) { struct security_ace *ace = &sd->dacl->aces[i]; + bool is_owner_rights_ace = false; if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) { continue; } - /* - * We need the Owner Rights permissions to ensure we - * give or deny the correct permissions to the owner. Replace - * owner_rights with the perms here if it is present. - * - * We don't care if we are not the owner because that is taken - * care of below when we check if our token has the owner SID. - * - */ - if (dom_sid_equal(&ace->trustee, &global_sid_Owner_Rights)) { - if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED) { - owner_rights_allowed |= ace->access_mask; - owner_rights_default = false; - } else if (ace->type == SEC_ACE_TYPE_ACCESS_DENIED) { - owner_rights_denied |= (bits_remaining & ace->access_mask); - owner_rights_default = false; - } - continue; + if (am_owner) { + is_owner_rights_ace = dom_sid_equal( + &ace->trustee, &global_sid_Owner_Rights); } - if (!security_token_has_sid(token, &ace->trustee)) { + if (!is_owner_rights_ace && + !security_token_has_sid(token, &ace->trustee)) + { continue; } @@ -246,21 +290,6 @@ NTSTATUS se_access_check(const struct security_descriptor *sd, /* Explicitly denied bits always override */ bits_remaining |= explicitly_denied_bits; - /* The owner always gets owner rights as defined above. */ - if (security_token_has_sid(token, sd->owner_sid)) { - if (owner_rights_default) { - /* - * Just remove them, no need to check if they are - * there. - */ - bits_remaining &= ~(SEC_STD_WRITE_DAC | - SEC_STD_READ_CONTROL); - } else { - bits_remaining &= ~owner_rights_allowed; - bits_remaining |= owner_rights_denied; - } - } - /* * We check privileges here because they override even DENY entries. */ diff --git a/script/autobuild.py b/script/autobuild.py index 2ea9e55b932..67c18a1aa35 100755 --- a/script/autobuild.py +++ b/script/autobuild.py @@ -51,6 +51,8 @@ builddirs = { "samba-ad-dc-py2": ".", "samba-ad-dc-2": ".", "samba-ad-dc-2-py2": ".", + "samba-ad-dc-backup": ".", + "samba-ad-dc-backup-py2": ".", "samba-systemkrb5": ".", "samba-nopython": ".", "samba-buildpy2-only": ".", @@ -166,6 +168,17 @@ tasks = { "--include-env=vampire_2000_dc " "--include-env=fl2000dc " "--include-env=ad_dc_no_nss " + "'", + "text/plain"), + ("check-clean-tree", "script/clean-source-tree.sh", "text/plain")], + + # run the backup/restore testenvs separately as they're fairly standalone + # (and CI seems to max out at ~8 different DCs running at once) + "samba-ad-dc-backup": [("random-sleep", "script/random-sleep.sh 60 600", "text/plain"), + ("configure", "./configure.developer --with-selftest-prefix=./bin/ab" + samba_configure_params, "text/plain"), + ("make", "make -j", "text/plain"), + ("test", "make test FAIL_IMMEDIATELY=1 " + "TESTS='${PY3_ONLY}" "--include-env=backupfromdc " "--include-env=restoredc " "--include-env=renamedc " diff --git a/source3/lib/idmap_cache.c b/source3/lib/idmap_cache.c index 77618dd5aa1..9d2149844ed 100644 --- a/source3/lib/idmap_cache.c +++ b/source3/lib/idmap_cache.c @@ -203,19 +203,23 @@ static void idmap_cache_xid2sid_parser(const struct gencache_timeout *timeout, (struct idmap_cache_xid2sid_state *)private_data; char *value; - ZERO_STRUCTP(state->sid); - state->ret = false; - if ((blob.length == 0) || (blob.data[blob.length-1] != 0)) { /* * Not a string, can't be a valid mapping */ + state->ret = false; return; } value = (char *)blob.data; - if (value[0] != '-') { + if ((value[0] == '-') && (value[1] == '\0')) { + /* + * Return NULL SID, see comment to uid2sid + */ + *state->sid = (struct dom_sid) {0}; + state->ret = true; + } else { state->ret = string_to_sid(state->sid, value); } if (state->ret) { @@ -273,6 +277,42 @@ bool idmap_cache_find_gid2sid(gid_t gid, struct dom_sid *sid, bool *expired) return state.ret; } +/** + * Find a xid2sid mapping + * @param[in] id the unix id to map + * @param[out] sid where to put the result + * @param[out] expired is the cache entry expired? + * @retval Was anything in the cache at all? + * + * If "is_null_sid(sid)", this was a negative mapping. + */ +bool idmap_cache_find_xid2sid( + const struct unixid *id, struct dom_sid *sid, bool *expired) +{ + struct idmap_cache_xid2sid_state state = { + .sid = sid, .expired = expired + }; + fstring key; + char c; + + switch (id->type) { + case ID_TYPE_UID: + c = 'U'; + break; + case ID_TYPE_GID: + c = 'G'; + break; + default: + return false; + } + + fstr_sprintf(key, "IDMAP/%cID2SID/%d", c, (int)id->id); + + gencache_parse(key, idmap_cache_xid2sid_parser, &state); + return state.ret; +} + + /** * Store a mapping in the idmap cache * @param[in] sid the sid to map diff --git a/source3/lib/idmap_cache.h b/source3/lib/idmap_cache.h index dc497022e3b..d5afa170e1a 100644 --- a/source3/lib/idmap_cache.h +++ b/source3/lib/idmap_cache.h @@ -31,6 +31,8 @@ bool idmap_cache_find_sid2gid(const struct dom_sid *sid, gid_t *pgid, bool *expired); bool idmap_cache_find_uid2sid(uid_t uid, struct dom_sid *sid, bool *expired); bool idmap_cache_find_gid2sid(gid_t gid, struct dom_sid *sid, bool *expired); +bool idmap_cache_find_xid2sid( + const struct unixid *id, struct dom_sid *sid, bool *expired); void idmap_cache_set_sid2unixid(const struct dom_sid *sid, struct unixid *unix_id); bool idmap_cache_del_uid(uid_t uid); diff --git a/source3/lib/winbind_util.c b/source3/lib/winbind_util.c index a072166ce18..0c1f2c2552a 100644 --- a/source3/lib/winbind_util.c +++ b/source3/lib/winbind_util.c @@ -23,10 +23,10 @@ #include "../lib/util/util_pw.h" #include "nsswitch/libwbclient/wbclient.h" -#if defined(WITH_WINBIND) - #include "lib/winbind_util.h" +#if defined(WITH_WINBIND) + struct passwd * winbind_getpwnam(const char * name) { wbcErr result; @@ -198,6 +198,36 @@ bool winbind_gid_to_sid(struct dom_sid *sid, gid_t gid) return (result == WBC_ERR_SUCCESS); } +bool winbind_xid_to_sid(struct dom_sid *sid, const struct unixid *xid) +{ + struct wbcUnixId wbc_xid; + struct wbcDomainSid dom_sid; + wbcErr result; + + switch (xid->type) { + case ID_TYPE_UID: + wbc_xid = (struct wbcUnixId) { + .type = WBC_ID_TYPE_UID, .id.uid = xid->id + }; + break; + case ID_TYPE_GID: + wbc_xid = (struct wbcUnixId) { + .type = WBC_ID_TYPE_GID, .id.gid = xid->id + }; + break; + default: + return false; + } + + result = wbcUnixIdsToSids(&wbc_xid, 1, &dom_sid); + if (result != WBC_ERR_SUCCESS) { -- Samba Shared Repository