From a9bbd7dc86aff14308e0a5491e0f660fe3c49a2e Mon Sep 17 00:00:00 2001 From: Damian Dixon Date: Sat, 1 Jan 2011 20:19:55 +0000 Subject: [PATCH] advapi32: Implement SetEntriesInAclA by calling SetEntriesInAclW. --- dlls/advapi32/security.c | 57 +++++++++++++- dlls/advapi32/tests/security.c | 138 ++++++++++++++++++++++++++++++++- 2 files changed, 189 insertions(+), 6 deletions(-) diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c index e24d90fd2f0..629a264e38c 100644 --- a/dlls/advapi32/security.c +++ b/dlls/advapi32/security.c @@ -3521,10 +3521,58 @@ 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) + { + 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; + 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; + } + + err = SetEntriesInAclW( count, pEntriesW, OldAcl, NewAcl ); + + 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 +3589,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 58107528054..5db4354cea4 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();