advapi32: implement SetEntriesInAclA by calling SetEntriesInAclW with parameters converted to wide char as necessary. Add additional NULL ptr check in SetEntriesInAclW for NewAcl. Add tests for SetEntriesInAclA by copying tests for SetEntriesInAclW.

Damian Dixon damian.dixon at gmail.com
Sat Jan 1 14:19:55 CST 2011


---
 dlls/advapi32/security.c       |   61 ++++++++++++++++-
 dlls/advapi32/tests/security.c |  138 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 193 insertions(+), 6 deletions(-)

diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c
index e24d90f..2757fff 100644
--- a/dlls/advapi32/security.c
+++ b/dlls/advapi32/security.c
@@ -3521,10 +3521,62 @@ BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
                                PACL OldAcl, PACL* NewAcl )
 {
-    FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
+    DWORD err = ERROR_SUCCESS;
+    PEXPLICIT_ACCESSW pEntriesW;
+
+    TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
+
     if (NewAcl)
-         *NewAcl = NULL;
-    return ERROR_SUCCESS;
+        *NewAcl = NULL;
+
+    if (!count && !OldAcl)
+        return ERROR_SUCCESS;
+
+    pEntriesW = HeapAlloc( GetProcessHeap(), 0, count*sizeof(EXPLICIT_ACCESSW) );
+    if (pEntriesW)
+    {
+        /* Convert from ANSI to Wide form */
+        int i, len;
+        LPWSTR wstr = NULL;
+        PEXPLICIT_ACCESSW ptrW = pEntriesW;
+        PEXPLICIT_ACCESSA ptrA = pEntries;
+
+        for (i = 0; i < count; ++i, ++ptrA, ++ptrW)
+        {
+            ptrW->grfAccessPermissions = ptrA->grfAccessPermissions;
+            ptrW->grfAccessMode = ptrA->grfAccessMode;
+            ptrW->grfInheritance = ptrA->grfInheritance;
+            ptrW->Trustee.pMultipleTrustee = NULL; /* currently not supported */
+            ptrW->Trustee.MultipleTrusteeOperation = ptrA->Trustee.MultipleTrusteeOperation;
+            ptrW->Trustee.TrusteeForm = ptrA->Trustee.TrusteeForm;
+            ptrW->Trustee.TrusteeType = ptrA->Trustee.TrusteeType;
+            /* Convert from multi-byte to wide char */ 
+            wstr = NULL;
+            if (ptrA->Trustee.ptstrName)
+            {
+                len = MultiByteToWideChar( CP_ACP, 0, ptrA->Trustee.ptstrName, -1, NULL, 0 );
+                wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
+                MultiByteToWideChar( CP_ACP, 0, ptrA->Trustee.ptstrName, -1, wstr, len );
+                ptrW->Trustee.ptstrName = wstr;
+            }
+            ptrW->Trustee.ptstrName = wstr;
+        }
+
+        err = SetEntriesInAclW( count, pEntriesW, OldAcl, NewAcl );
+
+        /* tidy up */
+        ptrW = pEntriesW;
+        for (i = 0; i < count; ++i, ++ptrW)
+        {
+            HeapFree( GetProcessHeap(), 0, ptrW->Trustee.ptstrName );
+        }
+        HeapFree( GetProcessHeap(), 0, pEntriesW );
+    }
+    else
+    {
+        err = ERROR_NOT_ENOUGH_MEMORY;
+    }
+    return err;
 }
 
 /******************************************************************************
@@ -3541,7 +3593,8 @@ DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
 
     TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
 
-    *NewAcl = NULL;
+    if (NewAcl)
+        *NewAcl = NULL;
 
     if (!count && !OldAcl)
         return ERROR_SUCCESS;
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index ff07513..6df4b29 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -107,6 +107,7 @@ static NTSTATUS (WINAPI *pLsaFreeMemory)(PVOID);
 static NTSTATUS (WINAPI *pLsaOpenPolicy)(PLSA_UNICODE_STRING,PLSA_OBJECT_ATTRIBUTES,ACCESS_MASK,PLSA_HANDLE);
 static NTSTATUS (WINAPI *pNtQueryObject)(HANDLE,OBJECT_INFORMATION_CLASS,PVOID,ULONG,PULONG);
 static DWORD (WINAPI *pSetEntriesInAclW)(ULONG, PEXPLICIT_ACCESSW, PACL, PACL*);
+static DWORD (WINAPI *pSetEntriesInAclA)(ULONG, PEXPLICIT_ACCESSA, PACL, PACL*);
 static BOOL (WINAPI *pSetSecurityDescriptorControl)(PSECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL,
                                                     SECURITY_DESCRIPTOR_CONTROL);
 static DWORD (WINAPI *pGetSecurityInfo)(HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION,
@@ -152,6 +153,7 @@ static void init(void)
     pIsValidSid = (void *)GetProcAddress(hmod, "IsValidSid");
     pMakeSelfRelativeSD = (void *)GetProcAddress(hmod, "MakeSelfRelativeSD");
     pSetEntriesInAclW = (void *)GetProcAddress(hmod, "SetEntriesInAclW");
+    pSetEntriesInAclA = (void *)GetProcAddress(hmod, "SetEntriesInAclA");
     pSetSecurityDescriptorControl = (void *)GetProcAddress(hmod, "SetSecurityDescriptorControl");
     pGetSecurityInfo = (void *)GetProcAddress(hmod, "GetSecurityInfo");
 
@@ -2478,7 +2480,7 @@ static void test_impersonation_level(void)
     HeapFree(GetProcessHeap(), 0, PrivilegeSet);
 }
 
-static void test_SetEntriesInAcl(void)
+static void test_SetEntriesInAclW(void)
 {
     DWORD res;
     PSID EveryoneSid = NULL, UsersSid = NULL;
@@ -2609,6 +2611,137 @@ static void test_SetEntriesInAcl(void)
     HeapFree(GetProcessHeap(), 0, OldAcl);
 }
 
+static void test_SetEntriesInAclA(void)
+{
+    DWORD res;
+    PSID EveryoneSid = NULL, UsersSid = NULL;
+    PACL OldAcl = NULL, NewAcl;
+    SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
+    SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY };
+    EXPLICIT_ACCESS ExplicitAccess;
+    static const CHAR szEveryone[] = {'E','v','e','r','y','o','n','e',0};
+    static const CHAR szCurrentUser[] = { 'C','U','R','R','E','N','T','_','U','S','E','R','\0'};
+
+    if (!pSetEntriesInAclA)
+    {
+        win_skip("SetEntriesInAclA is not available\n");
+        return;
+    }
+
+    NewAcl = (PACL)0xdeadbeef;
+    res = pSetEntriesInAclA(0, NULL, NULL, &NewAcl);
+    if(res == ERROR_CALL_NOT_IMPLEMENTED)
+    {
+        win_skip("SetEntriesInAclA is not implemented\n");
+        return;
+    }
+    ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res);
+    ok(NewAcl == NULL ||
+        broken(NewAcl != NULL), /* NT4 */
+        "NewAcl=%p, expected NULL\n", NewAcl);
+    LocalFree(NewAcl);
+
+    OldAcl = HeapAlloc(GetProcessHeap(), 0, 256);
+    res = InitializeAcl(OldAcl, 256, ACL_REVISION);
+    if(!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+    {
+        win_skip("ACLs not implemented - skipping tests\n");
+        HeapFree(GetProcessHeap(), 0, OldAcl);
+        return;
+    }
+    ok(res, "InitializeAcl failed with error %d\n", GetLastError());
+
+    res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid);
+    ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError());
+
+    res = AllocateAndInitializeSid( &SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
+        DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &UsersSid);
+    ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError());
+
+    res = AddAccessAllowedAce(OldAcl, ACL_REVISION, KEY_READ, UsersSid);
+    ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError());
+
+    ExplicitAccess.grfAccessPermissions = KEY_WRITE;
+    ExplicitAccess.grfAccessMode = GRANT_ACCESS;
+    ExplicitAccess.grfInheritance = NO_INHERITANCE;
+    ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
+    ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
+    ExplicitAccess.Trustee.ptstrName = EveryoneSid;
+    ExplicitAccess.Trustee.MultipleTrusteeOperation = 0xDEADBEEF;
+    ExplicitAccess.Trustee.pMultipleTrustee = (PVOID)0xDEADBEEF;
+    res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
+    ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res);
+    ok(NewAcl != NULL, "returned acl was NULL\n");
+    LocalFree(NewAcl);
+
+    ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
+    ExplicitAccess.Trustee.pMultipleTrustee = NULL;
+    ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
+    res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
+    ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res);
+    ok(NewAcl != NULL, "returned acl was NULL\n");
+    LocalFree(NewAcl);
+
+    if (PRIMARYLANGID(LANGIDFROMLCID(GetThreadLocale())) != LANG_ENGLISH)
+    {
+        skip("Non-english locale (test with hardcoded 'Everyone')\n");
+    }
+    else
+    {
+        ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_USER;
+        ExplicitAccess.Trustee.ptstrName = (LPSTR)szEveryone;
+        res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
+        ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res);
+        ok(NewAcl != NULL, "returned acl was NULL\n");
+        LocalFree(NewAcl);
+
+        ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_BAD_FORM;
+        res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
+        ok(res == ERROR_INVALID_PARAMETER ||
+            broken(res == ERROR_NOT_SUPPORTED), /* NT4 */
+            "SetEntriesInAclA failed: %u\n", res);
+        ok(NewAcl == NULL ||
+            broken(NewAcl != NULL), /* NT4 */
+            "returned acl wasn't NULL: %p\n", NewAcl);
+
+        ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_USER;
+        ExplicitAccess.Trustee.MultipleTrusteeOperation = TRUSTEE_IS_IMPERSONATE;
+        res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
+        ok(res == ERROR_INVALID_PARAMETER ||
+            broken(res == ERROR_NOT_SUPPORTED), /* NT4 */
+            "SetEntriesInAclA failed: %u\n", res);
+        ok(NewAcl == NULL ||
+            broken(NewAcl != NULL), /* NT4 */
+            "returned acl wasn't NULL: %p\n", NewAcl);
+
+        ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
+        ExplicitAccess.grfAccessMode = SET_ACCESS;
+        res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
+        ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res);
+        ok(NewAcl != NULL, "returned acl was NULL\n");
+        LocalFree(NewAcl);
+    }
+
+    ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_USER;
+    ExplicitAccess.Trustee.ptstrName = (LPSTR)szCurrentUser;
+    res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
+    ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res);
+    ok(NewAcl != NULL, "returned acl was NULL\n");
+    LocalFree(NewAcl);
+
+    ExplicitAccess.grfAccessMode = REVOKE_ACCESS;
+    ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
+    ExplicitAccess.Trustee.ptstrName = UsersSid;
+    res = pSetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
+    ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %u\n", res);
+    ok(NewAcl != NULL, "returned acl was NULL\n");
+    LocalFree(NewAcl);
+
+    FreeSid(UsersSid);
+    FreeSid(EveryoneSid);
+    HeapFree(GetProcessHeap(), 0, OldAcl);
+}
+
 static void test_GetNamedSecurityInfoA(void)
 {
     PSECURITY_DESCRIPTOR pSecDesc;
@@ -3388,7 +3521,8 @@ START_TEST(security)
     test_security_descriptor();
     test_process_security();
     test_impersonation_level();
-    test_SetEntriesInAcl();
+    test_SetEntriesInAclW();
+    test_SetEntriesInAclA();
     test_GetNamedSecurityInfoA();
     test_ConvertStringSecurityDescriptor();
     test_ConvertSecurityDescriptorToString();
-- 
1.6.4.2




More information about the wine-patches mailing list