Implement NtAccessCheck.
[wine/gsoc-2012-control.git] / dlls / advapi32 / tests / security.c
blobcc7f5379e1546a89f2b63a2bc291891da5dfac3f
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);
37 static HMODULE hmod;
39 fnBuildTrusteeWithSidA pBuildTrusteeWithSidA;
40 fnBuildTrusteeWithNameA pBuildTrusteeWithNameA;
41 fnConvertSidToStringSidA pConvertSidToStringSidA;
42 fnConvertStringSidToSidA pConvertStringSidToSidA;
43 fnGetFileSecurityA pGetFileSecurityA;
45 struct sidRef
47 SID_IDENTIFIER_AUTHORITY auth;
48 const char *refStr;
51 static void init(void)
53 hmod = GetModuleHandle("advapi32.dll");
56 void test_sid()
58 struct sidRef refs[] = {
59 { { {0x00,0x00,0x33,0x44,0x55,0x66} }, "S-1-860116326-1" },
60 { { {0x00,0x00,0x01,0x02,0x03,0x04} }, "S-1-16909060-1" },
61 { { {0x00,0x00,0x00,0x01,0x02,0x03} }, "S-1-66051-1" },
62 { { {0x00,0x00,0x00,0x00,0x01,0x02} }, "S-1-258-1" },
63 { { {0x00,0x00,0x00,0x00,0x00,0x02} }, "S-1-2-1" },
64 { { {0x00,0x00,0x00,0x00,0x00,0x0c} }, "S-1-12-1" },
66 const char noSubAuthStr[] = "S-1-5";
67 unsigned int i;
68 PSID psid = NULL;
69 BOOL r;
70 LPSTR str = NULL;
72 pConvertSidToStringSidA = (fnConvertSidToStringSidA)
73 GetProcAddress( hmod, "ConvertSidToStringSidA" );
74 if( !pConvertSidToStringSidA )
75 return;
76 pConvertStringSidToSidA = (fnConvertStringSidToSidA)
77 GetProcAddress( hmod, "ConvertStringSidToSidA" );
78 if( !pConvertStringSidToSidA )
79 return;
81 r = pConvertStringSidToSidA( NULL, NULL );
82 ok( !r, "expected failure with NULL parameters\n" );
83 if( GetLastError() == ERROR_CALL_NOT_IMPLEMENTED )
84 return;
85 ok( GetLastError() == ERROR_INVALID_PARAMETER,
86 "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",
87 GetLastError() );
89 r = pConvertStringSidToSidA( refs[0].refStr, NULL );
90 ok( !r && GetLastError() == ERROR_INVALID_PARAMETER,
91 "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",
92 GetLastError() );
94 r = pConvertStringSidToSidA( NULL, &str );
95 ok( !r && GetLastError() == ERROR_INVALID_PARAMETER,
96 "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",
97 GetLastError() );
99 r = pConvertStringSidToSidA( noSubAuthStr, &psid );
100 ok( !r,
101 "expected failure with no sub authorities\n" );
102 ok( GetLastError() == ERROR_INVALID_SID,
103 "expected GetLastError() is ERROR_INVALID_SID, got %ld\n",
104 GetLastError() );
106 for( i = 0; i < sizeof(refs) / sizeof(refs[0]); i++ )
108 PISID pisid;
110 r = AllocateAndInitializeSid( &refs[i].auth, 1,1,0,0,0,0,0,0,0,
111 &psid );
112 ok( r, "failed to allocate sid\n" );
113 r = pConvertSidToStringSidA( psid, &str );
114 ok( r, "failed to convert sid\n" );
115 if (r)
117 ok( !strcmp( str, refs[i].refStr ),
118 "incorrect sid, expected %s, got %s\n", refs[i].refStr, str );
119 LocalFree( str );
121 if( psid )
122 FreeSid( psid );
124 r = pConvertStringSidToSidA( refs[i].refStr, &psid );
125 ok( r, "failed to parse sid string\n" );
126 pisid = (PISID)psid;
127 ok( pisid &&
128 !memcmp( pisid->IdentifierAuthority.Value, refs[i].auth.Value,
129 sizeof(refs[i].auth) ),
130 "string sid %s didn't parse to expected value\n"
131 "(got 0x%04x%08lx, expected 0x%04x%08lx)\n",
132 refs[i].refStr,
133 MAKEWORD( pisid->IdentifierAuthority.Value[1],
134 pisid->IdentifierAuthority.Value[0] ),
135 MAKELONG( MAKEWORD( pisid->IdentifierAuthority.Value[5],
136 pisid->IdentifierAuthority.Value[4] ),
137 MAKEWORD( pisid->IdentifierAuthority.Value[3],
138 pisid->IdentifierAuthority.Value[2] ) ),
139 MAKEWORD( refs[i].auth.Value[1], refs[i].auth.Value[0] ),
140 MAKELONG( MAKEWORD( refs[i].auth.Value[5], refs[i].auth.Value[4] ),
141 MAKEWORD( refs[i].auth.Value[3], refs[i].auth.Value[2] ) ) );
142 if( psid )
143 LocalFree( psid );
147 void test_trustee()
149 TRUSTEE trustee;
150 PSID psid;
151 LPSTR str = "2jjj";
153 SID_IDENTIFIER_AUTHORITY auth = { {0x11,0x22,0,0,0, 0} };
155 pBuildTrusteeWithSidA = (fnBuildTrusteeWithSidA)
156 GetProcAddress( hmod, "BuildTrusteeWithSidA" );
157 pBuildTrusteeWithNameA = (fnBuildTrusteeWithNameA)
158 GetProcAddress( hmod, "BuildTrusteeWithNameA" );
159 if( !pBuildTrusteeWithSidA || !pBuildTrusteeWithNameA)
160 return;
162 if ( ! AllocateAndInitializeSid( &auth, 1, 42, 0,0,0,0,0,0,0,&psid ) )
164 trace( "failed to init SID\n" );
165 return;
168 memset( &trustee, 0xff, sizeof trustee );
169 pBuildTrusteeWithSidA( &trustee, psid );
171 ok( trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
172 ok( trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE,
173 "MultipleTrusteeOperation wrong\n");
174 ok( trustee.TrusteeForm == TRUSTEE_IS_SID, "TrusteeForm wrong\n");
175 ok( trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
176 ok( trustee.ptstrName == (LPSTR) psid, "ptstrName wrong\n" );
177 FreeSid( psid );
179 /* test BuildTrusteeWithNameA */
180 memset( &trustee, 0xff, sizeof trustee );
181 pBuildTrusteeWithNameA( &trustee, str );
183 ok( trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
184 ok( trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE,
185 "MultipleTrusteeOperation wrong\n");
186 ok( trustee.TrusteeForm == TRUSTEE_IS_NAME, "TrusteeForm wrong\n");
187 ok( trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
188 ok( trustee.ptstrName == str, "ptstrName wrong\n" );
191 /* If the first isn't defined, assume none is */
192 #ifndef SE_MIN_WELL_KNOWN_PRIVILEGE
193 #define SE_MIN_WELL_KNOWN_PRIVILEGE 2L
194 #define SE_CREATE_TOKEN_PRIVILEGE 2L
195 #define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE 3L
196 #define SE_LOCK_MEMORY_PRIVILEGE 4L
197 #define SE_INCREASE_QUOTA_PRIVILEGE 5L
198 #define SE_MACHINE_ACCOUNT_PRIVILEGE 6L
199 #define SE_TCB_PRIVILEGE 7L
200 #define SE_SECURITY_PRIVILEGE 8L
201 #define SE_TAKE_OWNERSHIP_PRIVILEGE 9L
202 #define SE_LOAD_DRIVER_PRIVILEGE 10L
203 #define SE_SYSTEM_PROFILE_PRIVILEGE 11L
204 #define SE_SYSTEMTIME_PRIVILEGE 12L
205 #define SE_PROF_SINGLE_PROCESS_PRIVILEGE 13L
206 #define SE_INC_BASE_PRIORITY_PRIVILEGE 14L
207 #define SE_CREATE_PAGEFILE_PRIVILEGE 15L
208 #define SE_CREATE_PERMANENT_PRIVILEGE 16L
209 #define SE_BACKUP_PRIVILEGE 17L
210 #define SE_RESTORE_PRIVILEGE 18L
211 #define SE_SHUTDOWN_PRIVILEGE 19L
212 #define SE_DEBUG_PRIVILEGE 20L
213 #define SE_AUDIT_PRIVILEGE 21L
214 #define SE_SYSTEM_ENVIRONMENT_PRIVILEGE 22L
215 #define SE_CHANGE_NOTIFY_PRIVILLEGE 23L
216 #define SE_REMOTE_SHUTDOWN_PRIVILEGE 24L
217 #define SE_UNDOCK_PRIVILEGE 25L
218 #define SE_SYNC_AGENT_PRIVILEGE 26L
219 #define SE_ENABLE_DELEGATION_PRIVILEGE 27L
220 #define SE_MANAGE_VOLUME_PRIVILEGE 28L
221 #define SE_IMPERSONATE_PRIVILEGE 29L
222 #define SE_CREATE_GLOBAL_PRIVILEGE 30L
223 #define SE_MAX_WELL_KNOWN_PRIVILEGE SE_CREATE_GLOBAL_PRIVILEGE
224 #endif /* ndef SE_MIN_WELL_KNOWN_PRIVILEGE */
226 static void test_allocateLuid(void)
228 BOOL (WINAPI *pAllocateLocallyUniqueId)(PLUID);
229 LUID luid1, luid2;
230 BOOL ret;
232 pAllocateLocallyUniqueId = (void*)GetProcAddress(hmod, "AllocateLocallyUniqueId");
233 if (!pAllocateLocallyUniqueId) return;
235 ret = pAllocateLocallyUniqueId(&luid1);
236 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
237 return;
239 ok(ret,
240 "AllocateLocallyUniqueId failed: %ld\n", GetLastError());
241 ret = pAllocateLocallyUniqueId(&luid2);
242 ok( ret,
243 "AllocateLocallyUniqueId failed: %ld\n", GetLastError());
244 ok(luid1.LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE || luid1.HighPart != 0,
245 "AllocateLocallyUniqueId returned a well-known LUID\n");
246 ok(luid1.LowPart != luid2.LowPart || luid1.HighPart != luid2.HighPart,
247 "AllocateLocallyUniqueId returned non-unique LUIDs\n");
248 ret = pAllocateLocallyUniqueId(NULL);
249 ok( !ret && GetLastError() == ERROR_NOACCESS,
250 "AllocateLocallyUniqueId(NULL) didn't return ERROR_NOACCESS: %ld\n",
251 GetLastError());
254 static void test_lookupPrivilegeName(void)
256 BOOL (WINAPI *pLookupPrivilegeNameA)(LPSTR, PLUID, LPSTR, LPDWORD);
257 char buf[MAX_PATH]; /* arbitrary, seems long enough */
258 DWORD cchName = sizeof(buf);
259 LUID luid = { 0, 0 };
260 LONG i;
261 BOOL ret;
263 /* check whether it's available first */
264 pLookupPrivilegeNameA = (void*)GetProcAddress(hmod, "LookupPrivilegeNameA");
265 if (!pLookupPrivilegeNameA) return;
266 luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
267 ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);
268 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
269 return;
271 /* check with a short buffer */
272 cchName = 0;
273 luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
274 ret = pLookupPrivilegeNameA(NULL, &luid, NULL, &cchName);
275 ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
276 "LookupPrivilegeNameA didn't fail with ERROR_INSUFFICIENT_BUFFER: %ld\n",
277 GetLastError());
278 ok(cchName == strlen("SeCreateTokenPrivilege") + 1,
279 "LookupPrivilegeNameA returned an incorrect required length for\n"
280 "SeCreateTokenPrivilege (got %ld, expected %d)\n", cchName,
281 strlen("SeCreateTokenPrivilege") + 1);
282 /* check a known value and its returned length on success */
283 cchName = sizeof(buf);
284 ok(pLookupPrivilegeNameA(NULL, &luid, buf, &cchName) &&
285 cchName == strlen("SeCreateTokenPrivilege"),
286 "LookupPrivilegeNameA returned an incorrect output length for\n"
287 "SeCreateTokenPrivilege (got %ld, expected %d)\n", cchName,
288 (int)strlen("SeCreateTokenPrivilege"));
289 /* check known values */
290 for (i = SE_MIN_WELL_KNOWN_PRIVILEGE; i < SE_MAX_WELL_KNOWN_PRIVILEGE; i++)
292 luid.LowPart = i;
293 cchName = sizeof(buf);
294 ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);
295 ok( ret || GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
296 "LookupPrivilegeNameA(0.%ld) failed: %ld\n", i, GetLastError());
298 /* check a bogus LUID */
299 luid.LowPart = 0xdeadbeef;
300 cchName = sizeof(buf);
301 ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);
302 ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
303 "LookupPrivilegeNameA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",
304 GetLastError());
305 /* check on a bogus system */
306 luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
307 cchName = sizeof(buf);
308 ret = pLookupPrivilegeNameA("b0gu5.Nam3", &luid, buf, &cchName);
309 ok( !ret && GetLastError() == RPC_S_SERVER_UNAVAILABLE,
310 "LookupPrivilegeNameA didn't fail with RPC_S_SERVER_UNAVAILABLE: %ld\n",
311 GetLastError());
314 struct NameToLUID
316 const char *name;
317 DWORD lowPart;
320 static void test_lookupPrivilegeValue(void)
322 static const struct NameToLUID privs[] = {
323 { "SeCreateTokenPrivilege", SE_CREATE_TOKEN_PRIVILEGE },
324 { "SeAssignPrimaryTokenPrivilege", SE_ASSIGNPRIMARYTOKEN_PRIVILEGE },
325 { "SeLockMemoryPrivilege", SE_LOCK_MEMORY_PRIVILEGE },
326 { "SeIncreaseQuotaPrivilege", SE_INCREASE_QUOTA_PRIVILEGE },
327 { "SeMachineAccountPrivilege", SE_MACHINE_ACCOUNT_PRIVILEGE },
328 { "SeTcbPrivilege", SE_TCB_PRIVILEGE },
329 { "SeSecurityPrivilege", SE_SECURITY_PRIVILEGE },
330 { "SeTakeOwnershipPrivilege", SE_TAKE_OWNERSHIP_PRIVILEGE },
331 { "SeLoadDriverPrivilege", SE_LOAD_DRIVER_PRIVILEGE },
332 { "SeSystemProfilePrivilege", SE_SYSTEM_PROFILE_PRIVILEGE },
333 { "SeSystemtimePrivilege", SE_SYSTEMTIME_PRIVILEGE },
334 { "SeProfileSingleProcessPrivilege", SE_PROF_SINGLE_PROCESS_PRIVILEGE },
335 { "SeIncreaseBasePriorityPrivilege", SE_INC_BASE_PRIORITY_PRIVILEGE },
336 { "SeCreatePagefilePrivilege", SE_CREATE_PAGEFILE_PRIVILEGE },
337 { "SeCreatePermanentPrivilege", SE_CREATE_PERMANENT_PRIVILEGE },
338 { "SeBackupPrivilege", SE_BACKUP_PRIVILEGE },
339 { "SeRestorePrivilege", SE_RESTORE_PRIVILEGE },
340 { "SeShutdownPrivilege", SE_SHUTDOWN_PRIVILEGE },
341 { "SeDebugPrivilege", SE_DEBUG_PRIVILEGE },
342 { "SeAuditPrivilege", SE_AUDIT_PRIVILEGE },
343 { "SeSystemEnvironmentPrivilege", SE_SYSTEM_ENVIRONMENT_PRIVILEGE },
344 { "SeChangeNotifyPrivilege", SE_CHANGE_NOTIFY_PRIVILLEGE },
345 { "SeRemoteShutdownPrivilege", SE_REMOTE_SHUTDOWN_PRIVILEGE },
346 { "SeUndockPrivilege", SE_UNDOCK_PRIVILEGE },
347 { "SeSyncAgentPrivilege", SE_SYNC_AGENT_PRIVILEGE },
348 { "SeEnableDelegationPrivilege", SE_ENABLE_DELEGATION_PRIVILEGE },
349 { "SeManageVolumePrivilege", SE_MANAGE_VOLUME_PRIVILEGE },
350 { "SeImpersonatePrivilege", SE_IMPERSONATE_PRIVILEGE },
351 { "SeCreateGlobalPrivilege", SE_CREATE_GLOBAL_PRIVILEGE },
353 BOOL (WINAPI *pLookupPrivilegeValueA)(LPCSTR, LPCSTR, PLUID);
354 int i;
355 LUID luid;
356 BOOL ret;
358 /* check whether it's available first */
359 pLookupPrivilegeValueA = (void*)GetProcAddress(hmod, "LookupPrivilegeValueA");
360 if (!pLookupPrivilegeValueA) return;
361 ret = pLookupPrivilegeValueA(NULL, "SeCreateTokenPrivilege", &luid);
362 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
363 return;
365 /* check a bogus system name */
366 ret = pLookupPrivilegeValueA("b0gu5.Nam3", "SeCreateTokenPrivilege", &luid);
367 ok( !ret && GetLastError() == RPC_S_SERVER_UNAVAILABLE,
368 "LookupPrivilegeValueA didn't fail with RPC_S_SERVER_UNAVAILABLE: %ld\n",
369 GetLastError());
370 /* check a NULL string */
371 ret = pLookupPrivilegeValueA(NULL, 0, &luid);
372 ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
373 "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",
374 GetLastError());
375 /* check a bogus privilege name */
376 ret = pLookupPrivilegeValueA(NULL, "SeBogusPrivilege", &luid);
377 ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
378 "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",
379 GetLastError());
380 /* check case insensitive */
381 ret = pLookupPrivilegeValueA(NULL, "sEcREATEtOKENpRIVILEGE", &luid);
382 ok( ret,
383 "LookupPrivilegeValueA(NULL, sEcREATEtOKENpRIVILEGE, &luid) failed: %ld\n",
384 GetLastError());
385 for (i = 0; i < sizeof(privs) / sizeof(privs[0]); i++)
387 /* Not all privileges are implemented on all Windows versions, so
388 * don't worry if the call fails
390 if (pLookupPrivilegeValueA(NULL, privs[i].name, &luid))
392 ok(luid.LowPart == privs[i].lowPart,
393 "LookupPrivilegeValueA returned an invalid LUID for %s\n",
394 privs[i].name);
399 static void test_luid(void)
401 test_allocateLuid();
402 test_lookupPrivilegeName();
403 test_lookupPrivilegeValue();
406 static void test_FileSecurity(void)
408 char directory[MAX_PATH];
409 DWORD retval, outSize;
410 BOOL result;
411 BYTE buffer[0x40];
413 pGetFileSecurityA = (fnGetFileSecurityA)
414 GetProcAddress( hmod, "GetFileSecurityA" );
415 if( !pGetFileSecurityA )
416 return;
418 retval = GetTempPathA(sizeof(directory), directory);
419 if (!retval) {
420 trace("GetTempPathA failed\n");
421 return;
424 strcpy(directory, "\\Should not exist");
426 SetLastError(NO_ERROR);
427 result = pGetFileSecurityA( directory,OWNER_SECURITY_INFORMATION,buffer,0x40,&outSize);
428 ok(!result, "GetFileSecurityA should fail for not existing directories/files\n");
429 ok( (GetLastError() == ERROR_FILE_NOT_FOUND ) ||
430 (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) ,
431 "last error ERROR_FILE_NOT_FOUND / ERROR_CALL_NOT_IMPLEMENTED (98) "
432 "expected, got %ld\n", GetLastError());
435 START_TEST(security)
437 init();
438 if (!hmod) return;
439 test_sid();
440 test_trustee();
441 test_luid();
442 test_FileSecurity();