From 5c19cb0685dd47e7eb36dce9729200b79da61b11 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
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 |  6 +++---
 server/file.c                  | 23 +++++++++++++++++++++++
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index f7ae089..0013c3c 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -4501,8 +4501,8 @@ 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,
-                     "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
+        ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n",
+                                  ace->Mask);
     }
     if (acl_size.AceCount > 1)
     {
@@ -4512,7 +4512,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 ed7ddfc..6663927 100644
--- a/server/file.c
+++ b/server/file.c
@@ -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 */
+static void convert_generic_sd( struct security_descriptor *sd )
+{
+    const ACL *dacl;
+    int present;
+
+    dacl = sd_get_dacl( sd, &present );
+    if (present && dacl)
+    {
+        const ACE_HEADER *ace = (const ACE_HEADER *)(dacl + 1);
+        ULONG i;
+
+        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 )
 {
@@ -608,6 +628,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.5

