ACL data is now stored in binary instead of converting it to ASCII.

This commit is contained in:
Erich E. Hoover 2014-04-17 16:53:10 -06:00
parent 4d01de8fcd
commit eecf7c4a68
11 changed files with 344 additions and 289 deletions

1
debian/changelog vendored
View File

@ -2,6 +2,7 @@ wine-compholio (1.7.16-1) UNRELEASED; urgency=low
* Split Arial replacement into two patches.
* Removed dynamic unwind patches (accepted upstream).
* Removed linguistic casing patches (accepted upstream).
* ACL data is now stored in binary instead of converting it to ASCII.
-- Erich E. Hoover <erich.e.hoover@gmail.com> Sat, 05 Apr 2014 17:38:41 -0600
wine-compholio (1.7.16-1) unstable; urgency=low

View File

@ -1,6 +1,6 @@
From ee79e1be71635431d0d05841c7f9cea720411ba6 Mon Sep 17 00:00:00 2001
From 379e01b2aea67fa305d2ccd08b589d2d31cd0da0 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 13 Feb 2014 15:45:41 -0700
Date: Thu, 17 Apr 2014 16:07:46 -0600
Subject: server: Unify the storage of security attributes for files and
directories.
@ -11,7 +11,7 @@ Subject: server: Unify the storage of security attributes for files and
3 files changed, 25 insertions(+), 48 deletions(-)
diff --git a/server/change.c b/server/change.c
index f6d56b0..76fc9f7 100644
index f6d56b0..7cea06b 100644
--- a/server/change.c
+++ b/server/change.c
@@ -317,49 +317,15 @@ static struct security_descriptor *dir_get_sd( struct object *obj )
@ -64,14 +64,14 @@ index f6d56b0..76fc9f7 100644
- }
- return 1;
+ fd = dir_get_fd( obj );
+ ret = file_set_acls( obj, fd, sd, set_info );
+ ret = set_file_sd( obj, fd, sd, set_info );
+ release_object( fd );
+ return ret;
}
static struct change_record *get_first_change_record( struct dir *dir )
diff --git a/server/file.c b/server/file.c
index cceb8ad..13ebaf9 100644
index cceb8ad..fb89272 100644
--- a/server/file.c
+++ b/server/file.c
@@ -534,18 +534,13 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner )
@ -80,8 +80,8 @@ index cceb8ad..13ebaf9 100644
-static int file_set_sd( struct object *obj, const struct security_descriptor *sd,
- unsigned int set_info )
+int file_set_acls( struct object *obj, struct fd *fd, const struct security_descriptor *sd,
+ unsigned int set_info )
+int set_file_sd( struct object *obj, struct fd *fd, const struct security_descriptor *sd,
+ unsigned int set_info )
{
- struct file *file = (struct file *)obj;
+ int unix_fd = get_unix_fd( fd );
@ -109,7 +109,7 @@ index cceb8ad..13ebaf9 100644
+ assert( obj->ops == &file_ops );
+
+ fd = file_get_fd( obj );
+ ret = file_set_acls( obj, fd, sd, set_info );
+ ret = set_file_sd( obj, fd, sd, set_info );
+ release_object( fd );
+ return ret;
+}
@ -118,15 +118,15 @@ index cceb8ad..13ebaf9 100644
{
struct file *file = (struct file *)obj;
diff --git a/server/file.h b/server/file.h
index 493d30b..11c3220 100644
index 493d30b..76cb383 100644
--- a/server/file.h
+++ b/server/file.h
@@ -122,6 +122,8 @@ extern struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access,
extern void file_set_error(void);
extern struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID *group );
extern mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner );
+extern int file_set_acls( struct object *obj, struct fd *fd, const struct security_descriptor *sd,
+ unsigned int set_info );
+extern int set_file_sd( struct object *obj, struct fd *fd, const struct security_descriptor *sd,
+ unsigned int set_info );
/* file mapping functions */

View File

