Mark some functions as implemented in the spec files.
[wine/wine-gecko.git] / dlls / advapi32 / tests / security.c
blobe908ea35889df7077d0a6723dd6618c704738068
1 /*
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
21 #include <stdio.h>
23 #include "wine/test.h"
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "aclapi.h"
28 #include "winnt.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);
38 static HMODULE hmod;
40 fnBuildTrusteeWithSidA pBuildTrusteeWithSidA;
41 fnBuildTrusteeWithNameA pBuildTrusteeWithNameA;
42 fnConvertSidToStringSidA pConvertSidToStringSidA;
43 fnConvertStringSidToSidA pConvertStringSidToSidA;
44 fnGetFileSecurityA pGetFileSecurityA;
45 fnRtlAdjustPrivilege pRtlAdjustPrivilege;
47 struct sidRef
49 SID_IDENTIFIER_AUTHORITY auth;
50 const char *refStr;
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";
69 unsigned int i;
70 PSID psid = NULL;
71 BOOL r;
72 LPSTR str = NULL;
74 pConvertSidToStringSidA = (fnConvertSidToStringSidA)
75 GetProcAddress( hmod, "ConvertSidToStringSidA" );
76 if( !pConvertSidToStringSidA )
77 return;
78 pConvertStringSidToSidA = (fnConvertStringSidToSidA)
79 GetProcAddress( hmod, "ConvertStringSidToSidA" );
80 if( !pConvertStringSidToSidA )
81 return;
83 r = pConvertStringSidToSidA( NULL, NULL );
84 ok( !r, "expected failure with NULL parameters\n" );
85 if( GetLastError() == ERROR_CALL_NOT_IMPLEMENTED )
86 return;
87 ok( GetLastError() == ERROR_INVALID_PARAMETER,
88 "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",
89 GetLastError() );
91 r = pConvertStringSidToSidA( refs[0].refStr, NULL );
92 ok( !r && GetLastError() == ERROR_INVALID_PARAMETER,
93 "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",
94 GetLastError() );
96 r = pConvertStringSidToSidA( NULL, &str );
97 ok( !r && GetLastError() == ERROR_INVALID_PARAMETER,
98 "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",
99 GetLastError() );
101 r = pConvertStringSidToSidA( noSubAuthStr, &psid );
102 ok( !r,
103 "expected failure with no sub authorities\n" );
104 ok( GetLastError() == ERROR_INVALID_SID,
105 "expected GetLastError() is ERROR_INVALID_SID, got %ld\n",
106 GetLastError() );
108 for( i = 0; i < sizeof(refs) / sizeof(refs[0]); i++ )
110 PISID pisid;
112 r = AllocateAndInitializeSid( &refs[i].auth, 1,1,0,0,0,0,0,0,0,
113 &psid );
114 ok( r, "failed to allocate sid\n" );
115 r = pConvertSidToStringSidA( psid, &str );
116 ok( r, "failed to convert sid\n" );
117 if (r)
119 ok( !strcmp( str, refs[i].refStr ),
120 "incorrect sid, expected %s, got %s\n", refs[i].refStr, str );
121 LocalFree( str );
123 if( psid )
124 FreeSid( psid );
126 r = pConvertStringSidToSidA( refs[i].refStr, &psid );
127 ok( r, "failed to parse sid string\n" );
128 pisid = (PISID)psid;
129 ok( pisid &&
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",
134 refs[i].refStr,
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] ) ) );
144 if( psid )
145 LocalFree( psid );
149 static void test_trustee(void)
151 TRUSTEE trustee;
152 PSID psid;
153 char str[] = "2jjj";
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)
162 return;
164 if ( ! AllocateAndInitializeSid( &auth, 1, 42, 0,0,0,0,0,0,0,&psid ) )
166 trace( "failed to init SID\n" );
167 return;
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" );
179 FreeSid( psid );
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);
231 LUID luid1, luid2;
232 BOOL ret;
234 pAllocateLocallyUniqueId = (void*)GetProcAddress(hmod, "AllocateLocallyUniqueId");
235 if (!pAllocateLocallyUniqueId) return;
237 ret = pAllocateLocallyUniqueId(&luid1);
238 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
239 return;
241 ok(ret,
242 "AllocateLocallyUniqueId failed: %ld\n", GetLastError());
243 ret = pAllocateLocallyUniqueId(&luid2);
244 ok( ret,
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",
253 GetLastError());
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 };
262 LONG i;
263 BOOL ret;
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)
271 return;
273 /* check with a short buffer */
274 cchName = 0;
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",
279 GetLastError());
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++)
294 luid.LowPart = 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",
306 GetLastError());
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",
313 GetLastError());
316 struct NameToLUID
318 const char *name;
319 DWORD lowPart;
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);
356 int i;
357 LUID luid;
358 BOOL ret;
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)
365 return;
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",
371 GetLastError());
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",
376 GetLastError());
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",
381 GetLastError());
382 /* check case insensitive */
383 ret = pLookupPrivilegeValueA(NULL, "sEcREATEtOKENpRIVILEGE", &luid);
384 ok( ret,
385 "LookupPrivilegeValueA(NULL, sEcREATEtOKENpRIVILEGE, &luid) failed: %ld\n",
386 GetLastError());
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",
396 privs[i].name);
401 static void test_luid(void)
403 test_allocateLuid();
404 test_lookupPrivilegeName();
405 test_lookupPrivilegeValue();
408 static void test_FileSecurity(void)
410 char directory[MAX_PATH];
411 DWORD retval, outSize;
412 BOOL result;
413 BYTE buffer[0x40];
415 pGetFileSecurityA = (fnGetFileSecurityA)
416 GetProcAddress( hmod, "GetFileSecurityA" );
417 if( !pGetFileSecurityA )
418 return;
420 retval = GetTempPathA(sizeof(directory), directory);
421 if (!retval) {
422 trace("GetTempPathA failed\n");
423 return;
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;
440 PACL Acl = 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 };
445 ACCESS_MASK Access;
446 BOOL AccessStatus;
447 HANDLE Token;
448 BOOL ret;
449 DWORD PrivSetLen;
450 PRIVILEGE_SET *PrivSet;
451 BOOL res;
452 HMODULE NtDllModule;
453 BOOLEAN Enabled;
455 NtDllModule = GetModuleHandle("ntdll.dll");
457 if (!NtDllModule)
459 trace("not running on NT, skipping test\n");
460 return;
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");
471 return;
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",
523 GetLastError());
525 ret = AccessCheck(SecurityDescriptor, Token, MAXIMUM_ALLOWED, &Mapping,
526 PrivSet, &PrivSetLen, &Access, &AccessStatus);
527 ok(ret, "AccessCheck failed with error %ld\n", GetLastError());
528 ok(AccessStatus,
529 "AccessCheck failed to grant any access with error %ld\n",
530 GetLastError());
531 trace("AccessCheck with MAXIMUM_ALLOWED got Access 0x%08lx\n", Access);
533 SetLastError(0);
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",
539 GetLastError());
541 ret = pRtlAdjustPrivilege(SE_SECURITY_PRIVILEGE, TRUE, TRUE, &Enabled);
542 if (!ret)
544 SetLastError(0);
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",
550 GetLastError());
551 ok(Access == ACCESS_SYSTEM_SECURITY,
552 "Access should be equal to ACCESS_SYSTEM_SECURITY instead of 0x%08lx\n",
553 Access);
555 else
556 trace("Couldn't get SE_SECURITY_PRIVILEGE (0x%08x), skipping ACCESS_SYSTEM_SECURITY test\n",
557 ret);
559 RevertToSelf();
561 if (EveryoneSid)
562 FreeSid(EveryoneSid);
563 if (AdminSid)
564 FreeSid(AdminSid);
565 if (UsersSid)
566 FreeSid(UsersSid);
567 HeapFree(GetProcessHeap(), 0, Acl);
568 HeapFree(GetProcessHeap(), 0, SecurityDescriptor);
569 HeapFree(GetProcessHeap(), 0, PrivSet);
572 START_TEST(security)
574 init();
575 if (!hmod) return;
576 test_sid();
577 test_trustee();
578 test_luid();
579 test_FileSecurity();
580 test_AccessCheck();