Mail Archives: cygwin-developers/2000/01/10/15:46:35
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 <corinna AT vinschen DOT de>
* 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--
- Raw text -