@ -1,6 +1,6 @@
From bf6cb3c547ce790864af7b244f7934d3f5e3780d Mon Sep 17 00:00:00 2001
From e20db446df6bb0177f90964cd09dd9a993d120f3 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Tue, 15 Apr 2014 14:19:26 -0600
Date: Thu, 17 Apr 2014 16:07:50 -0600
Subject: server: Unify the retrieval of security attributes for files and
directories.
@ -11,7 +11,7 @@ Subject: server: Unify the retrieval of security attributes for files and
3 files changed, 28 insertions(+), 38 deletions(-)
diff --git a/server/change.c b/server/change.c
index 76fc9f7..eb16923 100644
index 7cea06b..c391180 100644
--- a/server/change.c
+++ b/server/change.c
@@ -278,39 +278,17 @@ static struct fd *dir_get_fd( struct object *obj )
@ -54,13 +54,13 @@ index 76fc9f7..eb16923 100644
- free( obj->sd );
- obj->sd = sd;
+ fd = dir_get_fd( obj );
+ sd = file_get_acls( obj, fd, &dir->mode, &dir->uid );
+ sd = set_file_sd( obj, fd, &dir->mode, &dir->uid );
+ release_object( fd );
return sd;
}
diff --git a/server/file.c b/server/file.c
index 13ebaf9..c98f045 100644
index fb89272..1f008ea 100644
--- a/server/file.c
+++ b/server/file.c
@@ -424,23 +424,19 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
@ -68,8 +68,8 @@ index 13ebaf9..c98f045 100644
}
-static struct security_descriptor *file_get_sd( struct object *obj )
+struct security_descriptor *file_get_acls( struct object *obj, struct fd *fd, mode_t *mode,
+ uid_t *uid )
+struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode,
+ uid_t *uid )
{
- struct file *file = (struct file *)obj;
+ int unix_fd = get_unix_fd( fd );
@ -114,7 +114,7 @@ index 13ebaf9..c98f045 100644
+ assert( obj->ops == &file_ops );
+
+ fd = file_get_fd( obj );
+ sd = file_get_acls( obj, fd, &file->mode, &file->uid );
+ sd = get_file_sd( obj, fd, &file->mode, &file->uid );
+ release_object( fd );
+ return sd;
+}
@ -123,15 +123,15 @@ index 13ebaf9..c98f045 100644
{
mode_t mode = 0;
diff --git a/server/file.h b/server/file.h
index 11c3220..89b5888 100644
index 76cb383..43a234f 100644
--- a/server/file.h
+++ b/server/file.h
@@ -124,6 +124,8 @@ extern struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, con
extern mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner );
extern int file_set_acls( struct object *obj, struct fd *fd, const struct security_descriptor *sd,
unsigned int set_info );
+extern struct security_descriptor *file_get_acls( struct object *obj, struct fd *fd, mode_t *mode,
+ uid_t *uid );
extern int set_file_sd( struct object *obj, struct fd *fd, const struct security_descriptor *sd,
unsigned int set_info );
+extern struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode,
+ uid_t *uid );
/* file mapping functions */

View File

