Update ACL patches to store user/group data instead of replacing it on the retrieval side.

This commit is contained in:
Erich E. Hoover 2014-04-18 15:29:56 -06:00
parent eecf7c4a68
commit 4328f2e964
8 changed files with 176 additions and 111 deletions

View File

@ -1,13 +1,13 @@
From a82ce7ae33ae842f531c96cc9457a73430c45773 Mon Sep 17 00:00:00 2001
From 4f9fa356757454feea9c84a51dacbfa39b013503 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 17 Apr 2014 16:08:03 -0600
Date: Fri, 18 Apr 2014 13:58:24 -0600
Subject: server: Store file security attributes with extended file
attributes.
---
configure.ac | 12 ++++++++++++
server/file.c | 31 +++++++++++++++++++++++++++++++
2 files changed, 43 insertions(+)
configure.ac | 12 ++++++++
server/file.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 106 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index 46602d6..99fcb9b 100644
@ -40,7 +40,7 @@ index 46602d6..99fcb9b 100644
AC_SUBST(dlldir,"\${libdir}/wine")
diff --git a/server/file.c b/server/file.c
index 1f008ea..ceb57be 100644
index 1f008ea..b9106a8 100644
--- a/server/file.c
+++ b/server/file.c
@@ -32,6 +32,7 @@
@ -61,15 +61,16 @@ index 1f008ea..ceb57be 100644
#include "ntstatus.h"
#define WIN32_NO_STATUS
@@ -178,6 +182,30 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_
@@ -178,11 +182,75 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_
return &file->obj;
}
+void set_xattr_sd( int fd, const struct security_descriptor *sd )
+void set_xattr_sd( int fd, const struct security_descriptor *sd, const SID *user, const SID *group )
+{
+#ifdef HAVE_ATTR_XATTR_H
+ char buffer[XATTR_SIZE_MAX];
+ int present, len;
+ char buffer[XATTR_SIZE_MAX], *dst_ptr = &buffer[2], *src_ptr = (char *)sd;
+ int present, len, owner_len, group_len;
+ struct security_descriptor *dst_sd;
+ const ACL *dacl;
+
+ /* there's no point in storing the security descriptor if there's no DACL */
@ -77,14 +78,52 @@ index 1f008ea..ceb57be 100644
+ dacl = sd_get_dacl( sd, &present );
+ if (!present || !dacl) return;
+
+ len = 2 + sizeof(struct security_descriptor) + sd->owner_len + sd->group_len + sd->sacl_len
+ /* make sure that we always store the ownership information */
+ if (!sd->owner_len)
+ owner_len = FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]);
+ else
+ owner_len = sd->owner_len;
+ if (!sd->group_len)
+ group_len = FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]);
+ else
+ group_len = sd->group_len;
+ len = 2 + sizeof(struct security_descriptor) + owner_len + group_len + sd->sacl_len
+ + sd->dacl_len;
+ if (len > XATTR_SIZE_MAX) return;
+
+ /* include the descriptor revision and resource manager control bits */
+ buffer[0] = SECURITY_DESCRIPTOR_REVISION;
+ buffer[1] = 0;
+ memcpy( &buffer[2], sd, len - 2 );
+ memcpy( dst_ptr, sd, sizeof(struct security_descriptor) );
+ dst_sd = (struct security_descriptor *)dst_ptr;
+ src_ptr += sizeof(struct security_descriptor);
+ dst_ptr += sizeof(struct security_descriptor);
+ dst_sd->owner_len = owner_len;
+ dst_sd->group_len = group_len;
+ /* copy the appropriate ownership information (explicit or inferred) */
+ if (sd->owner_len)
+ {
+ memcpy( dst_ptr, src_ptr, sd->owner_len );
+ src_ptr += sd->owner_len;
+ }
+ else
+ memcpy( dst_ptr, user, owner_len );
+ dst_ptr += owner_len;
+ if (sd->group_len)
+ {
+ memcpy( dst_ptr, src_ptr, sd->group_len );
+ src_ptr += sd->group_len;
+ }
+ else
+ memcpy( dst_ptr, group, group_len );
+ dst_ptr += group_len;
+ /* copy the ACL information (explicit only) */
+ memcpy( dst_ptr, src_ptr, sd->sacl_len );
+ src_ptr += sd->sacl_len;
+ dst_ptr += sd->sacl_len;
+ memcpy( dst_ptr, src_ptr, sd->dacl_len );
+ src_ptr += sd->dacl_len;
+ dst_ptr += sd->dacl_len;
+ fsetxattr( fd, "user.wine.sd", buffer, len, 0 );
+#endif
+}
@ -92,19 +131,73 @@ index 1f008ea..ceb57be 100644
static struct object *create_file( struct fd *root, const char *nameptr, data_size_t len,
unsigned int access, unsigned int sharing, int create,
unsigned int options, unsigned int attrs,
@@ -239,6 +267,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
const struct security_descriptor *sd )
{
+ const SID *owner = NULL, *group = NULL;
struct object *obj = NULL;
struct fd *fd;
int flags;
@@ -213,9 +281,12 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
if (sd)
{
- const SID *owner = sd_get_owner( sd );
+ owner = sd_get_owner( sd );
if (!owner)
owner = token_get_user( current->process->token );
+ group = sd_get_group( sd );
+ if (!group)
+ group = token_get_primary_group( current->process->token );
mode = sd_to_mode( sd, owner );
}
else if (options & FILE_DIRECTORY_FILE)
@@ -239,6 +310,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
/* FIXME: should set error to STATUS_OBJECT_NAME_COLLISION if file existed before */
fd = open_fd( root, name, flags | O_NONBLOCK | O_LARGEFILE, &mode, access, sharing, options );
if (!fd) goto done;
+ set_xattr_sd( get_unix_fd( fd ), sd );
+ set_xattr_sd( get_unix_fd( fd ), sd, owner, group );
if (S_ISDIR(mode))
obj = create_dir_obj( fd, access, mode );
@@ -580,6 +609,8 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
@@ -548,7 +620,7 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
unsigned int set_info )
{
int unix_fd = get_unix_fd( fd );
- const SID *owner;
+ const SID *owner, *group;
struct stat st;
mode_t mode;
@@ -572,6 +644,24 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
else
owner = token_get_user( current->process->token );
+ if (set_info & GROUP_SECURITY_INFORMATION)
+ {
+ group = sd_get_group( sd );
+ if (!group)
+ {
+ set_error( STATUS_INVALID_SECURITY_DESCR );
+ return 0;
+ }
+ if (!obj->sd || !security_equal_sid( group, sd_get_group( obj->sd ) ))
+ {
+ /* FIXME: get Unix uid and call fchown */
+ }
+ }
+ else if (obj->sd)
+ group = sd_get_group( obj->sd );
+ else
+ group = token_get_primary_group( current->process->token );
+
/* group and sacl not supported */
if (set_info & DACL_SECURITY_INFORMATION)
@@ -580,6 +670,8 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX);
mode |= sd_to_mode( sd, owner );
+ set_xattr_sd( unix_fd, sd );
+ set_xattr_sd( unix_fd, sd, owner, group );
+
if (((st.st_mode ^ mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, mode ) == -1)
{

View File

@ -1,13 +1,14 @@
From 469fa2de7b5ea74c880a64c4acbb31a2397c8dc4 Mon Sep 17 00:00:00 2001
From e031dc5069bebd63770a405d684ee75a14d1826b Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 17 Apr 2014 16:09:01 -0600
Date: Fri, 18 Apr 2014 14:01:35 -0600
Subject: server: Retrieve file security attributes with extended file
attributes.
---
dlls/advapi32/tests/security.c | 49 ++++++++++++++--------------
server/file.c | 70 ++++++++++++++++++++++++++++++++++++++--
2 files changed, 91 insertions(+), 28 deletions(-)
dlls/advapi32/tests/security.c | 49 ++++++++++++++++++++--------------------
server/change.c | 2 +-
server/file.c | 28 ++++++++++++++++++++---
3 files changed, 50 insertions(+), 29 deletions(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index bd45189..e5ef7e6 100644
@ -109,70 +110,41 @@ index bd45189..e5ef7e6 100644
}
CloseHandle(obj);
}
diff --git a/server/change.c b/server/change.c
index c391180..77c01bb 100644
--- a/server/change.c
+++ b/server/change.c
@@ -287,7 +287,7 @@ static struct security_descriptor *dir_get_sd( struct object *obj )
assert( obj->ops == &dir_ops );
fd = dir_get_fd( obj );
- sd = set_file_sd( obj, fd, &dir->mode, &dir->uid );
+ sd = get_file_sd( obj, fd, &dir->mode, &dir->uid );
release_object( fd );
return sd;
}
diff --git a/server/file.c b/server/file.c
index ceb57be..430d183 100644
index b9106a8..c4706b6 100644
--- a/server/file.c
+++ b/server/file.c
@@ -453,12 +453,75 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
@@ -496,12 +496,33 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
return sd;
}
+struct security_descriptor *get_xattr_sd( int fd, const SID *user, const SID *group )
+struct security_descriptor *get_xattr_sd( int fd )
+{
+#ifdef HAVE_ATTR_XATTR_H
+ char buffer[XATTR_SIZE_MAX], *sd_ptr, *buffer_ptr;
+ struct security_descriptor *sd;
+ int n, owner_len, group_len;
+ char buffer[XATTR_SIZE_MAX];
+ int n;
+
+ n = fgetxattr( fd, "user.wine.sd", buffer, sizeof(buffer) );
+ if (n == -1) return NULL;
+ /* validate that we can handle the descriptor */
+ if (buffer[0] != SECURITY_DESCRIPTOR_REVISION || buffer[1] != 0) return NULL;
+
+ owner_len = FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]);
+ group_len = FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]);
+ sd = mem_alloc( n - 2 + owner_len + group_len );
+ sd_ptr = (char *)sd;
+ buffer_ptr = &buffer[2];
+ memcpy( sd_ptr, buffer_ptr, sizeof(struct security_descriptor));
+ sd_ptr += sizeof(struct security_descriptor);
+ buffer_ptr += sizeof(struct security_descriptor);
+
+ /* if no owner or group information is stored in the SD then return the corresponding data
+ * from the information stored in the filesystem */
+ if (!sd->owner_len)
+ {
+ memcpy( sd_ptr, user, owner_len );
+ sd_ptr += owner_len;
+ }
+ else
+ {
+ memcpy( sd_ptr, buffer_ptr, sd->owner_len );
+ sd_ptr += sd->owner_len;
+ }
+ buffer_ptr += sd->owner_len;
+ if (!sd->owner_len)
+ {
+ memcpy( sd_ptr, group, group_len );
+ sd_ptr += group_len;
+ }
+ else
+ {
+ memcpy( sd_ptr, buffer_ptr, sd->group_len );
+ sd_ptr += sd->group_len;
+ }
+ buffer_ptr += sd->group_len;
+
+ memcpy( sd_ptr, buffer_ptr, sd->sacl_len );
+ sd_ptr += sd->sacl_len;
+ buffer_ptr += sd->sacl_len;
+ memcpy( sd_ptr, buffer_ptr, sd->dacl_len );
+ sd_ptr += sd->dacl_len;
+ buffer_ptr += sd->dacl_len;
+
+ sd->owner_len = owner_len;
+ sd->group_len = group_len;
+
+ sd = mem_alloc( n - 2 );
+ memcpy( sd, &buffer[2], n - 2 );
+ return sd;
+#else
+ return NULL;
@ -189,7 +161,7 @@ index ceb57be..430d183 100644
if (unix_fd == -1 || fstat( unix_fd, &st ) == -1)
return obj->sd;
@@ -468,9 +531,10 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
@@ -511,9 +532,10 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
(st.st_uid == *uid))
return obj->sd;
@ -198,7 +170,7 @@ index ceb57be..430d183 100644
- token_get_primary_group( current->process->token ));
+ user = security_unix_uid_to_sid( st.st_uid );
+ group = token_get_primary_group( current->process->token );
+ sd = get_xattr_sd( unix_fd, user, group );
+ sd = get_xattr_sd( unix_fd );
+ if (!sd) sd = mode_to_sd( st.st_mode, user, group);
if (!sd) return obj->sd;

