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 );
37 fnBuildTrusteeWithSidA pBuildTrusteeWithSidA;
38 fnBuildTrusteeWithNameA pBuildTrusteeWithNameA;
39 fnConvertSidToStringSidA pConvertSidToStringSidA;
40 fnConvertStringSidToSidA pConvertStringSidToSidA;
44 SID_IDENTIFIER_AUTHORITY auth;
48 static void init(void)
50 hmod = GetModuleHandle("advapi32.dll");
55 struct sidRef refs[] = {
56 { { {0x00,0x00,0x33,0x44,0x55,0x66} }, "S-1-860116326-1" },
57 { { {0x00,0x00,0x01,0x02,0x03,0x04} }, "S-1-16909060-1" },
58 { { {0x00,0x00,0x00,0x01,0x02,0x03} }, "S-1-66051-1" },
59 { { {0x00,0x00,0x00,0x00,0x01,0x02} }, "S-1-258-1" },
60 { { {0x00,0x00,0x00,0x00,0x00,0x02} }, "S-1-2-1" },
61 { { {0x00,0x00,0x00,0x00,0x00,0x0c} }, "S-1-12-1" },
63 const char noSubAuthStr[] = "S-1-5";
69 pConvertSidToStringSidA = (fnConvertSidToStringSidA)
70 GetProcAddress( hmod, "ConvertSidToStringSidA" );
71 if( !pConvertSidToStringSidA )
73 pConvertStringSidToSidA = (fnConvertStringSidToSidA)
74 GetProcAddress( hmod, "ConvertStringSidToSidA" );
75 if( !pConvertStringSidToSidA )
78 r = pConvertStringSidToSidA( NULL, NULL );
79 ok( !r, "expected failure with NULL parameters\n" );
80 if( GetLastError() == ERROR_CALL_NOT_IMPLEMENTED )
82 ok( GetLastError() == ERROR_INVALID_PARAMETER,
83 "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",
86 r = pConvertStringSidToSidA( refs[0].refStr, NULL );
87 ok( !r && GetLastError() == ERROR_INVALID_PARAMETER,
88 "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",
91 r = pConvertStringSidToSidA( NULL, &str );
92 ok( !r && GetLastError() == ERROR_INVALID_PARAMETER,
93 "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",
96 r = pConvertStringSidToSidA( noSubAuthStr, &psid );
98 "expected failure with no sub authorities\n" );
99 ok( GetLastError() == ERROR_INVALID_SID,
100 "expected GetLastError() is ERROR_INVALID_SID, got %ld\n",
103 for( i = 0; i < sizeof(refs) / sizeof(refs[0]); i++ )
107 r = AllocateAndInitializeSid( &refs[i].auth, 1,1,0,0,0,0,0,0,0,
109 ok( r, "failed to allocate sid\n" );
110 r = pConvertSidToStringSidA( psid, &str );
111 ok( r, "failed to convert sid\n" );
114 ok( !strcmp( str, refs[i].refStr ),
115 "incorrect sid, expected %s, got %s\n", refs[i].refStr, str );
121 r = pConvertStringSidToSidA( refs[i].refStr, &psid );
122 ok( r, "failed to parse sid string\n" );
125 !memcmp( pisid->IdentifierAuthority.Value, refs[i].auth.Value,
126 sizeof(refs[i].auth) ),
127 "string sid %s didn't parse to expected value\n"
128 "(got 0x%04x%08lx, expected 0x%04x%08lx)\n",
130 MAKEWORD( pisid->IdentifierAuthority.Value[1],
131 pisid->IdentifierAuthority.Value[0] ),
132 MAKELONG( MAKEWORD( pisid->IdentifierAuthority.Value[5],
133 pisid->IdentifierAuthority.Value[4] ),
134 MAKEWORD( pisid->IdentifierAuthority.Value[3],
135 pisid->IdentifierAuthority.Value[2] ) ),
136 MAKEWORD( refs[i].auth.Value[1], refs[i].auth.Value[0] ),
137 MAKELONG( MAKEWORD( refs[i].auth.Value[5], refs[i].auth.Value[4] ),
138 MAKEWORD( refs[i].auth.Value[3], refs[i].auth.Value[2] ) ) );
150 SID_IDENTIFIER_AUTHORITY auth = { {0x11,0x22,0,0,0, 0} };
152 pBuildTrusteeWithSidA = (fnBuildTrusteeWithSidA)
153 GetProcAddress( hmod, "BuildTrusteeWithSidA" );
154 pBuildTrusteeWithNameA = (fnBuildTrusteeWithNameA)
155 GetProcAddress( hmod, "BuildTrusteeWithNameA" );
156 if( !pBuildTrusteeWithSidA || !pBuildTrusteeWithNameA)
159 if ( ! AllocateAndInitializeSid( &auth, 1, 42, 0,0,0,0,0,0,0,&psid ) )
161 trace( "failed to init SID\n" );
165 memset( &trustee, 0xff, sizeof trustee );
166 pBuildTrusteeWithSidA( &trustee, psid );
168 ok( trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
169 ok( trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE,
170 "MultipleTrusteeOperation wrong\n");
171 ok( trustee.TrusteeForm == TRUSTEE_IS_SID, "TrusteeForm wrong\n");
172 ok( trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
173 ok( trustee.ptstrName == (LPSTR) psid, "ptstrName wrong\n" );
176 /* test BuildTrusteeWithNameA */
177 memset( &trustee, 0xff, sizeof trustee );
178 pBuildTrusteeWithNameA( &trustee, str );
180 ok( trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
181 ok( trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE,
182 "MultipleTrusteeOperation wrong\n");
183 ok( trustee.TrusteeForm == TRUSTEE_IS_NAME, "TrusteeForm wrong\n");
184 ok( trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
185 ok( trustee.ptstrName == str, "ptstrName wrong\n" );
188 /* If the first isn't defined, assume none is */
189 #ifndef SE_MIN_WELL_KNOWN_PRIVILEGE
190 #define SE_MIN_WELL_KNOWN_PRIVILEGE 2L
191 #define SE_CREATE_TOKEN_PRIVILEGE 2L
192 #define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE 3L
193 #define SE_LOCK_MEMORY_PRIVILEGE 4L
194 #define SE_INCREASE_QUOTA_PRIVILEGE 5L
195 #define SE_MACHINE_ACCOUNT_PRIVILEGE 6L
196 #define SE_TCB_PRIVILEGE 7L
197 #define SE_SECURITY_PRIVILEGE 8L
198 #define SE_TAKE_OWNERSHIP_PRIVILEGE 9L
199 #define SE_LOAD_DRIVER_PRIVILEGE 10L
200 #define SE_SYSTEM_PROFILE_PRIVILEGE 11L
201 #define SE_SYSTEMTIME_PRIVILEGE 12L
202 #define SE_PROF_SINGLE_PROCESS_PRIVILEGE 13L
203 #define SE_INC_BASE_PRIORITY_PRIVILEGE 14L
204 #define SE_CREATE_PAGEFILE_PRIVILEGE 15L
205 #define SE_CREATE_PERMANENT_PRIVILEGE 16L
206 #define SE_BACKUP_PRIVILEGE 17L
207 #define SE_RESTORE_PRIVILEGE 18L
208 #define SE_SHUTDOWN_PRIVILEGE 19L
209 #define SE_DEBUG_PRIVILEGE 20L
210 #define SE_AUDIT_PRIVILEGE 21L
211 #define SE_SYSTEM_ENVIRONMENT_PRIVILEGE 22L
212 #define SE_CHANGE_NOTIFY_PRIVILLEGE 23L
213 #define SE_REMOTE_SHUTDOWN_PRIVILEGE 24L
214 #define SE_UNDOCK_PRIVILEGE 25L
215 #define SE_SYNC_AGENT_PRIVILEGE 26L
216 #define SE_ENABLE_DELEGATION_PRIVILEGE 27L
217 #define SE_MANAGE_VOLUME_PRIVILEGE 28L
218 #define SE_IMPERSONATE_PRIVILEGE 29L
219 #define SE_CREATE_GLOBAL_PRIVILEGE 30L
220 #define SE_MAX_WELL_KNOWN_PRIVILEGE SE_CREATE_GLOBAL_PRIVILEGE
221 #endif /* ndef SE_MIN_WELL_KNOWN_PRIVILEGE */
223 static void test_allocateLuid(void)
225 BOOL (WINAPI *pAllocateLocallyUniqueId)(PLUID);
229 pAllocateLocallyUniqueId = (void*)GetProcAddress(hmod, "AllocateLocallyUniqueId");
230 if (!pAllocateLocallyUniqueId) return;
232 ret = pAllocateLocallyUniqueId(&luid1);
233 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
237 "AllocateLocallyUniqueId failed: %ld\n", GetLastError());
238 ret = pAllocateLocallyUniqueId(&luid2);
240 "AllocateLocallyUniqueId failed: %ld\n", GetLastError());
241 ok(luid1.LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE || luid1.HighPart != 0,
242 "AllocateLocallyUniqueId returned a well-known LUID\n");
243 ok(luid1.LowPart != luid2.LowPart || luid1.HighPart != luid2.HighPart,
244 "AllocateLocallyUniqueId returned non-unique LUIDs\n");
245 ret = pAllocateLocallyUniqueId(NULL);
246 ok( !ret && GetLastError() == ERROR_NOACCESS,
247 "AllocateLocallyUniqueId(NULL) didn't return ERROR_NOACCESS: %ld\n",
251 static void test_lookupPrivilegeName(void)
253 BOOL (WINAPI *pLookupPrivilegeNameA)(LPSTR, PLUID, LPSTR, LPDWORD);
254 char buf[MAX_PATH]; /* arbitrary, seems long enough */
255 DWORD cchName = sizeof(buf);
256 LUID luid = { 0, 0 };
260 /* check whether it's available first */
261 pLookupPrivilegeNameA = (void*)GetProcAddress(hmod, "LookupPrivilegeNameA");
262 if (!pLookupPrivilegeNameA) return;
263 luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
264 ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);
265 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
268 /* check with a short buffer */
270 luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
271 ret = pLookupPrivilegeNameA(NULL, &luid, NULL, &cchName);
272 ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
273 "LookupPrivilegeNameA didn't fail with ERROR_INSUFFICIENT_BUFFER: %ld\n",
275 ok(cchName == strlen("SeCreateTokenPrivilege") + 1,
276 "LookupPrivilegeNameA returned an incorrect required length for\n"
277 "SeCreateTokenPrivilege (got %ld, expected %d)\n", cchName,
278 strlen("SeCreateTokenPrivilege") + 1);
279 /* check a known value and its returned length on success */
280 cchName = sizeof(buf);
281 ok(pLookupPrivilegeNameA(NULL, &luid, buf, &cchName) &&
282 cchName == strlen("SeCreateTokenPrivilege"),
283 "LookupPrivilegeNameA returned an incorrect output length for\n"
284 "SeCreateTokenPrivilege (got %ld, expected %d)\n", cchName,
285 (int)strlen("SeCreateTokenPrivilege"));
286 /* check known values */
287 for (i = SE_MIN_WELL_KNOWN_PRIVILEGE; i < SE_MAX_WELL_KNOWN_PRIVILEGE; i++)
290 cchName = sizeof(buf);
291 ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);
292 ok( ret && GetLastError() != ERROR_NO_SUCH_PRIVILEGE,
293 "LookupPrivilegeNameA(0.%ld) failed: %ld\n", i, GetLastError());
295 /* check a bogus LUID */
296 luid.LowPart = 0xdeadbeef;
297 cchName = sizeof(buf);
298 ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);
299 ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
300 "LookupPrivilegeNameA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",
302 /* check on a bogus system */
303 luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
304 cchName = sizeof(buf);
305 ret = pLookupPrivilegeNameA("b0gu5.Nam3", &luid, buf, &cchName);
306 ok( !ret && GetLastError() == RPC_S_SERVER_UNAVAILABLE,
307 "LookupPrivilegeNameA didn't fail with RPC_S_SERVER_UNAVAILABLE: %ld\n",
317 static void test_lookupPrivilegeValue(void)
319 static const struct NameToLUID privs[] = {
320 { "SeCreateTokenPrivilege", SE_CREATE_TOKEN_PRIVILEGE },
321 { "SeAssignPrimaryTokenPrivilege", SE_ASSIGNPRIMARYTOKEN_PRIVILEGE },
322 { "SeLockMemoryPrivilege", SE_LOCK_MEMORY_PRIVILEGE },
323 { "SeIncreaseQuotaPrivilege", SE_INCREASE_QUOTA_PRIVILEGE },
324 { "SeMachineAccountPrivilege", SE_MACHINE_ACCOUNT_PRIVILEGE },
325 { "SeTcbPrivilege", SE_TCB_PRIVILEGE },
326 { "SeSecurityPrivilege", SE_SECURITY_PRIVILEGE },
327 { "SeTakeOwnershipPrivilege", SE_TAKE_OWNERSHIP_PRIVILEGE },
328 { "SeLoadDriverPrivilege", SE_LOAD_DRIVER_PRIVILEGE },
329 { "SeSystemProfilePrivilege", SE_SYSTEM_PROFILE_PRIVILEGE },
330 { "SeSystemtimePrivilege", SE_SYSTEMTIME_PRIVILEGE },
331 { "SeProfileSingleProcessPrivilege", SE_PROF_SINGLE_PROCESS_PRIVILEGE },
332 { "SeIncreaseBasePriorityPrivilege", SE_INC_BASE_PRIORITY_PRIVILEGE },
333 { "SeCreatePagefilePrivilege", SE_CREATE_PAGEFILE_PRIVILEGE },
334 { "SeCreatePermanentPrivilege", SE_CREATE_PERMANENT_PRIVILEGE },
335 { "SeBackupPrivilege", SE_BACKUP_PRIVILEGE },
336 { "SeRestorePrivilege", SE_RESTORE_PRIVILEGE },
337 { "SeShutdownPrivilege", SE_SHUTDOWN_PRIVILEGE },
338 { "SeDebugPrivilege", SE_DEBUG_PRIVILEGE },
339 { "SeAuditPrivilege", SE_AUDIT_PRIVILEGE },
340 { "SeSystemEnvironmentPrivilege", SE_SYSTEM_ENVIRONMENT_PRIVILEGE },
341 { "SeChangeNotifyPrivilege", SE_CHANGE_NOTIFY_PRIVILLEGE },
342 { "SeRemoteShutdownPrivilege", SE_REMOTE_SHUTDOWN_PRIVILEGE },
343 { "SeUndockPrivilege", SE_UNDOCK_PRIVILEGE },
344 { "SeSyncAgentPrivilege", SE_SYNC_AGENT_PRIVILEGE },
345 { "SeEnableDelegationPrivilege", SE_ENABLE_DELEGATION_PRIVILEGE },
346 { "SeManageVolumePrivilege", SE_MANAGE_VOLUME_PRIVILEGE },
347 { "SeImpersonatePrivilege", SE_IMPERSONATE_PRIVILEGE },
348 { "SeCreateGlobalPrivilege", SE_CREATE_GLOBAL_PRIVILEGE },
350 BOOL (WINAPI *pLookupPrivilegeValueA)(LPCSTR, LPCSTR, PLUID);
355 /* check whether it's available first */
356 pLookupPrivilegeValueA = (void*)GetProcAddress(hmod, "LookupPrivilegeValueA");
357 if (!pLookupPrivilegeValueA) return;
358 ret = pLookupPrivilegeValueA(NULL, "SeCreateTokenPrivilege", &luid);
359 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
362 /* check a bogus system name */
363 ret = pLookupPrivilegeValueA("b0gu5.Nam3", "SeCreateTokenPrivilege", &luid);
364 ok( !ret && GetLastError() == RPC_S_SERVER_UNAVAILABLE,
365 "LookupPrivilegeValueA didn't fail with RPC_S_SERVER_UNAVAILABLE: %ld\n",
367 /* check a NULL string */
368 ret = pLookupPrivilegeValueA(NULL, 0, &luid);
369 ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
370 "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",
372 /* check a bogus privilege name */
373 ret = pLookupPrivilegeValueA(NULL, "SeBogusPrivilege", &luid);
374 ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
375 "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",
377 /* check case insensitive */
378 ret = pLookupPrivilegeValueA(NULL, "sEcREATEtOKENpRIVILEGE", &luid);
380 "LookupPrivilegeValueA(NULL, sEcREATEtOKENpRIVILEGE, &luid) failed: %ld\n",
382 for (i = 0; i < sizeof(privs) / sizeof(privs[0]); i++)
384 /* Not all privileges are implemented on all Windows versions, so
385 * don't worry if the call fails
387 if (pLookupPrivilegeValueA(NULL, privs[i].name, &luid))
389 ok(luid.LowPart == privs[i].lowPart,
390 "LookupPrivilegeValueA returned an invalid LUID for %s\n",
396 static void test_luid(void)
399 test_lookupPrivilegeName();
400 test_lookupPrivilegeValue();