Accelerator resource struct fix for sparc.
[wine] / dlls / advapi32 / tests / security.c
1 /*
2  * Unit tests for security functions
3  *
4  * Copyright (c) 2004 Mike McCormack
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include <stdio.h>
22
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"
29
30 typedef BOOL (WINAPI *fnConvertSidToStringSidA)( PSID pSid, LPSTR *str );
31 typedef BOOL (WINAPI *fnConvertStringSidToSidA)( LPCSTR str, PSID pSid );
32
33 static HMODULE hmod;
34
35 fnConvertSidToStringSidA pConvertSidToStringSidA;
36 fnConvertStringSidToSidA pConvertStringSidToSidA;
37
38 struct sidRef
39 {
40     SID_IDENTIFIER_AUTHORITY auth;
41     const char *refStr;
42 };
43
44 static void init(void)
45 {
46     hmod = GetModuleHandle("advapi32.dll");
47 }
48
49 void test_sid()
50 {
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"        },
58     };
59     const char noSubAuthStr[] = "S-1-5";
60     unsigned int i;
61     PSID psid = NULL;
62     BOOL r;
63     LPSTR str = NULL;
64
65     pConvertSidToStringSidA = (fnConvertSidToStringSidA)
66                     GetProcAddress( hmod, "ConvertSidToStringSidA" );
67     if( !pConvertSidToStringSidA )
68         return;
69     pConvertStringSidToSidA = (fnConvertStringSidToSidA)
70                     GetProcAddress( hmod, "ConvertStringSidToSidA" );
71     if( !pConvertStringSidToSidA )
72         return;
73
74     r = pConvertStringSidToSidA( NULL, NULL );
75     ok( !r, "expected failure with NULL parameters\n" );
76     if( GetLastError() == ERROR_CALL_NOT_IMPLEMENTED )
77         return;
78     ok( GetLastError() == ERROR_INVALID_PARAMETER,
79      "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",
80      GetLastError() );
81
82     r = pConvertStringSidToSidA( refs[0].refStr, NULL );
83     ok( !r && GetLastError() == ERROR_INVALID_PARAMETER,
84      "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",
85      GetLastError() );
86
87     r = pConvertStringSidToSidA( NULL, &str );
88     ok( !r && GetLastError() == ERROR_INVALID_PARAMETER,
89      "expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",
90      GetLastError() );
91
92     r = pConvertStringSidToSidA( noSubAuthStr, &psid );
93     ok( !r,
94      "expected failure with no sub authorities\n" );
95     ok( GetLastError() == ERROR_INVALID_SID,
96      "expected GetLastError() is ERROR_INVALID_SID, got %ld\n",
97      GetLastError() );
98
99     for( i = 0; i < sizeof(refs) / sizeof(refs[0]); i++ )
100     {
101         PISID pisid;
102
103         r = AllocateAndInitializeSid( &refs[i].auth, 1,1,0,0,0,0,0,0,0,
104          &psid );
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 );
110         if( str )
111             LocalFree( str );
112         if( psid )
113             FreeSid( psid );
114
115         r = pConvertStringSidToSidA( refs[i].refStr, &psid );
116         ok( r, "failed to parse sid string\n" );
117         pisid = (PISID)psid;
118         ok( pisid &&
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",
123          refs[i].refStr,
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] ) ) );
133         if( psid )
134             LocalFree( psid );
135     }
136 }
137
138 void test_trustee()
139 {
140     TRUSTEE trustee;
141     PSID psid;
142     LPSTR str = "2jjj";
143
144     SID_IDENTIFIER_AUTHORITY auth = { {0x11,0x22,0,0,0, 0} };
145
146     if ( ! AllocateAndInitializeSid( &auth, 1, 42, 0,0,0,0,0,0,0,&psid ) )
147     {
148         trace( "failed to init SID\n" );
149        return;
150     }
151
152     memset( &trustee, 0xff, sizeof trustee );
153     BuildTrusteeWithSidA( &trustee, psid );
154
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" );
161     FreeSid( psid );
162
163     /* test BuildTrusteeWithNameA */
164     memset( &trustee, 0xff, sizeof trustee );
165     BuildTrusteeWithNameA( &trustee, str );
166
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" );
173 }
174  
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 */
209
210 static void test_allocateLuid(void)
211 {
212     BOOL (WINAPI *pAllocateLocallyUniqueId)(PLUID);
213     LUID luid1, luid2;
214     BOOL ret;
215
216     pAllocateLocallyUniqueId = GetProcAddress(hmod, "AllocateLocallyUniqueId");
217     if (!pAllocateLocallyUniqueId) return;
218
219     ret = pAllocateLocallyUniqueId(&luid1);
220     if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
221         return;
222
223     ok(ret,
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",
233      GetLastError());
234 }
235
236 static void test_lookupPrivilegeName(void)
237 {
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 };
242     LONG i;
243     BOOL ret;
244
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)
251         return;
252
253     /* check with a short buffer */
254     cchName = 0;
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",
259      GetLastError());
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++)
273     {
274         luid.LowPart = i;
275         cchName = sizeof(buf);
276         ok(pLookupPrivilegeNameA(NULL, &luid, buf, &cchName),
277          "LookupPrivilegeNameA(0.%ld) failed: %ld\n", i, GetLastError());
278     }
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",
285      GetLastError());
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",
292      GetLastError());
293 }
294
295 struct NameToLUID
296 {
297     const char *name;
298     LONG lowPart;
299 };
300
301 static void test_lookupPrivilegeValue(void)
302 {
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 },
333     };
334     BOOL (WINAPI *pLookupPrivilegeValueA)(LPCSTR, LPCSTR, PLUID);
335     int i;
336     LUID luid;
337     BOOL ret;
338
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)
344         return;
345
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",
350      GetLastError());
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",
355      GetLastError());
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",
360      GetLastError());
361     /* check case insensitive */
362     ok(pLookupPrivilegeValueA(NULL, "sEcREATEtOKENpRIVILEGE", &luid),
363      "LookupPrivilegeValueA(NULL, sEcREATEtOKENpRIVILEGE, &luid) failed: %ld\n",
364      GetLastError());
365     for (i = 0; i < sizeof(privs) / sizeof(privs[0]); i++)
366     {
367         /* Not all privileges are implemented on all Windows versions, so
368          * don't worry if the call fails
369          */
370         if (pLookupPrivilegeValueA(NULL, privs[i].name, &luid))
371         {
372             ok(luid.LowPart == privs[i].lowPart,
373              "LookupPrivilegeValueA returned an invalid LUID for %s\n",
374              privs[i].name);
375         }
376     }
377 }
378
379 static void test_luid(void)
380 {
381     test_allocateLuid();
382     test_lookupPrivilegeName();
383     test_lookupPrivilegeValue();
384 }
385
386 START_TEST(security)
387 {
388     init();
389     if (!hmod) return;
390     test_sid();
391     test_trustee();
392     test_luid();
393 }