* fhandler.cc (fhandler_base::facl): Drop CLASS_OBJ entry.
* fhandler_disk_file.cc (fhandler_disk_file::facl): Ditto in noacl case. * sec_acl.cc (getacl): Compute useful fake CLASS_OBJ and DEF_CLASS_OBJ permission bits based on how these values are generated on Linux. Add commants to explain what the code is doing. * security.cc (get_attribute_from_acl): Compute group permission based on the actual primary group permissions and all secondary user and group ACCESS_ALLOWED_ACEs to emulate Linux' behaviour more closely. (check_access): Fix typos im comment. * include/cygwin/acl.h (MIN_ACL_ENTRIES): Redefine as 3.
This commit is contained in:
		| @@ -1,3 +1,16 @@ | |||||||
|  | 2014-08-28  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
|  | 	* fhandler.cc (fhandler_base::facl): Drop CLASS_OBJ entry. | ||||||
|  | 	* fhandler_disk_file.cc (fhandler_disk_file::facl): Ditto in noacl case. | ||||||
|  | 	* sec_acl.cc (getacl): Compute useful fake CLASS_OBJ and DEF_CLASS_OBJ | ||||||
|  | 	permission bits based on how these values are generated on Linux. | ||||||
|  | 	Add commants to explain what the code is doing. | ||||||
|  | 	* security.cc (get_attribute_from_acl): Compute group permission based | ||||||
|  | 	on the actual primary group permissions and all secondary user and group | ||||||
|  | 	ACCESS_ALLOWED_ACEs to emulate Linux' behaviour more closely. | ||||||
|  | 	(check_access): Fix typos im comment. | ||||||
|  | 	* include/cygwin/acl.h (MIN_ACL_ENTRIES): Redefine as 3. | ||||||
|  |  | ||||||
| 2014-08-28  Corinna Vinschen  <corinna@vinschen.de> | 2014-08-28  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
| 	* fhandler_disk_file.cc (fhandler_disk_file::fstatvfs): Try the | 	* fhandler_disk_file.cc (fhandler_disk_file::fstatvfs): Try the | ||||||
|   | |||||||
| @@ -1737,9 +1737,6 @@ fhandler_base::facl (int cmd, int nentries, aclent_t *aclbufp) | |||||||
| 	    aclbufp[2].a_type = OTHER_OBJ; | 	    aclbufp[2].a_type = OTHER_OBJ; | ||||||
| 	    aclbufp[2].a_id = ILLEGAL_GID; | 	    aclbufp[2].a_id = ILLEGAL_GID; | ||||||
| 	    aclbufp[2].a_perm = S_IROTH | S_IWOTH; | 	    aclbufp[2].a_perm = S_IROTH | S_IWOTH; | ||||||
| 	    aclbufp[3].a_type = CLASS_OBJ; |  | ||||||
| 	    aclbufp[3].a_id = ILLEGAL_GID; |  | ||||||
| 	    aclbufp[3].a_perm = S_IRWXU | S_IRWXG | S_IRWXO; |  | ||||||
| 	    res = MIN_ACL_ENTRIES; | 	    res = MIN_ACL_ENTRIES; | ||||||
| 	  } | 	  } | ||||||
| 	break; | 	break; | ||||||
|   | |||||||
| @@ -1045,9 +1045,6 @@ cant_access_acl: | |||||||
| 		    aclbufp[2].a_type = OTHER_OBJ; | 		    aclbufp[2].a_type = OTHER_OBJ; | ||||||
| 		    aclbufp[2].a_id = ILLEGAL_GID; | 		    aclbufp[2].a_id = ILLEGAL_GID; | ||||||
| 		    aclbufp[2].a_perm = st.st_mode & S_IRWXO; | 		    aclbufp[2].a_perm = st.st_mode & S_IRWXO; | ||||||
| 		    aclbufp[3].a_type = CLASS_OBJ; |  | ||||||
| 		    aclbufp[3].a_id = ILLEGAL_GID; |  | ||||||
| 		    aclbufp[3].a_perm = S_IRWXU | S_IRWXG | S_IRWXO; |  | ||||||
| 		    res = MIN_ACL_ENTRIES; | 		    res = MIN_ACL_ENTRIES; | ||||||
| 		  } | 		  } | ||||||
| 	      } | 	      } | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| /* cygwin/acl.h header file for Cygwin. | /* cygwin/acl.h header file for Cygwin. | ||||||
|  |  | ||||||
|    Copyright 1999, 2000, 2001, 2002, 2010 Red Hat, Inc. |    Copyright 1999, 2000, 2001, 2002, 2010, 2014 Red Hat, Inc. | ||||||
|    Written by C. Vinschen. |    Written by C. Vinschen. | ||||||
|  |  | ||||||
| This file is part of Cygwin. | This file is part of Cygwin. | ||||||
| @@ -25,7 +25,7 @@ extern "C" { | |||||||
| #define GETACL          (0x1) | #define GETACL          (0x1) | ||||||
| #define GETACLCNT       (0x2) | #define GETACLCNT       (0x2) | ||||||
|  |  | ||||||
| #define	MIN_ACL_ENTRIES (4)    // minimal acl entries from GETACLCNT | #define	MIN_ACL_ENTRIES (3)    // minimal acl entries from GETACLCNT | ||||||
| #define	MAX_ACL_ENTRIES	(256)  // max entries of each type | #define	MAX_ACL_ENTRIES	(256)  // max entries of each type | ||||||
|  |  | ||||||
| // Return values of aclcheck(3) in case of error */ | // Return values of aclcheck(3) in case of error */ | ||||||
|   | |||||||
| @@ -309,9 +309,6 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp) | |||||||
|   lacl[1].a_id = gid; |   lacl[1].a_id = gid; | ||||||
|   lacl[2].a_type = OTHER_OBJ; |   lacl[2].a_type = OTHER_OBJ; | ||||||
|   lacl[2].a_id = ILLEGAL_GID; |   lacl[2].a_id = ILLEGAL_GID; | ||||||
|   lacl[3].a_type = CLASS_OBJ; |  | ||||||
|   lacl[3].a_id = ILLEGAL_GID; |  | ||||||
|   lacl[3].a_perm = S_IROTH | S_IWOTH | S_IXOTH; |  | ||||||
|  |  | ||||||
|   PACL acl; |   PACL acl; | ||||||
|   BOOLEAN acl_exists; |   BOOLEAN acl_exists; | ||||||
| @@ -324,9 +321,11 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp) | |||||||
|     } |     } | ||||||
|  |  | ||||||
|   int pos, i, types_def = 0; |   int pos, i, types_def = 0; | ||||||
|  |   int pgrp_pos = 1, def_pgrp_pos = -1; | ||||||
|  |   mode_t class_perm = 0, def_class_perm = 0; | ||||||
|  |  | ||||||
|   if (!acl_exists || !acl) |   if (!acl_exists || !acl) | ||||||
|     for (pos = 0; pos < 3; ++pos) /* Don't change CLASS_OBJ entry */ |     for (pos = 0; pos < 3; ++pos) | ||||||
|       lacl[pos].a_perm = S_IROTH | S_IWOTH | S_IXOTH; |       lacl[pos].a_perm = S_IROTH | S_IWOTH | S_IXOTH; | ||||||
|   else |   else | ||||||
|     { |     { | ||||||
| @@ -358,13 +357,13 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp) | |||||||
| 	    } | 	    } | ||||||
| 	  else if (ace_sid == well_known_creator_group_sid) | 	  else if (ace_sid == well_known_creator_group_sid) | ||||||
| 	    { | 	    { | ||||||
| 	      type = GROUP_OBJ | ACL_DEFAULT; | 	      type = DEF_GROUP_OBJ; | ||||||
| 	      types_def |= type; | 	      types_def |= type; | ||||||
| 	      id = ILLEGAL_GID; | 	      id = ILLEGAL_GID; | ||||||
| 	    } | 	    } | ||||||
| 	  else if (ace_sid == well_known_creator_owner_sid) | 	  else if (ace_sid == well_known_creator_owner_sid) | ||||||
| 	    { | 	    { | ||||||
| 	      type = USER_OBJ | ACL_DEFAULT; | 	      type = DEF_USER_OBJ; | ||||||
| 	      types_def |= type; | 	      types_def |= type; | ||||||
| 	      id = ILLEGAL_GID; | 	      id = ILLEGAL_GID; | ||||||
| 	    } | 	    } | ||||||
| @@ -376,7 +375,12 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp) | |||||||
| 	  if (!(ace->Header.AceFlags & INHERIT_ONLY_ACE || type & ACL_DEFAULT)) | 	  if (!(ace->Header.AceFlags & INHERIT_ONLY_ACE || type & ACL_DEFAULT)) | ||||||
| 	    { | 	    { | ||||||
| 	      if ((pos = searchace (lacl, MAX_ACL_ENTRIES, type, id)) >= 0) | 	      if ((pos = searchace (lacl, MAX_ACL_ENTRIES, type, id)) >= 0) | ||||||
|  | 		{ | ||||||
| 		  getace (lacl[pos], type, id, ace->Mask, ace->Header.AceType); | 		  getace (lacl[pos], type, id, ace->Mask, ace->Header.AceType); | ||||||
|  | 		  /* Fix up CLASS_OBJ value. */ | ||||||
|  | 		  if (type == USER || type == GROUP) | ||||||
|  | 		    class_perm |= lacl[pos].a_perm; | ||||||
|  | 		} | ||||||
| 	    } | 	    } | ||||||
| 	  if ((ace->Header.AceFlags | 	  if ((ace->Header.AceFlags | ||||||
| 	      & (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE)) | 	      & (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE)) | ||||||
| @@ -389,13 +393,31 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp) | |||||||
| 	      type |= ACL_DEFAULT; | 	      type |= ACL_DEFAULT; | ||||||
| 	      types_def |= type; | 	      types_def |= type; | ||||||
| 	      if ((pos = searchace (lacl, MAX_ACL_ENTRIES, type, id)) >= 0) | 	      if ((pos = searchace (lacl, MAX_ACL_ENTRIES, type, id)) >= 0) | ||||||
|  | 		{ | ||||||
| 		  getace (lacl[pos], type, id, ace->Mask, ace->Header.AceType); | 		  getace (lacl[pos], type, id, ace->Mask, ace->Header.AceType); | ||||||
|  | 		  /* Fix up DEF_CLASS_OBJ value. */ | ||||||
|  | 		  if (type == DEF_USER || type == DEF_GROUP) | ||||||
|  | 		    def_class_perm |= lacl[pos].a_perm; | ||||||
|  | 		  /* And note the position of the DEF_GROUP_OBJ entry. */ | ||||||
|  | 		  else if (type == DEF_GROUP_OBJ) | ||||||
|  | 		    def_pgrp_pos = pos; | ||||||
| 		} | 		} | ||||||
| 	    } | 	    } | ||||||
|  | 	} | ||||||
|  |       /* If secondary user and group entries exist in the ACL, fake a matching | ||||||
|  | 	 CLASS_OBJ entry. The CLASS_OBJ permissions are the or'ed permissions | ||||||
|  | 	 of the primary group permissions and all secondary user and group | ||||||
|  | 	 permissions. */ | ||||||
|  |       if (class_perm && (pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) >= 0) | ||||||
|  | 	{ | ||||||
|  | 	  lacl[pos].a_type = CLASS_OBJ; | ||||||
|  | 	  lacl[pos].a_id = ILLEGAL_GID; | ||||||
|  | 	  lacl[pos].a_perm = class_perm | lacl[pgrp_pos].a_perm; | ||||||
|  | 	} | ||||||
|  |       /* Ensure that the default acl contains at least | ||||||
|  |       	 DEF_(USER|GROUP|OTHER)_OBJ entries.  */ | ||||||
|       if (types_def && (pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) >= 0) |       if (types_def && (pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) >= 0) | ||||||
| 	{ | 	{ | ||||||
| 	  /* Ensure that the default acl contains at |  | ||||||
| 	     least DEF_(USER|GROUP|OTHER)_OBJ entries.  */ |  | ||||||
| 	  if (!(types_def & USER_OBJ)) | 	  if (!(types_def & USER_OBJ)) | ||||||
| 	    { | 	    { | ||||||
| 	      lacl[pos].a_type = DEF_USER_OBJ; | 	      lacl[pos].a_type = DEF_USER_OBJ; | ||||||
| @@ -408,6 +430,8 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp) | |||||||
| 	      lacl[pos].a_type = DEF_GROUP_OBJ; | 	      lacl[pos].a_type = DEF_GROUP_OBJ; | ||||||
| 	      lacl[pos].a_id = gid; | 	      lacl[pos].a_id = gid; | ||||||
| 	      lacl[pos].a_perm = lacl[1].a_perm; | 	      lacl[pos].a_perm = lacl[1].a_perm; | ||||||
|  | 	      /* Note the position of the DEF_GROUP_OBJ entry. */ | ||||||
|  | 	      def_pgrp_pos = pos; | ||||||
| 	      pos++; | 	      pos++; | ||||||
| 	    } | 	    } | ||||||
| 	  if (!(types_def & OTHER_OBJ) && pos < MAX_ACL_ENTRIES) | 	  if (!(types_def & OTHER_OBJ) && pos < MAX_ACL_ENTRIES) | ||||||
| @@ -417,13 +441,18 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp) | |||||||
| 	      lacl[pos].a_perm = lacl[2].a_perm; | 	      lacl[pos].a_perm = lacl[2].a_perm; | ||||||
| 	      pos++; | 	      pos++; | ||||||
| 	    } | 	    } | ||||||
| 	  /* Include DEF_CLASS_OBJ if any named default ace exists.  */ | 	} | ||||||
| 	  if ((types_def & (USER|GROUP)) && pos < MAX_ACL_ENTRIES) |       /* If secondary user default and group default entries exist in the ACL, | ||||||
|  | 	 fake a matching DEF_CLASS_OBJ entry. The DEF_CLASS_OBJ permissions are | ||||||
|  | 	 the or'ed permissions of the primary group default permissions and all | ||||||
|  | 	 secondary user and group default permissions. */ | ||||||
|  |       if (def_class_perm && (pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) >= 0) | ||||||
| 	{ | 	{ | ||||||
| 	  lacl[pos].a_type = DEF_CLASS_OBJ; | 	  lacl[pos].a_type = DEF_CLASS_OBJ; | ||||||
| 	  lacl[pos].a_id = ILLEGAL_GID; | 	  lacl[pos].a_id = ILLEGAL_GID; | ||||||
| 	      lacl[pos].a_perm = S_IROTH | S_IWOTH | S_IXOTH; | 	  lacl[pos].a_perm = def_class_perm; | ||||||
| 	    } | 	  if (def_pgrp_pos >= 0) | ||||||
|  | 	    lacl[pos].a_perm |= lacl[def_pgrp_pos].a_perm; | ||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
|   if ((pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) < 0) |   if ((pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) < 0) | ||||||
|   | |||||||
| @@ -314,6 +314,21 @@ get_attribute_from_acl (mode_t *attribute, PACL acl, PSID owner_sid, | |||||||
| 	    *flags |= ((!(*anti & S_IXGRP)) ? S_IXGRP : 0) | 	    *flags |= ((!(*anti & S_IXGRP)) ? S_IXGRP : 0) | ||||||
| 		      | ((grp_member && !(*anti & S_IXUSR)) ? S_IXUSR : 0); | 		      | ((grp_member && !(*anti & S_IXUSR)) ? S_IXUSR : 0); | ||||||
| 	} | 	} | ||||||
|  |       else if (flags == &allow) | ||||||
|  | 	{ | ||||||
|  | 	  /* Simplified computation of additional group permissions based on | ||||||
|  | 	     the CLASS_OBJ value.  CLASS_OBJ represents the or'ed value of | ||||||
|  | 	     the primary group permissions and all secondary user and group | ||||||
|  | 	     permissions.  FIXME: This only takes ACCESS_ALLOWED_ACEs into | ||||||
|  | 	     account.  The computation with additional ACCESS_DENIED_ACE | ||||||
|  | 	     handling is much more complicated. */ | ||||||
|  | 	  if (ace->Mask & FILE_READ_BITS) | ||||||
|  | 	    *flags |= S_IRGRP; | ||||||
|  | 	  if (ace->Mask & FILE_WRITE_BITS) | ||||||
|  | 	    *flags |= S_IWGRP; | ||||||
|  | 	  if (ace->Mask & FILE_EXEC_BITS) | ||||||
|  | 	    *flags |= S_IXGRP; | ||||||
|  | 	} | ||||||
|     } |     } | ||||||
|   *attribute &= ~(S_IRWXU | S_IRWXG | S_IRWXO | S_ISVTX | S_ISGID | S_ISUID); |   *attribute &= ~(S_IRWXU | S_IRWXG | S_IRWXO | S_ISVTX | S_ISGID | S_ISUID); | ||||||
|   if (owner_sid && group_sid && RtlEqualSid (owner_sid, group_sid) |   if (owner_sid && group_sid && RtlEqualSid (owner_sid, group_sid) | ||||||
| @@ -1049,8 +1064,8 @@ check_access (security_descriptor &sd, GENERIC_MAPPING &mapping, | |||||||
|  |  | ||||||
| /* Samba override.  Check security descriptor for Samba UNIX user and group | /* 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. |    accounts and check if we have an RFC 2307 mapping to a Windows account. | ||||||
|    Create a new security descriptor with all of the UNIX acocunts with |    Create a new security descriptor with all of the UNIX accounts with | ||||||
|    valid mapping replaced with their WIndows counterpart. */ |    valid mapping replaced with their Windows counterpart. */ | ||||||
| static void | static void | ||||||
| convert_samba_sd (security_descriptor &sd_ret) | convert_samba_sd (security_descriptor &sd_ret) | ||||||
| { | { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user