This is the mail archive of the cygwin-developers@sourceware.cygnus.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

access-patch


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@vinschen.de>

	* security.cc (acl_access): New function.
	* syscalls.cc (access): Calls acl_access if ntsec is on.
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)
     {





Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]