Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2022-08-04 17:58:50 +0300
committerCorinna Vinschen <corinna@vinschen.de>2022-08-05 13:02:11 +0300
commit007e23d6390af11582e55453269b7a51c723d2dd (patch)
tree8e8cff3ca23f5e56d9766a5ee6c6abb366611b07 /winsup/cygwin/security.cc
parent1e428bee1c5ef7c76ba4e46e6693b913edc9bbf3 (diff)
Cygwin: Reorganize cygwin source dir
Create subdirs and move files accordingly: - DevDocs: doc files - fhandler: fhandler sources, split fhandler.cc into base.cc and null.cc - local_includes: local include files - scripts: scripts called during build - sec: security sources Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diffstat (limited to 'winsup/cygwin/security.cc')
-rw-r--r--winsup/cygwin/security.cc748
1 files changed, 0 insertions, 748 deletions
diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc
deleted file mode 100644
index 04e777852..000000000
--- a/winsup/cygwin/security.cc
+++ /dev/null
@@ -1,748 +0,0 @@
-/* security.cc: NT file access control functions
-
- Originaly written by Gunther Ebert, gunther.ebert@ixos-leipzig.de
- Completely rewritten by Corinna Vinschen <corinna@vinschen.de>
-
-This file is part of Cygwin.
-
-This software is a copyrighted work licensed under the terms of the
-Cygwin license. Please consult the file "CYGWIN_LICENSE" for
-details. */
-
-#include "winsup.h"
-#include <unistd.h>
-#include <stdlib.h>
-#include <cygwin/acl.h>
-#include "cygerrno.h"
-#include "security.h"
-#include "path.h"
-#include "fhandler.h"
-#include "dtable.h"
-#include "pinfo.h"
-#include "cygheap.h"
-#include "ntdll.h"
-#include "tls_pbuf.h"
-#include <aclapi.h>
-
-#define ALL_SECURITY_INFORMATION (DACL_SECURITY_INFORMATION \
- | GROUP_SECURITY_INFORMATION \
- | OWNER_SECURITY_INFORMATION)
-
-static GENERIC_MAPPING NO_COPY_RO file_mapping = { FILE_GENERIC_READ,
- FILE_GENERIC_WRITE,
- FILE_GENERIC_EXECUTE,
- FILE_ALL_ACCESS };
-LONG
-get_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd,
- bool justcreated)
-{
- NTSTATUS status = STATUS_SUCCESS;
- OBJECT_ATTRIBUTES attr;
- IO_STATUS_BLOCK io;
- ULONG len = SD_MAXIMUM_SIZE, rlen;
-
- /* Allocate space for the security descriptor. */
- if (!sd.malloc (len))
- {
- set_errno (ENOMEM);
- return -1;
- }
- /* Try to fetch the security descriptor if the handle is valid. */
- if (fh)
- {
- status = NtQuerySecurityObject (fh, ALL_SECURITY_INFORMATION,
- sd, len, &rlen);
- if (!NT_SUCCESS (status))
- debug_printf ("NtQuerySecurityObject (%S), status %y",
- pc.get_nt_native_path (), status);
- }
- /* If the handle was NULL, or fetching with the original handle didn't work,
- try to reopen the file with READ_CONTROL and fetch the security descriptor
- using that handle. */
- if (!fh || !NT_SUCCESS (status))
- {
- status = NtOpenFile (&fh, READ_CONTROL,
- fh ? pc.init_reopen_attr (attr, fh)
- : pc.get_object_attr (attr, sec_none_nih),
- &io, FILE_SHARE_VALID_FLAGS,
- FILE_OPEN_FOR_BACKUP_INTENT
- | pc.is_known_reparse_point ()
- ? FILE_OPEN_REPARSE_POINT : 0);
- if (!NT_SUCCESS (status))
- {
- sd.free ();
- __seterrno_from_nt_status (status);
- return -1;
- }
- status = NtQuerySecurityObject (fh, ALL_SECURITY_INFORMATION,
- sd, len, &rlen);
- NtClose (fh);
- if (!NT_SUCCESS (status))
- {
- sd.free ();
- __seterrno_from_nt_status (status);
- return -1;
- }
- }
- /* We have a security descriptor now. Unfortunately, if you want to know
- if an ACE is inherited from the parent object, this isn't sufficient.
-
- In the simple case, the SDs control word contains one of the
- SE_DACL_AUTO_INHERITED or SE_DACL_PROTECTED flags, or at least one of
- the ACEs has the INHERITED_ACE flag set. In all of these cases we
- know the DACL has been inherited.
-
- If none of these flags is set in the SD, the information whether
- or not an ACE has been inherited is not available in the DACL of the
- object. In this case GetSecurityInfo fetches the SD from the parent
- directory and tests if the object's SD contains inherited ACEs from the
- parent.
-
- Note that we're not testing the SE_DACL_AUTO_INHERITED and
- SE_DACL_PROTECTED flags here because we know the state the file's SD
- is in. Since we're creating all files with a NULL descriptor, the DACL
- is either inherited from the parent, or it's the default DACL. In
- neither case, one of these flags is set.
-
- For speed, we're not calling RtlConvertToAutoInheritSecurityObject
- anymore (but keep the code here for reference). Rather we just test
- if one of the parent's ACEs is inheritable. If so, we know we inherited
- it and set the SE_DACL_AUTO_INHERITED flag. If not, we may assume our
- object's DACL is the default DACL.
-
- This functionality is slow and the extra information is only required
- when the file has been created and the permissions are about to be set
- to POSIX permissions. Therefore we only use it in case the file just
- got created. */
- if (justcreated)
- {
- PACL dacl;
- BOOLEAN exists, def;
- ACCESS_ALLOWED_ACE *ace;
- UNICODE_STRING dirname;
- PSECURITY_DESCRIPTOR psd;
- tmp_pathbuf tp;
-
- /* Open the parent directory with READ_CONTROL... */
- RtlSplitUnicodePath (pc.get_nt_native_path (), &dirname, NULL);
- InitializeObjectAttributes (&attr, &dirname, pc.objcaseinsensitive (),
- NULL, NULL);
- status = NtOpenFile (&fh, READ_CONTROL, &attr, &io,
- FILE_SHARE_VALID_FLAGS,
- FILE_OPEN_FOR_BACKUP_INTENT
- | FILE_OPEN_REPARSE_POINT);
- if (!NT_SUCCESS (status))
- {
- debug_printf ("NtOpenFile (%S), status %y", &dirname, status);
- return 0;
- }
- /* ... fetch the parent's security descriptor ... */
- psd = (PSECURITY_DESCRIPTOR) tp.w_get ();
- status = NtQuerySecurityObject (fh, ALL_SECURITY_INFORMATION,
- psd, len, &rlen);
- NtClose (fh);
- if (!NT_SUCCESS (status))
- {
- debug_printf ("NtQuerySecurityObject (%S), status %y",
- &dirname, status);
- return 0;
- }
-#if 0
- /* ... and create a new security descriptor in which all inherited ACEs
- are marked with the INHERITED_ACE flag. For a description of the
- undocumented RtlConvertToAutoInheritSecurityObject function from
- ntdll.dll see the MSDN man page for the advapi32 function
- ConvertToAutoInheritPrivateObjectSecurity. Fortunately the latter
- is just a shim. */
- PSECURITY_DESCRIPTOR nsd;
- status = RtlConvertToAutoInheritSecurityObject (psd, sd, &nsd, NULL,
- pc.isdir (),
- &file_mapping);
- if (!NT_SUCCESS (status))
- {
- debug_printf ("RtlConvertToAutoInheritSecurityObject (%S), status %y",
- &dirname, status);
- return 0;
- }
- /* Eventually copy the new security descriptor into sd and delete the
- original one created by RtlConvertToAutoInheritSecurityObject from
- the heap. */
- len = RtlLengthSecurityDescriptor (nsd);
- memcpy ((PSECURITY_DESCRIPTOR) sd, nsd, len);
- RtlDeleteSecurityObject (&nsd);
-#else
- /* ... and check the parent descriptor for inheritable ACEs matching
- our current object type (file/dir). The simple truth in our case
- is, either the parent dir had inheritable ACEs and all our ACEs are
- inherited, or the parent dir didn't have inheritable ACEs and all
- our ACEs are taken from the default DACL. */
- bool inherited = false;
- BYTE search_flags = pc.isdir () ? SUB_CONTAINERS_AND_OBJECTS_INHERIT
- : SUB_OBJECTS_ONLY_INHERIT;
- if (NT_SUCCESS (RtlGetDaclSecurityDescriptor (psd, &exists, &dacl, &def))
- && exists && dacl)
- for (ULONG idx = 0; idx < dacl->AceCount; ++idx)
- if (NT_SUCCESS (RtlGetAce (dacl, idx, (PVOID *) &ace))
- && (ace->Header.AceFlags & search_flags))
- {
- inherited = true;
- break;
- }
- /* Then, if the parent descriptor contained inheritable ACEs, we mark
- the SD as SE_DACL_AUTO_INHERITED. Note that this requires the
- matching check in get_posix_access. If we ever revert to
- RtlConvertToAutoInheritSecurityObject, the check in get_posix_access
- has to test every single ACE for the INHERITED_ACE flag again. */
- if (inherited
- && NT_SUCCESS (RtlGetDaclSecurityDescriptor (sd, &exists, &dacl,
- &def))
- && exists && dacl)
- RtlSetControlSecurityDescriptor (sd, SE_DACL_AUTO_INHERITED,
- SE_DACL_AUTO_INHERITED);
-#endif
- }
- return 0;
-}
-
-LONG
-set_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd, bool is_chown)
-{
- NTSTATUS status = STATUS_SUCCESS;
- int retry = 0;
- int res = -1;
-
- for (; retry < 2; ++retry)
- {
- if (fh)
- {
- status = NtSetSecurityObject (fh,
- is_chown ? ALL_SECURITY_INFORMATION
- : DACL_SECURITY_INFORMATION,
- sd);
- if (NT_SUCCESS (status))
- {
- res = 0;
- break;
- }
- }
- if (!retry)
- {
- OBJECT_ATTRIBUTES attr;
- IO_STATUS_BLOCK io;
- status = NtOpenFile (&fh, (is_chown ? WRITE_OWNER : 0) | WRITE_DAC,
- fh ? pc.init_reopen_attr (attr, fh)
- : pc.get_object_attr (attr, sec_none_nih),
- &io,
- FILE_SHARE_VALID_FLAGS,
- FILE_OPEN_FOR_BACKUP_INTENT
- | pc.is_known_reparse_point ()
- ? FILE_OPEN_REPARSE_POINT : 0);
- if (!NT_SUCCESS (status))
- {
- fh = NULL;
- break;
- }
- }
- }
- if (retry && fh)
- NtClose (fh);
- if (!NT_SUCCESS (status))
- __seterrno_from_nt_status (status);
- return res;
-}
-
-static int
-get_reg_sd (HANDLE handle, security_descriptor &sd_ret)
-{
- LONG ret;
- DWORD len = 0;
-
- ret = RegGetKeySecurity ((HKEY) handle, ALL_SECURITY_INFORMATION,
- sd_ret, &len);
- if (ret == ERROR_INSUFFICIENT_BUFFER)
- {
- if (!sd_ret.malloc (len))
- set_errno (ENOMEM);
- else
- ret = RegGetKeySecurity ((HKEY) handle, ALL_SECURITY_INFORMATION,
- sd_ret, &len);
- }
- if (ret != ERROR_SUCCESS)
- {
- __seterrno ();
- return -1;
- }
- return 0;
-}
-
-int
-get_reg_attribute (HKEY hkey, mode_t *attribute, uid_t *uidret,
- gid_t *gidret)
-{
- security_descriptor sd;
-
- if (!get_reg_sd (hkey, sd))
- {
- get_posix_access (sd, attribute, uidret, gidret, NULL, 0);
- return 0;
- }
- /* The entries are already set to default values */
- return -1;
-}
-
-int
-get_file_attribute (HANDLE handle, path_conv &pc,
- mode_t *attribute, uid_t *uidret, gid_t *gidret)
-{
- if (pc.has_acls ())
- {
- security_descriptor sd;
-
- if (!get_file_sd (handle, pc, sd, false))
- {
- get_posix_access (sd, attribute, uidret, gidret, NULL, 0);
- return 0;
- }
- /* ENOSYS is returned by get_file_sd if fetching the DACL from a remote
- share returns STATUS_INVALID_NETWORK_RESPONSE, which in turn is
- converted to ERROR_BAD_NET_RESP. This potentially occurs when trying
- to fetch DACLs from a NT4 machine which is not part of the domain of
- the requesting machine. */
- else if (get_errno () != ENOSYS)
- {
- if (uidret)
- *uidret = ILLEGAL_UID;
- if (gidret)
- *gidret = ILLEGAL_GID;
-
- return -1;
- }
- }
-
- if (uidret)
- *uidret = myself->uid;
- if (gidret)
- *gidret = myself->gid;
-
- return -1;
-}
-
-bool
-add_access_allowed_ace (PACL acl, DWORD attributes, PSID sid, size_t &len_add,
- DWORD inherit)
-{
- NTSTATUS status = RtlAddAccessAllowedAceEx (acl, ACL_REVISION, inherit,
- attributes, sid);
- if (!NT_SUCCESS (status))
- {
- __seterrno_from_nt_status (status);
- return false;
- }
- len_add += sizeof (ACCESS_ALLOWED_ACE) - sizeof (DWORD) + RtlLengthSid (sid);
- return true;
-}
-
-bool
-add_access_denied_ace (PACL acl, DWORD attributes, PSID sid, size_t &len_add,
- DWORD inherit)
-{
- NTSTATUS status = RtlAddAccessDeniedAceEx (acl, ACL_REVISION, inherit,
- attributes, sid);
- if (!NT_SUCCESS (status))
- {
- __seterrno_from_nt_status (status);
- return false;
- }
- len_add += sizeof (ACCESS_DENIED_ACE) - sizeof (DWORD) + RtlLengthSid (sid);
- return true;
-}
-
-void
-set_security_attribute (path_conv &pc, int attribute, PSECURITY_ATTRIBUTES psa,
- security_descriptor &sd)
-{
- psa->lpSecurityDescriptor = sd.malloc (SECURITY_DESCRIPTOR_MIN_LENGTH);
- RtlCreateSecurityDescriptor ((PSECURITY_DESCRIPTOR) psa->lpSecurityDescriptor,
- SECURITY_DESCRIPTOR_REVISION);
- psa->lpSecurityDescriptor = set_posix_access (attribute, geteuid (),
- getegid (), NULL, 0,
- sd, false);
-}
-
-int
-get_object_sd (HANDLE handle, security_descriptor &sd)
-{
- ULONG len = 0;
- NTSTATUS status;
-
- status = NtQuerySecurityObject (handle, ALL_SECURITY_INFORMATION,
- sd, len, &len);
- if (status != STATUS_BUFFER_TOO_SMALL)
- {
- __seterrno_from_nt_status (status);
- return -1;
- }
- if (!sd.malloc (len))
- {
- set_errno (ENOMEM);
- return -1;
- }
- status = NtQuerySecurityObject (handle, ALL_SECURITY_INFORMATION,
- sd, len, &len);
- if (!NT_SUCCESS (status))
- {
- __seterrno_from_nt_status (status);
- return -1;
- }
- return 0;
-}
-
-int
-get_object_attribute (HANDLE handle, uid_t *uidret, gid_t *gidret,
- mode_t *attribute)
-{
- security_descriptor sd;
-
- if (get_object_sd (handle, sd))
- return -1;
- return get_posix_access (sd, attribute, uidret, gidret, NULL, 0)
- >= 0 ? 0 : -1;
-}
-
-int
-create_object_sd_from_attribute (uid_t uid, gid_t gid, mode_t attribute,
- security_descriptor &sd)
-{
- return set_posix_access (attribute, uid, gid, NULL, 0, sd, false)
- ? 0 : -1;
-}
-
-int
-set_object_sd (HANDLE handle, security_descriptor &sd, bool chown)
-{
- NTSTATUS status;
- status = NtSetSecurityObject (handle, chown ? ALL_SECURITY_INFORMATION
- : DACL_SECURITY_INFORMATION, sd);
- if (!NT_SUCCESS (status))
- {
- __seterrno_from_nt_status (status);
- return -1;
- }
- return 0;
-}
-
-int
-set_object_attribute (HANDLE handle, uid_t uid, gid_t gid, mode_t attribute)
-{
- security_descriptor sd;
-
- if (create_object_sd_from_attribute (uid, gid, attribute, sd)
- || set_object_sd (handle, sd, uid != ILLEGAL_UID || gid != ILLEGAL_GID))
- return -1;
- return 0;
-}
-
-int
-set_created_file_access (HANDLE handle, path_conv &pc, mode_t attr)
-{
- int ret = -1;
- security_descriptor sd, sd_ret;
- mode_t attr_rd;
- uid_t uid;
- gid_t gid;
- tmp_pathbuf tp;
- aclent_t *aclp;
- int nentries, idx;
- bool std_acl;
-
- if (!get_file_sd (handle, pc, sd, true))
- {
- attr |= S_JUSTCREATED;
- if (pc.isdir ())
- attr |= S_IFDIR;
- attr_rd = attr;
- aclp = (aclent_t *) tp.c_get ();
- if ((nentries = get_posix_access (sd, &attr_rd, &uid, &gid, aclp,
- MAX_ACL_ENTRIES, &std_acl)) >= 0)
- {
- if (S_ISLNK (attr))
- {
- /* Symlinks always get the request POSIX perms. */
- aclp[0].a_perm = (attr >> 6) & S_IRWXO;
- if ((idx = searchace (aclp, nentries, GROUP_OBJ)) >= 0)
- aclp[idx].a_perm = (attr >> 3) & S_IRWXO;
- if ((idx = searchace (aclp, nentries, CLASS_OBJ)) >= 0)
- aclp[idx].a_perm = (attr >> 3) & S_IRWXO;
- if ((idx = searchace (aclp, nentries, OTHER_OBJ)) >= 0)
- aclp[idx].a_perm = attr & S_IRWXO;
- }
- else
- {
- /* Overwrite ACL permissions as required by POSIX 1003.1e
- draft 17. */
- aclp[0].a_perm &= (attr >> 6) & S_IRWXO;
- if ((idx = searchace (aclp, nentries, CLASS_OBJ)) >= 0)
- aclp[idx].a_perm &= (attr >> 3) & S_IRWXO;
- if (std_acl
- && (idx = searchace (aclp, nentries, GROUP_OBJ)) >= 0)
- aclp[idx].a_perm &= (attr >> 3) & S_IRWXO;
- if ((idx = searchace (aclp, nentries, OTHER_OBJ)) >= 0)
- aclp[idx].a_perm &= attr & S_IRWXO;
- }
- /* Construct appropriate inherit attribute for new directories.
- Basically we do this only for the sake of non-Cygwin applications.
- Cygwin applications don't need these. Additionally, if the
- S_ISGID bit is set, propagate it. */
- if (S_ISDIR (attr))
- {
- if (searchace (aclp, nentries, DEF_USER_OBJ) < 0)
- {
- aclp[nentries].a_type = DEF_USER_OBJ;
- aclp[nentries].a_id = ILLEGAL_UID;
- aclp[nentries++].a_perm = (attr >> 6) & S_IRWXO;
- }
- if (searchace (aclp, nentries, DEF_GROUP_OBJ) < 0)
- {
- aclp[nentries].a_type = DEF_GROUP_OBJ;
- aclp[nentries].a_id = ILLEGAL_GID;
- aclp[nentries++].a_perm = (attr >> 3) & S_IRWXO;
- }
- if (searchace (aclp, nentries, DEF_OTHER_OBJ) < 0)
- {
- aclp[nentries].a_type = DEF_OTHER_OBJ;
- aclp[nentries].a_id = ILLEGAL_UID;
- aclp[nentries++].a_perm = attr & S_IRWXO;
- }
- if (attr_rd & S_ISGID)
- attr |= S_ISGID;
- }
- if (set_posix_access (attr, uid, gid, aclp, nentries, sd_ret,
- pc.fs_is_samba ()))
- ret = set_file_sd (handle, pc, sd_ret, attr_rd & S_ISGID);
- }
- }
- return ret;
-}
-
-static int
-check_access (security_descriptor &sd, GENERIC_MAPPING &mapping,
- ACCESS_MASK desired, int flags, bool effective)
-{
- int ret = -1;
- NTSTATUS status, allow;
- ACCESS_MASK granted;
- DWORD plen = sizeof (PRIVILEGE_SET) + 3 * sizeof (LUID_AND_ATTRIBUTES);
- PPRIVILEGE_SET pset = (PPRIVILEGE_SET) alloca (plen);
- HANDLE tok = ((effective && cygheap->user.issetuid ())
- ? cygheap->user.imp_token ()
- : hProcImpToken);
-
- if (!tok)
- {
- if (!DuplicateTokenEx (hProcToken, MAXIMUM_ALLOWED, NULL,
- SecurityImpersonation, TokenImpersonation,
- &hProcImpToken))
- {
- __seterrno ();
- return ret;
- }
- tok = hProcImpToken;
- }
-
- status = NtAccessCheck (sd, tok, desired, &mapping, pset, &plen, &granted,
- &allow);
- if (!NT_SUCCESS (status))
- __seterrno ();
- else if (!NT_SUCCESS (allow))
- {
- /* CV, 2006-10-16: Now, that's really weird. Imagine a user who has no
- standard access to a file, but who has backup and restore privileges
- and these privileges are enabled in the access token. One would
- expect that the AccessCheck function takes this into consideration
- when returning the access status. Otherwise, why bother with the
- pset parameter, right?
- But not so. AccessCheck actually returns a status of "false" here,
- even though opening a file with backup resp. restore intent
- naturally succeeds for this user. This definitely spoils the results
- of access(2) for administrative users or the SYSTEM account. So, in
- case the access check fails, another check against the user's
- backup/restore privileges has to be made. Sigh. */
- int granted_flags = 0;
- BOOLEAN has_priv;
-
- if (flags & R_OK)
- {
- pset->PrivilegeCount = 1;
- pset->Control = 0;
- pset->Privilege[0].Luid.HighPart = 0L;
- pset->Privilege[0].Luid.LowPart = SE_BACKUP_PRIVILEGE;
- pset->Privilege[0].Attributes = 0;
- status = NtPrivilegeCheck (tok, pset, &has_priv);
- if (NT_SUCCESS (status) && has_priv)
- granted_flags |= R_OK;
- }
- if (flags & W_OK)
- {
- pset->PrivilegeCount = 1;
- pset->Control = 0;
- pset->Privilege[0].Luid.HighPart = 0L;
- pset->Privilege[0].Luid.LowPart = SE_RESTORE_PRIVILEGE;
- pset->Privilege[0].Attributes = 0;
- status = NtPrivilegeCheck (tok, pset, &has_priv);
- if (NT_SUCCESS (status) && has_priv)
- granted_flags |= W_OK;
- }
- if (granted_flags == flags)
- ret = 0;
- else
- set_errno (EACCES);
- }
- else
- ret = 0;
- 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 accounts 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 if (sid_sub_auth (ace_sid, 0) == 2) /* 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, 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)
-{
- security_descriptor sd;
- int ret = -1;
- ACCESS_MASK desired = 0;
- if (flags & R_OK)
- desired |= FILE_READ_DATA;
- if (flags & W_OK)
- desired |= FILE_WRITE_DATA;
- if (flags & X_OK)
- desired |= FILE_EXECUTE;
- if (!get_file_sd (pc.handle (), pc, sd, false))
- {
- /* 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;
-}
-
-int
-check_registry_access (HANDLE hdl, int flags, bool effective)
-{
- security_descriptor sd;
- int ret = -1;
- static GENERIC_MAPPING NO_COPY_RO reg_mapping = { KEY_READ,
- KEY_WRITE,
- KEY_EXECUTE,
- KEY_ALL_ACCESS };
- ACCESS_MASK desired = 0;
- if (flags & R_OK)
- desired |= KEY_ENUMERATE_SUB_KEYS;
- if (flags & W_OK)
- desired |= KEY_SET_VALUE;
- if (flags & X_OK)
- desired |= KEY_QUERY_VALUE;
-
- if ((HKEY) hdl == HKEY_PERFORMANCE_DATA)
- /* RegGetKeySecurity() always fails with ERROR_INVALID_HANDLE. */
- ret = 0;
- else if (!get_reg_sd (hdl, sd))
- ret = check_access (sd, reg_mapping, desired, flags, effective);
-
- /* As long as we can't write the registry... */
- if (flags & W_OK)
- {
- set_errno (EROFS);
- ret = -1;
- }
- debug_printf ("flags %y, ret %d", flags, ret);
- return ret;
-}