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" );
112 ok( !strcmp( str, refs[i].refStr ),
113 "incorrect sid, expected %s, got %s\n", refs[i].refStr, str );
119 r = pConvertStringSidToSidA( refs[i].refStr, &psid );
120 ok( r, "failed to parse sid string\n" );
123 !memcmp( pisid->IdentifierAuthority.Value, refs[i].auth.Value,
124 sizeof(refs[i].auth) ),
125 "string sid %s didn't parse to expected value\n"
126 "(got 0x%04x%08lx, expected 0x%04x%08lx)\n",
128 MAKEWORD( pisid->IdentifierAuthority.Value[1],
129 pisid->IdentifierAuthority.Value[0] ),
130 MAKELONG( MAKEWORD( pisid->IdentifierAuthority.Value[5],
131 pisid->IdentifierAuthority.Value[4] ),
132 MAKEWORD( pisid->IdentifierAuthority.Value[3],
133 pisid->IdentifierAuthority.Value[2] ) ),
134 MAKEWORD( refs[i].auth.Value[1], refs[i].auth.Value[0] ),
135 MAKELONG( MAKEWORD( refs[i].auth.Value[5], refs[i].auth.Value[4] ),
136 MAKEWORD( refs[i].auth.Value[3], refs[i].auth.Value[2] ) ) );
148 SID_IDENTIFIER_AUTHORITY auth = { {0x11,0x22,0,0,0, 0} };
150 pBuildTrusteeWithSidA = (fnBuildTrusteeWithSidA)
151 GetProcAddress( hmod, "BuildTrusteeWithSidA" );
152 pBuildTrusteeWithNameA = (fnBuildTrusteeWithNameA)
153 GetProcAddress( hmod, "BuildTrusteeWithNameA" );
154 if( !pBuildTrusteeWithSidA || !pBuildTrusteeWithNameA)
157 if ( ! AllocateAndInitializeSid( &auth, 1, 42, 0,0,0,0,0,0,0,&psid ) )
159 trace( "failed to init SID\n" );
163 memset( &trustee, 0xff, sizeof trustee );
164 pBuildTrusteeWithSidA( &trustee, psid );
166 ok( trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
167 ok( trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE,
168 "MultipleTrusteeOperation wrong\n");
169 ok( trustee.TrusteeForm == TRUSTEE_IS_SID, "TrusteeForm wrong\n");
170 ok( trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
171 ok( trustee.ptstrName == (LPSTR) psid, "ptstrName wrong\n" );
174 /* test BuildTrusteeWithNameA */
175 memset( &trustee, 0xff, sizeof trustee );
176 pBuildTrusteeWithNameA( &trustee, str );
178 ok( trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
179 ok( trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE,
180 "MultipleTrusteeOperation wrong\n");
181 ok( trustee.TrusteeForm == TRUSTEE_IS_NAME, "TrusteeForm wrong\n");
182 ok( trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
183 ok( trustee.ptstrName == str, "ptstrName wrong\n" );
186 /* If the first isn't defined, assume none is */
187 #ifndef SE_MIN_WELL_KNOWN_PRIVILEGE
188 #define SE_MIN_WELL_KNOWN_PRIVILEGE 2L
189 #define SE_CREATE_TOKEN_PRIVILEGE 2L
190 #define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE 3L
191 #define SE_LOCK_MEMORY_PRIVILEGE 4L
192 #define SE_INCREASE_QUOTA_PRIVILEGE 5L
193 #define SE_MACHINE_ACCOUNT_PRIVILEGE 6L
194 #define SE_TCB_PRIVILEGE 7L
195 #define SE_SECURITY_PRIVILEGE 8L
196 #define SE_TAKE_OWNERSHIP_PRIVILEGE 9L
197 #define SE_LOAD_DRIVER_PRIVILEGE 10L
198 #define SE_SYSTEM_PROFILE_PRIVILEGE 11L
199 #define SE_SYSTEMTIME_PRIVILEGE 12L
200 #define SE_PROF_SINGLE_PROCESS_PRIVILEGE 13L
201 #define SE_INC_BASE_PRIORITY_PRIVILEGE 14L
202 #define SE_CREATE_PAGEFILE_PRIVILEGE 15L
203 #define SE_CREATE_PERMANENT_PRIVILEGE 16L
204 #define SE_BACKUP_PRIVILEGE 17L
205 #define SE_RESTORE_PRIVILEGE 18L
206 #define SE_SHUTDOWN_PRIVILEGE 19L
207 #define SE_DEBUG_PRIVILEGE 20L
208 #define SE_AUDIT_PRIVILEGE 21L
209 #define SE_SYSTEM_ENVIRONMENT_PRIVILEGE 22L
210 #define SE_CHANGE_NOTIFY_PRIVILLEGE 23L
211 #define SE_REMOTE_SHUTDOWN_PRIVILEGE 24L
212 #define SE_UNDOCK_PRIVILEGE 25L
213 #define SE_SYNC_AGENT_PRIVILEGE 26L
214 #define SE_ENABLE_DELEGATION_PRIVILEGE 27L
215 #define SE_MANAGE_VOLUME_PRIVILEGE 28L
216 #define SE_IMPERSONATE_PRIVILEGE 29L
217 #define SE_CREATE_GLOBAL_PRIVILEGE 30L
218 #define SE_MAX_WELL_KNOWN_PRIVILEGE SE_CREATE_GLOBAL_PRIVILEGE
219 #endif /* ndef SE_MIN_WELL_KNOWN_PRIVILEGE */
221 static void test_allocateLuid(void)
223 BOOL (WINAPI *pAllocateLocallyUniqueId)(PLUID);
227 pAllocateLocallyUniqueId = (void*)GetProcAddress(hmod, "AllocateLocallyUniqueId");
228 if (!pAllocateLocallyUniqueId) return;
230 ret = pAllocateLocallyUniqueId(&luid1);
231 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
235 "AllocateLocallyUniqueId failed: %ld\n", GetLastError());
236 ret = pAllocateLocallyUniqueId(&luid2);
238 "AllocateLocallyUniqueId failed: %ld\n", GetLastError());
239 ok(luid1.LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE || luid1.HighPart != 0,
240 "AllocateLocallyUniqueId returned a well-known LUID\n");
241 ok(luid1.LowPart != luid2.LowPart || luid1.HighPart != luid2.HighPart,
242 "AllocateLocallyUniqueId returned non-unique LUIDs\n");
243 ret = pAllocateLocallyUniqueId(NULL);
244 ok( !ret && GetLastError() == ERROR_NOACCESS,
245 "AllocateLocallyUniqueId(NULL) didn't return ERROR_NOACCESS: %ld\n",
249 static void test_lookupPrivilegeName(void)
251 BOOL (WINAPI *pLookupPrivilegeNameA)(LPSTR, PLUID, LPSTR, LPDWORD);
252 char buf[MAX_PATH]; /* arbitrary, seems long enough */
253 DWORD cchName = sizeof(buf);
254 LUID luid = { 0, 0 };
258 /* check whether it's available first */
259 pLookupPrivilegeNameA = (void*)GetProcAddress(hmod, "LookupPrivilegeNameA");
260 if (!pLookupPrivilegeNameA) return;
261 luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
262 ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);
263 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
266 /* check with a short buffer */
268 luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
269 ret = pLookupPrivilegeNameA(NULL, &luid, NULL, &cchName);
270 ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
271 "LookupPrivilegeNameA didn't fail with ERROR_INSUFFICIENT_BUFFER: %ld\n",
273 ok(cchName == strlen("SeCreateTokenPrivilege") + 1,
274 "LookupPrivilegeNameA returned an incorrect required length for\n"
275 "SeCreateTokenPrivilege (got %ld, expected %d)\n", cchName,
276 strlen("SeCreateTokenPrivilege") + 1);
277 /* check a known value and its returned length on success */
278 cchName = sizeof(buf);
279 ok(pLookupPrivilegeNameA(NULL, &luid, buf, &cchName) &&
280 cchName == strlen("SeCreateTokenPrivilege"),
281 "LookupPrivilegeNameA returned an incorrect output length for\n"
282 "SeCreateTokenPrivilege (got %ld, expected %d)\n", cchName,
283 (int)strlen("SeCreateTokenPrivilege"));
284 /* check known values */
285 for (i = SE_MIN_WELL_KNOWN_PRIVILEGE; i < SE_MAX_WELL_KNOWN_PRIVILEGE; i++)
288 cchName = sizeof(buf);
289 ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);
291 "LookupPrivilegeNameA(0.%ld) failed: %ld\n", i, GetLastError());
293 /* check a bogus LUID */
294 luid.LowPart = 0xdeadbeef;
295 cchName = sizeof(buf);
296 ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);
297 ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
298 "LookupPrivilegeNameA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",
300 /* check on a bogus system */
301 luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
302 cchName = sizeof(buf);
303 ret = pLookupPrivilegeNameA("b0gu5.Nam3", &luid, buf, &cchName);
304 ok( !ret && GetLastError() == RPC_S_SERVER_UNAVAILABLE,
305 "LookupPrivilegeNameA didn't fail with RPC_S_SERVER_UNAVAILABLE: %ld\n",
315 static void test_lookupPrivilegeValue(void)
317 static const struct NameToLUID privs[] = {
318 { "SeCreateTokenPrivilege", SE_CREATE_TOKEN_PRIVILEGE },
319 { "SeAssignPrimaryTokenPrivilege", SE_ASSIGNPRIMARYTOKEN_PRIVILEGE },
320 { "SeLockMemoryPrivilege", SE_LOCK_MEMORY_PRIVILEGE },
321 { "SeIncreaseQuotaPrivilege", SE_INCREASE_QUOTA_PRIVILEGE },
322 { "SeMachineAccountPrivilege", SE_MACHINE_ACCOUNT_PRIVILEGE },
323 { "SeTcbPrivilege", SE_TCB_PRIVILEGE },
324 { "SeSecurityPrivilege", SE_SECURITY_PRIVILEGE },
325 { "SeTakeOwnershipPrivilege", SE_TAKE_OWNERSHIP_PRIVILEGE },
326 { "SeLoadDriverPrivilege", SE_LOAD_DRIVER_PRIVILEGE },
327 { "SeSystemProfilePrivilege", SE_SYSTEM_PROFILE_PRIVILEGE },
328 { "SeSystemtimePrivilege", SE_SYSTEMTIME_PRIVILEGE },
329 { "SeProfileSingleProcessPrivilege", SE_PROF_SINGLE_PROCESS_PRIVILEGE },
330 { "SeIncreaseBasePriorityPrivilege", SE_INC_BASE_PRIORITY_PRIVILEGE },
331 { "SeCreatePagefilePrivilege", SE_CREATE_PAGEFILE_PRIVILEGE },
332 { "SeCreatePermanentPrivilege", SE_CREATE_PERMANENT_PRIVILEGE },
333 { "SeBackupPrivilege", SE_BACKUP_PRIVILEGE },
334 { "SeRestorePrivilege", SE_RESTORE_PRIVILEGE },
335 { "SeShutdownPrivilege", SE_SHUTDOWN_PRIVILEGE },
336 { "SeDebugPrivilege", SE_DEBUG_PRIVILEGE },
337 { "SeAuditPrivilege", SE_AUDIT_PRIVILEGE },
338 { "SeSystemEnvironmentPrivilege", SE_SYSTEM_ENVIRONMENT_PRIVILEGE },
339 { "SeChangeNotifyPrivilege", SE_CHANGE_NOTIFY_PRIVILLEGE },
340 { "SeRemoteShutdownPrivilege", SE_REMOTE_SHUTDOWN_PRIVILEGE },
341 { "SeUndockPrivilege", SE_UNDOCK_PRIVILEGE },
342 { "SeSyncAgentPrivilege", SE_SYNC_AGENT_PRIVILEGE },
343 { "SeEnableDelegationPrivilege", SE_ENABLE_DELEGATION_PRIVILEGE },
344 { "SeManageVolumePrivilege", SE_MANAGE_VOLUME_PRIVILEGE },
345 { "SeImpersonatePrivilege", SE_IMPERSONATE_PRIVILEGE },
346 { "SeCreateGlobalPrivilege", SE_CREATE_GLOBAL_PRIVILEGE },
348 BOOL (WINAPI *pLookupPrivilegeValueA)(LPCSTR, LPCSTR, PLUID);
353 /* check whether it's available first */
354 pLookupPrivilegeValueA = (void*)GetProcAddress(hmod, "LookupPrivilegeValueA");
355 if (!pLookupPrivilegeValueA) return;
356 ret = pLookupPrivilegeValueA(NULL, "SeCreateTokenPrivilege", &luid);
357 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
360 /* check a bogus system name */
361 ret = pLookupPrivilegeValueA("b0gu5.Nam3", "SeCreateTokenPrivilege", &luid);
362 ok( !ret && GetLastError() == RPC_S_SERVER_UNAVAILABLE,
363 "LookupPrivilegeValueA didn't fail with RPC_S_SERVER_UNAVAILABLE: %ld\n",
365 /* check a NULL string */
366 ret = pLookupPrivilegeValueA(NULL, 0, &luid);
367 ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
368 "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",
370 /* check a bogus privilege name */
371 ret = pLookupPrivilegeValueA(NULL, "SeBogusPrivilege", &luid);
372 ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
373 "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",
375 /* check case insensitive */
376 ret = pLookupPrivilegeValueA(NULL, "sEcREATEtOKENpRIVILEGE", &luid);
378 "LookupPrivilegeValueA(NULL, sEcREATEtOKENpRIVILEGE, &luid) failed: %ld\n",
380 for (i = 0; i < sizeof(privs) / sizeof(privs[0]); i++)
382 /* Not all privileges are implemented on all Windows versions, so
383 * don't worry if the call fails
385 if (pLookupPrivilegeValueA(NULL, privs[i].name, &luid))
387 ok(luid.LowPart == privs[i].lowPart,
388 "LookupPrivilegeValueA returned an invalid LUID for %s\n",
394 static void test_luid(void)
397 test_lookupPrivilegeName();
398 test_lookupPrivilegeValue();