@ -1,16 +1,16 @@
From be78120bae662c7290b09433b020548a2b299361 Mon Sep 17 00:00:00 2001
From a82ce7ae33ae842f531c96cc9457a73430c45773 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Tue, 15 Apr 2014 15:03:12 -0600
Date: Thu, 17 Apr 2014 16:08:03 -0600
Subject: server: Store file security attributes with extended file
attributes.
---
configure.ac | 12 ++++++++++
server/file.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 83 insertions(+)
configure.ac | 12 ++++++++++++
server/file.c | 31 +++++++++++++++++++++++++++++++
2 files changed, 43 insertions(+)
diff --git a/configure.ac b/configure.ac
index 7e463b9..c0cc653 100644
index 46602d6..99fcb9b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -73,6 +73,7 @@ AC_ARG_WITH(pthread, AS_HELP_STRING([--without-pthread],[do not use the pthrea
@ -40,7 +40,7 @@ index 7e463b9..c0cc653 100644
AC_SUBST(dlldir,"\${libdir}/wine")
diff --git a/server/file.c b/server/file.c
index c98f045..032205e 100644
index 1f008ea..ceb57be 100644
--- a/server/file.c
+++ b/server/file.c
@@ -32,6 +32,7 @@
@ -61,90 +61,50 @@ index c98f045..032205e 100644
#include "ntstatus.h"
#define WIN32_NO_STATUS
@@ -178,6 +182,70 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_
@@ -178,6 +182,30 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_
return &file->obj;
}
+void set_xattr_acls( int fd, const struct security_descriptor *sd )
+void set_xattr_sd( int fd, const struct security_descriptor *sd )
+{
+#ifdef HAVE_ATTR_XATTR_H
+ char buffer[XATTR_SIZE_MAX], *p = buffer;
+ const ACE_HEADER *ace;
+ int present, i, j, n;
+ char buffer[XATTR_SIZE_MAX];
+ int present, len;
+ const ACL *dacl;
+
+ /* there's no point in storing the security descriptor if there's no DACL */
+ if (!sd) return;
+ dacl = sd_get_dacl( sd, &present );
+ if (!present || !dacl) return;
+ ace = (const ACE_HEADER *)(dacl + 1);
+
+ for (i = 0; i < dacl->AceCount; i++, ace = ace_next( ace ))
+ {
+ BYTE type = ace->AceType, flags;
+ const ACCESS_ALLOWED_ACE *aaa;
+ const ACCESS_DENIED_ACE *ada;
+ char sidtxt[100], *s;
+ const SID *sid;
+ DWORD mask;
+ len = 2 + sizeof(struct security_descriptor) + sd->owner_len + sd->group_len + sd->sacl_len
+ + sd->dacl_len;
+ if (len > XATTR_SIZE_MAX) return;
+
+ switch (type)
+ {
+ case ACCESS_DENIED_ACE_TYPE:
+ ada = (const ACCESS_DENIED_ACE *)ace;
+ flags = ada->Header.AceFlags;
+ mask = ada->Mask;
+ sid = (const SID *)&ada->SidStart;
+ break;
+ case ACCESS_ALLOWED_ACE_TYPE:
+ aaa = (const ACCESS_ALLOWED_ACE *)ace;
+ flags = aaa->Header.AceFlags;
+ mask = aaa->Mask;
+ sid = (const SID *)&aaa->SidStart;
+ break;
+ default:
+ continue;
+ }
+
+ /* verify that the SubAuthorityCount does not exceed the maximum permitted value */
+ if (sid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES)
+ continue;
+
+ n = sprintf( sidtxt, "S-%u-%d", sid->Revision,
+ MAKELONG(
+ MAKEWORD( sid->IdentifierAuthority.Value[5],
+ sid->IdentifierAuthority.Value[4] ),
+ MAKEWORD( sid->IdentifierAuthority.Value[3],
+ sid->IdentifierAuthority.Value[2] )
+ ) );
+ s = sidtxt + n;
+ for( j=0; j<sid->SubAuthorityCount; j++ )
+ s += sprintf( s, "-%u", sid->SubAuthority[j] );
+
+ p += snprintf( p, XATTR_SIZE_MAX-(p-buffer), "%s%x,%x,%x,%s",
+ (p != buffer ? ";" : ""), type, flags, mask, sidtxt );
+ }
+
+ buffer[XATTR_SIZE_MAX-1] = 0; /* ensure NULL terminated if snprintf truncated the buffer */
+ fsetxattr( fd, "user.wine.acl", buffer, p-buffer, 0 );
+ /* include the descriptor revision and resource manager control bits */
+ buffer[0] = SECURITY_DESCRIPTOR_REVISION;
+ buffer[1] = 0;
+ memcpy( &buffer[2], sd, len - 2 );
+ fsetxattr( fd, "user.wine.sd", buffer, len, 0 );
+#endif
+}
+
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 +307,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
@@ -239,6 +267,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_acls( get_unix_fd( fd ), sd );
+ set_xattr_sd( get_unix_fd( fd ), sd );
if (S_ISDIR(mode))
obj = create_dir_obj( fd, access, mode );
@@ -580,6 +649,8 @@ int file_set_acls( struct object *obj, struct fd *fd, const struct security_desc
@@ -580,6 +609,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_acls( unix_fd, sd );
+ set_xattr_sd( unix_fd, sd );
+
if (((st.st_mode ^ mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, mode ) == -1)
{

View File

@ -1,13 +1,13 @@
From b08167fa305b8cee98df3b8712c01ebbc5f56dde Mon Sep 17 00:00:00 2001
From 469fa2de7b5ea74c880a64c4acbb31a2397c8dc4 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Tue, 15 Apr 2014 15:04:29 -0600
Date: Thu, 17 Apr 2014 16:09:01 -0600
Subject: server: Retrieve file security attributes with extended file
attributes.
---
dlls/advapi32/tests/security.c | 49 ++++++------
server/file.c | 169 +++++++++++++++++++++++++++++++++++++++-
2 files changed, 190 insertions(+), 28 deletions(-)
dlls/advapi32/tests/security.c | 49 ++++++++++++++--------------
server/file.c | 70 ++++++++++++++++++++++++++++++++++++++--
2 files changed, 91 insertions(+), 28 deletions(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index bd45189..e5ef7e6 100644
@ -110,167 +110,68 @@ index bd45189..e5ef7e6 100644
CloseHandle(obj);
}
diff --git a/server/file.c b/server/file.c
index 032205e..945b82a 100644
index ceb57be..430d183 100644
--- a/server/file.c
+++ b/server/file.c
@@ -493,12 +493,174 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
@@ -453,12 +453,75 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
return sd;
}
+struct security_descriptor *get_xattr_acls( int fd, const SID *user, const SID *group )
+struct security_descriptor *get_xattr_sd( int fd, const SID *user, const SID *group )
+{
+#ifdef HAVE_ATTR_XATTR_H
+ int ace_count = 0, dacl_size = sizeof(ACL), i, n;
+ char buffer[XATTR_SIZE_MAX], *p = buffer, *pn;
+ char buffer[XATTR_SIZE_MAX], *sd_ptr, *buffer_ptr;
+ struct security_descriptor *sd;
+ ACE_HEADER *current_ace;
+ ACCESS_ALLOWED_ACE *aaa;
+ ACCESS_DENIED_ACE *ada;
+ int type, flags, mask;
+ ACL *dacl;
+ char *ptr;
+ int n, owner_len, group_len;
+
+ n = fgetxattr( fd, "user.wine.acl", buffer, sizeof(buffer) );
+ n = fgetxattr( fd, "user.wine.sd", buffer, sizeof(buffer) );
+ if (n == -1) return NULL;
+ buffer[n] = 0; /* ensure NULL terminated buffer for string functions */
+ /* validate that we can handle the descriptor */
+ if (buffer[0] != SECURITY_DESCRIPTOR_REVISION || buffer[1] != 0) return NULL;
+
+ do
+ 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)
+ {
+ int sub_authority_count = 0;
+
+ pn = strchr(p, ';');
+ if (pn) pn++;
+ sscanf(p, "%x", &type);
+ do
+ {
+ p = strchr(p, '-');
+ if (p) p++;
+ sub_authority_count++;
+ }
+ while(p && (!pn || p < pn));
+ sub_authority_count -= 3; /* Revision and IdentifierAuthority don't count */
+ p = pn; /* prepare for the next ACE */
+
+ /* verify that the SubAuthorityCount does not exceed the maximum permitted value */
+ if (sub_authority_count > SID_MAX_SUB_AUTHORITIES)
+ continue;
+
+ switch (type)
+ {
+ case ACCESS_DENIED_ACE_TYPE:
+ dacl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) +
+ FIELD_OFFSET(SID, SubAuthority[sub_authority_count]);
+ break;
+ case ACCESS_ALLOWED_ACE_TYPE:
+ dacl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) +
+ FIELD_OFFSET(SID, SubAuthority[sub_authority_count]);
+ break;
+ default:
+ continue;
+ }
+ ace_count++;
+ memcpy( sd_ptr, user, owner_len );
+ sd_ptr += owner_len;
+ }
+ while(p);
+
+ sd = mem_alloc( sizeof(struct security_descriptor) +
+ FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]) +
+ FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]) +
+ dacl_size );
+
+ sd->control = SE_DACL_PRESENT;
+ sd->owner_len = FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]);
+ sd->group_len = FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]);
+ sd->sacl_len = 0;
+ sd->dacl_len = dacl_size;
+
+ ptr = (char *)(sd + 1);
+ memcpy( ptr, user, sd->owner_len );
+ ptr += sd->owner_len;
+ memcpy( ptr, group, sd->group_len );
+ ptr += sd->group_len;
+
+ dacl = (ACL *)ptr;
+ dacl->AclRevision = ACL_REVISION;
+ dacl->Sbz1 = 0;
+ dacl->AclSize = dacl_size;
+ dacl->AceCount = ace_count;
+ dacl->Sbz2 = 0;
+ aaa = (ACCESS_ALLOWED_ACE *)(dacl + 1);
+ current_ace = &aaa->Header;
+
+ p = buffer;
+ for(i=0; i<ace_count; i++)
+ else
+ {
+ char b[sizeof(SID) + sizeof(ULONG) * SID_MAX_SUB_AUTHORITIES];
+ int sub_authority_count = 0;
+ SID *sid = (SID *)&b[0];
+ char sidtxt[100];
+ int rev, ia, sa;
+
+ if (i != 0)
+ {
+ aaa = (ACCESS_ALLOWED_ACE *)ace_next( current_ace );
+ current_ace = &aaa->Header;
+ }
+ pn = strchr(p, ';');
+ if (pn) pn++;
+ sscanf(p, "%x,%x,%x,%[^;]", &type, &flags, &mask, sidtxt);
+ sscanf(sidtxt, "S-%u-%d", &rev, &ia);
+ sid->Revision = rev;
+ sid->IdentifierAuthority.Value[0] = 0;
+ sid->IdentifierAuthority.Value[1] = 0;
+ sid->IdentifierAuthority.Value[2] = HIBYTE(HIWORD(ia));
+ 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(p, '-')+1; /* Revision doesn't count */
+ p = strchr(p, '-')+1; /* IdentifierAuthority doesn't count */
+ do
+ {
+ if (sub_authority_count == SID_MAX_SUB_AUTHORITIES)
+ {
+ sub_authority_count++; /* fail on this SID and move on to the next one */
+ break;
+ }
+ sscanf(p, "%u", &sa);
+ sid->SubAuthority[sub_authority_count] = sa;
+ p = strchr(p, '-');
+ if (p) p++;
+ sub_authority_count++;
+ }
+ while(p);
+ sid->SubAuthorityCount = sub_authority_count;
+ p = pn; /* prepare for the next ACE */
+
+ /* verify that the SubAuthorityCount does not exceed the maximum permitted value */
+ if (sub_authority_count > SID_MAX_SUB_AUTHORITIES)
+ continue;
+
+ /* Handle the specific ACE */
+ switch (type)
+ {
+ case ACCESS_DENIED_ACE_TYPE:
+ ada = (ACCESS_DENIED_ACE *)aaa;
+ ada->Header.AceType = type;
+ ada->Header.AceFlags = flags;
+ ada->Header.AceSize = FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) +
+ FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]);
+ ada->Mask = mask;
+ memcpy( &ada->SidStart, sid, FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]) );
+ break;
+ case ACCESS_ALLOWED_ACE_TYPE:
+ aaa->Header.AceType = type;
+ aaa->Header.AceFlags = flags;
+ aaa->Header.AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) +
+ FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]);
+ aaa->Mask = mask;
+ memcpy( &aaa->SidStart, sid, FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]) );
+ break;
+ default:
+ continue;
+ }
+ 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;
+
+ return sd;
+#else
@ -278,8 +179,8 @@ index 032205e..945b82a 100644
+#endif
+}
+
struct security_descriptor *file_get_acls( struct object *obj, struct fd *fd, mode_t *mode,
uid_t *uid )
struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode,
uid_t *uid )
{
int unix_fd = get_unix_fd( fd );
struct stat st;
@ -288,7 +189,7 @@ index 032205e..945b82a 100644
if (unix_fd == -1 || fstat( unix_fd, &st ) == -1)
return obj->sd;
@@ -508,9 +670,10 @@ struct security_descriptor *file_get_acls( struct object *obj, struct fd *fd, mo
@@ -468,9 +531,10 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
(st.st_uid == *uid))
return obj->sd;
@ -297,7 +198,7 @@ index 032205e..945b82a 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_acls( unix_fd, user, group );
+ sd = get_xattr_sd( unix_fd, user, group );
+ if (!sd) sd = mode_to_sd( st.st_mode, user, group);
if (!sd) return obj->sd;

View File

@ -1,6 +1,6 @@
From e1b3d93adab31966d145ea41a9246d8f498c09d6 Mon Sep 17 00:00:00 2001
From b4c7ea2450c3f02b761909812403c0b83ebb7e97 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 13 Feb 2014 16:06:54 -0700
Date: Thu, 17 Apr 2014 16:09:32 -0600
Subject: server: Convert return of file security masks with generic access
mappings.
@ -10,7 +10,7 @@ Subject: server: Convert return of file security masks with generic access
2 files changed, 34 insertions(+), 12 deletions(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index f107abc..b71bad3 100644
index e5ef7e6..5b7e6a6 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -3109,8 +3109,8 @@ static void test_CreateDirectoryA(void)
@ -80,10 +80,10 @@ index f107abc..b71bad3 100644
CloseHandle(obj);
}
diff --git a/server/file.c b/server/file.c
index b9135b9..0df2245 100644
index 430d183..572b31f 100644
--- a/server/file.c
+++ b/server/file.c
@@ -637,6 +637,27 @@ struct security_descriptor *get_xattr_acls( int fd, const SID *user, const SID *
@@ -515,6 +515,27 @@ struct security_descriptor *get_xattr_sd( int fd, const SID *user, const SID *gr
#endif
}
@ -108,13 +108,13 @@ index b9135b9..0df2245 100644
+ }
+}
+
struct security_descriptor *file_get_acls( struct object *obj, struct fd *fd, mode_t *mode,
uid_t *uid )
struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode,
uid_t *uid )
{
@@ -656,6 +677,7 @@ struct security_descriptor *file_get_acls( struct object *obj, struct fd *fd, mo
@@ -534,6 +555,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_acls( unix_fd, user, group );
sd = get_xattr_sd( unix_fd, user, group );
+ 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 0c94a31c11260ec1ead91c47737d32cde97fee63 Mon Sep 17 00:00:00 2001
From 657456dc0bb9846fb79ca5c3b3705b70fb13bfe1 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Tue, 15 Apr 2014 15:19:52 -0600
Date: Thu, 17 Apr 2014 16:10:07 -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 eb16923..1571eb8 100644
index c391180..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 = file_get_acls( obj, fd, &dir->mode, &dir->uid );
+ sd = file_get_acls( obj, fd, &dir->mode, &dir->uid, TRUE );
- sd = set_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 a12679d..eae4984 100644
index 572b31f..0a29948 100644
--- a/server/file.c
+++ b/server/file.c
@@ -246,11 +246,141 @@ void set_xattr_acls( int fd, const struct security_descriptor *sd )
@@ -206,11 +206,141 @@ void set_xattr_sd( int fd, const struct security_descriptor *sd )
#endif
}
@ -210,7 +210,7 @@ index a12679d..eae4984 100644
+ fd = file_get_fd( obj );
+ if (fd)
+ {
+ sd = file_get_acls( obj, fd, &file->mode, &file->uid, FALSE );
+ sd = get_file_sd( obj, fd, &file->mode, &file->uid, FALSE );
+ release_object( fd );
+ }
+ if (sd)
@ -231,7 +231,7 @@ index a12679d..eae4984 100644
struct object *obj = NULL;
struct fd *fd;
int flags;
@@ -279,6 +409,10 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
@@ -239,6 +369,10 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
default: set_error( STATUS_INVALID_PARAMETER ); goto done;
}
@ -242,7 +242,7 @@ index a12679d..eae4984 100644
if (sd)
{
const SID *owner = sd_get_owner( sd );
@@ -319,6 +453,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
@@ -279,6 +413,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
release_object( fd );
done:
@ -250,43 +250,43 @@ index a12679d..eae4984 100644
free( name );
return obj;
}
@@ -676,7 +811,7 @@ void convert_generic_sd( struct security_descriptor *sd )
@@ -537,7 +672,7 @@ void convert_generic_sd( struct security_descriptor *sd )
}
struct security_descriptor *file_get_acls( struct object *obj, struct fd *fd, mode_t *mode,
- uid_t *uid )
+ uid_t *uid, int convert_generic )
struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode,
- uid_t *uid )
+ uid_t *uid, int convert_generic )
{
int unix_fd = get_unix_fd( fd );
struct stat st;
@@ -694,7 +829,7 @@ struct security_descriptor *file_get_acls( struct object *obj, struct fd *fd, mo
@@ -555,7 +690,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_acls( unix_fd, user, group );
sd = get_xattr_sd( unix_fd, user, group );
- 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;
@@ -714,7 +849,7 @@ static struct security_descriptor *file_get_sd( struct object *obj )
@@ -575,7 +710,7 @@ static struct security_descriptor *file_get_sd( struct object *obj )
assert( obj->ops == &file_ops );
fd = file_get_fd( obj );
- sd = file_get_acls( obj, fd, &file->mode, &file->uid );
+ sd = file_get_acls( obj, fd, &file->mode, &file->uid, TRUE );
- sd = get_file_sd( obj, fd, &file->mode, &file->uid );
+ sd = get_file_sd( obj, fd, &file->mode, &file->uid, TRUE );
release_object( fd );
return sd;
}
diff --git a/server/file.h b/server/file.h
index 89b5888..0905fbb 100644
index 43a234f..2f537cf 100644
--- a/server/file.h
+++ b/server/file.h
@@ -125,7 +125,7 @@ extern mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner
extern int file_set_acls( struct object *obj, struct fd *fd, const struct security_descriptor *sd,
unsigned int set_info );
extern struct security_descriptor *file_get_acls( struct object *obj, struct fd *fd, mode_t *mode,
- uid_t *uid );
+ uid_t *uid, int convert_generic );
extern int set_file_sd( struct object *obj, struct fd *fd, const struct security_descriptor *sd,
unsigned int set_info );
extern struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode,
- uid_t *uid );
+ uid_t *uid, int convert_generic );
/* file mapping functions */

