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 *fnConvertSidToStringSidA)( PSID pSid, LPSTR *str );
31 typedef BOOL (WINAPI *fnConvertStringSidToSidA)( LPCSTR str, PSID pSid );
35 fnConvertSidToStringSidA pConvertSidToStringSidA;
36 fnConvertStringSidToSidA pConvertStringSidToSidA;
40 SID_IDENTIFIER_AUTHORITY auth;
44 static void init(void)
46 hmod = GetModuleHandle("advapi32.dll");
51 struct sidRef refs[] = {
52 { { {0x00,0x00,0x33,0x44,0x55,0x66} }, "S-1-860116326-1" },
53 { { {0x00,0x00,0x01,0x02,0x03,0x04} }, "S-1-16909060-1" },
54 { { {0x00,0x00,0x00,0x01,0x02,0x03} }, "S-1-66051-1" },
55 { { {0x00,0x00,0x00,0x00,0x01,0x02} }, "S-1-258-1" },
56 { { {0x00,0x00,0x00,0x00,0x00,0x02} }, "S-1-2-1" },
57 { { {0x00,0x00,0x00,0x00,0x00,0x0c} }, "S-1-12-1" },
59 const char noSubAuthStr[] = "S-1-5";
65 pConvertSidToStringSidA = (fnConvertSidToStringSidA)
66 GetProcAddress( hmod, "ConvertSidToStringSidA" );
67 if( !pConvertSidToStringSidA )
69 pConvertStringSidToSidA = (fnConvertStringSidToSidA)
70 GetProcAddress( hmod, "ConvertStringSidToSidA" );
71 if( !pConvertStringSidToSidA )
74 r = pConvertStringSidToSidA( NULL, NULL );
75 ok( !r, "expected failure with NULL parameters\n" );
76 if( GetLastError() == ERROR_CALL_NOT_IMPLEMENTED )
78 ok( GetLastError() == ERROR_INVALID_PARAMETER,
79 "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",
82 r = pConvertStringSidToSidA( refs[0].refStr, NULL );
83 ok( !r && GetLastError() == ERROR_INVALID_PARAMETER,
84 "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",
87 r = pConvertStringSidToSidA( NULL, &str );
88 ok( !r && GetLastError() == ERROR_INVALID_PARAMETER,
89 "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",
92 r = pConvertStringSidToSidA( noSubAuthStr, &psid );
94 "expected failure with no sub authorities\n" );
95 ok( GetLastError() == ERROR_INVALID_SID,
96 "expected GetLastError() is ERROR_INVALID_SID, got %ld\n",
99 for( i = 0; i < sizeof(refs) / sizeof(refs[0]); i++ )
103 r = AllocateAndInitializeSid( &refs[i].auth, 1,1,0,0,0,0,0,0,0,
105 ok( r, "failed to allocate sid\n" );
106 r = pConvertSidToStringSidA( psid, &str );
107 ok( r, "failed to convert sid\n" );
108 ok( !strcmp( str, refs[i].refStr ),
109 "incorrect sid, expected %s, got %s\n", refs[i].refStr, str );
115 r = pConvertStringSidToSidA( refs[i].refStr, &psid );
116 ok( r, "failed to parse sid string\n" );
119 !memcmp( pisid->IdentifierAuthority.Value, refs[i].auth.Value,
120 sizeof(refs[i].auth) ),
121 "string sid %s didn't parse to expected value\n"
122 "(got 0x%04x%08lx, expected 0x%04x%08lx)\n",
124 MAKEWORD( pisid->IdentifierAuthority.Value[1],
125 pisid->IdentifierAuthority.Value[0] ),
126 MAKELONG( MAKEWORD( pisid->IdentifierAuthority.Value[5],
127 pisid->IdentifierAuthority.Value[4] ),
128 MAKEWORD( pisid->IdentifierAuthority.Value[3],
129 pisid->IdentifierAuthority.Value[2] ) ),
130 MAKEWORD( refs[i].auth.Value[1], refs[i].auth.Value[0] ),
131 MAKELONG( MAKEWORD( refs[i].auth.Value[5], refs[i].auth.Value[4] ),
132 MAKEWORD( refs[i].auth.Value[3], refs[i].auth.Value[2] ) ) );
144 SID_IDENTIFIER_AUTHORITY auth = { {0x11,0x22,0,0,0, 0} };
146 if ( ! AllocateAndInitializeSid( &auth, 1, 42, 0,0,0,0,0,0,0,&psid ) )
148 trace( "failed to init SID\n" );
152 memset( &trustee, 0xff, sizeof trustee );
153 BuildTrusteeWithSidA( &trustee, psid );
155 ok( trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
156 ok( trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE,
157 "MultipleTrusteeOperation wrong\n");
158 ok( trustee.TrusteeForm == TRUSTEE_IS_SID, "TrusteeForm wrong\n");
159 ok( trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
160 ok( trustee.ptstrName == (LPSTR) psid, "ptstrName wrong\n" );
163 /* test BuildTrusteeWithNameA */
164 memset( &trustee, 0xff, sizeof trustee );
165 BuildTrusteeWithNameA( &trustee, str );
167 ok( trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
168 ok( trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE,
169 "MultipleTrusteeOperation wrong\n");
170 ok( trustee.TrusteeForm == TRUSTEE_IS_NAME, "TrusteeForm wrong\n");
171 ok( trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
172 ok( trustee.ptstrName == str, "ptstrName wrong\n" );
175 /* If the first isn't defined, assume none is */
176 #ifndef SE_MIN_WELL_KNOWN_PRIVILEGE
177 #define SE_MIN_WELL_KNOWN_PRIVILEGE 2L
178 #define SE_CREATE_TOKEN_PRIVILEGE 2L
179 #define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE 3L
180 #define SE_LOCK_MEMORY_PRIVILEGE 4L
181 #define SE_INCREASE_QUOTA_PRIVILEGE 5L
182 #define SE_MACHINE_ACCOUNT_PRIVILEGE 6L
183 #define SE_TCB_PRIVILEGE 7L
184 #define SE_SECURITY_PRIVILEGE 8L
185 #define SE_TAKE_OWNERSHIP_PRIVILEGE 9L
186 #define SE_LOAD_DRIVER_PRIVILEGE 10L
187 #define SE_SYSTEM_PROFILE_PRIVILEGE 11L
188 #define SE_SYSTEMTIME_PRIVILEGE 12L
189 #define SE_PROF_SINGLE_PROCESS_PRIVILEGE 13L
190 #define SE_INC_BASE_PRIORITY_PRIVILEGE 14L
191 #define SE_CREATE_PAGEFILE_PRIVILEGE 15L
192 #define SE_CREATE_PERMANENT_PRIVILEGE 16L
193 #define SE_BACKUP_PRIVILEGE 17L
194 #define SE_RESTORE_PRIVILEGE 18L
195 #define SE_SHUTDOWN_PRIVILEGE 19L
196 #define SE_DEBUG_PRIVILEGE 20L
197 #define SE_AUDIT_PRIVILEGE 21L
198 #define SE_SYSTEM_ENVIRONMENT_PRIVILEGE 22L
199 #define SE_CHANGE_NOTIFY_PRIVILLEGE 23L
200 #define SE_REMOTE_SHUTDOWN_PRIVILEGE 24L
201 #define SE_UNDOCK_PRIVILEGE 25L
202 #define SE_SYNC_AGENT_PRIVILEGE 26L
203 #define SE_ENABLE_DELEGATION_PRIVILEGE 27L
204 #define SE_MANAGE_VOLUME_PRIVILEGE 28L
205 #define SE_IMPERSONATE_PRIVILEGE 29L
206 #define SE_CREATE_GLOBAL_PRIVILEGE 30L
207 #define SE_MAX_WELL_KNOWN_PRIVILEGE SE_CREATE_GLOBAL_PRIVILEGE
208 #endif /* ndef SE_MIN_WELL_KNOWN_PRIVILEGE */
210 static void test_allocateLuid(void)
212 BOOL (WINAPI *pAllocateLocallyUniqueId)(PLUID);
216 pAllocateLocallyUniqueId = GetProcAddress(hmod, "AllocateLocallyUniqueId");
217 if (!pAllocateLocallyUniqueId) return;
219 ret = pAllocateLocallyUniqueId(&luid1);
220 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
224 "AllocateLocallyUniqueId failed: %ld\n", GetLastError());
225 ok(pAllocateLocallyUniqueId(&luid2),
226 "AllocateLocallyUniqueId failed: %ld\n", GetLastError());
227 ok(luid1.LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE || luid1.HighPart != 0,
228 "AllocateLocallyUniqueId returned a well-known LUID\n");
229 ok(luid1.LowPart != luid2.LowPart || luid1.HighPart != luid2.HighPart,
230 "AllocateLocallyUniqueId returned non-unique LUIDs\n");
231 ok(!pAllocateLocallyUniqueId(NULL) && GetLastError() == ERROR_NOACCESS,
232 "AllocateLocallyUniqueId(NULL) didn't return ERROR_NOACCESS: %ld\n",
236 static void test_lookupPrivilegeName(void)
238 BOOL (WINAPI *pLookupPrivilegeNameA)(LPSTR, PLUID, LPSTR, LPDWORD);
239 char buf[MAX_PATH]; /* arbitrary, seems long enough */
240 DWORD cchName = sizeof(buf);
241 LUID luid = { 0, 0 };
245 /* check whether it's available first */
246 pLookupPrivilegeNameA = GetProcAddress(hmod, "LookupPrivilegeNameA");
247 if (!pLookupPrivilegeNameA) return;
248 luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
249 ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);
250 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
253 /* check with a short buffer */
255 luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
256 ok(!pLookupPrivilegeNameA(NULL, &luid, NULL, &cchName) &&
257 GetLastError() == ERROR_INSUFFICIENT_BUFFER,
258 "LookupPrivilegeNameA didn't fail with ERROR_INSUFFICIENT_BUFFER: %ld\n",
260 ok(cchName == strlen("SeCreateTokenPrivilege") + 1,
261 "LookupPrivilegeNameA returned an incorrect required length for\n"
262 "SeCreateTokenPrivilege (got %ld, expected %d)\n", cchName,
263 strlen("SeCreateTokenPrivilege") + 1);
264 /* check a known value and its returned length on success */
265 cchName = sizeof(buf);
266 ok(pLookupPrivilegeNameA(NULL, &luid, buf, &cchName) &&
267 cchName == strlen("SeCreateTokenPrivilege"),
268 "LookupPrivilegeNameA returned an incorrect output length for\n"
269 "SeCreateTokenPrivilege (got %ld, expected %d)\n", cchName,
270 strlen("SeCreateTokenPrivilege"));
271 /* check known values */
272 for (i = SE_MIN_WELL_KNOWN_PRIVILEGE; i < SE_MAX_WELL_KNOWN_PRIVILEGE; i++)
275 cchName = sizeof(buf);
276 ok(pLookupPrivilegeNameA(NULL, &luid, buf, &cchName),
277 "LookupPrivilegeNameA(0.%ld) failed: %ld\n", i, GetLastError());
279 /* check a bogus LUID */
280 luid.LowPart = 0xdeadbeef;
281 cchName = sizeof(buf);
282 ok(!pLookupPrivilegeNameA(NULL, &luid, buf, &cchName) &&
283 GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
284 "LookupPrivilegeNameA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",
286 /* check on a bogus system */
287 luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
288 cchName = sizeof(buf);
289 ok(!pLookupPrivilegeNameA("b0gu5.Nam3", &luid, buf, &cchName) &&
290 GetLastError() == RPC_S_SERVER_UNAVAILABLE,
291 "LookupPrivilegeNameA didn't fail with RPC_S_SERVER_UNAVAILABLE: %ld\n",
301 static void test_lookupPrivilegeValue(void)
303 static const struct NameToLUID privs[] = {
304 { "SeCreateTokenPrivilege", SE_CREATE_TOKEN_PRIVILEGE },
305 { "SeAssignPrimaryTokenPrivilege", SE_ASSIGNPRIMARYTOKEN_PRIVILEGE },
306 { "SeLockMemoryPrivilege", SE_LOCK_MEMORY_PRIVILEGE },
307 { "SeIncreaseQuotaPrivilege", SE_INCREASE_QUOTA_PRIVILEGE },
308 { "SeMachineAccountPrivilege", SE_MACHINE_ACCOUNT_PRIVILEGE },
309 { "SeTcbPrivilege", SE_TCB_PRIVILEGE },
310 { "SeSecurityPrivilege", SE_SECURITY_PRIVILEGE },
311 { "SeTakeOwnershipPrivilege", SE_TAKE_OWNERSHIP_PRIVILEGE },
312 { "SeLoadDriverPrivilege", SE_LOAD_DRIVER_PRIVILEGE },
313 { "SeSystemProfilePrivilege", SE_SYSTEM_PROFILE_PRIVILEGE },
314 { "SeSystemtimePrivilege", SE_SYSTEMTIME_PRIVILEGE },
315 { "SeProfileSingleProcessPrivilege", SE_PROF_SINGLE_PROCESS_PRIVILEGE },
316 { "SeIncreaseBasePriorityPrivilege", SE_INC_BASE_PRIORITY_PRIVILEGE },
317 { "SeCreatePagefilePrivilege", SE_CREATE_PAGEFILE_PRIVILEGE },
318 { "SeCreatePermanentPrivilege", SE_CREATE_PERMANENT_PRIVILEGE },
319 { "SeBackupPrivilege", SE_BACKUP_PRIVILEGE },
320 { "SeRestorePrivilege", SE_RESTORE_PRIVILEGE },
321 { "SeShutdownPrivilege", SE_SHUTDOWN_PRIVILEGE },
322 { "SeDebugPrivilege", SE_DEBUG_PRIVILEGE },
323 { "SeAuditPrivilege", SE_AUDIT_PRIVILEGE },
324 { "SeSystemEnvironmentPrivilege", SE_SYSTEM_ENVIRONMENT_PRIVILEGE },
325 { "SeChangeNotifyPrivilege", SE_CHANGE_NOTIFY_PRIVILLEGE },
326 { "SeRemoteShutdownPrivilege", SE_REMOTE_SHUTDOWN_PRIVILEGE },
327 { "SeUndockPrivilege", SE_UNDOCK_PRIVILEGE },
328 { "SeSyncAgentPrivilege", SE_SYNC_AGENT_PRIVILEGE },
329 { "SeEnableDelegationPrivilege", SE_ENABLE_DELEGATION_PRIVILEGE },
330 { "SeManageVolumePrivilege", SE_MANAGE_VOLUME_PRIVILEGE },
331 { "SeImpersonatePrivilege", SE_IMPERSONATE_PRIVILEGE },
332 { "SeCreateGlobalPrivilege", SE_CREATE_GLOBAL_PRIVILEGE },
334 BOOL (WINAPI *pLookupPrivilegeValueA)(LPCSTR, LPCSTR, PLUID);
339 /* check whether it's available first */
340 pLookupPrivilegeValueA = GetProcAddress(hmod, "LookupPrivilegeValueA");
341 if (!pLookupPrivilegeValueA) return;
342 ret = pLookupPrivilegeValueA(NULL, "SeCreateTokenPrivilege", &luid);
343 if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
346 /* check a bogus system name */
347 ok(!pLookupPrivilegeValueA("b0gu5.Nam3", "SeCreateTokenPrivilege", &luid)
348 && GetLastError() == RPC_S_SERVER_UNAVAILABLE,
349 "LookupPrivilegeValueA didn't fail with RPC_S_SERVER_UNAVAILABLE: %ld\n",
351 /* check a NULL string */
352 ok(!pLookupPrivilegeValueA(NULL, 0, &luid) &&
353 GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
354 "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",
356 /* check a bogus privilege name */
357 ok(!pLookupPrivilegeValueA(NULL, "SeBogusPrivilege", &luid) &&
358 GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
359 "LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",
361 /* check case insensitive */
362 ok(pLookupPrivilegeValueA(NULL, "sEcREATEtOKENpRIVILEGE", &luid),
363 "LookupPrivilegeValueA(NULL, sEcREATEtOKENpRIVILEGE, &luid) failed: %ld\n",
365 for (i = 0; i < sizeof(privs) / sizeof(privs[0]); i++)
367 /* Not all privileges are implemented on all Windows versions, so
368 * don't worry if the call fails
370 if (pLookupPrivilegeValueA(NULL, privs[i].name, &luid))
372 ok(luid.LowPart == privs[i].lowPart,
373 "LookupPrivilegeValueA returned an invalid LUID for %s\n",
379 static void test_luid(void)
382 test_lookupPrivilegeName();
383 test_lookupPrivilegeValue();