diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2014-03-03 16:03:47 +0400 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2014-03-03 16:03:47 +0400 |
commit | c7b9a091a5037a884948329b264f9b44102d28ce (patch) | |
tree | 9ed777ef3d73057e59765186668c62b1acf9adf9 /winsup/cygwin/security.cc | |
parent | f024a32928391c6ed6b16915aea98a9142f4f58e (diff) |
* sec_helper.cc (cygpsid::get_id): Move Samba SID->uid/gid mapping
from get_sids_info here.
(get_sids_info): Vice versa.
* security.cc (convert_samba_sd): New static function to map a Samba
security descriptor to a security descriptor with UNIX users and groups
converted to Windows SIDs per RFC 2307 mapping.
(check_file_access): Call convert_samba_sd on Samba security
descriptors.
Diffstat (limited to 'winsup/cygwin/security.cc')
-rw-r--r-- | winsup/cygwin/security.cc | 96 |
1 files changed, 95 insertions, 1 deletions
diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc index 200bfb782..07b3fa00d 100644 --- a/winsup/cygwin/security.cc +++ b/winsup/cygwin/security.cc @@ -1046,6 +1046,95 @@ check_access (security_descriptor &sd, GENERIC_MAPPING &mapping, return ret; } +/* Samba override. Check security descriptor for Samba UNIX user and group + accounts and check if we have an RFC 2307 mapping to a Windows account. + Create a new security descriptor with all of the UNIX acocunts with + valid mapping replaced with their WIndows counterpart. */ +static void +convert_samba_sd (security_descriptor &sd_ret) +{ + NTSTATUS status; + BOOLEAN dummy; + PSID sid; + cygsid owner; + cygsid group; + SECURITY_DESCRIPTOR sd; + cyg_ldap cldap; + tmp_pathbuf tp; + PACL acl, oacl; + size_t acl_len; + PACCESS_ALLOWED_ACE ace; + + if (!NT_SUCCESS (RtlGetOwnerSecurityDescriptor (sd_ret, &sid, &dummy))) + return; + owner = sid; + if (!NT_SUCCESS (RtlGetGroupSecurityDescriptor (sd_ret, &sid, &dummy))) + return; + group = sid; + + if (sid_id_auth (owner) == 22) + { + struct passwd *pwd; + uid_t uid = owner.get_uid (&cldap); + if (uid < UNIX_POSIX_OFFSET && (pwd = internal_getpwuid (uid))) + owner.getfrompw (pwd); + } + if (sid_id_auth (group) == 22) + { + struct group *grp; + gid_t gid = group.get_gid (&cldap); + if (gid < UNIX_POSIX_OFFSET && (grp = internal_getgrgid (gid))) + group.getfromgr (grp); + } + + if (!NT_SUCCESS (RtlGetDaclSecurityDescriptor (sd_ret, &dummy, + &oacl, &dummy))) + return; + acl = (PACL) tp.w_get (); + RtlCreateAcl (acl, ACL_MAXIMUM_SIZE, ACL_REVISION); + acl_len = sizeof (ACL); + + for (DWORD i = 0; i < oacl->AceCount; ++i) + if (NT_SUCCESS (RtlGetAce (oacl, i, (PVOID *) &ace))) + { + cygsid ace_sid ((PSID) &ace->SidStart); + if (sid_id_auth (ace_sid) == 22) + { + if (sid_sub_auth (ace_sid, 0) == 1) /* user */ + { + struct passwd *pwd; + uid_t uid = ace_sid.get_uid (&cldap); + if (uid < UNIX_POSIX_OFFSET && (pwd = internal_getpwuid (uid))) + ace_sid.getfrompw (pwd); + } + else /* group */ + { + struct group *grp; + gid_t gid = ace_sid.get_gid (&cldap); + if (gid < UNIX_POSIX_OFFSET && (grp = internal_getgrgid (gid))) + ace_sid.getfromgr (grp); + } + if (!add_access_allowed_ace (acl, i, ace->Mask, ace_sid, acl_len, + ace->Header.AceFlags)) + return; + } + } + acl->AclSize = acl_len; + + RtlCreateSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION); + RtlSetControlSecurityDescriptor (&sd, SE_DACL_PROTECTED, SE_DACL_PROTECTED); + RtlSetOwnerSecurityDescriptor (&sd, owner, FALSE); + RtlSetGroupSecurityDescriptor (&sd, group, FALSE); + + status = RtlSetDaclSecurityDescriptor (&sd, TRUE, acl, FALSE); + if (!NT_SUCCESS (status)) + return; + DWORD sd_size = 0; + status = RtlAbsoluteToSelfRelativeSD (&sd, sd_ret, &sd_size); + if (sd_size > 0 && sd_ret.malloc (sd_size)) + RtlAbsoluteToSelfRelativeSD (&sd, sd_ret, &sd_size); +} + int check_file_access (path_conv &pc, int flags, bool effective) { @@ -1059,7 +1148,12 @@ check_file_access (path_conv &pc, int flags, bool effective) if (flags & X_OK) desired |= FILE_EXECUTE; if (!get_file_sd (pc.handle (), pc, sd, false)) - ret = check_access (sd, file_mapping, desired, flags, effective); + { + /* Tweak Samba security descriptor as necessary. */ + if (pc.fs_is_samba ()) + convert_samba_sd (sd); + ret = check_access (sd, file_mapping, desired, flags, effective); + } debug_printf ("flags %y, ret %d", flags, ret); return ret; } |