Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-developers-owner AT sourceware DOT cygnus DOT com Delivered-To: mailing list cygwin-developers AT sourceware DOT cygnus DOT com Message-ID: <387A450F.6F2F272A@vinschen.de> Date: Mon, 10 Jan 2000 21:46:07 +0100 From: Corinna Vinschen X-Mailer: Mozilla 4.7 [en] (WinNT; I) X-Accept-Language: de,en MIME-Version: 1.0 To: Chris Faylor CC: cygdev Subject: access-patch Content-Type: multipart/mixed; boundary="------------852BB2150249D672388444B3" This is a multi-part message in MIME format. --------------852BB2150249D672388444B3 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hello Chris, this access patch has the result that the function access(2) now takes the complete ACL into account instead of only evaluating the POSIX mode bits if ntsec is ON. The new function acl_access in security.cc uses the result of acl(GETACL, ...) for the evaluation. This has yet one disadvantage: In some seldom cases it's possible that the effect of ACCESS_DENIED_ACEs is not fully evaluated. In the worst case the user has apparently more rights than in reality. Nevertheless the result is exacter than only using POSIX mode bits. Later this year I will patch the acl functions so that denies are better represented. Corinna ChangeLog: ========== Mon Jan 10 01:11:00 2000 Corinna Vinschen * security.cc (acl_access): New function. * syscalls.cc (access): Calls acl_access if ntsec is on. --------------852BB2150249D672388444B3 Content-Type: text/plain; charset=us-ascii; name="access-patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="access-patch" Index: cygwin/security.cc =================================================================== RCS file: /src/cvsroot/winsup-000108/cygwin/security.cc,v retrieving revision 1.2 diff -u -p -r1.2 security.cc --- cygwin/security.cc 2000/01/09 23:52:31 1.2 +++ cygwin/security.cc 2000/01/10 14:23:27 @@ -1446,6 +1446,74 @@ getacl (const char *file, DWORD attr, in return pos; } +int +acl_access (const char *path, int flags) +{ + aclent_t acls[MAX_ACL_ENTRIES]; + int cnt; + + if ((cnt = acl (path, GETACL, MAX_ACL_ENTRIES, acls)) < 1) + return -1; + + // Only check existance. + 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 group, check is_grp_member + char owner_sidbuf[MAX_SID_LEN]; + PSID owner_sid = (PSID) owner_sidbuf; + char group_sidbuf[MAX_SID_LEN]; + PSID group_sid = (PSID) group_sidbuf; + struct passwd *pw; + struct group *gr = NULL; + + if (group_sem > 0) + continue; + ++group_sem; + if ((pw = getpwuid (acls[i].a_id)) != NULL + && get_pw_sid (owner_sid, pw)) + { + while (gr = getgrent ()) + if (get_gr_sid (group_sid, gr) + && EqualSid (owner_sid, group_sid) + && is_grp_member (myself->uid, gr->gr_gid)) + break; + endgrent (); + } + --group_sem; + if (! gr) + continue; + } + break; + case GROUP_OBJ: + case GROUP: + if (acls[i].a_id != myself->gid && + !is_grp_member (myself->uid, acls[i].a_id)) + continue; + break; + case OTHER_OBJ: + break; + default: + continue; + } + if ((!(flags & R_OK) || (acls[i].a_perm & S_IREAD)) + && (!(flags & W_OK) || (acls[i].a_perm & S_IWRITE)) + && (!(flags & X_OK) || (acls[i].a_perm & S_IEXEC))) + return 0; + } + set_errno (EACCES); + return -1; +} + extern "C" int acl (const char *path, int cmd, int nentries, aclent_t *aclbufp) Index: cygwin/syscalls.cc =================================================================== RCS file: /src/cvsroot/winsup-000108/cygwin/syscalls.cc,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 syscalls.cc --- cygwin/syscalls.cc 2000/01/09 10:50:55 1.1.1.1 +++ cygwin/syscalls.cc 2000/01/10 02:12:34 @@ -1017,22 +1017,26 @@ lstat (const char *name, struct stat *bu return stat_worker ("lstat", name, buf, 1); } +extern int acl_access (const char *, int); + extern "C" int access (const char *fn, int flags) { - struct stat st; - int r; - - r = stat (fn, &st); - if (r) - return -1; // flags were incorrectly specified if (flags & ~(F_OK|R_OK|W_OK|X_OK)) { set_errno (EINVAL); return -1; } + + if (os_being_run == winNT && allow_ntsec) + return acl_access (fn, flags); + + struct stat st; + int r = stat (fn, &st); + if (r) + return -1; r = -1; if (flags & R_OK) { --------------852BB2150249D672388444B3--