View File

@ -1,6 +1,6 @@
From b4c7ea2450c3f02b761909812403c0b83ebb7e97 Mon Sep 17 00:00:00 2001
From 74d97eda7172d7eae8468c7a32d4e330382afca2 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 17 Apr 2014 16:09:32 -0600
Date: Fri, 18 Apr 2014 14:05:32 -0600
Subject: server: Convert return of file security masks with generic access
mappings.
@ -80,10 +80,10 @@ index e5ef7e6..5b7e6a6 100644
CloseHandle(obj);
}
diff --git a/server/file.c b/server/file.c
index 430d183..572b31f 100644
index c4706b6..75f015b 100644
--- a/server/file.c
+++ b/server/file.c
@@ -515,6 +515,27 @@ struct security_descriptor *get_xattr_sd( int fd, const SID *user, const SID *gr
@@ -516,6 +516,27 @@ struct security_descriptor *get_xattr_sd( int fd )
#endif
}
@ -111,10 +111,10 @@ index 430d183..572b31f 100644
struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode,
uid_t *uid )
{
@@ -534,6 +555,7 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
@@ -535,6 +556,7 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
user = security_unix_uid_to_sid( st.st_uid );
group = token_get_primary_group( current->process->token );
sd = get_xattr_sd( unix_fd, user, group );
sd = get_xattr_sd( unix_fd );
+ if (sd) convert_generic_sd( sd );
if (!sd) sd = mode_to_sd( st.st_mode, user, group);
if (!sd) return obj->sd;

View File

@ -1,6 +1,6 @@
From 657456dc0bb9846fb79ca5c3b3705b70fb13bfe1 Mon Sep 17 00:00:00 2001
From fba93c12801c694d0e1248cd582c9d679e3a246a Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 17 Apr 2014 16:10:07 -0600
Date: Fri, 18 Apr 2014 14:08:36 -0600
Subject: server: Inherit security attributes from parent directories on
creation.
@ -73,23 +73,23 @@ index 5b7e6a6..68b63a0 100644
HeapFree(GetProcessHeap(), 0, user);
bret = RemoveDirectoryA(tmpdir);
diff --git a/server/change.c b/server/change.c
index c391180..2cf1cab 100644
index 77c01bb..2cf1cab 100644
--- a/server/change.c
+++ b/server/change.c
@@ -287,7 +287,7 @@ static struct security_descriptor *dir_get_sd( struct object *obj )
assert( obj->ops == &dir_ops );
fd = dir_get_fd( obj );
- sd = set_file_sd( obj, fd, &dir->mode, &dir->uid );
- sd = get_file_sd( obj, fd, &dir->mode, &dir->uid );
+ sd = get_file_sd( obj, fd, &dir->mode, &dir->uid, TRUE );
release_object( fd );
return sd;
}
diff --git a/server/file.c b/server/file.c
index 572b31f..0a29948 100644
index 75f015b..6ce8806 100644
--- a/server/file.c
+++ b/server/file.c
@@ -206,11 +206,141 @@ void set_xattr_sd( int fd, const struct security_descriptor *sd )
@@ -245,11 +245,141 @@ void set_xattr_sd( int fd, const struct security_descriptor *sd, const SID *user
#endif
}
@ -228,10 +228,10 @@ index 572b31f..0a29948 100644
const struct security_descriptor *sd )
{
+ struct security_descriptor *temp_sd = NULL;
const SID *owner = NULL, *group = NULL;
struct object *obj = NULL;
struct fd *fd;
int flags;
@@ -239,6 +369,10 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
@@ -279,6 +409,10 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
default: set_error( STATUS_INVALID_PARAMETER ); goto done;
}
@ -241,8 +241,8 @@ index 572b31f..0a29948 100644
+
if (sd)
{
const SID *owner = sd_get_owner( sd );
@@ -279,6 +413,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
owner = sd_get_owner( sd );
@@ -322,6 +456,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
release_object( fd );
done:
@ -250,7 +250,7 @@ index 572b31f..0a29948 100644
free( name );
return obj;
}
@@ -537,7 +672,7 @@ void convert_generic_sd( struct security_descriptor *sd )
@@ -538,7 +673,7 @@ void convert_generic_sd( struct security_descriptor *sd )
}
struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode,
@ -259,16 +259,16 @@ index 572b31f..0a29948 100644
{
int unix_fd = get_unix_fd( fd );
struct stat st;
@@ -555,7 +690,7 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
@@ -556,7 +691,7 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
user = security_unix_uid_to_sid( st.st_uid );
group = token_get_primary_group( current->process->token );
sd = get_xattr_sd( unix_fd, user, group );
sd = get_xattr_sd( unix_fd );
- if (sd) convert_generic_sd( sd );
+ if (sd && convert_generic) convert_generic_sd( sd );
if (!sd) sd = mode_to_sd( st.st_mode, user, group);
if (!sd) return obj->sd;
@@ -575,7 +710,7 @@ static struct security_descriptor *file_get_sd( struct object *obj )
@@ -576,7 +711,7 @@ static struct security_descriptor *file_get_sd( struct object *obj )
assert( obj->ops == &file_ops );
fd = file_get_fd( obj );

View File

@ -1,6 +1,6 @@
From cefa61c21ee6aacaff75f9c98c779a362a01845d Mon Sep 17 00:00:00 2001
From 8a71e25b01c3910d022ca5f1c8d54af343190d57 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 17 Apr 2014 16:10:17 -0600
Date: Fri, 18 Apr 2014 14:10:49 -0600
Subject: server: Inherit security attributes from parent directories on
SetSecurityInfo.
@ -146,10 +146,10 @@ index fa8874c..9e6b9a8 100644
if (orig->inode)
diff --git a/server/file.c b/server/file.c
index 0a29948..fe0b88f 100644
index 6ce8806..e29d06b 100644
--- a/server/file.c
+++ b/server/file.c
@@ -286,6 +286,105 @@ struct security_descriptor *inherit_sd( const struct security_descriptor *parent
@@ -325,6 +325,105 @@ struct security_descriptor *inherit_sd( const struct security_descriptor *parent
return sd;
}
@ -255,7 +255,7 @@ index 0a29948..fe0b88f 100644
static struct security_descriptor *file_get_parent_sd( struct fd *root, const char *child_name,
int child_len, int is_dir )
{
@@ -794,16 +893,33 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner )
@@ -795,16 +894,33 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner )
return new_mode & ~denied_mode;
}
@ -266,7 +266,7 @@ index 0a29948..fe0b88f 100644
+ const struct security_descriptor *sd = new_sd;
+ struct security_descriptor *parent_sd = NULL;
int unix_fd = get_unix_fd( fd );
const SID *owner;
const SID *owner, *group;
struct stat st;
mode_t mode;
+ int ret = 1;
@ -290,7 +290,7 @@ index 0a29948..fe0b88f 100644
if (set_info & OWNER_SECURITY_INFORMATION)
{
owner = sd_get_owner( sd );
@@ -835,10 +951,14 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
@@ -854,10 +970,14 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
if (((st.st_mode ^ mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, mode ) == -1)
{
file_set_error();

View File

@ -1,6 +1,6 @@
From 2e2b2120c5b4930ec89aaf074c1c78e0dd61bc59 Mon Sep 17 00:00:00 2001
From 0be335ce9c2c93a186cf35be0a99519868ab8a0d Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 17 Apr 2014 16:11:25 -0600
Date: Fri, 18 Apr 2014 15:21:00 -0600
Subject: server: Add compatibility code for handling the old method of
storing ACLs.
@ -9,11 +9,11 @@ Subject: server: Add compatibility code for handling the old method of
1 file changed, 162 insertions(+)
diff --git a/server/file.c b/server/file.c
index fe0b88f..ea31a29 100644
index e29d06b..08231a7 100644
--- a/server/file.c
+++ b/server/file.c
@@ -687,6 +687,167 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
return sd;
@@ -750,6 +750,167 @@ struct security_descriptor *get_xattr_sd( int fd )
#endif
}
+struct security_descriptor *get_xattr_acls( int fd, const SID *user, const SID *group )
@ -122,7 +122,7 @@ index fe0b88f..ea31a29 100644
+ sid->IdentifierAuthority.Value[3] = LOBYTE(HIWORD(ia));
+ sid->IdentifierAuthority.Value[4] = HIBYTE(LOWORD(ia));
+ sid->IdentifierAuthority.Value[5] = LOBYTE(LOWORD(ia));
+ p = strchr(sidtxt, '-')+1;
+ p = strchr(sidtxt, '-')+1;
+ p = strchr(p, '-')+1; /* Revision doesn't count */
+ p = strchr(p, '-')+1; /* IdentifierAuthority doesn't count */
+ do
@ -177,13 +177,13 @@ index fe0b88f..ea31a29 100644
+#endif
+}
+
struct security_descriptor *get_xattr_sd( int fd, const SID *user, const SID *group )
/* Convert generic rights into standard access rights */
void convert_generic_sd( struct security_descriptor *sd )
{
#ifdef HAVE_ATTR_XATTR_H
@@ -789,6 +950,7 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
@@ -790,6 +951,7 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
user = security_unix_uid_to_sid( st.st_uid );
group = token_get_primary_group( current->process->token );
sd = get_xattr_sd( unix_fd, user, group );
sd = get_xattr_sd( unix_fd );
+ if (!sd) sd = get_xattr_acls( unix_fd, user, group );
if (sd && convert_generic) convert_generic_sd( sd );
if (!sd) sd = mode_to_sd( st.st_mode, user, group);

View File

@ -1,3 +1,3 @@
Revision: 3
Revision: 4
Author: Erich E. Hoover
Title: Store and return security attributes with extended file attributes.

View File

@ -47,7 +47,7 @@ index a273502..5fa0cd5 100644
+ const char *title;
+} wine_patch_data[] = {
+ { "8a366b6d-8ad6-4581-8aa9-66a03590a57b:2", "Erich E. Hoover", "Implement SIO_ADDRESS_LIST_CHANGE." },
+ { "92938b89-506b-430a-ba50-32de8b286e56:3", "Erich E. Hoover", "Store and return security attributes with extended file attributes." },
+ { "92938b89-506b-430a-ba50-32de8b286e56:4", "Erich E. Hoover", "Store and return security attributes with extended file attributes." },
+ { "5d6bb7b5-ec88-4ed3-907d-9ad2173a2f88:1", "Sebastian Lackner", "Enable/disable windows when they are (un)mapped by foreign applications." },
+ { "94186fff-6dbf-44d0-8eb1-2463d1608a0f:1", "Sebastian Lackner", "Update gl_drawable for embedded windows." },
+ { "cbe240e8-2c58-430a-b61c-7fbb9d0e1e11:1", "Sebastian Lackner", "Change return value of stub SetNamedPipeHandleState to TRUE." },