View File

@ -1,6 +1,6 @@
From c71273c87839889d351fe8c5b84f3c947783500a Mon Sep 17 00:00:00 2001
From cefa61c21ee6aacaff75f9c98c779a362a01845d Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Tue, 15 Apr 2014 15:23:46 -0600
Date: Thu, 17 Apr 2014 16:10:17 -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 eae4984..08d2db0 100644
index 0a29948..fe0b88f 100644
--- a/server/file.c
+++ b/server/file.c
@@ -326,6 +326,105 @@ struct security_descriptor *inherit_sd( const struct security_descriptor *parent
@@ -286,6 +286,105 @@ struct security_descriptor *inherit_sd( const struct security_descriptor *parent
return sd;
}
@ -255,13 +255,13 @@ index eae4984..08d2db0 100644
static struct security_descriptor *file_get_parent_sd( struct fd *root, const char *child_name,
int child_len, int is_dir )
{
@@ -933,16 +1032,33 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner )
@@ -794,16 +893,33 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner )
return new_mode & ~denied_mode;
}
-int file_set_acls( struct object *obj, struct fd *fd, const struct security_descriptor *sd,
+int file_set_acls( struct object *obj, struct fd *fd, const struct security_descriptor *new_sd,
unsigned int set_info )
-int set_file_sd( struct object *obj, struct fd *fd, const struct security_descriptor *sd,
+int set_file_sd( struct object *obj, struct fd *fd, const struct security_descriptor *new_sd,
unsigned int set_info )
{
+ const struct security_descriptor *sd = new_sd;
+ struct security_descriptor *parent_sd = NULL;
@ -290,7 +290,7 @@ index eae4984..08d2db0 100644
if (set_info & OWNER_SECURITY_INFORMATION)
{
owner = sd_get_owner( sd );
@@ -974,10 +1090,14 @@ int file_set_acls( struct object *obj, struct fd *fd, const struct security_desc
@@ -835,10 +951,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();
@ -308,7 +308,7 @@ index eae4984..08d2db0 100644
static int file_set_sd( struct object *obj, const struct security_descriptor *sd,
diff --git a/server/file.h b/server/file.h
index 0905fbb..8cbc4cb 100644
index 2f537cf..fa83001 100644
--- a/server/file.h
+++ b/server/file.h
@@ -77,6 +77,7 @@ extern void allow_fd_caching( struct fd *fd );

View File

@ -0,0 +1,193 @@
From 2e2b2120c5b4930ec89aaf074c1c78e0dd61bc59 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
Subject: server: Add compatibility code for handling the old method of
storing ACLs.
---
server/file.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 162 insertions(+)
diff --git a/server/file.c b/server/file.c
index fe0b88f..ea31a29 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;
}
+struct security_descriptor *get_xattr_acls( int fd, const SID *user, const SID *group )
+{
+#ifdef HAVE_ATTR_XATTR_H
+ int ace_count = 0, dacl_size = sizeof(ACL), i, n;
+ char buffer[XATTR_SIZE_MAX], *p = buffer, *pn;
+ struct security_descriptor *sd;
+ ACE_HEADER *current_ace;
+ ACCESS_ALLOWED_ACE *aaa;
+ ACCESS_DENIED_ACE *ada;
+ int type, flags, mask;
+ ACL *dacl;
+ char *ptr;
+
+ n = fgetxattr( fd, "user.wine.acl", buffer, sizeof(buffer) );
+ if (n == -1) return NULL;
+ buffer[n] = 0; /* ensure NULL terminated buffer for string functions */
+
+ do
+ {
+ int sub_authority_count = 0;
+
+ pn = strchr(p, ';');
+ if (pn) pn++;
+ sscanf(p, "%x", &type);
+ do
+ {
+ p = strchr(p, '-');
+ if (p) p++;
+ sub_authority_count++;
+ }
+ while(p && (!pn || p < pn));
+ sub_authority_count -= 3; /* Revision and IdentifierAuthority don't count */
+ p = pn; /* prepare for the next ACE */
+
+ /* verify that the SubAuthorityCount does not exceed the maximum permitted value */
+ if (sub_authority_count > SID_MAX_SUB_AUTHORITIES)
+ continue;
+
+ switch (type)
+ {
+ case ACCESS_DENIED_ACE_TYPE:
+ dacl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) +
+ FIELD_OFFSET(SID, SubAuthority[sub_authority_count]);
+ break;
+ case ACCESS_ALLOWED_ACE_TYPE:
+ dacl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) +
+ FIELD_OFFSET(SID, SubAuthority[sub_authority_count]);
+ break;
+ default:
+ continue;
+ }
+ ace_count++;
+ }
+ while(p);
+
+ sd = mem_alloc( sizeof(struct security_descriptor) +
+ FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]) +
+ FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]) +
+ dacl_size );
+
+ sd->control = SE_DACL_PRESENT;
+ sd->owner_len = FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]);
+ sd->group_len = FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]);
+ sd->sacl_len = 0;
+ sd->dacl_len = dacl_size;
+
+ ptr = (char *)(sd + 1);
+ memcpy( ptr, user, sd->owner_len );
+ ptr += sd->owner_len;
+ memcpy( ptr, group, sd->group_len );
+ ptr += sd->group_len;
+
+ dacl = (ACL *)ptr;
+ dacl->AclRevision = ACL_REVISION;
+ dacl->Sbz1 = 0;
+ dacl->AclSize = dacl_size;
+ dacl->AceCount = ace_count;
+ dacl->Sbz2 = 0;
+ aaa = (ACCESS_ALLOWED_ACE *)(dacl + 1);
+ current_ace = &aaa->Header;
+
+ p = buffer;
+ for(i=0; i<ace_count; i++)
+ {
+ char b[sizeof(SID) + sizeof(ULONG) * SID_MAX_SUB_AUTHORITIES];
+ int sub_authority_count = 0;
+ SID *sid = (SID *)&b[0];
+ char sidtxt[100];
+ int rev, ia, sa;
+
+ if (i != 0)
+ {
+ aaa = (ACCESS_ALLOWED_ACE *)ace_next( current_ace );
+ current_ace = &aaa->Header;
+ }
+ pn = strchr(p, ';');
+ if (pn) pn++;
+ sscanf(p, "%x,%x,%x,%[^;]", &type, &flags, &mask, sidtxt);
+ sscanf(sidtxt, "S-%u-%d", &rev, &ia);
+ sid->Revision = rev;
+ sid->IdentifierAuthority.Value[0] = 0;
+ sid->IdentifierAuthority.Value[1] = 0;
+ sid->IdentifierAuthority.Value[2] = HIBYTE(HIWORD(ia));
+ 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(p, '-')+1; /* Revision doesn't count */
+ p = strchr(p, '-')+1; /* IdentifierAuthority doesn't count */
+ do
+ {
+ if (sub_authority_count == SID_MAX_SUB_AUTHORITIES)
+ {
+ sub_authority_count++; /* fail on this SID and move on to the next one */
+ break;
+ }
+ sscanf(p, "%u", &sa);
+ sid->SubAuthority[sub_authority_count] = sa;
+ p = strchr(p, '-');
+ if (p) p++;
+ sub_authority_count++;
+ }
+ while(p);
+ sid->SubAuthorityCount = sub_authority_count;
+ p = pn; /* prepare for the next ACE */
+
+ /* verify that the SubAuthorityCount does not exceed the maximum permitted value */
+ if (sub_authority_count > SID_MAX_SUB_AUTHORITIES)
+ continue;
+
+ /* Handle the specific ACE */
+ switch (type)
+ {
+ case ACCESS_DENIED_ACE_TYPE:
+ ada = (ACCESS_DENIED_ACE *)aaa;
+ ada->Header.AceType = type;
+ ada->Header.AceFlags = flags;
+ ada->Header.AceSize = FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) +
+ FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]);
+ ada->Mask = mask;
+ memcpy( &ada->SidStart, sid, FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]) );
+ break;
+ case ACCESS_ALLOWED_ACE_TYPE:
+ aaa->Header.AceType = type;
+ aaa->Header.AceFlags = flags;
+ aaa->Header.AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) +
+ FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]);
+ aaa->Mask = mask;
+ memcpy( &aaa->SidStart, sid, FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]) );
+ break;
+ default:
+ continue;
+ }
+ }
+
+ return sd;
+#else
+ return NULL;
+#endif
+}
+
struct security_descriptor *get_xattr_sd( int fd, const SID *user, const SID *group )
{
#ifdef HAVE_ATTR_XATTR_H
@@ -789,6 +950,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 );
+ 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);
if (!sd) return obj->sd;
--
1.7.9.5

View File

@ -1,3 +1,3 @@
Revision: 2
Revision: 3
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:2", "Erich E. Hoover", "Store and return security attributes with extended file attributes." },
+ { "92938b89-506b-430a-ba50-32de8b286e56:3", "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." },