From e01e628f6e6aa9730c48544e0cac27a59613a9c2 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Mon, 30 Mar 2015 21:48:59 +0200 Subject: [PATCH] server-Stored_ACLs: Fix some issues causing out-of-sync of local security descriptors and extended attributes. --- ...Add-DACL-inheritance-support-in-SetS.patch | 26 +- patches/patchinstall.sh | 17 +- ...tibility-code-for-handling-the-old-m.patch | 38 +-- ...ecurity-attributes-from-parent-direc.patch | 20 +- ...ecurity-attributes-from-parent-direc.patch | 95 ++++---- ...-storage-of-security-attributes-for-.patch | 59 +++-- ...-retrieval-of-security-attributes-fo.patch | 26 +- ...per-function-set_sd_from_token_inter.patch | 147 ++++++++++++ ...r-and-group-inside-stored-extended-f.patch | 161 ------------- ...ly-store-the-full-security-descripto.patch | 222 ++++++++++++++++++ ...-security-attributes-with-extended-.patch} | 47 ++-- ...ile-security-attributes-with-extend.patch} | 12 +- ...turn-of-file-security-masks-with-ge.patch} | 68 ++++-- patches/server-Stored_ACLs/definition | 23 -- 14 files changed, 581 insertions(+), 380 deletions(-) create mode 100644 patches/server-Stored_ACLs/0003-server-Add-a-helper-function-set_sd_from_token_inter.patch delete mode 100644 patches/server-Stored_ACLs/0004-server-Store-user-and-group-inside-stored-extended-f.patch create mode 100644 patches/server-Stored_ACLs/0004-server-Temporarily-store-the-full-security-descripto.patch rename patches/server-Stored_ACLs/{0003-server-Store-file-security-attributes-with-extended-.patch => 0005-server-Store-file-security-attributes-with-extended-.patch} (66%) rename patches/server-Stored_ACLs/{0005-server-Retrieve-file-security-attributes-with-extend.patch => 0006-server-Retrieve-file-security-attributes-with-extend.patch} (95%) rename patches/server-Stored_ACLs/{0006-server-Convert-return-of-file-security-masks-with-ge.patch => 0007-server-Convert-return-of-file-security-masks-with-ge.patch} (60%) diff --git a/patches/advapi32-Revert_DACL/0001-Revert-advapi32-Add-DACL-inheritance-support-in-SetS.patch b/patches/advapi32-Revert_DACL/0001-Revert-advapi32-Add-DACL-inheritance-support-in-SetS.patch index a4fc3bdc..2d071cdb 100644 --- a/patches/advapi32-Revert_DACL/0001-Revert-advapi32-Add-DACL-inheritance-support-in-SetS.patch +++ b/patches/advapi32-Revert_DACL/0001-Revert-advapi32-Add-DACL-inheritance-support-in-SetS.patch @@ -1,4 +1,4 @@ -From d134911c9e25467a2aad8b783cbd12e29c2a4874 Mon Sep 17 00:00:00 2001 +From 8ea5a805609c2a13199ffcaa8b9b24f413d00d8b Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Fri, 27 Mar 2015 15:32:04 +0100 Subject: Revert "advapi32: Add DACL inheritance support in SetSecurityInfo." @@ -6,8 +6,8 @@ Subject: Revert "advapi32: Add DACL inheritance support in SetSecurityInfo." This reverts commit f974d726720eff4fcd7371bca95e6cdcc4b4a848. --- dlls/advapi32/security.c | 130 +---------------------------------------- - dlls/advapi32/tests/security.c | 27 +++++---- - 2 files changed, 16 insertions(+), 141 deletions(-) + dlls/advapi32/tests/security.c | 23 ++++---- + 2 files changed, 14 insertions(+), 139 deletions(-) diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c index 71a8c92..e8cdcc5 100644 @@ -172,7 +172,7 @@ index 71a8c92..e8cdcc5 100644 } diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c -index 0259b63..a2e4c98 100644 +index 10f3f8e..a10d781 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -3517,22 +3517,25 @@ static void test_GetNamedSecurityInfoA(void) @@ -211,24 +211,6 @@ index 0259b63..a2e4c98 100644 CloseHandle(h); /* NtSetSecurityObject doesn't inherit DACL entries */ -@@ -4302,7 +4305,7 @@ static void test_GetSecurityInfo(void) - bret = pGetAce(pDacl, 0, (VOID **)&ace); - ok(bret, "Failed to get Current User ACE.\n"); - bret = EqualSid(&ace->SidStart, user_sid); -- todo_wine ok(bret, "Current User ACE != Current User SID.\n"); -+ ok(bret, "Current User ACE != Current User SID.\n"); - ok(((ACE_HEADER *)ace)->AceFlags == 0, - "Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); - ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", -@@ -4313,7 +4316,7 @@ static void test_GetSecurityInfo(void) - bret = pGetAce(pDacl, 1, (VOID **)&ace); - ok(bret, "Failed to get Administators Group ACE.\n"); - bret = EqualSid(&ace->SidStart, admin_sid); -- todo_wine ok(bret, "Administators Group ACE != Administators Group SID.\n"); -+ ok(bret, "Administators Group ACE != Administators Group SID.\n"); - ok(((ACE_HEADER *)ace)->AceFlags == 0, - "Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); - ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", -- 2.3.3 diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 3b36c3fa..ca21f299 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -1412,20 +1412,23 @@ fi # | * [#33576] Support for stored file ACLs # | # | Modified files: -# | * dlls/advapi32/tests/security.c, include/wine/port.h, server/change.c, server/file.c, server/file.h +# | * dlls/advapi32/tests/security.c, include/wine/port.h, server/change.c, server/file.c, server/file.h, server/object.c, +# | server/object.h # | if test "$enable_server_Stored_ACLs" -eq 1; then patch_apply server-Stored_ACLs/0001-server-Unify-the-storage-of-security-attributes-for-.patch patch_apply server-Stored_ACLs/0002-server-Unify-the-retrieval-of-security-attributes-fo.patch - patch_apply server-Stored_ACLs/0003-server-Store-file-security-attributes-with-extended-.patch - patch_apply server-Stored_ACLs/0004-server-Store-user-and-group-inside-stored-extended-f.patch - patch_apply server-Stored_ACLs/0005-server-Retrieve-file-security-attributes-with-extend.patch - patch_apply server-Stored_ACLs/0006-server-Convert-return-of-file-security-masks-with-ge.patch + patch_apply server-Stored_ACLs/0003-server-Add-a-helper-function-set_sd_from_token_inter.patch + patch_apply server-Stored_ACLs/0004-server-Temporarily-store-the-full-security-descripto.patch + patch_apply server-Stored_ACLs/0005-server-Store-file-security-attributes-with-extended-.patch + patch_apply server-Stored_ACLs/0006-server-Retrieve-file-security-attributes-with-extend.patch + patch_apply server-Stored_ACLs/0007-server-Convert-return-of-file-security-masks-with-ge.patch ( echo '+ { "Erich E. Hoover", "server: Unify the storage of security attributes for files and directories.", 7 },'; echo '+ { "Erich E. Hoover", "server: Unify the retrieval of security attributes for files and directories.", 7 },'; - echo '+ { "Erich E. Hoover", "server: Store file security attributes with extended file attributes.", 7 },'; - echo '+ { "Erich E. Hoover", "server: Store user and group inside stored extended file attribute information.", 7 },'; + echo '+ { "Sebastian Lackner", "server: Add a helper function set_sd_from_token_internal to merge two security descriptors.", 1 },'; + echo '+ { "Sebastian Lackner", "server: Temporarily store the full security descriptor for file objects.", 1 },'; + echo '+ { "Erich E. Hoover", "server: Store file security attributes with extended file attributes.", 8 },'; echo '+ { "Erich E. Hoover", "server: Retrieve file security attributes with extended file attributes.", 7 },'; echo '+ { "Erich E. Hoover", "server: Convert return of file security masks with generic access mappings.", 7 },'; ) >> "$patchlist" diff --git a/patches/server-ACL_Compat/0001-server-Add-compatibility-code-for-handling-the-old-m.patch b/patches/server-ACL_Compat/0001-server-Add-compatibility-code-for-handling-the-old-m.patch index b89bba1b..725e2ef8 100644 --- a/patches/server-ACL_Compat/0001-server-Add-compatibility-code-for-handling-the-old-m.patch +++ b/patches/server-ACL_Compat/0001-server-Add-compatibility-code-for-handling-the-old-m.patch @@ -1,26 +1,26 @@ -From c7ee69405e7f18058ca0b1c05e8dfa7ee669df13 Mon Sep 17 00:00:00 2001 +From e474515fe1624147bde11553c701462b14d7850b Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Fri, 18 Apr 2014 15:21:00 -0600 Subject: server: Add compatibility code for handling the old method of storing ACLs. (try 6) --- - server/file.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 164 insertions(+), 3 deletions(-) + server/file.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 167 insertions(+), 3 deletions(-) diff --git a/server/file.c b/server/file.c -index 146ea68..4c72775 100644 +index 9031de3..4150d42 100644 --- a/server/file.c +++ b/server/file.c @@ -72,6 +72,7 @@ struct file static unsigned int generic_file_map_access( unsigned int access ); - struct security_descriptor *get_xattr_sd( int fd ); -+struct security_descriptor *get_xattr_acls( int fd, const SID *user, const SID *group ); + static struct security_descriptor *get_xattr_sd( int fd ); ++static struct security_descriptor *get_xattr_acls( int fd, const SID *user, const SID *group ); static void file_dump( struct object *obj, int verbose ); static struct fd *file_get_fd( struct object *obj ); -@@ -440,6 +441,7 @@ static struct security_descriptor *file_get_parent_sd( struct fd *root, const ch +@@ -408,6 +409,7 @@ static struct security_descriptor *file_get_parent_sd( struct fd *root, const ch mode_t parent_mode = 0555; char *p, *parent_name; struct fd *parent_fd; @@ -28,7 +28,7 @@ index 146ea68..4c72775 100644 int unix_fd; if (!(parent_name = mem_alloc( child_len + 1 ))) return NULL; -@@ -472,6 +474,9 @@ static struct security_descriptor *file_get_parent_sd( struct fd *root, const ch +@@ -440,6 +442,9 @@ static struct security_descriptor *file_get_parent_sd( struct fd *root, const ch if (unix_fd != -1) { parent_sd = get_xattr_sd( unix_fd ); @@ -38,11 +38,11 @@ index 146ea68..4c72775 100644 if (parent_sd) { sd = inherit_sd( parent_sd, is_dir ); -@@ -759,6 +764,160 @@ struct security_descriptor *get_xattr_sd( int fd ) - return sd; +@@ -723,6 +728,163 @@ static void convert_generic_sd( struct security_descriptor *sd ) + } } -+struct security_descriptor *get_xattr_acls( int fd, const SID *user, const SID *group ) ++static struct security_descriptor *get_xattr_acls( int fd, const SID *user, const SID *group ) +{ + int dacl_size = sizeof(ACL), n; + int offset, type, flags, mask, rev, ia, sa; @@ -189,17 +189,20 @@ index 146ea68..4c72775 100644 + while (*p); + + if (sd_is_valid( sd, n )) ++ { ++ convert_generic_sd( sd ); + return sd; ++ } + +err: + free( sd ); + return NULL; +} + - /* Convert generic rights into standard access rights */ - void convert_generic_sd( struct security_descriptor *sd ) + static struct security_descriptor *get_xattr_sd( int fd ) { -@@ -786,6 +945,7 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode + struct security_descriptor *sd; +@@ -752,6 +914,7 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode int unix_fd = get_unix_fd( fd ); struct stat st; struct security_descriptor *sd; @@ -207,22 +210,21 @@ index 146ea68..4c72775 100644 if (unix_fd == -1 || fstat( unix_fd, &st ) == -1) return obj->sd; -@@ -795,11 +955,12 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode +@@ -761,10 +924,11 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode (st.st_uid == *uid)) return obj->sd; + user = security_unix_uid_to_sid( st.st_uid ); + group = token_get_primary_group( current->process->token ); sd = get_xattr_sd( unix_fd ); -+ if (!sd) sd = get_xattr_acls( unix_fd, user, group ); - if (sd) convert_generic_sd( sd ); - if (!sd) sd = mode_to_sd( st.st_mode, - security_unix_uid_to_sid( st.st_uid ), - token_get_primary_group( current->process->token )); ++ if (!sd) sd = get_xattr_acls( unix_fd, user, group ); + if (!sd) sd = mode_to_sd( st.st_mode, user, group ); if (!sd) return obj->sd; *mode = st.st_mode; -- -2.3.2 +2.3.3 diff --git a/patches/server-Inherited_ACLs/0001-server-Inherit-security-attributes-from-parent-direc.patch b/patches/server-Inherited_ACLs/0001-server-Inherit-security-attributes-from-parent-direc.patch index 29a0fc41..f8b04ba7 100644 --- a/patches/server-Inherited_ACLs/0001-server-Inherit-security-attributes-from-parent-direc.patch +++ b/patches/server-Inherited_ACLs/0001-server-Inherit-security-attributes-from-parent-direc.patch @@ -1,4 +1,4 @@ -From bab9a36e823c7d0227bcc72d691eac90a5ff405d Mon Sep 17 00:00:00 2001 +From 2b904b005f24af58f0b74a7b4d4f3e4db31f2553 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Fri, 18 Apr 2014 14:08:36 -0600 Subject: server: Inherit security attributes from parent directories on @@ -10,7 +10,7 @@ Subject: server: Inherit security attributes from parent directories on 2 files changed, 137 insertions(+), 10 deletions(-) diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c -index f98bf2b..8eed015 100644 +index 137ac5a..fc666f4 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -3230,7 +3230,6 @@ static void test_CreateDirectoryA(void) @@ -70,22 +70,22 @@ index f98bf2b..8eed015 100644 "Inherited Administators Group ACE has unexpected flags (0x%x != 0x10)\n", ((ACE_HEADER *)ace)->AceFlags); ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", diff --git a/server/file.c b/server/file.c -index 09b7811..188e352 100644 +index d479440..14de2c5 100644 --- a/server/file.c +++ b/server/file.c @@ -71,6 +71,7 @@ struct file }; static unsigned int generic_file_map_access( unsigned int access ); -+struct security_descriptor *get_xattr_sd( int fd ); ++static struct security_descriptor *get_xattr_sd( int fd ); static void file_dump( struct object *obj, int verbose ); static struct fd *file_get_fd( struct object *obj ); -@@ -252,11 +253,142 @@ void set_xattr_sd( int fd, const struct security_descriptor *sd, const SID *user +@@ -220,11 +221,142 @@ static void set_xattr_sd( int fd, const struct security_descriptor *sd ) xattr_fset( fd, WINE_XATTR_SD, buffer, len ); } -+struct security_descriptor *inherit_sd( const struct security_descriptor *parent_sd, int is_dir ) ++static struct security_descriptor *inherit_sd( const struct security_descriptor *parent_sd, int is_dir ) +{ + const DWORD inheritance_mask = INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE; + struct security_descriptor *sd = NULL; @@ -221,10 +221,10 @@ index 09b7811..188e352 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; -@@ -286,6 +418,10 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si + int flags; +@@ -253,6 +385,10 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si default: set_error( STATUS_INVALID_PARAMETER ); goto done; } @@ -234,8 +234,8 @@ index 09b7811..188e352 100644 + if (sd) { - owner = sd_get_owner( sd ); -@@ -329,6 +465,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si + const SID *owner = sd_get_owner( sd ); +@@ -292,6 +428,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si release_object( fd ); done: diff --git a/patches/server-Inherited_ACLs/0002-server-Inherit-security-attributes-from-parent-direc.patch b/patches/server-Inherited_ACLs/0002-server-Inherit-security-attributes-from-parent-direc.patch index 17061f9f..cda05d5f 100644 --- a/patches/server-Inherited_ACLs/0002-server-Inherit-security-attributes-from-parent-direc.patch +++ b/patches/server-Inherited_ACLs/0002-server-Inherit-security-attributes-from-parent-direc.patch @@ -1,15 +1,36 @@ -From 72d852c01753120da3503f97dc1b9ab7d7c4d8f9 Mon Sep 17 00:00:00 2001 +From 5d79bee5c5ee1e9a17fb60a53c4ab0c489f17943 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Fri, 18 Apr 2014 14:10:49 -0600 Subject: server: Inherit security attributes from parent directories on SetSecurityInfo. (try 7) --- - server/fd.c | 13 +++++- - server/file.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- - server/file.h | 1 + - 3 files changed, 141 insertions(+), 6 deletions(-) + dlls/advapi32/tests/security.c | 2 + + server/fd.c | 13 ++++- + server/file.c | 121 +++++++++++++++++++++++++++++++++++++++++ + server/file.h | 1 + + 4 files changed, 135 insertions(+), 2 deletions(-) +diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c +index fc666f4..2bc7e56 100644 +--- a/dlls/advapi32/tests/security.c ++++ b/dlls/advapi32/tests/security.c +@@ -3230,6 +3230,7 @@ static void test_CreateDirectoryA(void) + ok(error == ERROR_SUCCESS, "Failed to get permissions on file.\n"); + bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); + ok(bret, "GetAclInformation failed\n"); ++ todo_wine + ok(acl_size.AceCount == 2, "GetAclInformation returned unexpected entry count (%d != 2).\n", + acl_size.AceCount); + if (acl_size.AceCount > 0) +@@ -3277,6 +3278,7 @@ static void test_CreateDirectoryA(void) + ok(error == ERROR_SUCCESS, "Failed to get permissions on file.\n"); + bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); + ok(bret, "GetAclInformation failed\n"); ++ todo_wine + ok(acl_size.AceCount == 2, "GetAclInformation returned unexpected entry count (%d != 2).\n", + acl_size.AceCount); + if (acl_size.AceCount > 0) diff --git a/server/fd.c b/server/fd.c index e3b722c..e6ec90a 100644 --- a/server/fd.c @@ -42,10 +63,10 @@ index e3b722c..e6ec90a 100644 if (orig->inode) diff --git a/server/file.c b/server/file.c -index 188e352..146ea68 100644 +index 14de2c5..9031de3 100644 --- a/server/file.c +++ b/server/file.c -@@ -333,6 +333,106 @@ struct security_descriptor *inherit_sd( const struct security_descriptor *parent +@@ -301,6 +301,106 @@ static struct security_descriptor *inherit_sd( const struct security_descriptor return sd; } @@ -152,18 +173,17 @@ index 188e352..146ea68 100644 static struct security_descriptor *file_get_parent_sd( struct fd *root, const char *child_name, int child_len, int is_dir ) { -@@ -805,20 +905,41 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner ) - int set_file_sd( struct object *obj, struct fd *fd, const struct security_descriptor *sd, - unsigned int set_info ) +@@ -770,6 +870,7 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner ) + int set_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid, + const struct security_descriptor *sd, unsigned int set_info ) { + struct security_descriptor *tmp_sd = NULL; + struct security_descriptor *new_sd; int unix_fd = get_unix_fd( fd ); const SID *owner, *group; - struct stat st; - mode_t mode; -+ int ret = 1; - - if (unix_fd == -1 || fstat( unix_fd, &st ) == -1) return 1; +@@ -779,8 +880,28 @@ int set_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid, + if (!set_info || unix_fd == -1 || fstat( unix_fd, &st ) == -1) return 1; + if (!obj->sd) get_file_sd( obj, fd, mode, uid ); + if (!(set_info & PROTECTED_DACL_SECURITY_INFORMATION)) + { @@ -183,46 +203,15 @@ index 188e352..146ea68 100644 + } + } + - if (set_info & OWNER_SECURITY_INFORMATION) - { - owner = sd_get_owner( sd ); - if (!owner) - { - set_error( STATUS_INVALID_SECURITY_DESCR ); -- return 0; -+ ret = 0; -+ goto err; - } - if (!obj->sd || !security_equal_sid( owner, sd_get_owner( obj->sd ) )) - { -@@ -836,7 +957,8 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri - if (!group) - { - set_error( STATUS_INVALID_SECURITY_DESCR ); -- return 0; -+ ret = 0; -+ goto err; - } - if (!obj->sd || !security_equal_sid( group, sd_get_group( obj->sd ) )) - { -@@ -861,10 +983,13 @@ 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(); -- return 0; -+ ret = 0; - } - } -- return 1; -+ -+err: + /* calculate the new sd, save to a temporary variable before assigning */ + new_sd = set_sd_from_token_internal( sd, obj->sd, set_info, current->process->token ); + free( tmp_sd ); -+ return ret; - } - - static int file_set_sd( struct object *obj, const struct security_descriptor *sd, ++ + if (new_sd) + { + /* convert generic rights into standard access rights */ diff --git a/server/file.h b/server/file.h -index e15fa2a..00bfa7a 100644 +index 16883b2..cf49b08 100644 --- a/server/file.h +++ b/server/file.h @@ -79,6 +79,7 @@ extern void allow_fd_caching( struct fd *fd ); diff --git a/patches/server-Stored_ACLs/0001-server-Unify-the-storage-of-security-attributes-for-.patch b/patches/server-Stored_ACLs/0001-server-Unify-the-storage-of-security-attributes-for-.patch index 16145b90..4aeb1601 100644 --- a/patches/server-Stored_ACLs/0001-server-Unify-the-storage-of-security-attributes-for-.patch +++ b/patches/server-Stored_ACLs/0001-server-Unify-the-storage-of-security-attributes-for-.patch @@ -1,24 +1,23 @@ -From f2866f1d9f575eab3034f71128c9e68c81e0138a Mon Sep 17 00:00:00 2001 +From 22b353ef160d234b8f73e9e9c36136181561a743 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Thu, 17 Apr 2014 16:07:46 -0600 Subject: server: Unify the storage of security attributes for files and directories. (try 7) --- - server/change.c | 46 ++++++---------------------------------------- - server/file.c | 25 +++++++++++++++++-------- - server/file.h | 2 ++ - 3 files changed, 25 insertions(+), 48 deletions(-) + server/change.c | 45 ++++++--------------------------------------- + server/file.c | 34 ++++++++++++++++++++++------------ + server/file.h | 2 ++ + 3 files changed, 30 insertions(+), 51 deletions(-) diff --git a/server/change.c b/server/change.c -index 3ac70a4..4f6ce81 100644 +index 3ac70a4..c2fe428 100644 --- a/server/change.c +++ b/server/change.c -@@ -320,49 +320,15 @@ static struct security_descriptor *dir_get_sd( struct object *obj ) - static int dir_set_sd( struct object *obj, const struct security_descriptor *sd, +@@ -321,48 +321,15 @@ static int dir_set_sd( struct object *obj, const struct security_descriptor *sd, unsigned int set_info ) { -- struct dir *dir = (struct dir *)obj; + struct dir *dir = (struct dir *)obj; - const SID *owner; - struct stat st; - mode_t mode; @@ -64,52 +63,68 @@ index 3ac70a4..4f6ce81 100644 - } - return 1; + fd = dir_get_fd( obj ); -+ ret = set_file_sd( obj, fd, sd, set_info ); ++ ret = set_file_sd( obj, fd, &dir->mode, &dir->uid, 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..fb89272 100644 +index f565f5a..f841b32 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 ) +@@ -538,18 +538,13 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner ) return new_mode & ~denied_mode; } -static int file_set_sd( struct object *obj, 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 ) ++int set_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid, ++ const struct security_descriptor *sd, unsigned int set_info ) { - struct file *file = (struct file *)obj; + int unix_fd = get_unix_fd( fd ); const SID *owner; struct stat st; - mode_t mode; +- mode_t mode; - int unix_fd; - - assert( obj->ops == &file_ops ); - - unix_fd = get_file_unix_fd( file ); ++ mode_t new_mode; if (unix_fd == -1 || fstat( unix_fd, &st ) == -1) return 1; -@@ -584,6 +579,20 @@ static int file_set_sd( struct object *obj, const struct security_descriptor *sd +@@ -576,10 +571,10 @@ static int file_set_sd( struct object *obj, const struct security_descriptor *sd + if (set_info & DACL_SECURITY_INFORMATION) + { + /* keep the bits that we don't map to access rights in the ACL */ +- mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX); +- mode |= sd_to_mode( sd, owner ); ++ new_mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX); ++ new_mode |= sd_to_mode( sd, owner ); + +- if (((st.st_mode ^ mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, mode ) == -1) ++ if (((st.st_mode ^ new_mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, new_mode ) == -1) + { + file_set_error(); + return 0; +@@ -588,6 +583,21 @@ static int file_set_sd( struct object *obj, const struct security_descriptor *sd return 1; } +static int file_set_sd( struct object *obj, const struct security_descriptor *sd, + unsigned int set_info ) +{ ++ struct file *file = (struct file *)obj; + struct fd *fd; + int ret; + + assert( obj->ops == &file_ops ); + + fd = file_get_fd( obj ); -+ ret = set_file_sd( obj, fd, sd, set_info ); ++ ret = set_file_sd( obj, fd, &file->mode, &file->uid, sd, set_info ); + release_object( fd ); + return ret; +} @@ -118,18 +133,18 @@ index cceb8ad..fb89272 100644 { struct file *file = (struct file *)obj; diff --git a/server/file.h b/server/file.h -index 493d30b..76cb383 100644 +index 85e4257..d1365b0 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, +@@ -124,6 +124,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 set_file_sd( 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, mode_t *mode, uid_t *uid, ++ const struct security_descriptor *sd, unsigned int set_info ); /* file mapping functions */ -- -1.7.9.5 +2.3.3 diff --git a/patches/server-Stored_ACLs/0002-server-Unify-the-retrieval-of-security-attributes-fo.patch b/patches/server-Stored_ACLs/0002-server-Unify-the-retrieval-of-security-attributes-fo.patch index 6b27128b..48191cc6 100644 --- a/patches/server-Stored_ACLs/0002-server-Unify-the-retrieval-of-security-attributes-fo.patch +++ b/patches/server-Stored_ACLs/0002-server-Unify-the-retrieval-of-security-attributes-fo.patch @@ -1,17 +1,17 @@ -From ba94c25ed29ed6d3fc1c49a13ddb5257f5b3f385 Mon Sep 17 00:00:00 2001 +From d28df1000aad8383a83cea9c18934be47f02f151 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Thu, 17 Apr 2014 16:07:50 -0600 Subject: server: Unify the retrieval of security attributes for files and directories. (try 7) --- - server/change.c | 32 +++++--------------------------- - server/file.c | 32 +++++++++++++++++++++----------- - server/file.h | 2 ++ + server/change.c | 32 +++++--------------------------- + server/file.c | 32 +++++++++++++++++++++----------- + server/file.h | 2 ++ 3 files changed, 28 insertions(+), 38 deletions(-) diff --git a/server/change.c b/server/change.c -index 4f6ce81..27dbe25 100644 +index c2fe428..29a48b3 100644 --- a/server/change.c +++ b/server/change.c @@ -281,39 +281,17 @@ static struct fd *dir_get_fd( struct object *obj ) @@ -60,10 +60,10 @@ index 4f6ce81..27dbe25 100644 } diff --git a/server/file.c b/server/file.c -index fb89272..1f008ea 100644 +index f841b32..932c036 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 +@@ -428,23 +428,19 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID return sd; } @@ -92,7 +92,7 @@ index fb89272..1f008ea 100644 return obj->sd; sd = mode_to_sd( st.st_mode, -@@ -448,13 +444,27 @@ static struct security_descriptor *file_get_sd( struct object *obj ) +@@ -452,13 +448,27 @@ static struct security_descriptor *file_get_sd( struct object *obj ) token_get_primary_group( current->process->token )); if (!sd) return obj->sd; @@ -123,18 +123,18 @@ index fb89272..1f008ea 100644 { mode_t mode = 0; diff --git a/server/file.h b/server/file.h -index 76cb383..43a234f 100644 +index d1365b0..c866312 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 +@@ -126,6 +126,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 set_file_sd( 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, mode_t *mode, uid_t *uid, + 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 */ -- -1.7.9.5 +2.3.3 diff --git a/patches/server-Stored_ACLs/0003-server-Add-a-helper-function-set_sd_from_token_inter.patch b/patches/server-Stored_ACLs/0003-server-Add-a-helper-function-set_sd_from_token_inter.patch new file mode 100644 index 00000000..2fe67e83 --- /dev/null +++ b/patches/server-Stored_ACLs/0003-server-Add-a-helper-function-set_sd_from_token_inter.patch @@ -0,0 +1,147 @@ +From 539af3804249e08ae39b6d6abb9f08dbe711a8a8 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Mon, 30 Mar 2015 12:32:34 +0200 +Subject: server: Add a helper function set_sd_from_token_internal to merge two + security descriptors. + +--- + server/object.c | 55 +++++++++++++++++++++++++++++++++++-------------------- + server/object.h | 3 +++ + 2 files changed, 38 insertions(+), 20 deletions(-) + +diff --git a/server/object.c b/server/object.c +index d4afefd..1a7e16a 100644 +--- a/server/object.c ++++ b/server/object.c +@@ -423,8 +423,9 @@ struct security_descriptor *default_get_sd( struct object *obj ) + return obj->sd; + } + +-int set_sd_defaults_from_token( struct object *obj, const struct security_descriptor *sd, +- unsigned int set_info, struct token *token ) ++struct security_descriptor *set_sd_from_token_internal( const struct security_descriptor *sd, ++ const struct security_descriptor *old_sd, ++ unsigned int set_info, struct token *token ) + { + struct security_descriptor new_sd, *new_sd_ptr; + int present; +@@ -432,8 +433,6 @@ int set_sd_defaults_from_token( struct object *obj, const struct security_descri + const ACL *sacl, *dacl; + char *ptr; + +- if (!set_info) return 1; +- + new_sd.control = sd->control & ~SE_SELF_RELATIVE; + + if (set_info & OWNER_SECURITY_INFORMATION && sd->owner_len) +@@ -441,10 +440,10 @@ int set_sd_defaults_from_token( struct object *obj, const struct security_descri + owner = sd_get_owner( sd ); + new_sd.owner_len = sd->owner_len; + } +- else if (obj->sd && obj->sd->owner_len) ++ else if (old_sd && old_sd->owner_len) + { +- owner = sd_get_owner( obj->sd ); +- new_sd.owner_len = obj->sd->owner_len; ++ owner = sd_get_owner( old_sd ); ++ new_sd.owner_len = old_sd->owner_len; + } + else if (token) + { +@@ -458,10 +457,10 @@ int set_sd_defaults_from_token( struct object *obj, const struct security_descri + group = sd_get_group( sd ); + new_sd.group_len = sd->group_len; + } +- else if (obj->sd && obj->sd->group_len) ++ else if (old_sd && old_sd->group_len) + { +- group = sd_get_group( obj->sd ); +- new_sd.group_len = obj->sd->group_len; ++ group = sd_get_group( old_sd ); ++ new_sd.group_len = old_sd->group_len; + } + else if (token) + { +@@ -476,10 +475,10 @@ int set_sd_defaults_from_token( struct object *obj, const struct security_descri + new_sd.sacl_len = sd->sacl_len; + else + { +- if (obj->sd) sacl = sd_get_sacl( obj->sd, &present ); ++ if (old_sd) sacl = sd_get_sacl( old_sd, &present ); + +- if (obj->sd && present) +- new_sd.sacl_len = obj->sd->sacl_len; ++ if (old_sd && present) ++ new_sd.sacl_len = old_sd->sacl_len; + else + new_sd.sacl_len = 0; + } +@@ -490,10 +489,10 @@ int set_sd_defaults_from_token( struct object *obj, const struct security_descri + new_sd.dacl_len = sd->dacl_len; + else + { +- if (obj->sd) dacl = sd_get_dacl( obj->sd, &present ); ++ if (old_sd) dacl = sd_get_dacl( old_sd, &present ); + +- if (obj->sd && present) +- new_sd.dacl_len = obj->sd->dacl_len; ++ if (old_sd && present) ++ new_sd.dacl_len = old_sd->dacl_len; + else if (token) + { + dacl = token_get_default_dacl( token ); +@@ -504,7 +503,7 @@ int set_sd_defaults_from_token( struct object *obj, const struct security_descri + + ptr = mem_alloc( sizeof(new_sd) + new_sd.owner_len + new_sd.group_len + + new_sd.sacl_len + new_sd.dacl_len ); +- if (!ptr) return 0; ++ if (!ptr) return NULL; + new_sd_ptr = (struct security_descriptor*)ptr; + + memcpy( ptr, &new_sd, sizeof(new_sd) ); +@@ -517,9 +516,25 @@ int set_sd_defaults_from_token( struct object *obj, const struct security_descri + ptr += new_sd.sacl_len; + memcpy( ptr, dacl, new_sd.dacl_len ); + +- free( obj->sd ); +- obj->sd = new_sd_ptr; +- return 1; ++ return new_sd_ptr; ++} ++ ++int set_sd_defaults_from_token( struct object *obj, const struct security_descriptor *sd, ++ unsigned int set_info, struct token *token ) ++{ ++ struct security_descriptor *new_sd; ++ ++ if (!set_info) return 1; ++ ++ new_sd = set_sd_from_token_internal( sd, obj->sd, set_info, token ); ++ if (new_sd) ++ { ++ free( obj->sd ); ++ obj->sd = new_sd; ++ return 1; ++ } ++ ++ return 0; + } + + /** Set the security descriptor using the current primary token for defaults. */ +diff --git a/server/object.h b/server/object.h +index 3817c75..c2c38b7 100644 +--- a/server/object.h ++++ b/server/object.h +@@ -139,6 +139,9 @@ extern struct fd *no_get_fd( struct object *obj ); + extern unsigned int no_map_access( struct object *obj, unsigned int access ); + extern struct security_descriptor *default_get_sd( struct object *obj ); + extern int default_set_sd( struct object *obj, const struct security_descriptor *sd, unsigned int set_info ); ++extern struct security_descriptor *set_sd_from_token_internal( const struct security_descriptor *sd, ++ const struct security_descriptor *old_sd, ++ unsigned int set_info, struct token *token ); + extern int set_sd_defaults_from_token( struct object *obj, const struct security_descriptor *sd, + unsigned int set_info, struct token *token ); + extern struct object *no_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attributes ); +-- +2.3.3 + diff --git a/patches/server-Stored_ACLs/0004-server-Store-user-and-group-inside-stored-extended-f.patch b/patches/server-Stored_ACLs/0004-server-Store-user-and-group-inside-stored-extended-f.patch deleted file mode 100644 index 6af8c283..00000000 --- a/patches/server-Stored_ACLs/0004-server-Store-user-and-group-inside-stored-extended-f.patch +++ /dev/null @@ -1,161 +0,0 @@ -From cd48ef93da9c34e4757d878403374edd0e616b64 Mon Sep 17 00:00:00 2001 -From: "Erich E. Hoover" -Date: Fri, 18 Apr 2014 15:35:24 -0600 -Subject: server: Store user and group inside stored extended file attribute - information. (try 7) - ---- - server/file.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++------- - 1 file changed, 70 insertions(+), 9 deletions(-) - -diff --git a/server/file.c b/server/file.c -index 502951c..72d6d95 100644 ---- a/server/file.c -+++ b/server/file.c -@@ -187,10 +187,11 @@ 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 ) - { -- 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 */ -@@ -198,14 +199,52 @@ void set_xattr_sd( int fd, const struct security_descriptor *sd ) - 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; -+ dst_sd->owner_len = owner_len; -+ dst_sd->group_len = group_len; -+ src_ptr += sizeof(struct security_descriptor); -+ dst_ptr += sizeof(struct security_descriptor); -+ /* 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; - xattr_fset( fd, WINE_XATTR_SD, buffer, len ); - } - -@@ -214,6 +253,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si - unsigned int options, unsigned int attrs, - const struct security_descriptor *sd ) - { -+ const SID *owner = NULL, *group = NULL; - struct object *obj = NULL; - struct fd *fd; - int flags; -@@ -244,9 +284,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) -@@ -270,7 +313,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,7 +623,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; - -@@ -604,6 +647,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) -@@ -612,7 +673,7 @@ 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) - { --- -1.7.9.5 - diff --git a/patches/server-Stored_ACLs/0004-server-Temporarily-store-the-full-security-descripto.patch b/patches/server-Stored_ACLs/0004-server-Temporarily-store-the-full-security-descripto.patch new file mode 100644 index 00000000..58b15434 --- /dev/null +++ b/patches/server-Stored_ACLs/0004-server-Temporarily-store-the-full-security-descripto.patch @@ -0,0 +1,222 @@ +From 556b2f79dc0f03bd9e7bba04003f2071b21baa08 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Mon, 30 Mar 2015 12:50:21 +0200 +Subject: server: Temporarily store the full security descriptor for file + objects. + +--- + dlls/advapi32/tests/security.c | 12 +++--- + server/change.c | 8 +++- + server/file.c | 83 ++++++++++++++++++++++++++++-------------- + server/file.h | 3 +- + 4 files changed, 70 insertions(+), 36 deletions(-) + +diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c +index 15c3b1d..0392add 100644 +--- a/dlls/advapi32/tests/security.c ++++ b/dlls/advapi32/tests/security.c +@@ -4148,22 +4148,22 @@ static void test_GetSecurityInfo(void) + bret = pGetAce(pDacl, 0, (VOID **)&ace); + ok(bret, "Failed to get Current User ACE.\n"); + bret = EqualSid(&ace->SidStart, user_sid); +- todo_wine ok(bret, "Current User ACE != Current User SID.\n"); ++ ok(bret, "Current User ACE != Current User SID.\n"); + ok(((ACE_HEADER *)ace)->AceFlags == 0, + "Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); +- ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", +- ace->Mask); ++ todo_wine ok(ace->Mask == 0x1f01ff, ++ "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask); + } + if (acl_size.AceCount > 1) + { + bret = pGetAce(pDacl, 1, (VOID **)&ace); + ok(bret, "Failed to get Administators Group ACE.\n"); + bret = EqualSid(&ace->SidStart, admin_sid); +- todo_wine ok(bret, "Administators Group ACE != Administators Group SID.\n"); ++ ok(bret, "Administators Group ACE != Administators Group SID.\n"); + ok(((ACE_HEADER *)ace)->AceFlags == 0, + "Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); +- ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", +- ace->Mask); ++ todo_wine ok(ace->Mask == 0x1f01ff, ++ "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask); + } + LocalFree(pSD); + CloseHandle(obj); +diff --git a/server/change.c b/server/change.c +index 29a48b3..87b45f8 100644 +--- a/server/change.c ++++ b/server/change.c +@@ -1020,7 +1020,8 @@ static int dir_add_to_existing_notify( struct dir *dir ) + + #endif /* USE_INOTIFY */ + +-struct object *create_dir_obj( struct fd *fd, unsigned int access, mode_t mode ) ++struct object *create_dir_obj( struct fd *fd, unsigned int access, mode_t mode, ++ const struct security_descriptor *sd ) + { + struct dir *dir; + +@@ -1039,6 +1040,11 @@ struct object *create_dir_obj( struct fd *fd, unsigned int access, mode_t mode ) + dir->uid = ~(uid_t)0; + set_fd_user( fd, &dir_fd_ops, &dir->obj ); + ++ if (sd) dir_set_sd( &dir->obj, sd, OWNER_SECURITY_INFORMATION | ++ GROUP_SECURITY_INFORMATION | ++ DACL_SECURITY_INFORMATION | ++ SACL_SECURITY_INFORMATION ); ++ + dir_add_to_existing_notify( dir ); + + return &dir->obj; +diff --git a/server/file.c b/server/file.c +index 932c036..7493735 100644 +--- a/server/file.c ++++ b/server/file.c +@@ -168,7 +168,8 @@ struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access, unsigne + return file; + } + +-static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_t mode ) ++static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_t mode, ++ const struct security_descriptor *sd ) + { + struct file *file = alloc_object( &file_ops ); + +@@ -179,6 +180,12 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_ + file->fd = fd; + grab_object( fd ); + set_fd_user( fd, &file_fd_ops, &file->obj ); ++ ++ if (sd) file_set_sd( &file->obj, sd, OWNER_SECURITY_INFORMATION | ++ GROUP_SECURITY_INFORMATION | ++ DACL_SECURITY_INFORMATION | ++ SACL_SECURITY_INFORMATION ); ++ + return &file->obj; + } + +@@ -245,11 +252,11 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si + if (!fd) goto done; + + if (S_ISDIR(mode)) +- obj = create_dir_obj( fd, access, mode ); ++ obj = create_dir_obj( fd, access, mode, sd ); + else if (S_ISCHR(mode) && is_serial_fd( fd )) + obj = create_serial( fd ); + else +- obj = create_file_obj( fd, access, mode ); ++ obj = create_file_obj( fd, access, mode, sd ); + + release_object( fd ); + +@@ -551,46 +558,66 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner ) + int set_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid, + const struct security_descriptor *sd, unsigned int set_info ) + { ++ struct security_descriptor *new_sd; + int unix_fd = get_unix_fd( fd ); +- const SID *owner; ++ const SID *owner, *group; + struct stat st; + mode_t new_mode; + +- if (unix_fd == -1 || fstat( unix_fd, &st ) == -1) return 1; ++ if (!set_info || unix_fd == -1 || fstat( unix_fd, &st ) == -1) return 1; ++ if (!obj->sd) get_file_sd( obj, fd, mode, uid ); + +- if (set_info & OWNER_SECURITY_INFORMATION) ++ /* calculate the new sd, save to a temporary variable before assigning */ ++ new_sd = set_sd_from_token_internal( sd, obj->sd, set_info, current->process->token ); ++ if (new_sd) + { +- owner = sd_get_owner( sd ); +- if (!owner) ++ if (set_info & OWNER_SECURITY_INFORMATION) + { +- set_error( STATUS_INVALID_SECURITY_DESCR ); +- return 0; ++ owner = sd_get_owner( new_sd ); ++ assert( owner ); ++ ++ if (!obj->sd || !security_equal_sid( owner, sd_get_owner( obj->sd ) )) ++ { ++ /* FIXME: get Unix uid and call fchown */ ++ } + } +- if (!obj->sd || !security_equal_sid( owner, sd_get_owner( obj->sd ) )) ++ ++ if (set_info & GROUP_SECURITY_INFORMATION) + { +- /* FIXME: get Unix uid and call fchown */ ++ group = sd_get_group( new_sd ); ++ assert( group ); ++ ++ if (!obj->sd || !security_equal_sid( group, sd_get_group( obj->sd ) )) ++ { ++ /* FIXME: get Unix uid and call fchown */ ++ } + } +- } +- else if (obj->sd) +- owner = sd_get_owner( obj->sd ); +- else +- owner = token_get_user( current->process->token ); + +- /* group and sacl not supported */ ++ if (set_info & DACL_SECURITY_INFORMATION) ++ { ++ owner = sd_get_owner( new_sd ); ++ assert( owner ); + +- if (set_info & DACL_SECURITY_INFORMATION) +- { +- /* keep the bits that we don't map to access rights in the ACL */ +- new_mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX); +- new_mode |= sd_to_mode( sd, owner ); ++ /* keep the bits that we don't map to access rights in the ACL */ ++ new_mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX); ++ new_mode |= sd_to_mode( new_sd, owner ); + +- if (((st.st_mode ^ new_mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, new_mode ) == -1) +- { +- file_set_error(); +- return 0; ++ if (((st.st_mode ^ new_mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, new_mode ) == -1) ++ { ++ free( new_sd ); ++ file_set_error(); ++ return 0; ++ } ++ ++ *mode = new_mode; + } ++ ++ free( obj->sd ); ++ obj->sd = new_sd; ++ return 1; + } +- return 1; ++ ++ return 0; + } + + static int file_set_sd( struct object *obj, const struct security_descriptor *sd, +diff --git a/server/file.h b/server/file.h +index c866312..16883b2 100644 +--- a/server/file.h ++++ b/server/file.h +@@ -142,7 +142,8 @@ extern int get_page_size(void); + + extern void do_change_notify( int unix_fd ); + extern void sigio_callback(void); +-extern struct object *create_dir_obj( struct fd *fd, unsigned int access, mode_t mode ); ++extern struct object *create_dir_obj( struct fd *fd, unsigned int access, mode_t mode, ++ const struct security_descriptor *sd ); + extern struct dir *get_dir_obj( struct process *process, obj_handle_t handle, unsigned int access ); + + /* completion */ +-- +2.3.3 + diff --git a/patches/server-Stored_ACLs/0003-server-Store-file-security-attributes-with-extended-.patch b/patches/server-Stored_ACLs/0005-server-Store-file-security-attributes-with-extended-.patch similarity index 66% rename from patches/server-Stored_ACLs/0003-server-Store-file-security-attributes-with-extended-.patch rename to patches/server-Stored_ACLs/0005-server-Store-file-security-attributes-with-extended-.patch index 38a8a5f7..9846b1f2 100644 --- a/patches/server-Stored_ACLs/0003-server-Store-file-security-attributes-with-extended-.patch +++ b/patches/server-Stored_ACLs/0005-server-Store-file-security-attributes-with-extended-.patch @@ -1,12 +1,12 @@ -From 687e5f2a153a1fbbac2631bea088b0237f2d4a20 Mon Sep 17 00:00:00 2001 +From be825014ca6fcdd6ecbad7e7270a5f949056b24b Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" -Date: Fri, 18 Apr 2014 15:34:47 -0600 -Subject: server: Store file security attributes with extended file - attributes. (try 7) +Date: Mon, 30 Mar 2015 13:04:23 +0200 +Subject: server: Store file security attributes with extended file attributes. + (v8) --- - include/wine/port.h | 3 +++ - server/file.c | 34 ++++++++++++++++++++++++++++++++++ + include/wine/port.h | 3 +++ + server/file.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/include/wine/port.h b/include/wine/port.h @@ -24,7 +24,7 @@ index 9e2b8165..71be265 100644 extern int xattr_fget( int filedes, const char *name, void *value, size_t size ); extern int xattr_fremove( int filedes, const char *name ); diff --git a/server/file.c b/server/file.c -index 1f008ea..502951c 100644 +index 7493735..be07f4e 100644 --- a/server/file.c +++ b/server/file.c @@ -32,6 +32,7 @@ @@ -50,11 +50,11 @@ index 1f008ea..502951c 100644 struct file { struct object obj; /* object header */ -@@ -178,6 +187,28 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_ +@@ -189,6 +198,28 @@ 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 ) ++static void set_xattr_sd( int fd, const struct security_descriptor *sd ) +{ + char buffer[XATTR_SIZE_MAX]; + int present, len; @@ -65,8 +65,8 @@ index 1f008ea..502951c 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 -+ + sd->dacl_len; ++ len = 2 + sizeof(struct security_descriptor) + sd->owner_len + ++ sd->group_len + sd->sacl_len + sd->dacl_len; + if (len > XATTR_SIZE_MAX) return; + + /* include the descriptor revision and resource manager control bits */ @@ -79,23 +79,16 @@ index 1f008ea..502951c 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 +270,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 ); +@@ -612,6 +643,9 @@ int set_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid, + *mode = new_mode; + } - if (S_ISDIR(mode)) - obj = create_dir_obj( fd, access, mode ); -@@ -580,6 +612,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 ); ++ /* extended attributes are set after the file mode, to ensure it stays in sync */ ++ set_xattr_sd( unix_fd, new_sd ); + - if (((st.st_mode ^ mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, mode ) == -1) - { - file_set_error(); + free( obj->sd ); + obj->sd = new_sd; + return 1; -- -1.7.9.5 +2.3.3 diff --git a/patches/server-Stored_ACLs/0005-server-Retrieve-file-security-attributes-with-extend.patch b/patches/server-Stored_ACLs/0006-server-Retrieve-file-security-attributes-with-extend.patch similarity index 95% rename from patches/server-Stored_ACLs/0005-server-Retrieve-file-security-attributes-with-extend.patch rename to patches/server-Stored_ACLs/0006-server-Retrieve-file-security-attributes-with-extend.patch index 4e7060a2..30c8fe1e 100644 --- a/patches/server-Stored_ACLs/0005-server-Retrieve-file-security-attributes-with-extend.patch +++ b/patches/server-Stored_ACLs/0006-server-Retrieve-file-security-attributes-with-extend.patch @@ -1,4 +1,4 @@ -From 74b5cfba80dbe32641406c63c74d9e82b599e138 Mon Sep 17 00:00:00 2001 +From b9b3e983c12ef8cdd08ac6c08c6c5b103fa12192 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Fri, 18 Apr 2014 14:01:35 -0600 Subject: server: Retrieve file security attributes with extended file @@ -10,7 +10,7 @@ Subject: server: Retrieve file security attributes with extended file 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c -index 15c3b1d..3457fbc 100644 +index 0392add..98b3f43 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -3193,24 +3193,24 @@ static void test_CreateDirectoryA(void) @@ -86,14 +86,14 @@ index 15c3b1d..3457fbc 100644 LocalFree(pSD); diff --git a/server/file.c b/server/file.c -index 5671e5a..33f9483 100644 +index be07f4e..a2cea64 100644 --- a/server/file.c +++ b/server/file.c -@@ -503,6 +503,25 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID +@@ -466,6 +466,25 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID return sd; } -+struct security_descriptor *get_xattr_sd( int fd ) ++static struct security_descriptor *get_xattr_sd( int fd ) +{ + struct security_descriptor *sd; + char buffer[XATTR_SIZE_MAX]; @@ -115,7 +115,7 @@ index 5671e5a..33f9483 100644 struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid ) { -@@ -518,9 +537,10 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode +@@ -481,9 +500,10 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode (st.st_uid == *uid)) return obj->sd; diff --git a/patches/server-Stored_ACLs/0006-server-Convert-return-of-file-security-masks-with-ge.patch b/patches/server-Stored_ACLs/0007-server-Convert-return-of-file-security-masks-with-ge.patch similarity index 60% rename from patches/server-Stored_ACLs/0006-server-Convert-return-of-file-security-masks-with-ge.patch rename to patches/server-Stored_ACLs/0007-server-Convert-return-of-file-security-masks-with-ge.patch index a492cf04..276d9ea3 100644 --- a/patches/server-Stored_ACLs/0006-server-Convert-return-of-file-security-masks-with-ge.patch +++ b/patches/server-Stored_ACLs/0007-server-Convert-return-of-file-security-masks-with-ge.patch @@ -1,16 +1,16 @@ -From 20110e2294539cba86a259a6b5fc6749f2e5cdd4 Mon Sep 17 00:00:00 2001 +From c544c9af2e3f6526b871d6d9e22ca77ee1bd7690 Mon Sep 17 00:00:00 2001 From: "Erich E. Hoover" Date: Fri, 18 Apr 2014 14:05:32 -0600 Subject: server: Convert return of file security masks with generic access mappings. (try 7) --- - dlls/advapi32/tests/security.c | 16 ++++++++-------- - server/file.c | 22 ++++++++++++++++++++++ - 2 files changed, 30 insertions(+), 8 deletions(-) + dlls/advapi32/tests/security.c | 20 ++++++++++---------- + server/file.c | 29 ++++++++++++++++++++++++++++- + 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c -index 3457fbc..c256753 100644 +index 98b3f43..fa4c86d 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -3197,8 +3197,8 @@ static void test_CreateDirectoryA(void) @@ -57,16 +57,34 @@ index 3457fbc..c256753 100644 } LocalFree(pSD); +@@ -4150,7 +4150,7 @@ static void test_GetSecurityInfo(void) + ok(bret, "Current User ACE != Current User SID.\n"); + ok(((ACE_HEADER *)ace)->AceFlags == 0, + "Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); +- todo_wine ok(ace->Mask == 0x1f01ff, ++ ok(ace->Mask == 0x1f01ff, + "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask); + } + if (acl_size.AceCount > 1) +@@ -4161,7 +4161,7 @@ static void test_GetSecurityInfo(void) + ok(bret, "Administators Group ACE != Administators Group SID.\n"); + ok(((ACE_HEADER *)ace)->AceFlags == 0, + "Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); +- todo_wine ok(ace->Mask == 0x1f01ff, ++ ok(ace->Mask == 0x1f01ff, + "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask); + } + LocalFree(pSD); diff --git a/server/file.c b/server/file.c -index 33f9483..a50276e 100644 +index a2cea64..d3a97af 100644 --- a/server/file.c +++ b/server/file.c -@@ -522,6 +522,27 @@ struct security_descriptor *get_xattr_sd( int fd ) +@@ -466,6 +466,26 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID return sd; } +/* Convert generic rights into standard access rights */ -+void convert_generic_sd( struct security_descriptor *sd ) ++static void convert_generic_sd( struct security_descriptor *sd ) +{ + const ACL *dacl; + int present; @@ -80,23 +98,37 @@ index 33f9483..a50276e 100644 + for (i = 0; i < dacl->AceCount; i++, ace = ace_next( ace )) + { + DWORD *mask = (DWORD *)(ace + 1); -+ + *mask = generic_file_map_access( *mask ); + } + } +} + - struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode, - uid_t *uid ) + static struct security_descriptor *get_xattr_sd( int fd ) { -@@ -538,6 +559,7 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode - return obj->sd; + struct security_descriptor *sd; +@@ -481,7 +501,11 @@ static struct security_descriptor *get_xattr_sd( int fd ) + return NULL; - sd = get_xattr_sd( unix_fd ); -+ if (sd) convert_generic_sd( sd ); - if (!sd) sd = mode_to_sd( st.st_mode, - security_unix_uid_to_sid( st.st_uid ), - token_get_primary_group( current->process->token )); + sd = mem_alloc( n - 2 ); +- if (sd) memcpy( sd, &buffer[2], n - 2 ); ++ if (sd) ++ { ++ memcpy( sd, &buffer[2], n - 2 ); ++ convert_generic_sd( sd ); /* for backwards compatibility */ ++ } + return sd; + } + +@@ -622,6 +646,9 @@ int set_file_sd( struct object *obj, struct fd *fd, mode_t *mode, uid_t *uid, + new_sd = set_sd_from_token_internal( sd, obj->sd, set_info, current->process->token ); + if (new_sd) + { ++ /* convert generic rights into standard access rights */ ++ convert_generic_sd( new_sd ); ++ + if (set_info & OWNER_SECURITY_INFORMATION) + { + owner = sd_get_owner( new_sd ); -- 2.3.3 diff --git a/patches/server-Stored_ACLs/definition b/patches/server-Stored_ACLs/definition index 5fbddecb..87d44e21 100644 --- a/patches/server-Stored_ACLs/definition +++ b/patches/server-Stored_ACLs/definition @@ -1,25 +1,2 @@ Depends: ntdll-DOS_Attributes Fixes: [33576] Support for stored file ACLs - -# Swapping order with advapi32-Revert_DACL added the following test failures. -# If the Revert_DACL patchset is removed those have to be fixed manually. -# -#@@ -4148,7 +4047,7 @@ static void test_GetSecurityInfo(void) -# bret = pGetAce(pDacl, 0, (VOID **)&ace); -# ok(bret, "Failed to get Current User ACE.\n"); -# bret = EqualSid(&ace->SidStart, user_sid); -#- ok(bret, "Current User ACE != Current User SID.\n"); -#+ todo_wine ok(bret, "Current User ACE != Current User SID.\n"); -# ok(((ACE_HEADER *)ace)->AceFlags == 0, -# "Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); -# ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", -#@@ -4159,7 +4058,7 @@ static void test_GetSecurityInfo(void) -# bret = pGetAce(pDacl, 1, (VOID **)&ace); -# ok(bret, "Failed to get Administators Group ACE.\n"); -# bret = EqualSid(&ace->SidStart, admin_sid); -#- ok(bret, "Administators Group ACE != Administators Group SID.\n"); -#+ todo_wine ok(bret, "Administators Group ACE != Administators Group SID.\n"); -# ok(((ACE_HEADER *)ace)->AceFlags == 0, -# "Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); -# ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", -#