Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2009-10-30 22:58:53 +0300
committerCorinna Vinschen <corinna@vinschen.de>2009-10-30 22:58:53 +0300
commitb42441d32b5a08a8d0e192535aaf7230236b2865 (patch)
tree43e5eef49ba6368ed8932a5405ed50f6d8805489 /winsup/cygwin/security.cc
parent53be6f3df61def98835a5b665064e2501986ccbd (diff)
* sec_helper.cc (security_descriptor::free): If sd_size is 0, call
LocalFree instead of ::free. * sec_acl.cc: Throughout replace old ACE flag definitions with current definitions as used in MSDN man pages. * security.cc: Ditto. * fhandler.cc (fhandler_base::open): Make sure file has really been just created before fixing file permissions. Add S_JUSTCREATED attribute to set_file_attribute call. * fhandler_disk_file.cc (fhandler_disk_file::mkdir): Always create dir with default security descriptor and fix descriptor afterwards. Add S_JUSTCREATED flag to set_file_attribute call. * fhandler_socket.cc (fhandler_socket::bind): Ditto for AF_LOCAL socket files. * path.cc (symlink_worker): Ditto for symlinks. * security.cc (get_file_sd): Call GetSecurityInfo rather than NtQuerySecurityObject. Explain why. Change error handling accordingly. (alloc_sd): Skip non-inherited, non-standard entries in ACL if S_JUSTCREATED attribute is set. Explain why. Minor format fixes. * security.h (S_JUSTCREATED): New define. (security_descriptor::operator=): New operator.
Diffstat (limited to 'winsup/cygwin/security.cc')
-rw-r--r--winsup/cygwin/security.cc64
1 files changed, 39 insertions, 25 deletions
diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc
index b8750eb8a..5d83060e6 100644
--- a/winsup/cygwin/security.cc
+++ b/winsup/cygwin/security.cc
@@ -24,6 +24,7 @@ details. */
#include "cygheap.h"
#include "ntdll.h"
#include "pwdgrp.h"
+#include <aclapi.h>
#define ALL_SECURITY_INFORMATION (DACL_SECURITY_INFORMATION \
| GROUP_SECURITY_INFORMATION \
@@ -32,8 +33,7 @@ details. */
LONG
get_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd)
{
- NTSTATUS status = STATUS_SUCCESS;
- ULONG len = 0;
+ DWORD error = ERROR_SUCCESS;
int retry = 0;
int res = -1;
@@ -41,20 +41,17 @@ get_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd)
{
if (fh)
{
- status = NtQuerySecurityObject (fh, ALL_SECURITY_INFORMATION,
- sd, len, &len);
- if (status == STATUS_BUFFER_TOO_SMALL)
- {
- if (!sd.malloc (len))
- {
- set_errno (ENOMEM);
- break;
- }
- status = NtQuerySecurityObject (fh, ALL_SECURITY_INFORMATION,
- sd, len, &len);
- }
- if (NT_SUCCESS (status))
+ /* Amazing but true. If you want to know if an ACE is inherited
+ from the parent object, you can't use the NtQuerySecurityObject
+ function. In the DACL returned by this functions, the
+ INHERITED_ACE flag is never set. Only by calling GetSecurityInfo
+ you get this information. Oh well. */
+ PSECURITY_DESCRIPTOR psd;
+ error = GetSecurityInfo (fh, SE_FILE_OBJECT, ALL_SECURITY_INFORMATION,
+ NULL, NULL, NULL, NULL, &psd);
+ if (error == ERROR_SUCCESS)
{
+ sd = psd;
res = 0;
break;
}
@@ -63,6 +60,7 @@ get_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd)
{
OBJECT_ATTRIBUTES attr;
IO_STATUS_BLOCK io;
+ NTSTATUS status;
status = NtOpenFile (&fh, READ_CONTROL,
pc.get_object_attr (attr, sec_none_nih),
@@ -71,14 +69,15 @@ get_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd)
if (!NT_SUCCESS (status))
{
fh = NULL;
+ error = RtlNtStatusToDosError (status);
break;
}
}
}
if (retry && fh)
NtClose (fh);
- if (!NT_SUCCESS (status))
- __seterrno_from_nt_status (status);
+ if (error != ERROR_SUCCESS)
+ __seterrno_from_win_error (error);
return res;
}
@@ -138,7 +137,7 @@ get_attribute_from_acl (mode_t *attribute, PACL acl, PSID owner_sid,
{
if (!GetAce (acl, i, (PVOID *) &ace))
continue;
- if (ace->Header.AceFlags & INHERIT_ONLY)
+ if (ace->Header.AceFlags & INHERIT_ONLY_ACE)
continue;
switch (ace->Header.AceType)
{
@@ -386,6 +385,9 @@ alloc_sd (path_conv &pc, __uid32_t uid, __gid32_t gid, int attribute,
{
BOOL dummy;
+ /* NOTE: If the high bit of attribute is set, we have just created
+ a file or directory. See below for an explanation. */
+
debug_printf("uid %d, gid %d, attribute %x", uid, gid, attribute);
/* Get owner and group from current security descriptor. */
@@ -583,15 +585,24 @@ alloc_sd (path_conv &pc, __uid32_t uid, __gid32_t gid, int attribute,
|| (ace_sid == group_sid)
|| (ace_sid == well_known_world_sid))
{
- if (ace->Header.AceFlags & SUB_CONTAINERS_AND_OBJECTS_INHERIT)
- ace->Header.AceFlags |= INHERIT_ONLY;
+ if (ace->Header.AceFlags
+ & (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE))
+ ace->Header.AceFlags |= INHERIT_ONLY_ACE;
else
continue;
}
+ else if ((attribute & S_JUSTCREATED)
+ && !(ace->Header.AceFlags & INHERITED_ACE))
+ /* Since files and dirs are created with a NULL descriptor,
+ inheritence rules kick in. However, if no inheritable entries
+ exist in the parent object, Windows will create entries from the
+ user token's default DACL in the file DACL. These entries are
+ not desired and we drop them silently here. */
+ continue;
/*
* Add unrelated ACCESS_DENIED_ACE to the beginning but
* behind the owner_deny, ACCESS_ALLOWED_ACE to the end.
- * FIXME: this would break the order of the inherit_only ACEs
+ * FIXME: this would break the order of the inherit-only ACEs
*/
if (!AddAce (acl, ACL_REVISION,
ace->Header.AceType == ACCESS_DENIED_ACE_TYPE?
@@ -611,9 +622,10 @@ alloc_sd (path_conv &pc, __uid32_t uid, __gid32_t gid, int attribute,
impact. */
/* Construct appropriate inherit attribute for new directories */
- if (S_ISDIR (attribute) && !acl_exists)
+ if (S_ISDIR (attribute) && (attribute & S_JUSTCREATED))
{
- const DWORD inherit = SUB_CONTAINERS_AND_OBJECTS_INHERIT | INHERIT_ONLY;
+ const DWORD inherit = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE
+ | INHERIT_ONLY_ACE;
#if 0 /* FIXME: Not done currently as this breaks the canonical order */
/* Set deny ACE for owner. */
@@ -630,7 +642,8 @@ alloc_sd (path_conv &pc, __uid32_t uid, __gid32_t gid, int attribute,
#endif
/* Set allow ACE for owner. */
if (!add_access_allowed_ace (acl, ace_off++, owner_allow,
- well_known_creator_owner_sid, acl_len, inherit))
+ well_known_creator_owner_sid, acl_len,
+ inherit))
return NULL;
#if 0 /* FIXME: Not done currently as this breaks the canonical order and
won't be preserved on chown and chmod */
@@ -642,7 +655,8 @@ alloc_sd (path_conv &pc, __uid32_t uid, __gid32_t gid, int attribute,
#endif
/* Set allow ACE for group. */
if (!add_access_allowed_ace (acl, ace_off++, group_allow,
- well_known_creator_group_sid, acl_len, inherit))
+ well_known_creator_group_sid, acl_len,
+ inherit))
return NULL;
/* Set allow ACE for everyone. */
if (!add_access_allowed_ace (acl, ace_off++, other_allow,