* autoload.cc (GetSecurityInfo): Define new autoload function.
(RegQueryInfoKeyA): Ditto. * fhandler.h (fhandler_virtual::fill_filebuf): Change return type to bool. (fhandler_proc::fill_filebuf): Ditto. (fhandler_registry::fill_filebuf): Ditto. (fhandler_process::fill_filebuf): Ditto. (fhandler_registry::value_name): Add new member. (fhandler_registry::close): Add new method. (fhandler_process::p): Remove member. * fhandler_proc.cc (fhandler_proc::open): Add set_nohandle after calling superclass method. Check return value of fill_filebuf. (fhandler_proc::fill_filebuf): Change return type to bool. Add return statement. * fhandler_process.cc (fhandler_process::open): Add set_nohandle after calling superclass method. Remove references to p. Check return value of fill_filebuf. (fhandler_process::fill_filebuf): Change return type to bool. Don't use dereference operator on p. Add return statement. (fhandler_process::format_process_stat): Fix typo. * fhandler_registry.cc: Add static open_key declaration. (fhandler_registry::exists): Assume path is already normalised. Try opening the path as a key in its own right first, before reverting to enumerating subkeys and values of the parent key. (fhandler_registry::fstat): Add additional code to return more relevant information about the registry key/value. (fhandler_registry::readdir): Explicitly set desired access when opening registry key. Remove output of buf from debug_printf format string. (fhandler_registry::open): Use set_io_handle to store registry key handle. Set value_name member. Move code to read a value from the registry to fill_filebuf. Add call to fill_filebuf. (fhandler_registry::close): New method. (fhandler_registry::fill_filebuf): Change return type to bool. Add code to read a value from registry. (fhandler_registry::open_key): Make function static. Use KEY_READ as desired access unless this is the last path component. Check the return value of RegOpenKeyEx for an error instead of hKey. * fhandler_virtual.cc (fhandler_virtual::lseek): Check the return value of fill_filebuf. (fhandler_virtual::open): Remove call to set_nohandle. (fhandler_virtual::fill_filebuf): Change return type to bool. Add return statement. * security.cc (get_nt_object_attribute): New function. (get_object_attribute): New function. * security.h (get_object_attribute): New function declaration.
This commit is contained in:
		| @@ -28,6 +28,7 @@ details. */ | ||||
