diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2016-03-12 17:56:21 +0100 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2016-03-12 17:56:21 +0100 |
commit | fc180edcf4231fdfbc73560432bc45e926c08eaa (patch) | |
tree | fabba57010981fb1484f931a62c981b13d5af0a5 /winsup/cygwin/sec_acl.cc | |
parent | 018fa93e2b9a78edbe58c9d6a281783aff38e527 (diff) | |
download | cygnal-fc180edcf4231fdfbc73560432bc45e926c08eaa.tar.gz cygnal-fc180edcf4231fdfbc73560432bc45e926c08eaa.tar.bz2 cygnal-fc180edcf4231fdfbc73560432bc45e926c08eaa.zip |
Fix reading/writing Samba ACLs using RFC2307 mapping
When using RFC2307 uid/gid-mapping on Samba shares, the POSIX ACL contains
the Windows SIDs. When writing back such an ACL we have to map the
Windows SIDs back to the corresponding Samba SIDs representing the UNIX
uid/gid value. When reading Samba SIDs, make sure never to evaluate a
UNIX user account as group.
* sec_acl.cc (set_posix_access): Convert Windows SIDs to
RFC2307-mapped Sambe UNIX SIDs.
* sec_helper.cc (cygpsid::get_id): Skip UNIX user accounts when
trying to evaluate a SID as group. Skip UNIX group accounts when
trying to evaluate a SID as user.
* cygheap.h (cygheap_ugid_cache::reverse_get): New method to
get nfs id from cygwin id.
(cygheap_ugid_cache::reverse_get_uid): Wrapper for uids.
(cygheap_ugid_cache::reverse_get_gid): Wrapper for gids.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diffstat (limited to 'winsup/cygwin/sec_acl.cc')
-rw-r--r-- | winsup/cygwin/sec_acl.cc | 59 |
1 files changed, 53 insertions, 6 deletions
diff --git a/winsup/cygwin/sec_acl.cc b/winsup/cygwin/sec_acl.cc index 399324929..1919fb75b 100644 --- a/winsup/cygwin/sec_acl.cc +++ b/winsup/cygwin/sec_acl.cc @@ -138,7 +138,8 @@ set_posix_access (mode_t attr, uid_t uid, gid_t gid, { SECURITY_DESCRIPTOR sd; cyg_ldap cldap; - PSID owner, group; + PSID owner = NULL, group = NULL; + cygsid smb_owner, smb_group; NTSTATUS status; tmp_pathbuf tp; cygpsid *aclsid; @@ -157,9 +158,27 @@ set_posix_access (mode_t attr, uid_t uid, gid_t gid, modified by inheritable ACEs. */ RtlSetControlSecurityDescriptor (&sd, SE_DACL_PROTECTED, SE_DACL_PROTECTED); - /* Fetch owner and group and set in security descriptor. */ - owner = sidfromuid (uid, &cldap); - group = sidfromgid (gid, &cldap); + /* Fetch owner and group and set in security descriptor. + + For Samba we check if there's an RFC2307 mapping in place, otherwise + we're trying to create an ACL with the wrong Windows SIDs rather than + the correct Unix SIDs. Same happens below for mapping other USER and + GROUP SIDs. */ + if (is_samba) + { + uint32_t smb_uid, smb_gid; + + smb_uid = cygheap->ugid_cache.reverse_get_uid (uid); + if (smb_uid != ILLEGAL_UID) + owner = smb_owner.create (22, 2, 1, smb_uid); + smb_gid = cygheap->ugid_cache.reverse_get_gid (gid); + if (smb_gid != ILLEGAL_GID) + group = smb_group.create (22, 2, 2, smb_gid); + } + if (!owner) + owner = sidfromuid (uid, &cldap); + if (!group) + group = sidfromgid (gid, &cldap); if (!owner || !group) { set_errno (EINVAL); @@ -224,7 +243,21 @@ set_posix_access (mode_t attr, uid_t uid, gid_t gid, break; case USER: case DEF_USER: - aclsid[idx] = sidfromuid (aclbufp[idx].a_id, &cldap); + aclsid[idx] = NO_SID; + if (is_samba) + { + uint32_t smb_uid; + cygsid *smb_sid; + + smb_uid = cygheap->ugid_cache.reverse_get_uid (aclbufp[idx].a_id); + if (smb_uid != ILLEGAL_UID) + { + smb_sid = (cygsid *) alloca (sizeof (cygsid)); + aclsid[idx] = smb_sid->create (22, 2, 1, smb_uid); + } + } + if (!aclsid[idx]) + aclsid[idx] = sidfromuid (aclbufp[idx].a_id, &cldap); break; case GROUP_OBJ: aclsid[idx] = group; @@ -235,7 +268,21 @@ set_posix_access (mode_t attr, uid_t uid, gid_t gid, break; case GROUP: case DEF_GROUP: - aclsid[idx] = sidfromgid (aclbufp[idx].a_id, &cldap); + aclsid[idx] = NO_SID; + if (is_samba) + { + uint32_t smb_gid; + cygsid *smb_sid; + + smb_gid = cygheap->ugid_cache.reverse_get_gid (aclbufp[idx].a_id); + if (smb_gid != ILLEGAL_GID) + { + smb_sid = (cygsid *) alloca (sizeof (cygsid)); + aclsid[idx] = smb_sid->create (22, 2, 2, smb_gid); + } + } + if (!aclsid[idx]) + aclsid[idx] = sidfromgid (aclbufp[idx].a_id, &cldap); break; case CLASS_OBJ: case DEF_CLASS_OBJ: |