Index: autoload.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/autoload.cc,v retrieving revision 1.62 diff -u -p -r1.62 autoload.cc --- autoload.cc 20 Feb 2003 11:12:44 -0000 1.62 +++ autoload.cc 21 Feb 2003 00:14:23 -0000 @@ -307,6 +307,7 @@ wsock_init () LoadDLLprime (wsock32, wsock_init) LoadDLLprime (ws2_32, wsock_init) +LoadDLLfunc (AccessCheck, 32, advapi32) LoadDLLfunc (AddAccessAllowedAce, 16, advapi32) LoadDLLfunc (AddAccessDeniedAce, 16, advapi32) LoadDLLfunc (AddAce, 20, advapi32) @@ -318,6 +319,7 @@ LoadDLLfuncEx (CryptAcquireContextA, 20, LoadDLLfuncEx (CryptGenRandom, 12, advapi32, 1) LoadDLLfuncEx (CryptReleaseContext, 8, advapi32, 1) LoadDLLfunc (DeregisterEventSource, 4, advapi32) +LoadDLLfunc (DuplicateToken, 12, advapi32) LoadDLLfuncEx (DuplicateTokenEx, 24, advapi32, 1) LoadDLLfunc (EqualSid, 8, advapi32) LoadDLLfunc (GetAce, 12, advapi32) Index: security.h =================================================================== RCS file: /cvs/src/src/winsup/cygwin/security.h,v retrieving revision 1.40 diff -u -p -r1.40 security.h --- security.h 10 Feb 2003 22:43:29 -0000 1.40 +++ security.h 21 Feb 2003 00:14:29 -0000 @@ -225,6 +225,7 @@ LONG __stdcall read_sd(const char *file, LONG __stdcall write_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, DWORD sd_size); BOOL __stdcall add_access_allowed_ace (PACL acl, int offset, DWORD attributes, PSID sid, size_t &len_add, DWORD inherit); BOOL __stdcall add_access_denied_ace (PACL acl, int offset, DWORD attributes, PSID sid, size_t &len_add, DWORD inherit); +int __stdcall check_file_access (const char *, int); void set_security_attribute (int attribute, PSECURITY_ATTRIBUTES psa, void *sd_buf, DWORD sd_buf_size); Index: syscalls.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/syscalls.cc,v retrieving revision 1.245 diff -u -p -r1.245 syscalls.cc --- syscalls.cc 10 Feb 2003 22:43:29 -0000 1.245 +++ syscalls.cc 21 Feb 2003 00:14:35 -0000 @@ -1163,8 +1163,6 @@ cygwin_lstat (const char *name, struct _ return ret; } -extern int acl_access (const char *, int); - extern "C" int access (const char *fn, int flags) { @@ -1176,11 +1174,33 @@ access (const char *fn, int flags) return -1; } - if (allow_ntsec) - return acl_access (fn, flags); + path_conv real_path (fn, PC_SYM_FOLLOW | PC_FULL, stat_suffixes); + if (real_path.error) + { + set_errno (real_path.error); + return -1; + } + + if (!real_path.exists ()) + { + set_errno (ENOENT); + return -1; + } + + if (!(flags & (R_OK | W_OK | X_OK))) + return 0; + + if (real_path.has_attribute (FILE_ATTRIBUTE_READONLY) && (flags & W_OK)) + { + set_errno (EACCES); + return -1; + } + + if (real_path.has_acls () && allow_ntsec) + return check_file_access (real_path, flags); struct __stat64 st; - int r = stat_worker (fn, &st, 0); + int r = stat_worker (real_path, &st, 0); if (r) return -1; r = -1; Index: security.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/security.cc,v retrieving revision 1.137 diff -u -p -r1.137 security.cc --- security.cc 10 Feb 2003 22:43:29 -0000 1.137 +++ security.cc 21 Feb 2003 00:14:41 -0000 @@ -1918,3 +1918,54 @@ set_file_attribute (int use_ntsec, const return set_file_attribute (use_ntsec, file, myself->uid, myself->gid, attribute); } + +int +check_file_access (const char *fn, int flags) +{ + int ret = -1; + char sd_buf[4096]; + DWORD sd_size = sizeof sd_buf; + PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf; + HANDLE hToken, hIToken; + BOOL status; + char pbuf[sizeof (PRIVILEGE_SET) + 3 * sizeof (LUID_AND_ATTRIBUTES)]; + DWORD desired = 0, granted, plength = sizeof pbuf; + static GENERIC_MAPPING NO_COPY mapping = { FILE_GENERIC_READ, + FILE_GENERIC_WRITE, + FILE_GENERIC_EXECUTE, + FILE_ALL_ACCESS }; + if (read_sd (fn, psd, &sd_size) <= 0) + goto done; + + if (cygheap->user.issetuid ()) + hToken = cygheap->user.token; + else if (!OpenProcessToken (hMainProc, TOKEN_DUPLICATE, &hToken)) + { + __seterrno (); + goto done; + } + if (!(status = DuplicateToken (hToken, SecurityIdentification, &hIToken))) + __seterrno (); + if (hToken != cygheap->user.token) + CloseHandle (hToken); + if (!status) + goto done; + + if (flags & R_OK) + desired |= FILE_READ_DATA; + if (flags & W_OK) + desired |= FILE_WRITE_DATA; + if (flags & X_OK) + desired |= FILE_EXECUTE; + if (!AccessCheck (psd, hIToken, desired, &mapping, + (PPRIVILEGE_SET) pbuf, &plength, &granted, &status)) + __seterrno (); + else if (!status) + set_errno (EACCES); + else + ret = 0; + CloseHandle (hIToken); + done: + debug_printf ("flags %x, ret %d", flags, ret); + return ret; +} Index: sec_acl.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/sec_acl.cc,v retrieving revision 1.26 diff -u -p -r1.26 sec_acl.cc --- sec_acl.cc 5 Feb 2003 16:15:22 -0000 1.26 +++ sec_acl.cc 21 Feb 2003 00:14:45 -0000 @@ -413,69 +413,6 @@ getacl (const char *file, DWORD attr, in return pos; } -int -acl_access (const char *path, int flags) -{ - __aclent32_t acls[MAX_ACL_ENTRIES]; - int cnt; - - if ((cnt = acl32 (path, GETACL, MAX_ACL_ENTRIES, acls)) < 1) - return -1; - - /* Only check existence. */ - if (!(flags & (R_OK | W_OK | X_OK))) - return 0; - - for (int i = 0; i < cnt; ++i) - { - switch (acls[i].a_type) - { - case USER_OBJ: - case USER: - if (acls[i].a_id != myself->uid) - { - /* - * Check if user is a NT group: - * Take SID from passwd, search SID in token groups - */ - cygsid owner; - struct passwd *pw; - - if ((pw = internal_getpwuid (acls[i].a_id)) != NULL - && owner.getfrompw (pw) - && internal_getgroups (0, NULL, &owner) > 0) - break; - continue; - } - break; - case GROUP_OBJ: - case GROUP: - if (acls[i].a_id != myself->gid) - { - cygsid group; - struct __group32 *gr = NULL; - - if ((gr = internal_getgrgid (acls[i].a_id)) != NULL - && group.getfromgr (gr) - && internal_getgroups (0, NULL, &group) > 0) - break; - continue; - } - break; - case OTHER_OBJ: - break; - default: - continue; - } - if ((!(flags & R_OK) || (acls[i].a_perm & S_IROTH)) - && (!(flags & W_OK) || (acls[i].a_perm & S_IWOTH)) - && (!(flags & X_OK) || (acls[i].a_perm & S_IXOTH))) - return 0; - } - set_errno (EACCES); - return -1; -} - static int acl_worker (const char *path, int cmd, int nentries, __aclent32_t *aclbufp,