2 * Unit tests for security functions
4 * Copyright (c) 2004 Mike McCormack
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "wine/test.h"
30 typedef BOOL (WINAPI
*fnBuildTrusteeWithSidA
)( TRUSTEE
*trustee
, PSID psid
);
31 typedef BOOL (WINAPI
*fnBuildTrusteeWithNameA
)( TRUSTEE
*trustee
, LPSTR str
);
32 typedef BOOL (WINAPI
*fnConvertSidToStringSidA
)( PSID pSid
, LPSTR
*str
);
33 typedef BOOL (WINAPI
*fnConvertStringSidToSidA
)( LPCSTR str
, PSID pSid
);
34 typedef BOOL (WINAPI
*fnGetFileSecurityA
)(LPCSTR
, SECURITY_INFORMATION
,
35 PSECURITY_DESCRIPTOR
, DWORD
, LPDWORD
);
36 typedef DWORD (WINAPI
*fnRtlAdjustPrivilege
)(ULONG
,BOOLEAN
,BOOLEAN
,PBOOLEAN
);
40 fnBuildTrusteeWithSidA pBuildTrusteeWithSidA
;
41 fnBuildTrusteeWithNameA pBuildTrusteeWithNameA
;
42 fnConvertSidToStringSidA pConvertSidToStringSidA
;
43 fnConvertStringSidToSidA pConvertStringSidToSidA
;
44 fnGetFileSecurityA pGetFileSecurityA
;
45 fnRtlAdjustPrivilege pRtlAdjustPrivilege
;
49 SID_IDENTIFIER_AUTHORITY auth
;
53 static void init(void)
55 hmod
= GetModuleHandle("advapi32.dll");
58 static void test_sid(void)
60 struct sidRef refs
[] = {
61 { { {0x00,0x00,0x33,0x44,0x55,0x66} }, "S-1-860116326-1" },
62 { { {0x00,0x00,0x01,0x02,0x03,0x04} }, "S-1-16909060-1" },
63 { { {0x00,0x00,0x00,0x01,0x02,0x03} }, "S-1-66051-1" },
64 { { {0x00,0x00,0x00,0x00,0x01,0x02} }, "S-1-258-1" },
65 { { {0x00,0x00,0x00,0x00,0x00,0x02} }, "S-1-2-1" },
66 { { {0x00,0x00,0x00,0x00,0x00,0x0c} }, "S-1-12-1" },
68 const char noSubAuthStr
[] = "S-1-5";
74 pConvertSidToStringSidA
= (fnConvertSidToStringSidA
)
75 GetProcAddress( hmod
, "ConvertSidToStringSidA" );
76 if( !pConvertSidToStringSidA
)
78 pConvertStringSidToSidA
= (fnConvertStringSidToSidA
)
79 GetProcAddress( hmod
, "ConvertStringSidToSidA" );
80 if( !pConvertStringSidToSidA
)
83 r
= pConvertStringSidToSidA( NULL
, NULL
);
84 ok( !r
, "expected failure with NULL parameters\n" );
85 if( GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
87 ok( GetLastError() == ERROR_INVALID_PARAMETER
,
88 "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",
91 r
= pConvertStringSidToSidA( refs
[0].refStr
, NULL
);
92 ok( !r
&& GetLastError() == ERROR_INVALID_PARAMETER
,
93 "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",
96 r
= pConvertStringSidToSidA( NULL
, &str
);
97 ok( !r
&& GetLastError() == ERROR_INVALID_PARAMETER
,
98 "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",
101 r
= pConvertStringSidToSidA( noSubAuthStr
, &psid
);
103 "expected failure with no sub authorities\n" );
104 ok( GetLastError() == ERROR_INVALID_SID
,
105 "expected GetLastError() is ERROR_INVALID_SID, got %ld\n",
108 for( i
= 0; i
< sizeof(refs
) / sizeof(refs
[0]); i
++ )
112 r
= AllocateAndInitializeSid( &refs
[i
].auth
, 1,1,0,0,0,0,0,0,0,
114 ok( r
, "failed to allocate sid\n" );
115 r
= pConvertSidToStringSidA( psid
, &str
);
116 ok( r
, "failed to convert sid\n" );
119 ok( !strcmp( str
, refs
[i
].refStr
),
120 "incorrect sid, expected %s, got %s\n", refs
[i
].refStr
, str
);
126 r
= pConvertStringSidToSidA( refs
[i
].refStr
, &psid
);
127 ok( r
, "failed to parse sid string\n" );
130 !memcmp( pisid
->IdentifierAuthority
.Value
, refs
[i
].auth
.Value
,
131 sizeof(refs
[i
].auth
) ),
132 "string sid %s didn't parse to expected value\n"
133 "(got 0x%04x%08lx, expected 0x%04x%08lx)\n",
135 MAKEWORD( pisid
->IdentifierAuthority
.Value
[1],
136 pisid
->IdentifierAuthority
.Value
[0] ),
137 MAKELONG( MAKEWORD( pisid
->IdentifierAuthority
.Value
[5],
138 pisid
->IdentifierAuthority
.Value
[4] ),
139 MAKEWORD( pisid
->IdentifierAuthority
.Value
[3],
140 pisid
->IdentifierAuthority
.Value
[2] ) ),
141 MAKEWORD( refs
[i
].auth
.Value
[1], refs
[i
].auth
.Value
[0] ),
142 MAKELONG( MAKEWORD( refs
[i
].auth
.Value
[5], refs
[i
].auth
.Value
[4] ),
143 MAKEWORD( refs
[i
].auth
.Value
[3], refs
[i
].auth
.Value
[2] ) ) );
149 static void test_trustee(void)
155 SID_IDENTIFIER_AUTHORITY auth
= { {0x11,0x22,0,0,0, 0} };
157 pBuildTrusteeWithSidA
= (fnBuildTrusteeWithSidA
)
158 GetProcAddress( hmod
, "BuildTrusteeWithSidA" );
159 pBuildTrusteeWithNameA
= (fnBuildTrusteeWithNameA
)
160 GetProcAddress( hmod
, "BuildTrusteeWithNameA" );
161 if( !pBuildTrusteeWithSidA
|| !pBuildTrusteeWithNameA
)
164 if ( ! AllocateAndInitializeSid( &auth
, 1, 42, 0,0,0,0,0,0,0,&psid
) )
166 trace( "failed to init SID\n" );
170 memset( &trustee
, 0xff, sizeof trustee
);
171 pBuildTrusteeWithSidA( &trustee
, psid
);
173 ok( trustee
.pMultipleTrustee
== NULL
, "pMultipleTrustee wrong\n");
174 ok( trustee
.MultipleTrusteeOperation
== NO_MULTIPLE_TRUSTEE
,
175 "MultipleTrusteeOperation wrong\n");
176 ok( trustee
.TrusteeForm
== TRUSTEE_IS_SID
, "TrusteeForm wrong\n");
177 ok( trustee
.TrusteeType
== TRUSTEE_IS_UNKNOWN
, "TrusteeType wrong\n");
178 ok( trustee
.ptstrName
== (LPSTR
) psid
, "ptstrName wrong\n" );
181 /* test BuildTrusteeWithNameA */
182 memset( &trustee
, 0xff, sizeof trustee
);
183 pBuildTrusteeWithNameA( &trustee
, str
);
185 ok( trustee
.pMultipleTrustee
== NULL
, "pMultipleTrustee wrong\n");
186 ok( trustee
.MultipleTrusteeOperation
== NO_MULTIPLE_TRUSTEE
,
187 "MultipleTrusteeOperation wrong\n");
188 ok( trustee
.TrusteeForm
== TRUSTEE_IS_NAME
, "TrusteeForm wrong\n");
189 ok( trustee
.TrusteeType
== TRUSTEE_IS_UNKNOWN
, "TrusteeType wrong\n");
190 ok( trustee
.ptstrName
== str
, "ptstrName wrong\n" );
193 /* If the first isn't defined, assume none is */
194 #ifndef SE_MIN_WELL_KNOWN_PRIVILEGE
195 #define SE_MIN_WELL_KNOWN_PRIVILEGE 2L
196 #define SE_CREATE_TOKEN_PRIVILEGE 2L
197 #define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE 3L
198 #define SE_LOCK_MEMORY_PRIVILEGE 4L
199 #define SE_INCREASE_QUOTA_PRIVILEGE 5L
200 #define SE_MACHINE_ACCOUNT_PRIVILEGE 6L
201 #define SE_TCB_PRIVILEGE 7L
202 #define SE_SECURITY_PRIVILEGE 8L
203 #define SE_TAKE_OWNERSHIP_PRIVILEGE 9L
204 #define SE_LOAD_DRIVER_PRIVILEGE 10L
205 #define SE_SYSTEM_PROFILE_PRIVILEGE 11L
206 #define SE_SYSTEMTIME_PRIVILEGE 12L
207 #define SE_PROF_SINGLE_PROCESS_PRIVILEGE 13L
208 #define SE_INC_BASE_PRIORITY_PRIVILEGE 14L
209 #define SE_CREATE_PAGEFILE_PRIVILEGE 15L
210 #define SE_CREATE_PERMANENT_PRIVILEGE 16L
211 #define SE_BACKUP_PRIVILEGE 17L
212 #define SE_RESTORE_PRIVILEGE 18L
213 #define SE_SHUTDOWN_PRIVILEGE 19L
214 #define SE_DEBUG_PRIVILEGE 20L
215 #define SE_AUDIT_PRIVILEGE 21L
216 #define SE_SYSTEM_ENVIRONMENT_PRIVILEGE 22L
217 #define SE_CHANGE_NOTIFY_PRIVILLEGE 23L
218 #define SE_REMOTE_SHUTDOWN_PRIVILEGE 24L
219 #define SE_UNDOCK_PRIVILEGE 25L
220 #define SE_SYNC_AGENT_PRIVILEGE 26L
221 #define SE_ENABLE_DELEGATION_PRIVILEGE 27L
222 #define SE_MANAGE_VOLUME_PRIVILEGE 28L
223 #define SE_IMPERSONATE_PRIVILEGE 29L
224 #define SE_CREATE_GLOBAL_PRIVILEGE 30L
225 #define SE_MAX_WELL_KNOWN_PRIVILEGE SE_CREATE_GLOBAL_PRIVILEGE
226 #endif /* ndef SE_MIN_WELL_KNOWN_PRIVILEGE */
228 static void test_allocateLuid(void)
230 BOOL (WINAPI
*pAllocateLocallyUniqueId
)(PLUID
);
234 pAllocateLocallyUniqueId
= (void*)GetProcAddress(hmod
, "AllocateLocallyUniqueId");
235 if (!pAllocateLocallyUniqueId
) return;
237 ret
= pAllocateLocallyUniqueId(&luid1
);
238 if (!ret
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
242 "AllocateLocallyUniqueId failed: %ld\n", GetLastError());
243 ret
= pAllocateLocallyUniqueId(&luid2
);
245 "AllocateLocallyUniqueId failed: %ld\n", GetLastError());
246 ok(luid1
.LowPart
> SE_MAX_WELL_KNOWN_PRIVILEGE
|| luid1
.HighPart
!= 0,
247 "AllocateLocallyUniqueId returned a well-known LUID\n");
248 ok(luid1
.LowPart
!= luid2
.LowPart
|| luid1
.HighPart
!= luid2
.HighPart
,
249 "AllocateLocallyUniqueId returned non-unique LUIDs\n");
250 ret
= pAllocateLocallyUniqueId(NULL
);
251 ok( !ret
&& GetLastError() == ERROR_NOACCESS
,
252 "AllocateLocallyUniqueId(NULL) didn't return ERROR_NOACCESS: %ld\n",
256 static void test_lookupPrivilegeName(void)
258 BOOL (WINAPI
*pLookupPrivilegeNameA
)(LPCSTR
, PLUID
, LPSTR
, LPDWORD
);
259 char buf
[MAX_PATH
]; /* arbitrary, seems long enough */
260 DWORD cchName
= sizeof(buf
);
261 LUID luid
= { 0, 0 };
265 /* check whether it's available first */
266 pLookupPrivilegeNameA
= (void*)GetProcAddress(hmod
, "LookupPrivilegeNameA");
267 if (!pLookupPrivilegeNameA
) return;
268 luid
.LowPart
= SE_CREATE_TOKEN_PRIVILEGE
;
269 ret
= pLookupPrivilegeNameA(NULL
, &luid
, buf
, &cchName
);
270 if (!ret
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
273 /* check with a short buffer */
275 luid
.LowPart
= SE_CREATE_TOKEN_PRIVILEGE
;
276 ret
= pLookupPrivilegeNameA(NULL
, &luid
, NULL
, &cchName
);
277 ok( !ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
278 "LookupPrivilegeNameA didn't fail with ERROR_INSUFFICIENT_BUFFER: %ld\n",
280 ok(cchName
== strlen("SeCreateTokenPrivilege") + 1,
281 "LookupPrivilegeNameA returned an incorrect required length for\n"
282 "SeCreateTokenPrivilege (got %ld, expected %d)\n", cchName
,
283 strlen("SeCreateTokenPrivilege") + 1);
284 /* check a known value and its returned length on success */
285 cchName
= sizeof(buf
);
286 ok(pLookupPrivilegeNameA(NULL
, &luid
, buf
, &cchName
) &&
287 cchName
== strlen("SeCreateTokenPrivilege"),
288 "LookupPrivilegeNameA returned an incorrect output length for\n"
289 "SeCreateTokenPrivilege (got %ld, expected %d)\n", cchName
,
290 (int)strlen("SeCreateTokenPrivilege"));
291 /* check known values */
292 for (i
= SE_MIN_WELL_KNOWN_PRIVILEGE
; i
< SE_MAX_WELL_KNOWN_PRIVILEGE
; i
++)
295 cchName
= sizeof(buf
);
296 ret
= pLookupPrivilegeNameA(NULL
, &luid
, buf
, &cchName
);
297 ok( ret
|| GetLastError() == ERROR_NO_SUCH_PRIVILEGE
,
298 "LookupPrivilegeNameA(0.%ld) failed: %ld\n", i
, GetLastError());
300 /* check a bogus LUID */
301 luid
.LowPart
= 0xdeadbeef;
302 cchName
= sizeof(buf
);
303 ret
= pLookupPrivilegeNameA(NULL
, &luid
, buf
, &cchName
);
304 ok( !ret
&& GetLastError() == ERROR_NO_SUCH_PRIVILEGE
,
305 "LookupPrivilegeNameA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",
307 /* check on a bogus system */
308 luid
.LowPart
= SE_CREATE_TOKEN_PRIVILEGE
;
309 cchName
= sizeof(buf
);
310 ret
= pLookupPrivilegeNameA("b0gu5.Nam3", &luid
, buf
, &cchName
);
311 ok( !ret
&& GetLastError() == RPC_S_SERVER_UNAVAILABLE
,
312 "LookupPrivilegeNameA didn't fail with RPC_S_SERVER_UNAVAILABLE: %ld\n",
322 static void test_lookupPrivilegeValue(void)
324 static const struct NameToLUID privs
[] = {
325 { "SeCreateTokenPrivilege", SE_CREATE_TOKEN_PRIVILEGE
},
326 { "SeAssignPrimaryTokenPrivilege", SE_ASSIGNPRIMARYTOKEN_PRIVILEGE
},
327 { "SeLockMemoryPrivilege", SE_LOCK_MEMORY_PRIVILEGE
},
328 { "SeIncreaseQuotaPrivilege", SE_INCREASE_QUOTA_PRIVILEGE
},
329 { "SeMachineAccountPrivilege", SE_MACHINE_ACCOUNT_PRIVILEGE
},
330 { "SeTcbPrivilege", SE_TCB_PRIVILEGE
},
331 { "SeSecurityPrivilege", SE_SECURITY_PRIVILEGE
},
332 { "SeTakeOwnershipPrivilege", SE_TAKE_OWNERSHIP_PRIVILEGE
},
333 { "SeLoadDriverPrivilege", SE_LOAD_DRIVER_PRIVILEGE
},
334 { "SeSystemProfilePrivilege", SE_SYSTEM_PROFILE_PRIVILEGE
},
335 { "SeSystemtimePrivilege", SE_SYSTEMTIME_PRIVILEGE
},
336 { "SeProfileSingleProcessPrivilege", SE_PROF_SINGLE_PROCESS_PRIVILEGE
},
337 { "SeIncreaseBasePriorityPrivilege", SE_INC_BASE_PRIORITY_PRIVILEGE
},
338 { "SeCreatePagefilePrivilege", SE_CREATE_PAGEFILE_PRIVILEGE
},
339 { "SeCreatePermanentPrivilege", SE_CREATE_PERMANENT_PRIVILEGE
},
340 { "SeBackupPrivilege", SE_BACKUP_PRIVILEGE
},
341 { "SeRestorePrivilege", SE_RESTORE_PRIVILEGE
},
342 { "SeShutdownPrivilege", SE_SHUTDOWN_PRIVILEGE
},
343 { "SeDebugPrivilege", SE_DEBUG_PRIVILEGE
},
344 { "SeAuditPrivilege", SE_AUDIT_PRIVILEGE
},
345 { "SeSystemEnvironmentPrivilege", SE_SYSTEM_ENVIRONMENT_PRIVILEGE
},
346 { "SeChangeNotifyPrivilege", SE_CHANGE_NOTIFY_PRIVILLEGE
},
347 { "SeRemoteShutdownPrivilege", SE_REMOTE_SHUTDOWN_PRIVILEGE
},
348 { "SeUndockPrivilege", SE_UNDOCK_PRIVILEGE
},
349 { "SeSyncAgentPrivilege", SE_SYNC_AGENT_PRIVILEGE
},
350 { "SeEnableDelegationPrivilege", SE_ENABLE_DELEGATION_PRIVILEGE
},
351 { "SeManageVolumePrivilege", SE_MANAGE_VOLUME_PRIVILEGE
},
352 { "SeImpersonatePrivilege", SE_IMPERSONATE_PRIVILEGE
},
353 { "SeCreateGlobalPrivilege", SE_CREATE_GLOBAL_PRIVILEGE
},
355 BOOL (WINAPI
*pLookupPrivilegeValueA
)(LPCSTR
, LPCSTR
, PLUID
);
360 /* check whether it's available first */
361 pLookupPrivilegeValueA
= (void*)GetProcAddress(hmod
, "LookupPrivilegeValueA");
362 if (!pLookupPrivilegeValueA
) return;
363 ret
= pLookupPrivilegeValueA(NULL
, "SeCreateTokenPrivilege", &luid
);
364 if (!ret
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
367 /* check a bogus system name */
368 ret
= pLookupPrivilegeValueA("b0gu5.Nam3", "SeCreateTokenPrivilege", &luid
);
369 ok( !ret
&& GetLastError() == RPC_S_SERVER_UNAVAILABLE
,
370 "LookupPrivilegeValueA didn't fail with RPC_S_SERVER_UNAVAILABLE: %ld\n",
372 /* check a NULL string */
373 ret
= pLookupPrivilegeValueA(NULL
, 0, &luid
);
374 ok( !ret
&& GetLastError() == ERROR_NO_SUCH_PRIVILEGE
,
375 "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",
377 /* check a bogus privilege name */
378 ret
= pLookupPrivilegeValueA(NULL
, "SeBogusPrivilege", &luid
);
379 ok( !ret
&& GetLastError() == ERROR_NO_SUCH_PRIVILEGE
,
380 "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",
382 /* check case insensitive */
383 ret
= pLookupPrivilegeValueA(NULL
, "sEcREATEtOKENpRIVILEGE", &luid
);
385 "LookupPrivilegeValueA(NULL, sEcREATEtOKENpRIVILEGE, &luid) failed: %ld\n",
387 for (i
= 0; i
< sizeof(privs
) / sizeof(privs
[0]); i
++)
389 /* Not all privileges are implemented on all Windows versions, so
390 * don't worry if the call fails
392 if (pLookupPrivilegeValueA(NULL
, privs
[i
].name
, &luid
))
394 ok(luid
.LowPart
== privs
[i
].lowPart
,
395 "LookupPrivilegeValueA returned an invalid LUID for %s\n",
401 static void test_luid(void)
404 test_lookupPrivilegeName();
405 test_lookupPrivilegeValue();
408 static void test_FileSecurity(void)
410 char directory
[MAX_PATH
];
411 DWORD retval
, outSize
;
415 pGetFileSecurityA
= (fnGetFileSecurityA
)
416 GetProcAddress( hmod
, "GetFileSecurityA" );
417 if( !pGetFileSecurityA
)
420 retval
= GetTempPathA(sizeof(directory
), directory
);
422 trace("GetTempPathA failed\n");
426 strcpy(directory
, "\\Should not exist");
428 SetLastError(NO_ERROR
);
429 result
= pGetFileSecurityA( directory
,OWNER_SECURITY_INFORMATION
,buffer
,0x40,&outSize
);
430 ok(!result
, "GetFileSecurityA should fail for not existing directories/files\n");
431 ok( (GetLastError() == ERROR_FILE_NOT_FOUND
) ||
432 (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
) ,
433 "last error ERROR_FILE_NOT_FOUND / ERROR_CALL_NOT_IMPLEMENTED (98) "
434 "expected, got %ld\n", GetLastError());
437 static void test_AccessCheck(void)
439 PSID EveryoneSid
= NULL
, AdminSid
= NULL
, UsersSid
= NULL
;
441 SECURITY_DESCRIPTOR
*SecurityDescriptor
= NULL
;
442 SID_IDENTIFIER_AUTHORITY SIDAuthWorld
= { SECURITY_WORLD_SID_AUTHORITY
};
443 SID_IDENTIFIER_AUTHORITY SIDAuthNT
= { SECURITY_NT_AUTHORITY
};
444 GENERIC_MAPPING Mapping
= { KEY_READ
, KEY_WRITE
, KEY_EXECUTE
, KEY_ALL_ACCESS
};
450 PRIVILEGE_SET
*PrivSet
;
455 NtDllModule
= GetModuleHandle("ntdll.dll");
459 trace("not running on NT, skipping test\n");
462 pRtlAdjustPrivilege
= (fnRtlAdjustPrivilege
)
463 GetProcAddress(NtDllModule
, "RtlAdjustPrivilege");
464 if (!pRtlAdjustPrivilege
) return;
466 Acl
= HeapAlloc(GetProcessHeap(), 0, 256);
467 res
= InitializeAcl(Acl
, 256, ACL_REVISION
);
468 if(!res
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
470 trace("ACLs not implemented - skipping tests\n");
473 ok(res
, "InitializeAcl failed with error %ld\n", GetLastError());
475 res
= AllocateAndInitializeSid( &SIDAuthWorld
, 1, SECURITY_WORLD_RID
, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid
);
476 ok(res
, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
478 res
= AllocateAndInitializeSid( &SIDAuthNT
, 2, SECURITY_BUILTIN_DOMAIN_RID
,
479 DOMAIN_ALIAS_RID_ADMINS
, 0, 0, 0, 0, 0, 0, &AdminSid
);
480 ok(res
, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
482 res
= AllocateAndInitializeSid( &SIDAuthNT
, 2, SECURITY_BUILTIN_DOMAIN_RID
,
483 DOMAIN_ALIAS_RID_USERS
, 0, 0, 0, 0, 0, 0, &UsersSid
);
484 ok(res
, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
486 res
= AddAccessAllowedAce(Acl
, ACL_REVISION
, KEY_READ
, EveryoneSid
);
487 ok(res
, "AddAccessAllowedAceEx failed with error %ld\n", GetLastError());
489 res
= AddAccessAllowedAce(Acl
, ACL_REVISION
, KEY_ALL_ACCESS
, AdminSid
);
490 ok(res
, "AddAccessAllowedAceEx failed with error %ld\n", GetLastError());
492 SecurityDescriptor
= HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH
);
494 res
= InitializeSecurityDescriptor(SecurityDescriptor
, SECURITY_DESCRIPTOR_REVISION
);
495 ok(res
, "InitializeSecurityDescriptor failed with error %ld\n", GetLastError());
497 res
= SetSecurityDescriptorDacl(SecurityDescriptor
, TRUE
, Acl
, FALSE
);
498 ok(res
, "SetSecurityDescriptorDacl failed with error %ld\n", GetLastError());
500 res
= SetSecurityDescriptorOwner(SecurityDescriptor
, AdminSid
, FALSE
);
501 ok(res
, "SetSecurityDescriptorOwner failed with error %ld\n", GetLastError());
503 res
= SetSecurityDescriptorGroup(SecurityDescriptor
, UsersSid
, TRUE
);
504 ok(res
, "SetSecurityDescriptorGroup failed with error %ld\n", GetLastError());
506 PrivSetLen
= FIELD_OFFSET(PRIVILEGE_SET
, Privilege
[16]);
507 PrivSet
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, PrivSetLen
);
508 PrivSet
->PrivilegeCount
= 16;
510 ImpersonateSelf(SecurityImpersonation
);
512 pRtlAdjustPrivilege(SE_SECURITY_PRIVILEGE
, FALSE
, TRUE
, &Enabled
);
514 ret
= OpenThreadToken(GetCurrentThread(),
515 TOKEN_QUERY
, TRUE
, &Token
);
516 ok(ret
, "OpenThreadToken failed with error %ld\n", GetLastError());
518 ret
= AccessCheck(SecurityDescriptor
, Token
, KEY_READ
, &Mapping
,
519 PrivSet
, &PrivSetLen
, &Access
, &AccessStatus
);
520 ok(ret
, "AccessCheck failed with error %ld\n", GetLastError());
521 ok(AccessStatus
&& (Access
== KEY_READ
),
522 "AccessCheck failed to grant access with error %ld\n",
525 ret
= AccessCheck(SecurityDescriptor
, Token
, MAXIMUM_ALLOWED
, &Mapping
,
526 PrivSet
, &PrivSetLen
, &Access
, &AccessStatus
);
527 ok(ret
, "AccessCheck failed with error %ld\n", GetLastError());
529 "AccessCheck failed to grant any access with error %ld\n",
531 trace("AccessCheck with MAXIMUM_ALLOWED got Access 0x%08lx\n", Access
);
534 PrivSet
->PrivilegeCount
= 16;
535 ret
= AccessCheck(SecurityDescriptor
, Token
, ACCESS_SYSTEM_SECURITY
, &Mapping
,
536 PrivSet
, &PrivSetLen
, &Access
, &AccessStatus
);
537 ok(ret
&& !AccessStatus
&& GetLastError() == ERROR_PRIVILEGE_NOT_HELD
,
538 "AccessCheck should have failed with ERROR_PRIVILEGE_NOT_HELD, instead of %ld\n",
541 ret
= pRtlAdjustPrivilege(SE_SECURITY_PRIVILEGE
, TRUE
, TRUE
, &Enabled
);
545 PrivSet
->PrivilegeCount
= 16;
546 ret
= AccessCheck(SecurityDescriptor
, Token
, ACCESS_SYSTEM_SECURITY
, &Mapping
,
547 PrivSet
, &PrivSetLen
, &Access
, &AccessStatus
);
548 ok(ret
&& AccessStatus
&& GetLastError() == 0,
549 "AccessCheck should have succeeded, error %ld\n",
551 ok(Access
== ACCESS_SYSTEM_SECURITY
,
552 "Access should be equal to ACCESS_SYSTEM_SECURITY instead of 0x%08lx\n",
556 trace("Couldn't get SE_SECURITY_PRIVILEGE (0x%08x), skipping ACCESS_SYSTEM_SECURITY test\n",
562 FreeSid(EveryoneSid
);
567 HeapFree(GetProcessHeap(), 0, Acl
);
568 HeapFree(GetProcessHeap(), 0, SecurityDescriptor
);
569 HeapFree(GetProcessHeap(), 0, PrivSet
);