| #include <wininet.h> | ||||
| #include <ntsecapi.h> | ||||
| #include <subauth.h> | ||||
| #include <aclapi.h> | ||||
| #include "cygerrno.h" | ||||
| #include "security.h" | ||||
| #include "fhandler.h" | ||||
| @@ -1301,6 +1302,174 @@ get_file_attribute (int use_ntsec, const char *file, | ||||
|   return res > 0 ? 0 : -1; | ||||
| } | ||||
|  | ||||
| static int | ||||
| get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, int *attribute, | ||||
| 		  __uid32_t *uidret, __gid32_t *gidret) | ||||
| { | ||||
|   if (!wincap.has_security ()) | ||||
|     return 0; | ||||
|  | ||||
|   PSECURITY_DESCRIPTOR psd = NULL; | ||||
|   PSID owner_sid; | ||||
|   PSID group_sid; | ||||
|   PACL acl; | ||||
|  | ||||
|   if (ERROR_SUCCESS != GetSecurityInfo (handle, object_type, | ||||
|                                         DACL_SECURITY_INFORMATION | | ||||
|                                         GROUP_SECURITY_INFORMATION | | ||||
|                                         OWNER_SECURITY_INFORMATION, | ||||
|                                         &owner_sid, | ||||
|                                         &group_sid, | ||||
|                                         &acl, | ||||
|                                         NULL, | ||||
|                                         &psd)) | ||||
| 	{ | ||||
| 	  __seterrno (); | ||||
| 	  debug_printf ("GetSecurityInfo %E"); | ||||
| 	  return -1; | ||||
|     } | ||||
|  | ||||
|   __uid32_t uid = cygsid (owner_sid).get_uid (); | ||||
|   __gid32_t gid = cygsid (group_sid).get_gid (); | ||||
|   if (uidret) | ||||
|     *uidret = uid; | ||||
|   if (gidret) | ||||
|     *gidret = gid; | ||||
|  | ||||
|   if (!attribute) | ||||
|     { | ||||
|       syscall_printf ("uid %d, gid %d", uid, gid); | ||||
|       LocalFree (psd); | ||||
|       return 0; | ||||
|     } | ||||
|  | ||||
|   BOOL grp_member = is_grp_member (uid, gid); | ||||
|  | ||||
|   if (!acl) | ||||
|     { | ||||
|       *attribute |= S_IRWXU | S_IRWXG | S_IRWXO; | ||||
|       syscall_printf ("No ACL = %x, uid %d, gid %d", | ||||
| 		      *attribute, uid, gid); | ||||
|       LocalFree (psd); | ||||
|       return 0; | ||||
|     } | ||||
|  | ||||
|   ACCESS_ALLOWED_ACE *ace; | ||||
|   int allow = 0; | ||||
|   int deny = 0; | ||||
|   int *flags, *anti; | ||||
|  | ||||
|   for (DWORD i = 0; i < acl->AceCount; ++i) | ||||
|     { | ||||
|       if (!GetAce (acl, i, (PVOID *) &ace)) | ||||
| 	continue; | ||||
|       if (ace->Header.AceFlags & INHERIT_ONLY_ACE) | ||||
| 	continue; | ||||
|       switch (ace->Header.AceType) | ||||
| 	{ | ||||
| 	case ACCESS_ALLOWED_ACE_TYPE: | ||||
| 	  flags = &allow; | ||||
| 	  anti = &deny; | ||||
| 	  break; | ||||
| 	case ACCESS_DENIED_ACE_TYPE: | ||||
| 	  flags = &deny; | ||||
| 	  anti = &allow; | ||||
| 	  break; | ||||
| 	default: | ||||
| 	  continue; | ||||
| 	} | ||||
|  | ||||
|       cygsid ace_sid ((PSID) &ace->SidStart); | ||||
|       if (owner_sid && ace_sid == owner_sid) | ||||
| 	{ | ||||
| 	  if (ace->Mask & FILE_READ_DATA) | ||||
| 	    *flags |= S_IRUSR; | ||||
| 	  if (ace->Mask & FILE_WRITE_DATA) | ||||
| 	    *flags |= S_IWUSR; | ||||
| 	  if (ace->Mask & FILE_EXECUTE) | ||||
| 	    *flags |= S_IXUSR; | ||||
| 	} | ||||
|       else if (group_sid && ace_sid == group_sid) | ||||
| 	{ | ||||
| 	  if (ace->Mask & FILE_READ_DATA) | ||||
| 	    *flags |= S_IRGRP | ||||
| 		      | ((grp_member && !(*anti & S_IRUSR)) ? S_IRUSR : 0); | ||||
| 	  if (ace->Mask & FILE_WRITE_DATA) | ||||
| 	    *flags |= S_IWGRP | ||||
| 		      | ((grp_member && !(*anti & S_IWUSR)) ? S_IWUSR : 0); | ||||
| 	  if (ace->Mask & FILE_EXECUTE) | ||||
| 	    *flags |= S_IXGRP | ||||
| 		      | ((grp_member && !(*anti & S_IXUSR)) ? S_IXUSR : 0); | ||||
| 	} | ||||
|       else if (ace_sid == well_known_world_sid) | ||||
| 	{ | ||||
| 	  if (ace->Mask & FILE_READ_DATA) | ||||
| 	    *flags |= S_IROTH | ||||
| 		      | ((!(*anti & S_IRGRP)) ? S_IRGRP : 0) | ||||
| 		      | ((!(*anti & S_IRUSR)) ? S_IRUSR : 0); | ||||
| 	  if (ace->Mask & FILE_WRITE_DATA) | ||||
| 	    *flags |= S_IWOTH | ||||
| 		      | ((!(*anti & S_IWGRP)) ? S_IWGRP : 0) | ||||
| 		      | ((!(*anti & S_IWUSR)) ? S_IWUSR : 0); | ||||
| 	  if (ace->Mask & FILE_EXECUTE) | ||||
| 	    { | ||||
| 	      *flags |= S_IXOTH | ||||
| 			| ((!(*anti & S_IXGRP)) ? S_IXGRP : 0) | ||||
| 			| ((!(*anti & S_IXUSR)) ? S_IXUSR : 0); | ||||
| 	    } | ||||
| 	  if ((*attribute & S_IFDIR) && | ||||
| 	      (ace->Mask & (FILE_WRITE_DATA | FILE_EXECUTE | FILE_DELETE_CHILD)) | ||||
| 	      == (FILE_WRITE_DATA | FILE_EXECUTE)) | ||||
| 	    *flags |= S_ISVTX; | ||||
| 	} | ||||
|       else if (ace_sid == well_known_null_sid) | ||||
| 	{ | ||||
| 	  /* Read SUID, SGID and VTX bits from NULL ACE. */ | ||||
| 	  if (ace->Mask & FILE_READ_DATA) | ||||
| 	    *flags |= S_ISVTX; | ||||
| 	  if (ace->Mask & FILE_WRITE_DATA) | ||||
| 	    *flags |= S_ISGID; | ||||
| 	  if (ace->Mask & FILE_APPEND_DATA) | ||||
| 	    *flags |= S_ISUID; | ||||
| 	} | ||||
|     } | ||||
|   *attribute &= ~(S_IRWXU | S_IRWXG | S_IRWXO | S_ISVTX | S_ISGID | S_ISUID); | ||||
|   *attribute |= allow; | ||||
|   *attribute &= ~deny; | ||||
|  | ||||
|   LocalFree (psd); | ||||
|  | ||||
|   syscall_printf ("%x, uid %d, gid %d", *attribute, uid, gid); | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| int | ||||
| get_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, | ||||
| 		    int *attribute, __uid32_t *uidret, __gid32_t *gidret) | ||||
| { | ||||
|   if (allow_ntsec) | ||||
|     { | ||||
|       int res = get_nt_object_attribute (handle, object_type, attribute, uidret, gidret); | ||||
|       if (attribute && (*attribute & S_IFLNK) == S_IFLNK) | ||||
| 	*attribute |= S_IRWXU | S_IRWXG | S_IRWXO; | ||||
|       return res; | ||||
|     } | ||||
|  | ||||
|   if (uidret) | ||||
|     *uidret = getuid32 (); | ||||
|   if (gidret) | ||||
|     *gidret = getgid32 (); | ||||
|  | ||||
|   if (!attribute) | ||||
|     return 0; | ||||
|  | ||||
|   /* symlinks are everything for everyone!*/ | ||||
|   if ((*attribute & S_IFLNK) == S_IFLNK) | ||||
|     *attribute |= S_IRWXU | S_IRWXG | S_IRWXO; | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| BOOL | ||||
| add_access_allowed_ace (PACL acl, int offset, DWORD attributes, | ||||
| 			PSID sid, size_t &len_add, DWORD inherit) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user