Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/advapi32/tests/security.c
4389 views
1
/*
2
* Unit tests for security functions
3
*
4
* Copyright (c) 2004 Mike McCormack
5
* Copyright (c) 2011 Dmitry Timoshkov
6
*
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20
*/
21
22
#include <stdarg.h>
23
#include <stdio.h>
24
25
#include "ntstatus.h"
26
#define WIN32_NO_STATUS
27
#include "windef.h"
28
#include "winbase.h"
29
#include "winerror.h"
30
#include "winternl.h"
31
#include "aclapi.h"
32
#include "winnt.h"
33
#include "sddl.h"
34
#include "ntsecapi.h"
35
#include "lmcons.h"
36
37
#include "wine/test.h"
38
39
#ifndef PROCESS_QUERY_LIMITED_INFORMATION
40
#define PROCESS_QUERY_LIMITED_INFORMATION 0x1000
41
#endif
42
43
/* PROCESS_ALL_ACCESS in Vista+ PSDKs is incompatible with older Windows versions */
44
#define PROCESS_ALL_ACCESS_NT4 (PROCESS_ALL_ACCESS & ~0xf000)
45
#define PROCESS_ALL_ACCESS_VISTA (PROCESS_ALL_ACCESS | 0xf000)
46
47
#ifndef EVENT_QUERY_STATE
48
#define EVENT_QUERY_STATE 0x0001
49
#endif
50
51
#ifndef SEMAPHORE_QUERY_STATE
52
#define SEMAPHORE_QUERY_STATE 0x0001
53
#endif
54
55
#ifndef THREAD_SET_LIMITED_INFORMATION
56
#define THREAD_SET_LIMITED_INFORMATION 0x0400
57
#define THREAD_QUERY_LIMITED_INFORMATION 0x0800
58
#endif
59
60
#define THREAD_ALL_ACCESS_NT4 (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff)
61
#define THREAD_ALL_ACCESS_VISTA (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xffff)
62
63
#define expect_eq(expr, value, type, format) { type ret_ = expr; ok((value) == ret_, #expr " expected " format " got " format "\n", (value), (ret_)); }
64
65
static BOOL (WINAPI *pAddMandatoryAce)(PACL,DWORD,DWORD,DWORD,PSID);
66
static VOID (WINAPI *pBuildTrusteeWithSidA)( PTRUSTEEA pTrustee, PSID pSid );
67
static VOID (WINAPI *pBuildTrusteeWithNameA)( PTRUSTEEA pTrustee, LPSTR pName );
68
static VOID (WINAPI *pBuildTrusteeWithObjectsAndNameA)( PTRUSTEEA pTrustee,
69
POBJECTS_AND_NAME_A pObjName,
70
SE_OBJECT_TYPE ObjectType,
71
LPSTR ObjectTypeName,
72
LPSTR InheritedObjectTypeName,
73
LPSTR Name );
74
static VOID (WINAPI *pBuildTrusteeWithObjectsAndSidA)( PTRUSTEEA pTrustee,
75
POBJECTS_AND_SID pObjSid,
76
GUID* pObjectGuid,
77
GUID* pInheritedObjectGuid,
78
PSID pSid );
79
static LPSTR (WINAPI *pGetTrusteeNameA)( PTRUSTEEA pTrustee );
80
static DWORD (WINAPI *pRtlAdjustPrivilege)(ULONG,BOOLEAN,BOOLEAN,PBOOLEAN);
81
static NTSTATUS (WINAPI *pNtAccessCheck)(PSECURITY_DESCRIPTOR, HANDLE, ACCESS_MASK, PGENERIC_MAPPING,
82
PPRIVILEGE_SET, PULONG, PULONG, NTSTATUS*);
83
static BOOL (WINAPI *pRtlDosPathNameToNtPathName_U)(LPCWSTR,PUNICODE_STRING,PWSTR*,CURDIR*);
84
85
static HMODULE hmod;
86
static int myARGC;
87
static char** myARGV;
88
89
static const char* debugstr_sid(PSID sid)
90
{
91
LPSTR sidstr;
92
DWORD le = GetLastError();
93
const char *res;
94
95
if (!ConvertSidToStringSidA(sid, &sidstr))
96
res = wine_dbg_sprintf("ConvertSidToStringSidA failed le=%lu", GetLastError());
97
else
98
{
99
res = __wine_dbg_strdup(sidstr);
100
LocalFree(sidstr);
101
}
102
/* Restore the last error in case ConvertSidToStringSidA() modified it */
103
SetLastError(le);
104
return res;
105
}
106
107
struct sidRef
108
{
109
SID_IDENTIFIER_AUTHORITY auth;
110
const char *refStr;
111
};
112
113
static void init(void)
114
{
115
HMODULE hntdll;
116
117
hntdll = GetModuleHandleA("ntdll.dll");
118
pNtAccessCheck = (void *)GetProcAddress( hntdll, "NtAccessCheck" );
119
pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(hntdll, "RtlDosPathNameToNtPathName_U");
120
121
hmod = GetModuleHandleA("advapi32.dll");
122
pAddMandatoryAce = (void *)GetProcAddress(hmod, "AddMandatoryAce");
123
124
myARGC = winetest_get_mainargs( &myARGV );
125
}
126
127
static SECURITY_DESCRIPTOR* test_get_security_descriptor(HANDLE handle, int line)
128
{
129
/* use free(sd); when done */
130
DWORD ret, length, needed;
131
SECURITY_DESCRIPTOR *sd;
132
133
needed = 0xdeadbeef;
134
SetLastError(0xdeadbeef);
135
ret = GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
136
NULL, 0, &needed);
137
ok_(__FILE__, line)(!ret, "GetKernelObjectSecurity should fail\n");
138
ok_(__FILE__, line)(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
139
ok_(__FILE__, line)(needed != 0xdeadbeef, "GetKernelObjectSecurity should return required buffer length\n");
140
141
length = needed;
142
sd = malloc(length);
143
144
needed = 0xdeadbeef;
145
SetLastError(0xdeadbeef);
146
ret = GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
147
sd, length, &needed);
148
ok_(__FILE__, line)(ret, "GetKernelObjectSecurity error %ld\n", GetLastError());
149
ok_(__FILE__, line)(needed == length || needed == 0 /* file, pipe */, "GetKernelObjectSecurity should return %lu instead of %lu\n", length, needed);
150
return sd;
151
}
152
153
static void test_owner_equal(HANDLE Handle, PSID expected, int line)
154
{
155
BOOL res;
156
SECURITY_DESCRIPTOR *queriedSD = NULL;
157
PSID owner;
158
BOOL owner_defaulted;
159
160
queriedSD = test_get_security_descriptor( Handle, line );
161
162
res = GetSecurityDescriptorOwner(queriedSD, &owner, &owner_defaulted);
163
ok_(__FILE__, line)(res, "GetSecurityDescriptorOwner failed with error %ld\n", GetLastError());
164
165
ok_(__FILE__, line)(EqualSid(owner, expected), "Owner SIDs are not equal %s != %s\n",
166
debugstr_sid(owner), debugstr_sid(expected));
167
ok_(__FILE__, line)(!owner_defaulted, "Defaulted is true\n");
168
169
free(queriedSD);
170
}
171
172
static void test_group_equal(HANDLE Handle, PSID expected, int line)
173
{
174
BOOL res;
175
SECURITY_DESCRIPTOR *queriedSD = NULL;
176
PSID group;
177
BOOL group_defaulted;
178
179
queriedSD = test_get_security_descriptor( Handle, line );
180
181
res = GetSecurityDescriptorGroup(queriedSD, &group, &group_defaulted);
182
ok_(__FILE__, line)(res, "GetSecurityDescriptorGroup failed with error %ld\n", GetLastError());
183
184
ok_(__FILE__, line)(EqualSid(group, expected), "Group SIDs are not equal %s != %s\n",
185
debugstr_sid(group), debugstr_sid(expected));
186
ok_(__FILE__, line)(!group_defaulted, "Defaulted is true\n");
187
188
free(queriedSD);
189
}
190
191
static void test_ConvertStringSidToSid(void)
192
{
193
struct sidRef refs[] = {
194
{ { {0x00,0x00,0x33,0x44,0x55,0x66} }, "S-1-860116326-1" },
195
{ { {0x00,0x00,0x01,0x02,0x03,0x04} }, "S-1-16909060-1" },
196
{ { {0x00,0x00,0x00,0x01,0x02,0x03} }, "S-1-66051-1" },
197
{ { {0x00,0x00,0x00,0x00,0x01,0x02} }, "S-1-258-1" },
198
{ { {0x00,0x00,0x00,0x00,0x00,0x02} }, "S-1-2-1" },
199
{ { {0x00,0x00,0x00,0x00,0x00,0x0c} }, "S-1-12-1" },
200
};
201
static const struct
202
{
203
const char *name;
204
const char *sid;
205
unsigned int optional;
206
}
207
str_to_sid_tests[] =
208
{
209
{ "WD", "S-1-1-0" },
210
{ "wD", "S-1-1-0" },
211
{ "CO", "S-1-3-0" },
212
{ "CG", "S-1-3-1" },
213
{ "OW", "S-1-3-4", 1 }, /* Vista+ */
214
{ "NU", "S-1-5-2" },
215
{ "IU", "S-1-5-4" },
216
{ "SU", "S-1-5-6" },
217
{ "AN", "S-1-5-7" },
218
{ "ED", "S-1-5-9" },
219
{ "PS", "S-1-5-10" },
220
{ "AU", "S-1-5-11" },
221
{ "RC", "S-1-5-12" },
222
{ "SY", "S-1-5-18" },
223
{ "LS", "S-1-5-19" },
224
{ "NS", "S-1-5-20" },
225
{ "LA", "S-1-5-21-*-*-*-500" },
226
{ "LG", "S-1-5-21-*-*-*-501" },
227
{ "BO", "S-1-5-32-551" },
228
{ "BA", "S-1-5-32-544" },
229
{ "BU", "S-1-5-32-545" },
230
{ "BG", "S-1-5-32-546" },
231
{ "PU", "S-1-5-32-547" },
232
{ "AO", "S-1-5-32-548" },
233
{ "SO", "S-1-5-32-549" },
234
{ "PO", "S-1-5-32-550" },
235
{ "RE", "S-1-5-32-552" },
236
{ "RU", "S-1-5-32-554" },
237
{ "RD", "S-1-5-32-555" },
238
{ "NO", "S-1-5-32-556" },
239
{ "AC", "S-1-15-2-1", 1 }, /* Win8+ */
240
{ "CA", "", 1 },
241
{ "DA", "", 1 },
242
{ "DC", "", 1 },
243
{ "DD", "", 1 },
244
{ "DG", "", 1 },
245
{ "DU", "", 1 },
246
{ "EA", "", 1 },
247
{ "PA", "", 1 },
248
{ "RS", "", 1 },
249
{ "SA", "", 1 },
250
{ "s-1-12-1", "S-1-12-1" },
251
{ "S-0x1-0XC-0x1a", "S-1-12-26" },
252
};
253
254
const char noSubAuthStr[] = "S-1-5";
255
unsigned int i;
256
PSID psid = NULL;
257
SID *pisid;
258
BOOL r, ret;
259
LPSTR str = NULL;
260
261
r = ConvertStringSidToSidA( NULL, NULL );
262
ok( !r, "expected failure with NULL parameters\n" );
263
if( GetLastError() == ERROR_CALL_NOT_IMPLEMENTED )
264
return;
265
ok( GetLastError() == ERROR_INVALID_PARAMETER,
266
"expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",
267
GetLastError() );
268
269
r = ConvertStringSidToSidA( refs[0].refStr, NULL );
270
ok( !r && GetLastError() == ERROR_INVALID_PARAMETER,
271
"expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",
272
GetLastError() );
273
274
r = ConvertStringSidToSidA( NULL, &psid );
275
ok( !r && GetLastError() == ERROR_INVALID_PARAMETER,
276
"expected GetLastError() is ERROR_INVALID_PARAMETER, got %ld\n",
277
GetLastError() );
278
279
r = ConvertStringSidToSidA( noSubAuthStr, &psid );
280
ok( !r,
281
"expected failure with no sub authorities\n" );
282
ok( GetLastError() == ERROR_INVALID_SID,
283
"expected GetLastError() is ERROR_INVALID_SID, got %ld\n",
284
GetLastError() );
285
286
r = ConvertStringSidToSidA( "WDandmorecharacters", &psid );
287
ok( !r,
288
"expected failure with too many characters\n" );
289
ok( GetLastError() == ERROR_INVALID_SID,
290
"expected GetLastError() is ERROR_INVALID_SID, got %ld\n",
291
GetLastError() );
292
293
r = ConvertStringSidToSidA( "WD)", &psid );
294
ok( !r,
295
"expected failure with too many characters\n" );
296
ok( GetLastError() == ERROR_INVALID_SID,
297
"expected GetLastError() is ERROR_INVALID_SID, got %ld\n",
298
GetLastError() );
299
300
ok(ConvertStringSidToSidA("S-1-5-21-93476-23408-4576", &psid), "ConvertStringSidToSidA failed\n");
301
pisid = psid;
302
ok(pisid->SubAuthorityCount == 4, "Invalid sub authority count - expected 4, got %d\n", pisid->SubAuthorityCount);
303
ok(pisid->SubAuthority[0] == 21, "Invalid subauthority 0 - expected 21, got %ld\n", pisid->SubAuthority[0]);
304
ok(pisid->SubAuthority[3] == 4576, "Invalid subauthority 0 - expected 4576, got %ld\n", pisid->SubAuthority[3]);
305
LocalFree(str);
306
LocalFree(psid);
307
308
for( i = 0; i < ARRAY_SIZE(refs); i++ )
309
{
310
r = AllocateAndInitializeSid( &refs[i].auth, 1,1,0,0,0,0,0,0,0,
311
&psid );
312
ok( r, "failed to allocate sid\n" );
313
r = ConvertSidToStringSidA( psid, &str );
314
ok( r, "failed to convert sid\n" );
315
if (r)
316
{
317
ok( !strcmp( str, refs[i].refStr ),
318
"incorrect sid, expected %s, got %s\n", refs[i].refStr, str );
319
LocalFree( str );
320
}
321
if( psid )
322
FreeSid( psid );
323
324
r = ConvertStringSidToSidA( refs[i].refStr, &psid );
325
ok( r, "failed to parse sid string\n" );
326
pisid = psid;
327
ok( pisid &&
328
!memcmp( pisid->IdentifierAuthority.Value, refs[i].auth.Value,
329
sizeof(refs[i].auth) ),
330
"string sid %s didn't parse to expected value\n"
331
"(got 0x%04x%08lx, expected 0x%04x%08lx)\n",
332
refs[i].refStr,
333
MAKEWORD( pisid->IdentifierAuthority.Value[1],
334
pisid->IdentifierAuthority.Value[0] ),
335
MAKELONG( MAKEWORD( pisid->IdentifierAuthority.Value[5],
336
pisid->IdentifierAuthority.Value[4] ),
337
MAKEWORD( pisid->IdentifierAuthority.Value[3],
338
pisid->IdentifierAuthority.Value[2] ) ),
339
MAKEWORD( refs[i].auth.Value[1], refs[i].auth.Value[0] ),
340
MAKELONG( MAKEWORD( refs[i].auth.Value[5], refs[i].auth.Value[4] ),
341
MAKEWORD( refs[i].auth.Value[3], refs[i].auth.Value[2] ) ) );
342
if( psid )
343
LocalFree( psid );
344
}
345
346
for (i = 0; i < ARRAY_SIZE(str_to_sid_tests); i++)
347
{
348
char *str;
349
350
ret = ConvertStringSidToSidA(str_to_sid_tests[i].name, &psid);
351
if (!ret && str_to_sid_tests[i].optional)
352
{
353
skip("%u: failed to convert %s.\n", i, str_to_sid_tests[i].name);
354
continue;
355
}
356
ok(ret, "%u: failed to convert string to sid.\n", i);
357
358
if (str_to_sid_tests[i].optional || !strcmp(str_to_sid_tests[i].name, "LA") ||
359
!strcmp(str_to_sid_tests[i].name, "LG"))
360
{
361
LocalFree(psid);
362
continue;
363
}
364
365
ret = ConvertSidToStringSidA(psid, &str);
366
ok(ret, "%u: failed to convert SID to string.\n", i);
367
ok(!strcmp(str, str_to_sid_tests[i].sid), "%u: unexpected sid %s.\n", i, str);
368
LocalFree(psid);
369
LocalFree(str);
370
}
371
}
372
373
static void test_trustee(void)
374
{
375
GUID ObjectType = {0x12345678, 0x1234, 0x5678, {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}};
376
GUID InheritedObjectType = {0x23456789, 0x2345, 0x6786, {0x2, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99}};
377
GUID ZeroGuid;
378
OBJECTS_AND_NAME_A oan;
379
OBJECTS_AND_SID oas;
380
TRUSTEEA trustee;
381
PSID psid;
382
char szObjectTypeName[] = "ObjectTypeName";
383
char szInheritedObjectTypeName[] = "InheritedObjectTypeName";
384
char szTrusteeName[] = "szTrusteeName";
385
SID_IDENTIFIER_AUTHORITY auth = { {0x11,0x22,0,0,0, 0} };
386
387
memset( &ZeroGuid, 0x00, sizeof (ZeroGuid) );
388
389
pBuildTrusteeWithSidA = (void *)GetProcAddress( hmod, "BuildTrusteeWithSidA" );
390
pBuildTrusteeWithNameA = (void *)GetProcAddress( hmod, "BuildTrusteeWithNameA" );
391
pBuildTrusteeWithObjectsAndNameA = (void *)GetProcAddress (hmod, "BuildTrusteeWithObjectsAndNameA" );
392
pBuildTrusteeWithObjectsAndSidA = (void *)GetProcAddress (hmod, "BuildTrusteeWithObjectsAndSidA" );
393
pGetTrusteeNameA = (void *)GetProcAddress (hmod, "GetTrusteeNameA" );
394
if( !pBuildTrusteeWithSidA || !pBuildTrusteeWithNameA ||
395
!pBuildTrusteeWithObjectsAndNameA || !pBuildTrusteeWithObjectsAndSidA ||
396
!pGetTrusteeNameA )
397
return;
398
399
if ( ! AllocateAndInitializeSid( &auth, 1, 42, 0,0,0,0,0,0,0,&psid ) )
400
{
401
trace( "failed to init SID\n" );
402
return;
403
}
404
405
/* test BuildTrusteeWithSidA */
406
memset( &trustee, 0xff, sizeof trustee );
407
pBuildTrusteeWithSidA( &trustee, psid );
408
409
ok( trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
410
ok( trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE,
411
"MultipleTrusteeOperation wrong\n");
412
ok( trustee.TrusteeForm == TRUSTEE_IS_SID, "TrusteeForm wrong\n");
413
ok( trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
414
ok( trustee.ptstrName == psid, "ptstrName wrong\n" );
415
416
/* test BuildTrusteeWithObjectsAndSidA (test 1) */
417
memset( &trustee, 0xff, sizeof trustee );
418
memset( &oas, 0xff, sizeof(oas) );
419
pBuildTrusteeWithObjectsAndSidA(&trustee, &oas, &ObjectType,
420
&InheritedObjectType, psid);
421
422
ok(trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
423
ok(trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, "MultipleTrusteeOperation wrong\n");
424
ok(trustee.TrusteeForm == TRUSTEE_IS_OBJECTS_AND_SID, "TrusteeForm wrong\n");
425
ok(trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
426
ok(trustee.ptstrName == (LPSTR)&oas, "ptstrName wrong\n");
427
428
ok(oas.ObjectsPresent == (ACE_OBJECT_TYPE_PRESENT | ACE_INHERITED_OBJECT_TYPE_PRESENT), "ObjectsPresent wrong\n");
429
ok(!memcmp(&oas.ObjectTypeGuid, &ObjectType, sizeof(GUID)), "ObjectTypeGuid wrong\n");
430
ok(!memcmp(&oas.InheritedObjectTypeGuid, &InheritedObjectType, sizeof(GUID)), "InheritedObjectTypeGuid wrong\n");
431
ok(oas.pSid == psid, "pSid wrong\n");
432
433
/* test GetTrusteeNameA */
434
ok(pGetTrusteeNameA(&trustee) == (LPSTR)&oas, "GetTrusteeName returned wrong value\n");
435
436
/* test BuildTrusteeWithObjectsAndSidA (test 2) */
437
memset( &trustee, 0xff, sizeof trustee );
438
memset( &oas, 0xff, sizeof(oas) );
439
pBuildTrusteeWithObjectsAndSidA(&trustee, &oas, NULL,
440
&InheritedObjectType, psid);
441
442
ok(trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
443
ok(trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, "MultipleTrusteeOperation wrong\n");
444
ok(trustee.TrusteeForm == TRUSTEE_IS_OBJECTS_AND_SID, "TrusteeForm wrong\n");
445
ok(trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
446
ok(trustee.ptstrName == (LPSTR)&oas, "ptstrName wrong\n");
447
448
ok(oas.ObjectsPresent == ACE_INHERITED_OBJECT_TYPE_PRESENT, "ObjectsPresent wrong\n");
449
ok(!memcmp(&oas.ObjectTypeGuid, &ZeroGuid, sizeof(GUID)), "ObjectTypeGuid wrong\n");
450
ok(!memcmp(&oas.InheritedObjectTypeGuid, &InheritedObjectType, sizeof(GUID)), "InheritedObjectTypeGuid wrong\n");
451
ok(oas.pSid == psid, "pSid wrong\n");
452
453
FreeSid( psid );
454
455
/* test BuildTrusteeWithNameA */
456
memset( &trustee, 0xff, sizeof trustee );
457
pBuildTrusteeWithNameA( &trustee, szTrusteeName );
458
459
ok( trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
460
ok( trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE,
461
"MultipleTrusteeOperation wrong\n");
462
ok( trustee.TrusteeForm == TRUSTEE_IS_NAME, "TrusteeForm wrong\n");
463
ok( trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
464
ok( trustee.ptstrName == szTrusteeName, "ptstrName wrong\n" );
465
466
/* test BuildTrusteeWithObjectsAndNameA (test 1) */
467
memset( &trustee, 0xff, sizeof trustee );
468
memset( &oan, 0xff, sizeof(oan) );
469
pBuildTrusteeWithObjectsAndNameA(&trustee, &oan, SE_KERNEL_OBJECT, szObjectTypeName,
470
szInheritedObjectTypeName, szTrusteeName);
471
472
ok(trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
473
ok(trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, "MultipleTrusteeOperation wrong\n");
474
ok(trustee.TrusteeForm == TRUSTEE_IS_OBJECTS_AND_NAME, "TrusteeForm wrong\n");
475
ok(trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
476
ok(trustee.ptstrName == (LPSTR)&oan, "ptstrName wrong\n");
477
478
ok(oan.ObjectsPresent == (ACE_OBJECT_TYPE_PRESENT | ACE_INHERITED_OBJECT_TYPE_PRESENT), "ObjectsPresent wrong\n");
479
ok(oan.ObjectType == SE_KERNEL_OBJECT, "ObjectType wrong\n");
480
ok(oan.InheritedObjectTypeName == szInheritedObjectTypeName, "InheritedObjectTypeName wrong\n");
481
ok(oan.ptstrName == szTrusteeName, "szTrusteeName wrong\n");
482
483
/* test GetTrusteeNameA */
484
ok(pGetTrusteeNameA(&trustee) == (LPSTR)&oan, "GetTrusteeName returned wrong value\n");
485
486
/* test BuildTrusteeWithObjectsAndNameA (test 2) */
487
memset( &trustee, 0xff, sizeof trustee );
488
memset( &oan, 0xff, sizeof(oan) );
489
pBuildTrusteeWithObjectsAndNameA(&trustee, &oan, SE_KERNEL_OBJECT, NULL,
490
szInheritedObjectTypeName, szTrusteeName);
491
492
ok(trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
493
ok(trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, "MultipleTrusteeOperation wrong\n");
494
ok(trustee.TrusteeForm == TRUSTEE_IS_OBJECTS_AND_NAME, "TrusteeForm wrong\n");
495
ok(trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
496
ok(trustee.ptstrName == (LPSTR)&oan, "ptstrName wrong\n");
497
498
ok(oan.ObjectsPresent == ACE_INHERITED_OBJECT_TYPE_PRESENT, "ObjectsPresent wrong\n");
499
ok(oan.ObjectType == SE_KERNEL_OBJECT, "ObjectType wrong\n");
500
ok(oan.InheritedObjectTypeName == szInheritedObjectTypeName, "InheritedObjectTypeName wrong\n");
501
ok(oan.ptstrName == szTrusteeName, "szTrusteeName wrong\n");
502
503
/* test BuildTrusteeWithObjectsAndNameA (test 3) */
504
memset( &trustee, 0xff, sizeof trustee );
505
memset( &oan, 0xff, sizeof(oan) );
506
pBuildTrusteeWithObjectsAndNameA(&trustee, &oan, SE_KERNEL_OBJECT, szObjectTypeName,
507
NULL, szTrusteeName);
508
509
ok(trustee.pMultipleTrustee == NULL, "pMultipleTrustee wrong\n");
510
ok(trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE, "MultipleTrusteeOperation wrong\n");
511
ok(trustee.TrusteeForm == TRUSTEE_IS_OBJECTS_AND_NAME, "TrusteeForm wrong\n");
512
ok(trustee.TrusteeType == TRUSTEE_IS_UNKNOWN, "TrusteeType wrong\n");
513
ok(trustee.ptstrName == (LPSTR)&oan, "ptstrName wrong\n");
514
515
ok(oan.ObjectsPresent == ACE_OBJECT_TYPE_PRESENT, "ObjectsPresent wrong\n");
516
ok(oan.ObjectType == SE_KERNEL_OBJECT, "ObjectType wrong\n");
517
ok(oan.InheritedObjectTypeName == NULL, "InheritedObjectTypeName wrong\n");
518
ok(oan.ptstrName == szTrusteeName, "szTrusteeName wrong\n");
519
}
520
521
/* If the first isn't defined, assume none is */
522
#ifndef SE_MIN_WELL_KNOWN_PRIVILEGE
523
#define SE_MIN_WELL_KNOWN_PRIVILEGE 2L
524
#define SE_CREATE_TOKEN_PRIVILEGE 2L
525
#define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE 3L
526
#define SE_LOCK_MEMORY_PRIVILEGE 4L
527
#define SE_INCREASE_QUOTA_PRIVILEGE 5L
528
#define SE_MACHINE_ACCOUNT_PRIVILEGE 6L
529
#define SE_TCB_PRIVILEGE 7L
530
#define SE_SECURITY_PRIVILEGE 8L
531
#define SE_TAKE_OWNERSHIP_PRIVILEGE 9L
532
#define SE_LOAD_DRIVER_PRIVILEGE 10L
533
#define SE_SYSTEM_PROFILE_PRIVILEGE 11L
534
#define SE_SYSTEMTIME_PRIVILEGE 12L
535
#define SE_PROF_SINGLE_PROCESS_PRIVILEGE 13L
536
#define SE_INC_BASE_PRIORITY_PRIVILEGE 14L
537
#define SE_CREATE_PAGEFILE_PRIVILEGE 15L
538
#define SE_CREATE_PERMANENT_PRIVILEGE 16L
539
#define SE_BACKUP_PRIVILEGE 17L
540
#define SE_RESTORE_PRIVILEGE 18L
541
#define SE_SHUTDOWN_PRIVILEGE 19L
542
#define SE_DEBUG_PRIVILEGE 20L
543
#define SE_AUDIT_PRIVILEGE 21L
544
#define SE_SYSTEM_ENVIRONMENT_PRIVILEGE 22L
545
#define SE_CHANGE_NOTIFY_PRIVILEGE 23L
546
#define SE_REMOTE_SHUTDOWN_PRIVILEGE 24L
547
#define SE_UNDOCK_PRIVILEGE 25L
548
#define SE_SYNC_AGENT_PRIVILEGE 26L
549
#define SE_ENABLE_DELEGATION_PRIVILEGE 27L
550
#define SE_MANAGE_VOLUME_PRIVILEGE 28L
551
#define SE_IMPERSONATE_PRIVILEGE 29L
552
#define SE_CREATE_GLOBAL_PRIVILEGE 30L
553
#define SE_MAX_WELL_KNOWN_PRIVILEGE SE_CREATE_GLOBAL_PRIVILEGE
554
#endif /* ndef SE_MIN_WELL_KNOWN_PRIVILEGE */
555
556
static void test_allocateLuid(void)
557
{
558
BOOL (WINAPI *pAllocateLocallyUniqueId)(PLUID);
559
LUID luid1, luid2;
560
BOOL ret;
561
562
pAllocateLocallyUniqueId = (void*)GetProcAddress(hmod, "AllocateLocallyUniqueId");
563
if (!pAllocateLocallyUniqueId) return;
564
565
ret = pAllocateLocallyUniqueId(&luid1);
566
if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
567
return;
568
569
ok(ret,
570
"AllocateLocallyUniqueId failed: %ld\n", GetLastError());
571
ret = pAllocateLocallyUniqueId(&luid2);
572
ok( ret,
573
"AllocateLocallyUniqueId failed: %ld\n", GetLastError());
574
ok(luid1.LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE || luid1.HighPart != 0,
575
"AllocateLocallyUniqueId returned a well-known LUID\n");
576
ok(luid1.LowPart != luid2.LowPart || luid1.HighPart != luid2.HighPart,
577
"AllocateLocallyUniqueId returned non-unique LUIDs\n");
578
ret = pAllocateLocallyUniqueId(NULL);
579
ok( !ret && GetLastError() == ERROR_NOACCESS,
580
"AllocateLocallyUniqueId(NULL) didn't return ERROR_NOACCESS: %ld\n",
581
GetLastError());
582
}
583
584
static void test_lookupPrivilegeName(void)
585
{
586
BOOL (WINAPI *pLookupPrivilegeNameA)(LPCSTR, PLUID, LPSTR, LPDWORD);
587
char buf[MAX_PATH]; /* arbitrary, seems long enough */
588
DWORD cchName = sizeof(buf);
589
LUID luid = { 0, 0 };
590
LONG i;
591
BOOL ret;
592
593
/* check whether it's available first */
594
pLookupPrivilegeNameA = (void*)GetProcAddress(hmod, "LookupPrivilegeNameA");
595
if (!pLookupPrivilegeNameA) return;
596
luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
597
ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);
598
if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
599
return;
600
601
/* check with a short buffer */
602
cchName = 0;
603
luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
604
ret = pLookupPrivilegeNameA(NULL, &luid, NULL, &cchName);
605
ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
606
"LookupPrivilegeNameA didn't fail with ERROR_INSUFFICIENT_BUFFER: %ld\n",
607
GetLastError());
608
ok(cchName == strlen("SeCreateTokenPrivilege") + 1,
609
"LookupPrivilegeNameA returned an incorrect required length for\n"
610
"SeCreateTokenPrivilege (got %ld, expected %d)\n", cchName,
611
lstrlenA("SeCreateTokenPrivilege") + 1);
612
/* check a known value and its returned length on success */
613
cchName = sizeof(buf);
614
ok(pLookupPrivilegeNameA(NULL, &luid, buf, &cchName) &&
615
cchName == strlen("SeCreateTokenPrivilege"),
616
"LookupPrivilegeNameA returned an incorrect output length for\n"
617
"SeCreateTokenPrivilege (got %ld, expected %d)\n", cchName,
618
(int)strlen("SeCreateTokenPrivilege"));
619
/* check known values */
620
for (i = SE_MIN_WELL_KNOWN_PRIVILEGE; i <= SE_MAX_WELL_KNOWN_PRIVILEGE; i++)
621
{
622
luid.LowPart = i;
623
cchName = sizeof(buf);
624
ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);
625
ok( ret || GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
626
"LookupPrivilegeNameA(0.%ld) failed: %ld\n", i, GetLastError());
627
}
628
/* check a bogus LUID */
629
luid.LowPart = 0xdeadbeef;
630
cchName = sizeof(buf);
631
ret = pLookupPrivilegeNameA(NULL, &luid, buf, &cchName);
632
ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
633
"LookupPrivilegeNameA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",
634
GetLastError());
635
/* check on a bogus system */
636
luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE;
637
cchName = sizeof(buf);
638
ret = pLookupPrivilegeNameA("b0gu5.Nam3", &luid, buf, &cchName);
639
ok( !ret && (GetLastError() == RPC_S_SERVER_UNAVAILABLE ||
640
GetLastError() == RPC_S_INVALID_NET_ADDR) /* w2k8 */,
641
"LookupPrivilegeNameA didn't fail with RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR: %ld\n",
642
GetLastError());
643
}
644
645
struct NameToLUID
646
{
647
const char *name;
648
DWORD lowPart;
649
};
650
651
static void test_lookupPrivilegeValue(void)
652
{
653
static const struct NameToLUID privs[] = {
654
{ "SeCreateTokenPrivilege", SE_CREATE_TOKEN_PRIVILEGE },
655
{ "SeAssignPrimaryTokenPrivilege", SE_ASSIGNPRIMARYTOKEN_PRIVILEGE },
656
{ "SeLockMemoryPrivilege", SE_LOCK_MEMORY_PRIVILEGE },
657
{ "SeIncreaseQuotaPrivilege", SE_INCREASE_QUOTA_PRIVILEGE },
658
{ "SeMachineAccountPrivilege", SE_MACHINE_ACCOUNT_PRIVILEGE },
659
{ "SeTcbPrivilege", SE_TCB_PRIVILEGE },
660
{ "SeSecurityPrivilege", SE_SECURITY_PRIVILEGE },
661
{ "SeTakeOwnershipPrivilege", SE_TAKE_OWNERSHIP_PRIVILEGE },
662
{ "SeLoadDriverPrivilege", SE_LOAD_DRIVER_PRIVILEGE },
663
{ "SeSystemProfilePrivilege", SE_SYSTEM_PROFILE_PRIVILEGE },
664
{ "SeSystemtimePrivilege", SE_SYSTEMTIME_PRIVILEGE },
665
{ "SeProfileSingleProcessPrivilege", SE_PROF_SINGLE_PROCESS_PRIVILEGE },
666
{ "SeIncreaseBasePriorityPrivilege", SE_INC_BASE_PRIORITY_PRIVILEGE },
667
{ "SeCreatePagefilePrivilege", SE_CREATE_PAGEFILE_PRIVILEGE },
668
{ "SeCreatePermanentPrivilege", SE_CREATE_PERMANENT_PRIVILEGE },
669
{ "SeBackupPrivilege", SE_BACKUP_PRIVILEGE },
670
{ "SeRestorePrivilege", SE_RESTORE_PRIVILEGE },
671
{ "SeShutdownPrivilege", SE_SHUTDOWN_PRIVILEGE },
672
{ "SeDebugPrivilege", SE_DEBUG_PRIVILEGE },
673
{ "SeAuditPrivilege", SE_AUDIT_PRIVILEGE },
674
{ "SeSystemEnvironmentPrivilege", SE_SYSTEM_ENVIRONMENT_PRIVILEGE },
675
{ "SeChangeNotifyPrivilege", SE_CHANGE_NOTIFY_PRIVILEGE },
676
{ "SeRemoteShutdownPrivilege", SE_REMOTE_SHUTDOWN_PRIVILEGE },
677
{ "SeUndockPrivilege", SE_UNDOCK_PRIVILEGE },
678
{ "SeSyncAgentPrivilege", SE_SYNC_AGENT_PRIVILEGE },
679
{ "SeEnableDelegationPrivilege", SE_ENABLE_DELEGATION_PRIVILEGE },
680
{ "SeManageVolumePrivilege", SE_MANAGE_VOLUME_PRIVILEGE },
681
{ "SeImpersonatePrivilege", SE_IMPERSONATE_PRIVILEGE },
682
{ "SeCreateGlobalPrivilege", SE_CREATE_GLOBAL_PRIVILEGE },
683
};
684
BOOL (WINAPI *pLookupPrivilegeValueA)(LPCSTR, LPCSTR, PLUID);
685
unsigned int i;
686
LUID luid;
687
BOOL ret;
688
689
/* check whether it's available first */
690
pLookupPrivilegeValueA = (void*)GetProcAddress(hmod, "LookupPrivilegeValueA");
691
if (!pLookupPrivilegeValueA) return;
692
ret = pLookupPrivilegeValueA(NULL, "SeCreateTokenPrivilege", &luid);
693
if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
694
return;
695
696
/* check a bogus system name */
697
ret = pLookupPrivilegeValueA("b0gu5.Nam3", "SeCreateTokenPrivilege", &luid);
698
ok( !ret && (GetLastError() == RPC_S_SERVER_UNAVAILABLE ||
699
GetLastError() == RPC_S_INVALID_NET_ADDR) /* w2k8 */,
700
"LookupPrivilegeValueA didn't fail with RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR: %ld\n",
701
GetLastError());
702
/* check a NULL string */
703
ret = pLookupPrivilegeValueA(NULL, 0, &luid);
704
ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
705
"LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",
706
GetLastError());
707
/* check a bogus privilege name */
708
ret = pLookupPrivilegeValueA(NULL, "SeBogusPrivilege", &luid);
709
ok( !ret && GetLastError() == ERROR_NO_SUCH_PRIVILEGE,
710
"LookupPrivilegeValueA didn't fail with ERROR_NO_SUCH_PRIVILEGE: %ld\n",
711
GetLastError());
712
/* check case insensitive */
713
ret = pLookupPrivilegeValueA(NULL, "sEcREATEtOKENpRIVILEGE", &luid);
714
ok( ret,
715
"LookupPrivilegeValueA(NULL, sEcREATEtOKENpRIVILEGE, &luid) failed: %ld\n",
716
GetLastError());
717
for (i = 0; i < ARRAY_SIZE(privs); i++)
718
{
719
/* Not all privileges are implemented on all Windows versions, so
720
* don't worry if the call fails
721
*/
722
if (pLookupPrivilegeValueA(NULL, privs[i].name, &luid))
723
{
724
ok(luid.LowPart == privs[i].lowPart,
725
"LookupPrivilegeValueA returned an invalid LUID for %s\n",
726
privs[i].name);
727
}
728
}
729
}
730
731
static void test_FileSecurity(void)
732
{
733
char wintmpdir [MAX_PATH];
734
char path [MAX_PATH];
735
char file [MAX_PATH];
736
HANDLE fh, token;
737
DWORD sdSize, retSize, rc, granted, priv_set_len;
738
PRIVILEGE_SET priv_set;
739
BOOL status;
740
BYTE *sd;
741
GENERIC_MAPPING mapping = { FILE_READ_DATA, FILE_WRITE_DATA, FILE_EXECUTE, FILE_ALL_ACCESS };
742
const SECURITY_INFORMATION request = OWNER_SECURITY_INFORMATION
743
| GROUP_SECURITY_INFORMATION
744
| DACL_SECURITY_INFORMATION;
745
746
if (!GetTempPathA (sizeof (wintmpdir), wintmpdir)) {
747
win_skip ("GetTempPathA failed\n");
748
return;
749
}
750
751
/* Create a temporary directory and in it a temporary file */
752
strcat (strcpy (path, wintmpdir), "rary");
753
SetLastError(0xdeadbeef);
754
rc = CreateDirectoryA (path, NULL);
755
ok (rc || GetLastError() == ERROR_ALREADY_EXISTS, "CreateDirectoryA "
756
"failed for '%s' with %ld\n", path, GetLastError());
757
758
strcat (strcpy (file, path), "\\ess");
759
SetLastError(0xdeadbeef);
760
fh = CreateFileA (file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
761
ok (fh != INVALID_HANDLE_VALUE, "CreateFileA "
762
"failed for '%s' with %ld\n", file, GetLastError());
763
CloseHandle (fh);
764
765
/* For the temporary file ... */
766
767
/* Get size needed */
768
retSize = 0;
769
SetLastError(0xdeadbeef);
770
rc = GetFileSecurityA (file, request, NULL, 0, &retSize);
771
if (!rc && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) {
772
win_skip("GetFileSecurityA is not implemented\n");
773
goto cleanup;
774
}
775
ok (!rc, "GetFileSecurityA "
776
"was expected to fail for '%s'\n", file);
777
ok (GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetFileSecurityA "
778
"returned %ld; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
779
ok (retSize > sizeof (SECURITY_DESCRIPTOR), "GetFileSecurityA returned size %ld\n", retSize);
780
781
sdSize = retSize;
782
sd = malloc(sdSize);
783
784
/* Get security descriptor for real */
785
retSize = -1;
786
SetLastError(0xdeadbeef);
787
rc = GetFileSecurityA (file, request, sd, sdSize, &retSize);
788
ok (rc, "GetFileSecurityA "
789
"was not expected to fail '%s': %ld\n", file, GetLastError());
790
ok (retSize == sdSize,
791
"GetFileSecurityA returned size %ld; expected %ld\n", retSize, sdSize);
792
793
/* Use it to set security descriptor */
794
SetLastError(0xdeadbeef);
795
rc = SetFileSecurityA (file, request, sd);
796
ok (rc, "SetFileSecurityA "
797
"was not expected to fail '%s': %ld\n", file, GetLastError());
798
799
free(sd);
800
801
/* Repeat for the temporary directory ... */
802
803
/* Get size needed */
804
retSize = 0;
805
SetLastError(0xdeadbeef);
806
rc = GetFileSecurityA (path, request, NULL, 0, &retSize);
807
ok (!rc, "GetFileSecurityA "
808
"was expected to fail for '%s'\n", path);
809
ok (GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetFileSecurityA "
810
"returned %ld; expected ERROR_INSUFFICIENT_BUFFER\n", GetLastError());
811
ok (retSize > sizeof (SECURITY_DESCRIPTOR), "GetFileSecurityA returned size %ld\n", retSize);
812
813
sdSize = retSize;
814
sd = malloc(sdSize);
815
816
/* Get security descriptor for real */
817
retSize = -1;
818
SetLastError(0xdeadbeef);
819
rc = GetFileSecurityA (path, request, sd, sdSize, &retSize);
820
ok (rc, "GetFileSecurityA "
821
"was not expected to fail '%s': %ld\n", path, GetLastError());
822
ok (retSize == sdSize,
823
"GetFileSecurityA returned size %ld; expected %ld\n", retSize, sdSize);
824
825
/* Use it to set security descriptor */
826
SetLastError(0xdeadbeef);
827
rc = SetFileSecurityA (path, request, sd);
828
ok (rc, "SetFileSecurityA "
829
"was not expected to fail '%s': %ld\n", path, GetLastError());
830
free(sd);
831
832
/* Old test */
833
strcpy (wintmpdir, "\\Should not exist");
834
SetLastError(0xdeadbeef);
835
rc = GetFileSecurityA (wintmpdir, OWNER_SECURITY_INFORMATION, NULL, 0, &sdSize);
836
ok (!rc, "GetFileSecurityA should fail for not existing directories/files\n");
837
ok (GetLastError() == ERROR_FILE_NOT_FOUND,
838
"last error ERROR_FILE_NOT_FOUND expected, got %ld\n", GetLastError());
839
840
cleanup:
841
/* Remove temporary file and directory */
842
DeleteFileA(file);
843
RemoveDirectoryA(path);
844
845
/* Test file access permissions for a file with FILE_ATTRIBUTE_ARCHIVE */
846
SetLastError(0xdeadbeef);
847
rc = GetTempPathA(sizeof(wintmpdir), wintmpdir);
848
ok(rc, "GetTempPath error %ld\n", GetLastError());
849
850
SetLastError(0xdeadbeef);
851
rc = GetTempFileNameA(wintmpdir, "tmp", 0, file);
852
ok(rc, "GetTempFileName error %ld\n", GetLastError());
853
854
rc = GetFileAttributesA(file);
855
rc &= ~(FILE_ATTRIBUTE_NOT_CONTENT_INDEXED|FILE_ATTRIBUTE_COMPRESSED);
856
ok(rc == FILE_ATTRIBUTE_ARCHIVE, "expected FILE_ATTRIBUTE_ARCHIVE got %#lx\n", rc);
857
858
rc = GetFileSecurityA(file, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION,
859
NULL, 0, &sdSize);
860
ok(!rc, "GetFileSecurity should fail\n");
861
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
862
"expected ERROR_INSUFFICIENT_BUFFER got %ld\n", GetLastError());
863
ok(sdSize > sizeof(SECURITY_DESCRIPTOR), "got sd size %ld\n", sdSize);
864
865
sd = malloc(sdSize);
866
retSize = 0xdeadbeef;
867
SetLastError(0xdeadbeef);
868
rc = GetFileSecurityA(file, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION,
869
sd, sdSize, &retSize);
870
ok(rc, "GetFileSecurity error %ld\n", GetLastError());
871
ok(retSize == sdSize, "expected %ld, got %ld\n", sdSize, retSize);
872
873
SetLastError(0xdeadbeef);
874
rc = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &token);
875
ok(!rc, "OpenThreadToken should fail\n");
876
ok(GetLastError() == ERROR_NO_TOKEN, "expected ERROR_NO_TOKEN, got %ld\n", GetLastError());
877
878
SetLastError(0xdeadbeef);
879
rc = ImpersonateSelf(SecurityIdentification);
880
ok(rc, "ImpersonateSelf error %ld\n", GetLastError());
881
882
SetLastError(0xdeadbeef);
883
rc = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &token);
884
ok(rc, "OpenThreadToken error %ld\n", GetLastError());
885
886
SetLastError(0xdeadbeef);
887
rc = RevertToSelf();
888
ok(rc, "RevertToSelf error %ld\n", GetLastError());
889
890
priv_set_len = sizeof(priv_set);
891
granted = 0xdeadbeef;
892
status = 0xdeadbeef;
893
SetLastError(0xdeadbeef);
894
rc = AccessCheck(sd, token, FILE_READ_DATA, &mapping, &priv_set, &priv_set_len, &granted, &status);
895
ok(rc, "AccessCheck error %ld\n", GetLastError());
896
ok(status == 1, "expected 1, got %d\n", status);
897
ok(granted == FILE_READ_DATA, "expected FILE_READ_DATA, got %#lx\n", granted);
898
899
granted = 0xdeadbeef;
900
status = 0xdeadbeef;
901
SetLastError(0xdeadbeef);
902
rc = AccessCheck(sd, token, FILE_WRITE_DATA, &mapping, &priv_set, &priv_set_len, &granted, &status);
903
ok(rc, "AccessCheck error %ld\n", GetLastError());
904
ok(status == 1, "expected 1, got %d\n", status);
905
ok(granted == FILE_WRITE_DATA, "expected FILE_WRITE_DATA, got %#lx\n", granted);
906
907
granted = 0xdeadbeef;
908
status = 0xdeadbeef;
909
SetLastError(0xdeadbeef);
910
rc = AccessCheck(sd, token, FILE_EXECUTE, &mapping, &priv_set, &priv_set_len, &granted, &status);
911
ok(rc, "AccessCheck error %ld\n", GetLastError());
912
ok(status == 1, "expected 1, got %d\n", status);
913
ok(granted == FILE_EXECUTE, "expected FILE_EXECUTE, got %#lx\n", granted);
914
915
granted = 0xdeadbeef;
916
status = 0xdeadbeef;
917
SetLastError(0xdeadbeef);
918
rc = AccessCheck(sd, token, DELETE, &mapping, &priv_set, &priv_set_len, &granted, &status);
919
ok(rc, "AccessCheck error %ld\n", GetLastError());
920
ok(status == 1, "expected 1, got %d\n", status);
921
ok(granted == DELETE, "expected DELETE, got %#lx\n", granted);
922
923
granted = 0xdeadbeef;
924
status = 0xdeadbeef;
925
SetLastError(0xdeadbeef);
926
rc = AccessCheck(sd, token, FILE_DELETE_CHILD, &mapping, &priv_set, &priv_set_len, &granted, &status);
927
ok(rc, "AccessCheck error %ld\n", GetLastError());
928
ok(status == 1, "expected 1, got %d\n", status);
929
ok(granted == FILE_DELETE_CHILD, "expected FILE_DELETE_CHILD, got %#lx\n", granted);
930
931
granted = 0xdeadbeef;
932
status = 0xdeadbeef;
933
SetLastError(0xdeadbeef);
934
rc = AccessCheck(sd, token, 0x1ff, &mapping, &priv_set, &priv_set_len, &granted, &status);
935
ok(rc, "AccessCheck error %ld\n", GetLastError());
936
ok(status == 1, "expected 1, got %d\n", status);
937
ok(granted == 0x1ff, "expected 0x1ff, got %#lx\n", granted);
938
939
granted = 0xdeadbeef;
940
status = 0xdeadbeef;
941
SetLastError(0xdeadbeef);
942
rc = AccessCheck(sd, token, FILE_ALL_ACCESS, &mapping, &priv_set, &priv_set_len, &granted, &status);
943
ok(rc, "AccessCheck error %ld\n", GetLastError());
944
ok(status == 1, "expected 1, got %d\n", status);
945
ok(granted == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#lx\n", granted);
946
947
SetLastError(0xdeadbeef);
948
rc = AccessCheck(sd, token, 0xffffffff, &mapping, &priv_set, &priv_set_len, &granted, &status);
949
ok(!rc, "AccessCheck should fail\n");
950
ok(GetLastError() == ERROR_GENERIC_NOT_MAPPED, "expected ERROR_GENERIC_NOT_MAPPED, got %ld\n", GetLastError());
951
952
/* Test file access permissions for a file with FILE_ATTRIBUTE_READONLY */
953
SetLastError(0xdeadbeef);
954
fh = CreateFileA(file, FILE_READ_DATA, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_READONLY, 0);
955
ok(fh != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
956
retSize = 0xdeadbeef;
957
SetLastError(0xdeadbeef);
958
rc = WriteFile(fh, "1", 1, &retSize, NULL);
959
ok(!rc, "WriteFile should fail\n");
960
ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
961
ok(retSize == 0, "expected 0, got %ld\n", retSize);
962
CloseHandle(fh);
963
964
rc = GetFileAttributesA(file);
965
rc &= ~(FILE_ATTRIBUTE_NOT_CONTENT_INDEXED|FILE_ATTRIBUTE_COMPRESSED);
966
todo_wine
967
ok(rc == (FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY),
968
"expected FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY got %#lx\n", rc);
969
970
SetLastError(0xdeadbeef);
971
rc = SetFileAttributesA(file, FILE_ATTRIBUTE_ARCHIVE);
972
ok(rc, "SetFileAttributes error %ld\n", GetLastError());
973
SetLastError(0xdeadbeef);
974
rc = DeleteFileA(file);
975
ok(rc, "DeleteFile error %ld\n", GetLastError());
976
977
SetLastError(0xdeadbeef);
978
fh = CreateFileA(file, FILE_READ_DATA, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_READONLY, 0);
979
ok(fh != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
980
retSize = 0xdeadbeef;
981
SetLastError(0xdeadbeef);
982
rc = WriteFile(fh, "1", 1, &retSize, NULL);
983
ok(!rc, "WriteFile should fail\n");
984
ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
985
ok(retSize == 0, "expected 0, got %ld\n", retSize);
986
CloseHandle(fh);
987
988
rc = GetFileAttributesA(file);
989
rc &= ~(FILE_ATTRIBUTE_NOT_CONTENT_INDEXED|FILE_ATTRIBUTE_COMPRESSED);
990
ok(rc == (FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY),
991
"expected FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY got %#lx\n", rc);
992
993
retSize = 0xdeadbeef;
994
SetLastError(0xdeadbeef);
995
rc = GetFileSecurityA(file, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION,
996
sd, sdSize, &retSize);
997
ok(rc, "GetFileSecurity error %ld\n", GetLastError());
998
ok(retSize == sdSize, "expected %ld, got %ld\n", sdSize, retSize);
999
1000
priv_set_len = sizeof(priv_set);
1001
granted = 0xdeadbeef;
1002
status = 0xdeadbeef;
1003
SetLastError(0xdeadbeef);
1004
rc = AccessCheck(sd, token, FILE_READ_DATA, &mapping, &priv_set, &priv_set_len, &granted, &status);
1005
ok(rc, "AccessCheck error %ld\n", GetLastError());
1006
ok(status == 1, "expected 1, got %d\n", status);
1007
ok(granted == FILE_READ_DATA, "expected FILE_READ_DATA, got %#lx\n", granted);
1008
1009
granted = 0xdeadbeef;
1010
status = 0xdeadbeef;
1011
SetLastError(0xdeadbeef);
1012
rc = AccessCheck(sd, token, FILE_WRITE_DATA, &mapping, &priv_set, &priv_set_len, &granted, &status);
1013
ok(rc, "AccessCheck error %ld\n", GetLastError());
1014
todo_wine {
1015
ok(status == 1, "expected 1, got %d\n", status);
1016
ok(granted == FILE_WRITE_DATA, "expected FILE_WRITE_DATA, got %#lx\n", granted);
1017
}
1018
granted = 0xdeadbeef;
1019
status = 0xdeadbeef;
1020
SetLastError(0xdeadbeef);
1021
rc = AccessCheck(sd, token, FILE_EXECUTE, &mapping, &priv_set, &priv_set_len, &granted, &status);
1022
ok(rc, "AccessCheck error %ld\n", GetLastError());
1023
ok(status == 1, "expected 1, got %d\n", status);
1024
ok(granted == FILE_EXECUTE, "expected FILE_EXECUTE, got %#lx\n", granted);
1025
1026
granted = 0xdeadbeef;
1027
status = 0xdeadbeef;
1028
SetLastError(0xdeadbeef);
1029
rc = AccessCheck(sd, token, DELETE, &mapping, &priv_set, &priv_set_len, &granted, &status);
1030
ok(rc, "AccessCheck error %ld\n", GetLastError());
1031
ok(status == 1, "expected 1, got %d\n", status);
1032
ok(granted == DELETE, "expected DELETE, got %#lx\n", granted);
1033
1034
granted = 0xdeadbeef;
1035
status = 0xdeadbeef;
1036
SetLastError(0xdeadbeef);
1037
rc = AccessCheck(sd, token, WRITE_OWNER, &mapping, &priv_set, &priv_set_len, &granted, &status);
1038
ok(rc, "AccessCheck error %ld\n", GetLastError());
1039
ok(status == 1, "expected 1, got %d\n", status);
1040
ok(granted == WRITE_OWNER, "expected WRITE_OWNER, got %#lx\n", granted);
1041
1042
granted = 0xdeadbeef;
1043
status = 0xdeadbeef;
1044
SetLastError(0xdeadbeef);
1045
rc = AccessCheck(sd, token, SYNCHRONIZE, &mapping, &priv_set, &priv_set_len, &granted, &status);
1046
ok(rc, "AccessCheck error %ld\n", GetLastError());
1047
ok(status == 1, "expected 1, got %d\n", status);
1048
ok(granted == SYNCHRONIZE, "expected SYNCHRONIZE, got %#lx\n", granted);
1049
1050
granted = 0xdeadbeef;
1051
status = 0xdeadbeef;
1052
SetLastError(0xdeadbeef);
1053
rc = AccessCheck(sd, token, FILE_DELETE_CHILD, &mapping, &priv_set, &priv_set_len, &granted, &status);
1054
ok(rc, "AccessCheck error %ld\n", GetLastError());
1055
todo_wine {
1056
ok(status == 1, "expected 1, got %d\n", status);
1057
ok(granted == FILE_DELETE_CHILD, "expected FILE_DELETE_CHILD, got %#lx\n", granted);
1058
}
1059
granted = 0xdeadbeef;
1060
status = 0xdeadbeef;
1061
SetLastError(0xdeadbeef);
1062
rc = AccessCheck(sd, token, 0x1ff, &mapping, &priv_set, &priv_set_len, &granted, &status);
1063
ok(rc, "AccessCheck error %ld\n", GetLastError());
1064
todo_wine {
1065
ok(status == 1, "expected 1, got %d\n", status);
1066
ok(granted == 0x1ff, "expected 0x1ff, got %#lx\n", granted);
1067
}
1068
granted = 0xdeadbeef;
1069
status = 0xdeadbeef;
1070
SetLastError(0xdeadbeef);
1071
rc = AccessCheck(sd, token, FILE_ALL_ACCESS, &mapping, &priv_set, &priv_set_len, &granted, &status);
1072
ok(rc, "AccessCheck error %ld\n", GetLastError());
1073
todo_wine {
1074
ok(status == 1, "expected 1, got %d\n", status);
1075
ok(granted == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#lx\n", granted);
1076
}
1077
SetLastError(0xdeadbeef);
1078
rc = DeleteFileA(file);
1079
ok(!rc, "DeleteFile should fail\n");
1080
ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
1081
SetLastError(0xdeadbeef);
1082
rc = SetFileAttributesA(file, FILE_ATTRIBUTE_ARCHIVE);
1083
ok(rc, "SetFileAttributes error %ld\n", GetLastError());
1084
SetLastError(0xdeadbeef);
1085
rc = DeleteFileA(file);
1086
ok(rc, "DeleteFile error %ld\n", GetLastError());
1087
1088
CloseHandle(token);
1089
free(sd);
1090
}
1091
1092
static void test_AccessCheck(void)
1093
{
1094
PSID EveryoneSid = NULL, AdminSid = NULL, UsersSid = NULL;
1095
PACL Acl = NULL;
1096
SECURITY_DESCRIPTOR *SecurityDescriptor = NULL;
1097
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
1098
SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY };
1099
GENERIC_MAPPING Mapping = { KEY_READ, KEY_WRITE, KEY_EXECUTE, KEY_ALL_ACCESS };
1100
ACCESS_MASK Access;
1101
BOOL AccessStatus;
1102
HANDLE Token;
1103
HANDLE ProcessToken;
1104
BOOL ret;
1105
DWORD PrivSetLen;
1106
PRIVILEGE_SET *PrivSet;
1107
BOOL res;
1108
HMODULE NtDllModule;
1109
BOOLEAN Enabled;
1110
DWORD err;
1111
NTSTATUS ntret, ntAccessStatus;
1112
1113
NtDllModule = GetModuleHandleA("ntdll.dll");
1114
if (!NtDllModule)
1115
{
1116
skip("not running on NT, skipping test\n");
1117
return;
1118
}
1119
pRtlAdjustPrivilege = (void *)GetProcAddress(NtDllModule, "RtlAdjustPrivilege");
1120
if (!pRtlAdjustPrivilege)
1121
{
1122
win_skip("missing RtlAdjustPrivilege, skipping test\n");
1123
return;
1124
}
1125
1126
Acl = malloc(256);
1127
res = InitializeAcl(Acl, 256, ACL_REVISION);
1128
if(!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1129
{
1130
skip("ACLs not implemented - skipping tests\n");
1131
free(Acl);
1132
return;
1133
}
1134
ok(res, "InitializeAcl failed with error %ld\n", GetLastError());
1135
1136
res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid);
1137
ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
1138
1139
res = AllocateAndInitializeSid( &SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
1140
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdminSid);
1141
ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
1142
1143
res = AllocateAndInitializeSid( &SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
1144
DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &UsersSid);
1145
ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
1146
1147
SecurityDescriptor = malloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
1148
1149
res = InitializeSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
1150
ok(res, "InitializeSecurityDescriptor failed with error %ld\n", GetLastError());
1151
1152
res = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, Acl, FALSE);
1153
ok(res, "SetSecurityDescriptorDacl failed with error %ld\n", GetLastError());
1154
1155
PrivSetLen = FIELD_OFFSET(PRIVILEGE_SET, Privilege[16]);
1156
PrivSet = calloc(1, PrivSetLen);
1157
PrivSet->PrivilegeCount = 16;
1158
1159
res = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &ProcessToken);
1160
ok(res, "OpenProcessToken failed with error %ld\n", GetLastError());
1161
1162
pRtlAdjustPrivilege(SE_SECURITY_PRIVILEGE, FALSE, TRUE, &Enabled);
1163
1164
res = DuplicateToken(ProcessToken, SecurityImpersonation, &Token);
1165
ok(res, "DuplicateToken failed with error %ld\n", GetLastError());
1166
1167
/* SD without owner/group */
1168
SetLastError(0xdeadbeef);
1169
Access = AccessStatus = 0x1abe11ed;
1170
ret = AccessCheck(SecurityDescriptor, Token, KEY_QUERY_VALUE, &Mapping,
1171
PrivSet, &PrivSetLen, &Access, &AccessStatus);
1172
err = GetLastError();
1173
ok(!ret && err == ERROR_INVALID_SECURITY_DESCR, "AccessCheck should have "
1174
"failed with ERROR_INVALID_SECURITY_DESCR, instead of %ld\n", err);
1175
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1176
"Access and/or AccessStatus were changed!\n");
1177
1178
/* Set owner and group */
1179
res = SetSecurityDescriptorOwner(SecurityDescriptor, AdminSid, FALSE);
1180
ok(res, "SetSecurityDescriptorOwner failed with error %ld\n", GetLastError());
1181
res = SetSecurityDescriptorGroup(SecurityDescriptor, UsersSid, TRUE);
1182
ok(res, "SetSecurityDescriptorGroup failed with error %ld\n", GetLastError());
1183
1184
/* Generic access mask */
1185
SetLastError(0xdeadbeef);
1186
Access = AccessStatus = 0x1abe11ed;
1187
ret = AccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
1188
PrivSet, &PrivSetLen, &Access, &AccessStatus);
1189
err = GetLastError();
1190
ok(!ret && err == ERROR_GENERIC_NOT_MAPPED, "AccessCheck should have failed "
1191
"with ERROR_GENERIC_NOT_MAPPED, instead of %ld\n", err);
1192
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1193
"Access and/or AccessStatus were changed!\n");
1194
1195
/* Generic access mask - no privilegeset buffer */
1196
SetLastError(0xdeadbeef);
1197
Access = AccessStatus = 0x1abe11ed;
1198
ret = AccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
1199
NULL, &PrivSetLen, &Access, &AccessStatus);
1200
err = GetLastError();
1201
ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed "
1202
"with ERROR_NOACCESS, instead of %ld\n", err);
1203
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1204
"Access and/or AccessStatus were changed!\n");
1205
1206
/* Generic access mask - no returnlength */
1207
SetLastError(0xdeadbeef);
1208
Access = AccessStatus = 0x1abe11ed;
1209
ret = AccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
1210
PrivSet, NULL, &Access, &AccessStatus);
1211
err = GetLastError();
1212
ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed "
1213
"with ERROR_NOACCESS, instead of %ld\n", err);
1214
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1215
"Access and/or AccessStatus were changed!\n");
1216
1217
/* Generic access mask - no privilegeset buffer, no returnlength */
1218
SetLastError(0xdeadbeef);
1219
Access = AccessStatus = 0x1abe11ed;
1220
ret = AccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
1221
NULL, NULL, &Access, &AccessStatus);
1222
err = GetLastError();
1223
ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed "
1224
"with ERROR_NOACCESS, instead of %ld\n", err);
1225
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1226
"Access and/or AccessStatus were changed!\n");
1227
1228
/* sd with no dacl present */
1229
Access = AccessStatus = 0x1abe11ed;
1230
ret = SetSecurityDescriptorDacl(SecurityDescriptor, FALSE, NULL, FALSE);
1231
ok(ret, "SetSecurityDescriptorDacl failed with error %ld\n", GetLastError());
1232
ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1233
PrivSet, &PrivSetLen, &Access, &AccessStatus);
1234
ok(ret, "AccessCheck failed with error %ld\n", GetLastError());
1235
ok(AccessStatus && (Access == KEY_READ),
1236
"AccessCheck failed to grant access with error %ld\n",
1237
GetLastError());
1238
1239
/* sd with no dacl present - no privilegeset buffer */
1240
SetLastError(0xdeadbeef);
1241
Access = AccessStatus = 0x1abe11ed;
1242
ret = AccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
1243
NULL, &PrivSetLen, &Access, &AccessStatus);
1244
err = GetLastError();
1245
ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have failed "
1246
"with ERROR_NOACCESS, instead of %ld\n", err);
1247
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1248
"Access and/or AccessStatus were changed!\n");
1249
1250
if(pNtAccessCheck)
1251
{
1252
DWORD ntPrivSetLen = sizeof(PRIVILEGE_SET);
1253
1254
/* Generic access mask - no privilegeset buffer */
1255
SetLastError(0xdeadbeef);
1256
Access = ntAccessStatus = 0x1abe11ed;
1257
ntret = pNtAccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
1258
NULL, &ntPrivSetLen, &Access, &ntAccessStatus);
1259
err = GetLastError();
1260
ok(ntret == STATUS_ACCESS_VIOLATION,
1261
"NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %lx\n", ntret);
1262
ok(err == 0xdeadbeef,
1263
"NtAccessCheck shouldn't set last error, got %ld\n", err);
1264
ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed,
1265
"Access and/or AccessStatus were changed!\n");
1266
ok(ntPrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %ld\n", ntPrivSetLen);
1267
1268
/* Generic access mask - no returnlength */
1269
SetLastError(0xdeadbeef);
1270
Access = ntAccessStatus = 0x1abe11ed;
1271
ntret = pNtAccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
1272
PrivSet, NULL, &Access, &ntAccessStatus);
1273
err = GetLastError();
1274
ok(ntret == STATUS_ACCESS_VIOLATION,
1275
"NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %lx\n", ntret);
1276
ok(err == 0xdeadbeef,
1277
"NtAccessCheck shouldn't set last error, got %ld\n", err);
1278
ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed,
1279
"Access and/or AccessStatus were changed!\n");
1280
1281
/* Generic access mask - no privilegeset buffer, no returnlength */
1282
SetLastError(0xdeadbeef);
1283
Access = ntAccessStatus = 0x1abe11ed;
1284
ntret = pNtAccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
1285
NULL, NULL, &Access, &ntAccessStatus);
1286
err = GetLastError();
1287
ok(ntret == STATUS_ACCESS_VIOLATION,
1288
"NtAccessCheck should have failed with STATUS_ACCESS_VIOLATION, got %lx\n", ntret);
1289
ok(err == 0xdeadbeef,
1290
"NtAccessCheck shouldn't set last error, got %ld\n", err);
1291
ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed,
1292
"Access and/or AccessStatus were changed!\n");
1293
1294
/* Generic access mask - zero returnlength */
1295
SetLastError(0xdeadbeef);
1296
Access = ntAccessStatus = 0x1abe11ed;
1297
ntPrivSetLen = 0;
1298
ntret = pNtAccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
1299
PrivSet, &ntPrivSetLen, &Access, &ntAccessStatus);
1300
err = GetLastError();
1301
ok(ntret == STATUS_GENERIC_NOT_MAPPED,
1302
"NtAccessCheck should have failed with STATUS_GENERIC_NOT_MAPPED, got %lx\n", ntret);
1303
ok(err == 0xdeadbeef,
1304
"NtAccessCheck shouldn't set last error, got %ld\n", err);
1305
ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed,
1306
"Access and/or AccessStatus were changed!\n");
1307
ok(ntPrivSetLen == 0, "PrivSetLen returns %ld\n", ntPrivSetLen);
1308
1309
/* Generic access mask - insufficient returnlength */
1310
SetLastError(0xdeadbeef);
1311
Access = ntAccessStatus = 0x1abe11ed;
1312
ntPrivSetLen = sizeof(PRIVILEGE_SET)-1;
1313
ntret = pNtAccessCheck(SecurityDescriptor, Token, GENERIC_READ, &Mapping,
1314
PrivSet, &ntPrivSetLen, &Access, &ntAccessStatus);
1315
err = GetLastError();
1316
ok(ntret == STATUS_GENERIC_NOT_MAPPED,
1317
"NtAccessCheck should have failed with STATUS_GENERIC_NOT_MAPPED, got %lx\n", ntret);
1318
ok(err == 0xdeadbeef,
1319
"NtAccessCheck shouldn't set last error, got %ld\n", err);
1320
ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed,
1321
"Access and/or AccessStatus were changed!\n");
1322
ok(ntPrivSetLen == sizeof(PRIVILEGE_SET)-1, "PrivSetLen returns %ld\n", ntPrivSetLen);
1323
1324
/* Key access mask - zero returnlength */
1325
SetLastError(0xdeadbeef);
1326
Access = ntAccessStatus = 0x1abe11ed;
1327
ntPrivSetLen = 0;
1328
ntret = pNtAccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1329
PrivSet, &ntPrivSetLen, &Access, &ntAccessStatus);
1330
err = GetLastError();
1331
ok(ntret == STATUS_BUFFER_TOO_SMALL,
1332
"NtAccessCheck should have failed with STATUS_BUFFER_TOO_SMALL, got %lx\n", ntret);
1333
ok(err == 0xdeadbeef,
1334
"NtAccessCheck shouldn't set last error, got %ld\n", err);
1335
ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed,
1336
"Access and/or AccessStatus were changed!\n");
1337
ok(ntPrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %ld\n", ntPrivSetLen);
1338
1339
/* Key access mask - insufficient returnlength */
1340
SetLastError(0xdeadbeef);
1341
Access = ntAccessStatus = 0x1abe11ed;
1342
ntPrivSetLen = sizeof(PRIVILEGE_SET)-1;
1343
ntret = pNtAccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1344
PrivSet, &ntPrivSetLen, &Access, &ntAccessStatus);
1345
err = GetLastError();
1346
ok(ntret == STATUS_BUFFER_TOO_SMALL,
1347
"NtAccessCheck should have failed with STATUS_BUFFER_TOO_SMALL, got %lx\n", ntret);
1348
ok(err == 0xdeadbeef,
1349
"NtAccessCheck shouldn't set last error, got %ld\n", err);
1350
ok(Access == 0x1abe11ed && ntAccessStatus == 0x1abe11ed,
1351
"Access and/or AccessStatus were changed!\n");
1352
ok(ntPrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %ld\n", ntPrivSetLen);
1353
}
1354
else
1355
win_skip("NtAccessCheck unavailable. Skipping.\n");
1356
1357
/* sd with NULL dacl */
1358
Access = AccessStatus = 0x1abe11ed;
1359
ret = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, NULL, FALSE);
1360
ok(ret, "SetSecurityDescriptorDacl failed with error %ld\n", GetLastError());
1361
ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1362
PrivSet, &PrivSetLen, &Access, &AccessStatus);
1363
ok(ret, "AccessCheck failed with error %ld\n", GetLastError());
1364
ok(AccessStatus && (Access == KEY_READ),
1365
"AccessCheck failed to grant access with error %ld\n",
1366
GetLastError());
1367
ret = AccessCheck(SecurityDescriptor, Token, MAXIMUM_ALLOWED, &Mapping,
1368
PrivSet, &PrivSetLen, &Access, &AccessStatus);
1369
ok(ret, "AccessCheck failed with error %ld\n", GetLastError());
1370
ok(AccessStatus && (Access == KEY_ALL_ACCESS),
1371
"AccessCheck failed to grant access with error %ld\n",
1372
GetLastError());
1373
1374
/* sd with blank dacl */
1375
ret = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, Acl, FALSE);
1376
ok(ret, "SetSecurityDescriptorDacl failed with error %ld\n", GetLastError());
1377
ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1378
PrivSet, &PrivSetLen, &Access, &AccessStatus);
1379
ok(ret, "AccessCheck failed with error %ld\n", GetLastError());
1380
err = GetLastError();
1381
ok(!AccessStatus && err == ERROR_ACCESS_DENIED, "AccessCheck should have failed "
1382
"with ERROR_ACCESS_DENIED, instead of %ld\n", err);
1383
ok(!Access, "Should have failed to grant any access, got 0x%08lx\n", Access);
1384
1385
res = AddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, EveryoneSid);
1386
ok(res, "AddAccessAllowedAce failed with error %ld\n", GetLastError());
1387
1388
res = AddAccessDeniedAce(Acl, ACL_REVISION, KEY_SET_VALUE, AdminSid);
1389
ok(res, "AddAccessDeniedAce failed with error %ld\n", GetLastError());
1390
1391
/* sd with dacl */
1392
Access = AccessStatus = 0x1abe11ed;
1393
ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1394
PrivSet, &PrivSetLen, &Access, &AccessStatus);
1395
ok(ret, "AccessCheck failed with error %ld\n", GetLastError());
1396
ok(AccessStatus && (Access == KEY_READ),
1397
"AccessCheck failed to grant access with error %ld\n",
1398
GetLastError());
1399
1400
ret = AccessCheck(SecurityDescriptor, Token, MAXIMUM_ALLOWED, &Mapping,
1401
PrivSet, &PrivSetLen, &Access, &AccessStatus);
1402
ok(ret, "AccessCheck failed with error %ld\n", GetLastError());
1403
ok(AccessStatus,
1404
"AccessCheck failed to grant any access with error %ld\n",
1405
GetLastError());
1406
trace("AccessCheck with MAXIMUM_ALLOWED got Access 0x%08lx\n", Access);
1407
1408
/* Null PrivSet with null PrivSetLen pointer */
1409
SetLastError(0xdeadbeef);
1410
Access = AccessStatus = 0x1abe11ed;
1411
ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1412
NULL, NULL, &Access, &AccessStatus);
1413
err = GetLastError();
1414
ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have "
1415
"failed with ERROR_NOACCESS, instead of %ld\n", err);
1416
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1417
"Access and/or AccessStatus were changed!\n");
1418
1419
/* Null PrivSet with zero PrivSetLen */
1420
SetLastError(0xdeadbeef);
1421
Access = AccessStatus = 0x1abe11ed;
1422
PrivSetLen = 0;
1423
ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1424
0, &PrivSetLen, &Access, &AccessStatus);
1425
err = GetLastError();
1426
todo_wine
1427
ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
1428
"failed with ERROR_INSUFFICIENT_BUFFER, instead of %ld\n", err);
1429
todo_wine
1430
ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %ld\n", PrivSetLen);
1431
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1432
"Access and/or AccessStatus were changed!\n");
1433
1434
/* Null PrivSet with insufficient PrivSetLen */
1435
SetLastError(0xdeadbeef);
1436
Access = AccessStatus = 0x1abe11ed;
1437
PrivSetLen = 1;
1438
ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1439
0, &PrivSetLen, &Access, &AccessStatus);
1440
err = GetLastError();
1441
ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have "
1442
"failed with ERROR_NOACCESS, instead of %ld\n", err);
1443
ok(PrivSetLen == 1, "PrivSetLen returns %ld\n", PrivSetLen);
1444
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1445
"Access and/or AccessStatus were changed!\n");
1446
1447
/* Null PrivSet with insufficient PrivSetLen */
1448
SetLastError(0xdeadbeef);
1449
Access = AccessStatus = 0x1abe11ed;
1450
PrivSetLen = sizeof(PRIVILEGE_SET) - 1;
1451
ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1452
0, &PrivSetLen, &Access, &AccessStatus);
1453
err = GetLastError();
1454
ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have "
1455
"failed with ERROR_NOACCESS, instead of %ld\n", err);
1456
ok(PrivSetLen == sizeof(PRIVILEGE_SET) - 1, "PrivSetLen returns %ld\n", PrivSetLen);
1457
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1458
"Access and/or AccessStatus were changed!\n");
1459
1460
/* Null PrivSet with minimal sufficient PrivSetLen */
1461
SetLastError(0xdeadbeef);
1462
Access = AccessStatus = 0x1abe11ed;
1463
PrivSetLen = sizeof(PRIVILEGE_SET);
1464
ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1465
0, &PrivSetLen, &Access, &AccessStatus);
1466
err = GetLastError();
1467
ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have "
1468
"failed with ERROR_NOACCESS, instead of %ld\n", err);
1469
ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %ld\n", PrivSetLen);
1470
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1471
"Access and/or AccessStatus were changed!\n");
1472
1473
/* Valid PrivSet with zero PrivSetLen */
1474
SetLastError(0xdeadbeef);
1475
Access = AccessStatus = 0x1abe11ed;
1476
PrivSetLen = 0;
1477
ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1478
PrivSet, &PrivSetLen, &Access, &AccessStatus);
1479
err = GetLastError();
1480
ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
1481
"failed with ERROR_INSUFFICIENT_BUFFER, instead of %ld\n", err);
1482
ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %ld\n", PrivSetLen);
1483
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1484
"Access and/or AccessStatus were changed!\n");
1485
1486
/* Valid PrivSet with insufficient PrivSetLen */
1487
SetLastError(0xdeadbeef);
1488
Access = AccessStatus = 0x1abe11ed;
1489
PrivSetLen = 1;
1490
ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1491
PrivSet, &PrivSetLen, &Access, &AccessStatus);
1492
err = GetLastError();
1493
ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
1494
"failed with ERROR_INSUFFICIENT_BUFFER, instead of %ld\n", err);
1495
ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %ld\n", PrivSetLen);
1496
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1497
"Access and/or AccessStatus were changed!\n");
1498
1499
/* Valid PrivSet with insufficient PrivSetLen */
1500
SetLastError(0xdeadbeef);
1501
Access = AccessStatus = 0x1abe11ed;
1502
PrivSetLen = sizeof(PRIVILEGE_SET) - 1;
1503
PrivSet->PrivilegeCount = 0xdeadbeef;
1504
ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1505
PrivSet, &PrivSetLen, &Access, &AccessStatus);
1506
err = GetLastError();
1507
ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
1508
"failed with ERROR_INSUFFICIENT_BUFFER, instead of %ld\n", err);
1509
ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %ld\n", PrivSetLen);
1510
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1511
"Access and/or AccessStatus were changed!\n");
1512
ok(PrivSet->PrivilegeCount == 0xdeadbeef, "buffer contents should not be changed\n");
1513
1514
/* Valid PrivSet with minimal sufficient PrivSetLen */
1515
SetLastError(0xdeadbeef);
1516
Access = AccessStatus = 0x1abe11ed;
1517
PrivSetLen = sizeof(PRIVILEGE_SET);
1518
memset(PrivSet, 0xcc, PrivSetLen);
1519
ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1520
PrivSet, &PrivSetLen, &Access, &AccessStatus);
1521
err = GetLastError();
1522
ok(ret, "AccessCheck failed with error %ld\n", GetLastError());
1523
ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %ld\n", PrivSetLen);
1524
ok(AccessStatus && (Access == KEY_READ),
1525
"AccessCheck failed to grant access with error %ld\n", GetLastError());
1526
ok(PrivSet->PrivilegeCount == 0, "PrivilegeCount returns %ld, expects 0\n",
1527
PrivSet->PrivilegeCount);
1528
1529
/* Valid PrivSet with sufficient PrivSetLen */
1530
SetLastError(0xdeadbeef);
1531
Access = AccessStatus = 0x1abe11ed;
1532
PrivSetLen = sizeof(PRIVILEGE_SET) + 1;
1533
memset(PrivSet, 0xcc, PrivSetLen);
1534
ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1535
PrivSet, &PrivSetLen, &Access, &AccessStatus);
1536
err = GetLastError();
1537
ok(ret, "AccessCheck failed with error %ld\n", GetLastError());
1538
todo_wine
1539
ok(PrivSetLen == sizeof(PRIVILEGE_SET) + 1, "PrivSetLen returns %ld\n", PrivSetLen);
1540
ok(AccessStatus && (Access == KEY_READ),
1541
"AccessCheck failed to grant access with error %ld\n", GetLastError());
1542
ok(PrivSet->PrivilegeCount == 0, "PrivilegeCount returns %ld, expects 0\n",
1543
PrivSet->PrivilegeCount);
1544
1545
PrivSetLen = FIELD_OFFSET(PRIVILEGE_SET, Privilege[16]);
1546
1547
/* Null PrivSet with valid PrivSetLen */
1548
SetLastError(0xdeadbeef);
1549
Access = AccessStatus = 0x1abe11ed;
1550
ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1551
0, &PrivSetLen, &Access, &AccessStatus);
1552
err = GetLastError();
1553
ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have "
1554
"failed with ERROR_NOACCESS, instead of %ld\n", err);
1555
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1556
"Access and/or AccessStatus were changed!\n");
1557
1558
/* Access denied by SD */
1559
SetLastError(0xdeadbeef);
1560
Access = AccessStatus = 0x1abe11ed;
1561
ret = AccessCheck(SecurityDescriptor, Token, KEY_WRITE, &Mapping,
1562
PrivSet, &PrivSetLen, &Access, &AccessStatus);
1563
ok(ret, "AccessCheck failed with error %ld\n", GetLastError());
1564
err = GetLastError();
1565
ok(!AccessStatus && err == ERROR_ACCESS_DENIED, "AccessCheck should have failed "
1566
"with ERROR_ACCESS_DENIED, instead of %ld\n", err);
1567
ok(!Access, "Should have failed to grant any access, got 0x%08lx\n", Access);
1568
1569
SetLastError(0xdeadbeef);
1570
PrivSet->PrivilegeCount = 16;
1571
ret = AccessCheck(SecurityDescriptor, Token, ACCESS_SYSTEM_SECURITY, &Mapping,
1572
PrivSet, &PrivSetLen, &Access, &AccessStatus);
1573
ok(ret && !AccessStatus && GetLastError() == ERROR_PRIVILEGE_NOT_HELD,
1574
"AccessCheck should have failed with ERROR_PRIVILEGE_NOT_HELD, instead of %ld\n",
1575
GetLastError());
1576
1577
ret = ImpersonateLoggedOnUser(Token);
1578
ok(ret, "ImpersonateLoggedOnUser failed with error %ld\n", GetLastError());
1579
ret = pRtlAdjustPrivilege(SE_SECURITY_PRIVILEGE, TRUE, TRUE, &Enabled);
1580
if (!ret)
1581
{
1582
/* Valid PrivSet with zero PrivSetLen */
1583
SetLastError(0xdeadbeef);
1584
Access = AccessStatus = 0x1abe11ed;
1585
PrivSetLen = 0;
1586
ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1587
PrivSet, &PrivSetLen, &Access, &AccessStatus);
1588
err = GetLastError();
1589
ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
1590
"failed with ERROR_INSUFFICIENT_BUFFER, instead of %ld\n", err);
1591
ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %ld\n", PrivSetLen);
1592
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1593
"Access and/or AccessStatus were changed!\n");
1594
1595
/* Valid PrivSet with insufficient PrivSetLen */
1596
SetLastError(0xdeadbeef);
1597
Access = AccessStatus = 0x1abe11ed;
1598
PrivSetLen = sizeof(PRIVILEGE_SET) - 1;
1599
ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1600
PrivSet, &PrivSetLen, &Access, &AccessStatus);
1601
err = GetLastError();
1602
ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
1603
"failed with ERROR_INSUFFICIENT_BUFFER, instead of %ld\n", err);
1604
ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %ld\n", PrivSetLen);
1605
ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
1606
"Access and/or AccessStatus were changed!\n");
1607
1608
/* Valid PrivSet with minimal sufficient PrivSetLen */
1609
SetLastError(0xdeadbeef);
1610
Access = AccessStatus = 0x1abe11ed;
1611
PrivSetLen = sizeof(PRIVILEGE_SET);
1612
memset(PrivSet, 0xcc, PrivSetLen);
1613
ret = AccessCheck(SecurityDescriptor, Token, ACCESS_SYSTEM_SECURITY, &Mapping,
1614
PrivSet, &PrivSetLen, &Access, &AccessStatus);
1615
ok(ret && AccessStatus && GetLastError() == 0xdeadbeef,
1616
"AccessCheck should have succeeded, error %ld\n",
1617
GetLastError());
1618
ok(Access == ACCESS_SYSTEM_SECURITY,
1619
"Access should be equal to ACCESS_SYSTEM_SECURITY instead of 0x%08lx\n",
1620
Access);
1621
ok(PrivSet->PrivilegeCount == 1, "PrivilegeCount returns %ld, expects 1\n",
1622
PrivSet->PrivilegeCount);
1623
1624
/* Valid PrivSet with large PrivSetLen */
1625
SetLastError(0xdeadbeef);
1626
Access = AccessStatus = 0x1abe11ed;
1627
PrivSetLen = FIELD_OFFSET(PRIVILEGE_SET, Privilege[16]);
1628
memset(PrivSet, 0xcc, PrivSetLen);
1629
ret = AccessCheck(SecurityDescriptor, Token, ACCESS_SYSTEM_SECURITY, &Mapping,
1630
PrivSet, &PrivSetLen, &Access, &AccessStatus);
1631
ok(ret && AccessStatus && GetLastError() == 0xdeadbeef,
1632
"AccessCheck should have succeeded, error %ld\n",
1633
GetLastError());
1634
ok(Access == ACCESS_SYSTEM_SECURITY,
1635
"Access should be equal to ACCESS_SYSTEM_SECURITY instead of 0x%08lx\n",
1636
Access);
1637
ok(PrivSet->PrivilegeCount == 1, "PrivilegeCount returns %ld, expects 1\n",
1638
PrivSet->PrivilegeCount);
1639
}
1640
else
1641
trace("Couldn't get SE_SECURITY_PRIVILEGE (0x%08x), skipping ACCESS_SYSTEM_SECURITY test\n",
1642
ret);
1643
ret = RevertToSelf();
1644
ok(ret, "RevertToSelf failed with error %ld\n", GetLastError());
1645
1646
/* test INHERIT_ONLY_ACE */
1647
ret = InitializeAcl(Acl, 256, ACL_REVISION);
1648
ok(ret, "InitializeAcl failed with error %ld\n", GetLastError());
1649
1650
ret = AddAccessAllowedAceEx(Acl, ACL_REVISION, INHERIT_ONLY_ACE, KEY_READ, EveryoneSid);
1651
ok(ret, "AddAccessAllowedAceEx failed with error %ld\n", GetLastError());
1652
1653
ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
1654
PrivSet, &PrivSetLen, &Access, &AccessStatus);
1655
ok(ret, "AccessCheck failed with error %ld\n", GetLastError());
1656
err = GetLastError();
1657
ok(!AccessStatus && err == ERROR_ACCESS_DENIED, "AccessCheck should have failed "
1658
"with ERROR_ACCESS_DENIED, instead of %ld\n", err);
1659
ok(!Access, "Should have failed to grant any access, got 0x%08lx\n", Access);
1660
1661
CloseHandle(Token);
1662
1663
res = DuplicateToken(ProcessToken, SecurityAnonymous, &Token);
1664
ok(res, "DuplicateToken failed with error %ld\n", GetLastError());
1665
1666
SetLastError(0xdeadbeef);
1667
ret = AccessCheck(SecurityDescriptor, Token, MAXIMUM_ALLOWED, &Mapping,
1668
PrivSet, &PrivSetLen, &Access, &AccessStatus);
1669
err = GetLastError();
1670
ok(!ret && err == ERROR_BAD_IMPERSONATION_LEVEL, "AccessCheck should have failed "
1671
"with ERROR_BAD_IMPERSONATION_LEVEL, instead of %ld\n", err);
1672
1673
CloseHandle(Token);
1674
1675
SetLastError(0xdeadbeef);
1676
ret = AccessCheck(SecurityDescriptor, ProcessToken, KEY_READ, &Mapping,
1677
PrivSet, &PrivSetLen, &Access, &AccessStatus);
1678
err = GetLastError();
1679
ok(!ret && err == ERROR_NO_IMPERSONATION_TOKEN, "AccessCheck should have failed "
1680
"with ERROR_NO_IMPERSONATION_TOKEN, instead of %ld\n", err);
1681
1682
CloseHandle(ProcessToken);
1683
1684
if (EveryoneSid)
1685
FreeSid(EveryoneSid);
1686
if (AdminSid)
1687
FreeSid(AdminSid);
1688
if (UsersSid)
1689
FreeSid(UsersSid);
1690
free(Acl);
1691
free(SecurityDescriptor);
1692
free(PrivSet);
1693
}
1694
1695
static TOKEN_USER *get_alloc_token_user( HANDLE token )
1696
{
1697
TOKEN_USER *token_user;
1698
DWORD size;
1699
BOOL ret;
1700
1701
ret = GetTokenInformation( token, TokenUser, NULL, 0, &size );
1702
ok(!ret, "Expected failure, got %d\n", ret);
1703
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1704
"Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
1705
1706
token_user = malloc( size );
1707
ret = GetTokenInformation( token, TokenUser, token_user, size, &size );
1708
ok(ret, "GetTokenInformation failed with error %ld\n", GetLastError());
1709
1710
return token_user;
1711
}
1712
1713
static TOKEN_OWNER *get_alloc_token_owner( HANDLE token )
1714
{
1715
TOKEN_OWNER *token_owner;
1716
DWORD size;
1717
BOOL ret;
1718
1719
ret = GetTokenInformation( token, TokenOwner, NULL, 0, &size );
1720
ok(!ret, "Expected failure, got %d\n", ret);
1721
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1722
"Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
1723
1724
token_owner = malloc( size );
1725
ret = GetTokenInformation( token, TokenOwner, token_owner, size, &size );
1726
ok(ret, "GetTokenInformation failed with error %ld\n", GetLastError());
1727
1728
return token_owner;
1729
}
1730
1731
static TOKEN_PRIMARY_GROUP *get_alloc_token_primary_group( HANDLE token )
1732
{
1733
TOKEN_PRIMARY_GROUP *token_primary_group;
1734
DWORD size;
1735
BOOL ret;
1736
1737
ret = GetTokenInformation( token, TokenPrimaryGroup, NULL, 0, &size );
1738
ok(!ret, "Expected failure, got %d\n", ret);
1739
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1740
"Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
1741
1742
token_primary_group = malloc( size );
1743
ret = GetTokenInformation( token, TokenPrimaryGroup, token_primary_group, size, &size );
1744
ok(ret, "GetTokenInformation failed with error %ld\n", GetLastError());
1745
1746
return token_primary_group;
1747
}
1748
1749
/* test GetTokenInformation for the various attributes */
1750
static void test_token_attr(void)
1751
{
1752
HANDLE Token, ImpersonationToken;
1753
DWORD Size, Size2;
1754
TOKEN_PRIVILEGES *Privileges;
1755
TOKEN_GROUPS *Groups;
1756
TOKEN_USER *User;
1757
TOKEN_OWNER *Owner;
1758
TOKEN_DEFAULT_DACL *Dacl;
1759
BOOL ret;
1760
DWORD i, GLE;
1761
LPSTR SidString;
1762
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
1763
ACL *acl;
1764
1765
/* cygwin-like use case */
1766
SetLastError(0xdeadbeef);
1767
ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &Token);
1768
if(!ret && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
1769
{
1770
win_skip("OpenProcessToken is not implemented\n");
1771
return;
1772
}
1773
ok(ret, "OpenProcessToken failed with error %ld\n", GetLastError());
1774
if (ret)
1775
{
1776
DWORD buf[256]; /* GetTokenInformation wants a dword-aligned buffer */
1777
Size = sizeof(buf);
1778
ret = GetTokenInformation(Token, TokenUser,(void*)buf, Size, &Size);
1779
ok(ret, "GetTokenInformation failed with error %ld\n", GetLastError());
1780
Size = sizeof(ImpersonationLevel);
1781
ret = GetTokenInformation(Token, TokenImpersonationLevel, &ImpersonationLevel, Size, &Size);
1782
GLE = GetLastError();
1783
ok(!ret && (GLE == ERROR_INVALID_PARAMETER), "GetTokenInformation(TokenImpersonationLevel) on primary token should have failed with ERROR_INVALID_PARAMETER instead of %ld\n", GLE);
1784
CloseHandle(Token);
1785
}
1786
1787
SetLastError(0xdeadbeef);
1788
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &Token);
1789
ok(ret, "OpenProcessToken failed with error %ld\n", GetLastError());
1790
1791
/* groups */
1792
/* insufficient buffer length */
1793
SetLastError(0xdeadbeef);
1794
Size2 = 0;
1795
ret = GetTokenInformation(Token, TokenGroups, NULL, 0, &Size2);
1796
ok(Size2 > 1, "got %ld\n", Size2);
1797
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1798
"%d with error %ld\n", ret, GetLastError());
1799
Size2 -= 1;
1800
Groups = malloc(Size2);
1801
memset(Groups, 0xcc, Size2);
1802
Size = 0;
1803
ret = GetTokenInformation(Token, TokenGroups, Groups, Size2, &Size);
1804
ok(Size > 1, "got %ld\n", Size);
1805
ok((!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER) || broken(ret) /* wow64 */,
1806
"%d with error %ld\n", ret, GetLastError());
1807
if(!ret)
1808
ok(*((BYTE*)Groups) == 0xcc, "buffer altered\n");
1809
1810
free(Groups);
1811
1812
SetLastError(0xdeadbeef);
1813
ret = GetTokenInformation(Token, TokenGroups, NULL, 0, &Size);
1814
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1815
"GetTokenInformation(TokenGroups) %s with error %ld\n",
1816
ret ? "succeeded" : "failed", GetLastError());
1817
Groups = malloc(Size);
1818
SetLastError(0xdeadbeef);
1819
ret = GetTokenInformation(Token, TokenGroups, Groups, Size, &Size);
1820
ok(ret, "GetTokenInformation(TokenGroups) failed with error %ld\n", GetLastError());
1821
ok(GetLastError() == 0xdeadbeef,
1822
"GetTokenInformation shouldn't have set last error to %ld\n",
1823
GetLastError());
1824
trace("TokenGroups:\n");
1825
for (i = 0; i < Groups->GroupCount; i++)
1826
{
1827
DWORD NameLength = 255;
1828
CHAR Name[255];
1829
DWORD DomainLength = 255;
1830
CHAR Domain[255];
1831
SID_NAME_USE SidNameUse;
1832
Name[0] = '\0';
1833
Domain[0] = '\0';
1834
ret = LookupAccountSidA(NULL, Groups->Groups[i].Sid, Name, &NameLength, Domain, &DomainLength, &SidNameUse);
1835
if (ret)
1836
{
1837
ConvertSidToStringSidA(Groups->Groups[i].Sid, &SidString);
1838
trace("%s, %s\\%s use: %d attr: 0x%08lx\n", SidString, Domain, Name, SidNameUse, Groups->Groups[i].Attributes);
1839
LocalFree(SidString);
1840
}
1841
else trace("attr: 0x%08lx LookupAccountSid failed with error %ld\n", Groups->Groups[i].Attributes, GetLastError());
1842
}
1843
free(Groups);
1844
1845
/* user */
1846
ret = GetTokenInformation(Token, TokenUser, NULL, 0, &Size);
1847
ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1848
"GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError());
1849
User = malloc(Size);
1850
ret = GetTokenInformation(Token, TokenUser, User, Size, &Size);
1851
ok(ret,
1852
"GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError());
1853
1854
ConvertSidToStringSidA(User->User.Sid, &SidString);
1855
trace("TokenUser: %s attr: 0x%08lx\n", SidString, User->User.Attributes);
1856
LocalFree(SidString);
1857
free(User);
1858
1859
/* owner */
1860
ret = GetTokenInformation(Token, TokenOwner, NULL, 0, &Size);
1861
ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1862
"GetTokenInformation(TokenOwner) failed with error %ld\n", GetLastError());
1863
Owner = malloc(Size);
1864
ret = GetTokenInformation(Token, TokenOwner, Owner, Size, &Size);
1865
ok(ret,
1866
"GetTokenInformation(TokenOwner) failed with error %ld\n", GetLastError());
1867
1868
ConvertSidToStringSidA(Owner->Owner, &SidString);
1869
trace("TokenOwner: %s\n", SidString);
1870
LocalFree(SidString);
1871
free(Owner);
1872
1873
/* logon */
1874
ret = GetTokenInformation(Token, TokenLogonSid, NULL, 0, &Size);
1875
if (!ret && (GetLastError() == ERROR_INVALID_PARAMETER))
1876
todo_wine win_skip("TokenLogonSid not supported. Skipping tests\n");
1877
else
1878
{
1879
ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1880
"GetTokenInformation(TokenLogonSid) failed with error %ld\n", GetLastError());
1881
Groups = malloc(Size);
1882
ret = GetTokenInformation(Token, TokenLogonSid, Groups, Size, &Size);
1883
ok(ret,
1884
"GetTokenInformation(TokenLogonSid) failed with error %ld\n", GetLastError());
1885
if (ret)
1886
{
1887
ok(Groups->GroupCount == 1, "got %ld\n", Groups->GroupCount);
1888
if(Groups->GroupCount == 1)
1889
{
1890
ConvertSidToStringSidA(Groups->Groups[0].Sid, &SidString);
1891
trace("TokenLogon: %s\n", SidString);
1892
LocalFree(SidString);
1893
1894
/* S-1-5-5-0-XXXXXX */
1895
ret = IsWellKnownSid(Groups->Groups[0].Sid, WinLogonIdsSid);
1896
ok(ret, "Unknown SID\n");
1897
1898
ok(Groups->Groups[0].Attributes == (SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED | SE_GROUP_LOGON_ID),
1899
"got %lx\n", Groups->Groups[0].Attributes);
1900
}
1901
}
1902
1903
free(Groups);
1904
}
1905
1906
/* privileges */
1907
ret = GetTokenInformation(Token, TokenPrivileges, NULL, 0, &Size);
1908
ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1909
"GetTokenInformation(TokenPrivileges) failed with error %ld\n", GetLastError());
1910
Privileges = malloc(Size);
1911
ret = GetTokenInformation(Token, TokenPrivileges, Privileges, Size, &Size);
1912
ok(ret,
1913
"GetTokenInformation(TokenPrivileges) failed with error %ld\n", GetLastError());
1914
trace("TokenPrivileges:\n");
1915
for (i = 0; i < Privileges->PrivilegeCount; i++)
1916
{
1917
CHAR Name[256];
1918
DWORD NameLen = ARRAY_SIZE(Name);
1919
LookupPrivilegeNameA(NULL, &Privileges->Privileges[i].Luid, Name, &NameLen);
1920
trace("\t%s, 0x%lx\n", Name, Privileges->Privileges[i].Attributes);
1921
}
1922
free(Privileges);
1923
1924
ret = DuplicateToken(Token, SecurityAnonymous, &ImpersonationToken);
1925
ok(ret, "DuplicateToken failed with error %ld\n", GetLastError());
1926
1927
Size = sizeof(ImpersonationLevel);
1928
ret = GetTokenInformation(ImpersonationToken, TokenImpersonationLevel, &ImpersonationLevel, Size, &Size);
1929
ok(ret, "GetTokenInformation(TokenImpersonationLevel) failed with error %ld\n", GetLastError());
1930
ok(ImpersonationLevel == SecurityAnonymous, "ImpersonationLevel should have been SecurityAnonymous instead of %d\n", ImpersonationLevel);
1931
1932
CloseHandle(ImpersonationToken);
1933
1934
/* default dacl */
1935
ret = GetTokenInformation(Token, TokenDefaultDacl, NULL, 0, &Size);
1936
ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
1937
"GetTokenInformation(TokenDefaultDacl) failed with error %lu\n", GetLastError());
1938
1939
Dacl = malloc(Size);
1940
ret = GetTokenInformation(Token, TokenDefaultDacl, Dacl, Size, &Size);
1941
ok(ret, "GetTokenInformation(TokenDefaultDacl) failed with error %lu\n", GetLastError());
1942
1943
SetLastError(0xdeadbeef);
1944
ret = SetTokenInformation(Token, TokenDefaultDacl, NULL, 0);
1945
GLE = GetLastError();
1946
ok(!ret, "SetTokenInformation(TokenDefaultDacl) succeeded\n");
1947
ok(GLE == ERROR_BAD_LENGTH, "expected ERROR_BAD_LENGTH got %lu\n", GLE);
1948
1949
SetLastError(0xdeadbeef);
1950
ret = SetTokenInformation(Token, TokenDefaultDacl, NULL, Size);
1951
GLE = GetLastError();
1952
ok(!ret, "SetTokenInformation(TokenDefaultDacl) succeeded\n");
1953
ok(GLE == ERROR_NOACCESS, "expected ERROR_NOACCESS got %lu\n", GLE);
1954
1955
acl = Dacl->DefaultDacl;
1956
Dacl->DefaultDacl = NULL;
1957
1958
ret = SetTokenInformation(Token, TokenDefaultDacl, Dacl, Size);
1959
ok(ret, "SetTokenInformation(TokenDefaultDacl) succeeded\n");
1960
1961
Size2 = 0;
1962
Dacl->DefaultDacl = (ACL *)0xdeadbeef;
1963
ret = GetTokenInformation(Token, TokenDefaultDacl, Dacl, Size, &Size2);
1964
ok(ret, "GetTokenInformation(TokenDefaultDacl) failed with error %lu\n", GetLastError());
1965
ok(Dacl->DefaultDacl == NULL, "expected NULL, got %p\n", Dacl->DefaultDacl);
1966
ok(Size2 == sizeof(TOKEN_DEFAULT_DACL) || broken(Size2 == 2*sizeof(TOKEN_DEFAULT_DACL)), /* WoW64 */
1967
"got %lu expected sizeof(TOKEN_DEFAULT_DACL)\n", Size2);
1968
1969
Dacl->DefaultDacl = acl;
1970
ret = SetTokenInformation(Token, TokenDefaultDacl, Dacl, Size);
1971
ok(ret, "SetTokenInformation(TokenDefaultDacl) failed with error %lu\n", GetLastError());
1972
1973
if (Size2 == sizeof(TOKEN_DEFAULT_DACL)) {
1974
ret = GetTokenInformation(Token, TokenDefaultDacl, Dacl, Size, &Size2);
1975
ok(ret, "GetTokenInformation(TokenDefaultDacl) failed with error %lu\n", GetLastError());
1976
} else
1977
win_skip("TOKEN_DEFAULT_DACL size too small on WoW64\n");
1978
1979
free(Dacl);
1980
CloseHandle(Token);
1981
}
1982
1983
static void test_GetTokenInformation(void)
1984
{
1985
DWORD is_app_container, size;
1986
HANDLE token;
1987
BOOL ret;
1988
1989
ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token);
1990
ok(ret, "OpenProcessToken failed: %lu\n", GetLastError());
1991
1992
size = 0;
1993
is_app_container = 0xdeadbeef;
1994
ret = GetTokenInformation(token, TokenIsAppContainer, &is_app_container,
1995
sizeof(is_app_container), &size);
1996
ok(ret || broken(GetLastError() == ERROR_INVALID_PARAMETER ||
1997
GetLastError() == ERROR_INVALID_FUNCTION), /* pre-win8 */
1998
"GetTokenInformation failed: %lu\n", GetLastError());
1999
if(ret) {
2000
ok(size == sizeof(is_app_container), "size = %lu\n", size);
2001
ok(!is_app_container, "is_app_container = %lx\n", is_app_container);
2002
}
2003
2004
CloseHandle(token);
2005
}
2006
2007
typedef union _MAX_SID
2008
{
2009
SID sid;
2010
char max[SECURITY_MAX_SID_SIZE];
2011
} MAX_SID;
2012
2013
static void test_sid_str(PSID * sid)
2014
{
2015
char *str_sid;
2016
BOOL ret = ConvertSidToStringSidA(sid, &str_sid);
2017
ok(ret, "ConvertSidToStringSidA() failed: %ld\n", GetLastError());
2018
if (ret)
2019
{
2020
char account[MAX_PATH], domain[MAX_PATH];
2021
SID_NAME_USE use;
2022
DWORD acc_size = MAX_PATH;
2023
DWORD dom_size = MAX_PATH;
2024
ret = LookupAccountSidA (NULL, sid, account, &acc_size, domain, &dom_size, &use);
2025
ok(ret || GetLastError() == ERROR_NONE_MAPPED,
2026
"LookupAccountSid(%s) failed: %ld\n", str_sid, GetLastError());
2027
if (ret)
2028
trace(" %s %s\\%s %d\n", str_sid, domain, account, use);
2029
else if (GetLastError() == ERROR_NONE_MAPPED)
2030
trace(" %s couldn't be mapped\n", str_sid);
2031
LocalFree(str_sid);
2032
}
2033
}
2034
2035
static const struct well_known_sid_value
2036
{
2037
BOOL without_domain;
2038
const char *sid_string;
2039
} well_known_sid_values[] = {
2040
/* 0 */ {TRUE, "S-1-0-0"}, {TRUE, "S-1-1-0"}, {TRUE, "S-1-2-0"}, {TRUE, "S-1-3-0"},
2041
/* 4 */ {TRUE, "S-1-3-1"}, {TRUE, "S-1-3-2"}, {TRUE, "S-1-3-3"}, {TRUE, "S-1-5"},
2042
/* 8 */ {FALSE, "S-1-5-1"}, {TRUE, "S-1-5-2"}, {TRUE, "S-1-5-3"}, {TRUE, "S-1-5-4"},
2043
/* 12 */ {TRUE, "S-1-5-6"}, {TRUE, "S-1-5-7"}, {TRUE, "S-1-5-8"}, {TRUE, "S-1-5-9"},
2044
/* 16 */ {TRUE, "S-1-5-10"}, {TRUE, "S-1-5-11"}, {TRUE, "S-1-5-12"}, {TRUE, "S-1-5-13"},
2045
/* 20 */ {TRUE, "S-1-5-14"}, {FALSE, NULL}, {TRUE, "S-1-5-18"}, {TRUE, "S-1-5-19"},
2046
/* 24 */ {TRUE, "S-1-5-20"}, {TRUE, "S-1-5-32"},
2047
/* 26 */ {FALSE, "S-1-5-32-544"}, {TRUE, "S-1-5-32-545"}, {TRUE, "S-1-5-32-546"},
2048
/* 29 */ {TRUE, "S-1-5-32-547"}, {TRUE, "S-1-5-32-548"}, {TRUE, "S-1-5-32-549"},
2049
/* 32 */ {TRUE, "S-1-5-32-550"}, {TRUE, "S-1-5-32-551"}, {TRUE, "S-1-5-32-552"},
2050
/* 35 */ {TRUE, "S-1-5-32-554"}, {TRUE, "S-1-5-32-555"}, {TRUE, "S-1-5-32-556"},
2051
/* 38 */ {FALSE, "S-1-5-21-12-23-34-45-56-500"}, {FALSE, "S-1-5-21-12-23-34-45-56-501"},
2052
/* 40 */ {FALSE, "S-1-5-21-12-23-34-45-56-502"}, {FALSE, "S-1-5-21-12-23-34-45-56-512"},
2053
/* 42 */ {FALSE, "S-1-5-21-12-23-34-45-56-513"}, {FALSE, "S-1-5-21-12-23-34-45-56-514"},
2054
/* 44 */ {FALSE, "S-1-5-21-12-23-34-45-56-515"}, {FALSE, "S-1-5-21-12-23-34-45-56-516"},
2055
/* 46 */ {FALSE, "S-1-5-21-12-23-34-45-56-517"}, {FALSE, "S-1-5-21-12-23-34-45-56-518"},
2056
/* 48 */ {FALSE, "S-1-5-21-12-23-34-45-56-519"}, {FALSE, "S-1-5-21-12-23-34-45-56-520"},
2057
/* 50 */ {FALSE, "S-1-5-21-12-23-34-45-56-553"},
2058
/* Added in Windows Server 2003 */
2059
/* 51 */ {TRUE, "S-1-5-64-10"}, {TRUE, "S-1-5-64-21"}, {TRUE, "S-1-5-64-14"},
2060
/* 54 */ {TRUE, "S-1-5-15"}, {TRUE, "S-1-5-1000"}, {FALSE, "S-1-5-32-557"},
2061
/* 57 */ {TRUE, "S-1-5-32-558"}, {TRUE, "S-1-5-32-559"}, {TRUE, "S-1-5-32-560"},
2062
/* 60 */ {TRUE, "S-1-5-32-561"}, {TRUE, "S-1-5-32-562"},
2063
/* Added in Windows Vista: */
2064
/* 62 */ {TRUE, "S-1-5-32-568"},
2065
/* 63 */ {TRUE, "S-1-5-17"}, {FALSE, "S-1-5-32-569"}, {TRUE, "S-1-16-0"},
2066
/* 66 */ {TRUE, "S-1-16-4096"}, {TRUE, "S-1-16-8192"}, {TRUE, "S-1-16-12288"},
2067
/* 69 */ {TRUE, "S-1-16-16384"}, {TRUE, "S-1-5-33"}, {TRUE, "S-1-3-4"},
2068
/* 72 */ {FALSE, "S-1-5-21-12-23-34-45-56-571"}, {FALSE, "S-1-5-21-12-23-34-45-56-572"},
2069
/* 74 */ {TRUE, "S-1-5-22"}, {FALSE, "S-1-5-21-12-23-34-45-56-521"}, {TRUE, "S-1-5-32-573"},
2070
/* 77 */ {FALSE, "S-1-5-21-12-23-34-45-56-498"}, {TRUE, "S-1-5-32-574"}, {TRUE, "S-1-16-8448"},
2071
/* 80 */ {FALSE, NULL}, {TRUE, "S-1-2-1"}, {TRUE, "S-1-5-65-1"}, {FALSE, NULL},
2072
/* 84 */ {TRUE, "S-1-15-2-1"},
2073
};
2074
2075
static void test_CreateWellKnownSid(void)
2076
{
2077
SID_IDENTIFIER_AUTHORITY ident = { SECURITY_NT_AUTHORITY };
2078
PSID domainsid, sid;
2079
DWORD size, error;
2080
BOOL ret;
2081
unsigned int i;
2082
2083
size = 0;
2084
SetLastError(0xdeadbeef);
2085
ret = CreateWellKnownSid(WinInteractiveSid, NULL, NULL, &size);
2086
error = GetLastError();
2087
ok(!ret, "CreateWellKnownSid succeeded\n");
2088
ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %lu\n", error);
2089
ok(size, "expected size > 0\n");
2090
2091
SetLastError(0xdeadbeef);
2092
ret = CreateWellKnownSid(WinInteractiveSid, NULL, NULL, &size);
2093
error = GetLastError();
2094
ok(!ret, "CreateWellKnownSid succeeded\n");
2095
ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %lu\n", error);
2096
2097
sid = malloc(size);
2098
ret = CreateWellKnownSid(WinInteractiveSid, NULL, sid, &size);
2099
ok(ret, "CreateWellKnownSid failed %lu\n", GetLastError());
2100
free(sid);
2101
2102
/* a domain sid usually have three subauthorities but we test that CreateWellKnownSid doesn't check it */
2103
AllocateAndInitializeSid(&ident, 6, SECURITY_NT_NON_UNIQUE, 12, 23, 34, 45, 56, 0, 0, &domainsid);
2104
2105
for (i = 0; i < ARRAY_SIZE(well_known_sid_values); i++)
2106
{
2107
const struct well_known_sid_value *value = &well_known_sid_values[i];
2108
char sid_buffer[SECURITY_MAX_SID_SIZE];
2109
LPSTR str;
2110
DWORD cb;
2111
2112
if (value->sid_string == NULL)
2113
continue;
2114
2115
/* some SIDs aren't implemented by all Windows versions - detect it */
2116
cb = sizeof(sid_buffer);
2117
if (!CreateWellKnownSid(i, NULL, sid_buffer, &cb))
2118
{
2119
skip("Well known SID %u not implemented\n", i);
2120
continue;
2121
}
2122
2123
cb = sizeof(sid_buffer);
2124
ok(CreateWellKnownSid(i, value->without_domain ? NULL : domainsid, sid_buffer, &cb), "Couldn't create well known sid %u\n", i);
2125
expect_eq(GetSidLengthRequired(*GetSidSubAuthorityCount(sid_buffer)), cb, DWORD, "%ld");
2126
ok(IsValidSid(sid_buffer), "The sid is not valid\n");
2127
ok(ConvertSidToStringSidA(sid_buffer, &str), "Couldn't convert SID to string\n");
2128
ok(strcmp(str, value->sid_string) == 0, "%d: SID mismatch - expected %s, got %s\n", i,
2129
value->sid_string, str);
2130
LocalFree(str);
2131
2132
if (value->without_domain)
2133
{
2134
char buf2[SECURITY_MAX_SID_SIZE];
2135
cb = sizeof(buf2);
2136
ok(CreateWellKnownSid(i, domainsid, buf2, &cb), "Couldn't create well known sid %u with optional domain\n", i);
2137
expect_eq(GetSidLengthRequired(*GetSidSubAuthorityCount(sid_buffer)), cb, DWORD, "%ld");
2138
ok(memcmp(buf2, sid_buffer, cb) == 0, "SID create with domain is different than without (%u)\n", i);
2139
}
2140
}
2141
2142
FreeSid(domainsid);
2143
}
2144
2145
static void test_LookupAccountSid(void)
2146
{
2147
SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY };
2148
CHAR accountA[MAX_PATH], domainA[MAX_PATH], usernameA[MAX_PATH];
2149
DWORD acc_sizeA, dom_sizeA, user_sizeA;
2150
DWORD real_acc_sizeA, real_dom_sizeA;
2151
WCHAR accountW[MAX_PATH], domainW[MAX_PATH];
2152
LSA_OBJECT_ATTRIBUTES object_attributes;
2153
DWORD acc_sizeW, dom_sizeW;
2154
DWORD real_acc_sizeW, real_dom_sizeW;
2155
PSID pUsersSid = NULL;
2156
SID_NAME_USE use;
2157
BOOL ret;
2158
DWORD error, size, cbti = 0;
2159
MAX_SID max_sid;
2160
CHAR *str_sidA;
2161
int i;
2162
HANDLE hToken;
2163
PTOKEN_USER ptiUser = NULL;
2164
LSA_HANDLE handle;
2165
NTSTATUS status;
2166
2167
/* native windows crashes if account size, domain size, or name use is NULL */
2168
2169
ret = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
2170
DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &pUsersSid);
2171
ok(ret || (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED),
2172
"AllocateAndInitializeSid failed with error %ld\n", GetLastError());
2173
2174
/* not running on NT so give up */
2175
if (!ret && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
2176
return;
2177
2178
real_acc_sizeA = MAX_PATH;
2179
real_dom_sizeA = MAX_PATH;
2180
ret = LookupAccountSidA(NULL, pUsersSid, accountA, &real_acc_sizeA, domainA, &real_dom_sizeA, &use);
2181
ok(ret, "LookupAccountSidA() Expected TRUE, got FALSE\n");
2182
2183
/* try NULL account */
2184
acc_sizeA = MAX_PATH;
2185
dom_sizeA = MAX_PATH;
2186
ret = LookupAccountSidA(NULL, pUsersSid, NULL, &acc_sizeA, domainA, &dom_sizeA, &use);
2187
ok(ret, "LookupAccountSidA() Expected TRUE, got FALSE\n");
2188
2189
/* try NULL domain */
2190
acc_sizeA = MAX_PATH;
2191
dom_sizeA = MAX_PATH;
2192
ret = LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, NULL, &dom_sizeA, &use);
2193
ok(ret, "LookupAccountSidA() Expected TRUE, got FALSE\n");
2194
2195
/* try a small account buffer */
2196
acc_sizeA = 1;
2197
dom_sizeA = MAX_PATH;
2198
accountA[0] = 0;
2199
ret = LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use);
2200
ok(!ret, "LookupAccountSidA() Expected FALSE got TRUE\n");
2201
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2202
"LookupAccountSidA() Expected ERROR_NOT_ENOUGH_MEMORY, got %lu\n", GetLastError());
2203
2204
/* try a 0 sized account buffer */
2205
acc_sizeA = 0;
2206
dom_sizeA = MAX_PATH;
2207
accountA[0] = 0;
2208
LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use);
2209
/* this can fail or succeed depending on OS version but the size will always be returned */
2210
ok(acc_sizeA == real_acc_sizeA + 1,
2211
"LookupAccountSidA() Expected acc_size = %lu, got %lu\n",
2212
real_acc_sizeA + 1, acc_sizeA);
2213
2214
/* try a 0 sized account buffer */
2215
acc_sizeA = 0;
2216
dom_sizeA = MAX_PATH;
2217
LookupAccountSidA(NULL, pUsersSid, NULL, &acc_sizeA, domainA, &dom_sizeA, &use);
2218
/* this can fail or succeed depending on OS version but the size will always be returned */
2219
ok(acc_sizeA == real_acc_sizeA + 1,
2220
"LookupAccountSid() Expected acc_size = %lu, got %lu\n",
2221
real_acc_sizeA + 1, acc_sizeA);
2222
2223
/* try a small domain buffer */
2224
dom_sizeA = 1;
2225
acc_sizeA = MAX_PATH;
2226
accountA[0] = 0;
2227
ret = LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use);
2228
ok(!ret, "LookupAccountSidA() Expected FALSE got TRUE\n");
2229
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2230
"LookupAccountSidA() Expected ERROR_NOT_ENOUGH_MEMORY, got %lu\n", GetLastError());
2231
2232
/* try a 0 sized domain buffer */
2233
dom_sizeA = 0;
2234
acc_sizeA = MAX_PATH;
2235
accountA[0] = 0;
2236
LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use);
2237
/* this can fail or succeed depending on OS version but the size will always be returned */
2238
ok(dom_sizeA == real_dom_sizeA + 1,
2239
"LookupAccountSidA() Expected dom_size = %lu, got %lu\n",
2240
real_dom_sizeA + 1, dom_sizeA);
2241
2242
/* try a 0 sized domain buffer */
2243
dom_sizeA = 0;
2244
acc_sizeA = MAX_PATH;
2245
LookupAccountSidA(NULL, pUsersSid, accountA, &acc_sizeA, NULL, &dom_sizeA, &use);
2246
/* this can fail or succeed depending on OS version but the size will always be returned */
2247
ok(dom_sizeA == real_dom_sizeA + 1,
2248
"LookupAccountSidA() Expected dom_size = %lu, got %lu\n",
2249
real_dom_sizeA + 1, dom_sizeA);
2250
2251
real_acc_sizeW = MAX_PATH;
2252
real_dom_sizeW = MAX_PATH;
2253
ret = LookupAccountSidW(NULL, pUsersSid, accountW, &real_acc_sizeW, domainW, &real_dom_sizeW, &use);
2254
ok(ret, "LookupAccountSidW() Expected TRUE, got FALSE\n");
2255
2256
/* try an invalid system name */
2257
real_acc_sizeA = MAX_PATH;
2258
real_dom_sizeA = MAX_PATH;
2259
ret = LookupAccountSidA("deepthought", pUsersSid, accountA, &real_acc_sizeA, domainA, &real_dom_sizeA, &use);
2260
ok(!ret, "LookupAccountSidA() Expected FALSE got TRUE\n");
2261
ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == RPC_S_INVALID_NET_ADDR /* Vista */,
2262
"LookupAccountSidA() Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %lu\n", GetLastError());
2263
2264
/* native windows crashes if domainW or accountW is NULL */
2265
2266
/* try a small account buffer */
2267
acc_sizeW = 1;
2268
dom_sizeW = MAX_PATH;
2269
accountW[0] = 0;
2270
ret = LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, domainW, &dom_sizeW, &use);
2271
ok(!ret, "LookupAccountSidW() Expected FALSE got TRUE\n");
2272
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2273
"LookupAccountSidW() Expected ERROR_NOT_ENOUGH_MEMORY, got %lu\n", GetLastError());
2274
2275
/* try a 0 sized account buffer */
2276
acc_sizeW = 0;
2277
dom_sizeW = MAX_PATH;
2278
accountW[0] = 0;
2279
LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, domainW, &dom_sizeW, &use);
2280
/* this can fail or succeed depending on OS version but the size will always be returned */
2281
ok(acc_sizeW == real_acc_sizeW + 1,
2282
"LookupAccountSidW() Expected acc_size = %lu, got %lu\n",
2283
real_acc_sizeW + 1, acc_sizeW);
2284
2285
/* try a 0 sized account buffer */
2286
acc_sizeW = 0;
2287
dom_sizeW = MAX_PATH;
2288
LookupAccountSidW(NULL, pUsersSid, NULL, &acc_sizeW, domainW, &dom_sizeW, &use);
2289
/* this can fail or succeed depending on OS version but the size will always be returned */
2290
ok(acc_sizeW == real_acc_sizeW + 1,
2291
"LookupAccountSidW() Expected acc_size = %lu, got %lu\n",
2292
real_acc_sizeW + 1, acc_sizeW);
2293
2294
/* try a small domain buffer */
2295
dom_sizeW = 1;
2296
acc_sizeW = MAX_PATH;
2297
accountW[0] = 0;
2298
ret = LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, domainW, &dom_sizeW, &use);
2299
ok(!ret, "LookupAccountSidW() Expected FALSE got TRUE\n");
2300
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2301
"LookupAccountSidW() Expected ERROR_NOT_ENOUGH_MEMORY, got %lu\n", GetLastError());
2302
2303
/* try a 0 sized domain buffer */
2304
dom_sizeW = 0;
2305
acc_sizeW = MAX_PATH;
2306
accountW[0] = 0;
2307
LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, domainW, &dom_sizeW, &use);
2308
/* this can fail or succeed depending on OS version but the size will always be returned */
2309
ok(dom_sizeW == real_dom_sizeW + 1,
2310
"LookupAccountSidW() Expected dom_size = %lu, got %lu\n",
2311
real_dom_sizeW + 1, dom_sizeW);
2312
2313
/* try a 0 sized domain buffer */
2314
dom_sizeW = 0;
2315
acc_sizeW = MAX_PATH;
2316
LookupAccountSidW(NULL, pUsersSid, accountW, &acc_sizeW, NULL, &dom_sizeW, &use);
2317
/* this can fail or succeed depending on OS version but the size will always be returned */
2318
ok(dom_sizeW == real_dom_sizeW + 1,
2319
"LookupAccountSidW() Expected dom_size = %lu, got %lu\n",
2320
real_dom_sizeW + 1, dom_sizeW);
2321
2322
acc_sizeW = dom_sizeW = use = 0;
2323
SetLastError(0xdeadbeef);
2324
ret = LookupAccountSidW(NULL, pUsersSid, NULL, &acc_sizeW, NULL, &dom_sizeW, &use);
2325
error = GetLastError();
2326
ok(!ret, "LookupAccountSidW failed %lu\n", GetLastError());
2327
ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %lu\n", error);
2328
ok(acc_sizeW, "expected non-zero account size\n");
2329
ok(dom_sizeW, "expected non-zero domain size\n");
2330
ok(!use, "expected zero use %u\n", use);
2331
2332
FreeSid(pUsersSid);
2333
2334
/* Test LookupAccountSid with Sid retrieved from token information.
2335
This assumes this process is running under the account of the current user.*/
2336
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_DUPLICATE, &hToken);
2337
ok(ret, "OpenProcessToken failed with error %ld\n", GetLastError());
2338
ret = GetTokenInformation(hToken, TokenUser, NULL, 0, &cbti);
2339
ok(!ret, "GetTokenInformation failed with error %ld\n", GetLastError());
2340
ptiUser = malloc(cbti);
2341
if (GetTokenInformation(hToken, TokenUser, ptiUser, cbti, &cbti))
2342
{
2343
acc_sizeA = dom_sizeA = MAX_PATH;
2344
ret = LookupAccountSidA(NULL, ptiUser->User.Sid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use);
2345
ok(ret, "LookupAccountSidA() Expected TRUE, got FALSE\n");
2346
user_sizeA = MAX_PATH;
2347
ret = GetUserNameA(usernameA , &user_sizeA);
2348
ok(ret, "GetUserNameA() Expected TRUE, got FALSE\n");
2349
ok(lstrcmpA(usernameA, accountA) == 0, "LookupAccountSidA() Expected account name: %s got: %s\n", usernameA, accountA );
2350
}
2351
free(ptiUser);
2352
2353
trace("Well Known SIDs:\n");
2354
for (i = 0; i <= 60; i++)
2355
{
2356
size = SECURITY_MAX_SID_SIZE;
2357
if (CreateWellKnownSid(i, NULL, &max_sid.sid, &size))
2358
{
2359
if (ConvertSidToStringSidA(&max_sid.sid, &str_sidA))
2360
{
2361
acc_sizeA = MAX_PATH;
2362
dom_sizeA = MAX_PATH;
2363
if (LookupAccountSidA(NULL, &max_sid.sid, accountA, &acc_sizeA, domainA, &dom_sizeA, &use))
2364
trace(" %d: %s %s\\%s %d\n", i, str_sidA, domainA, accountA, use);
2365
LocalFree(str_sidA);
2366
}
2367
}
2368
else
2369
{
2370
if (GetLastError() != ERROR_INVALID_PARAMETER)
2371
trace(" CreateWellKnownSid(%d) failed: %ld\n", i, GetLastError());
2372
else
2373
trace(" %d: not supported\n", i);
2374
}
2375
}
2376
2377
ZeroMemory(&object_attributes, sizeof(object_attributes));
2378
object_attributes.Length = sizeof(object_attributes);
2379
2380
status = LsaOpenPolicy( NULL, &object_attributes, POLICY_ALL_ACCESS, &handle);
2381
ok(status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED,
2382
"LsaOpenPolicy(POLICY_ALL_ACCESS) returned 0x%08lx\n", status);
2383
2384
/* try a more restricted access mask if necessary */
2385
if (status == STATUS_ACCESS_DENIED) {
2386
trace("LsaOpenPolicy(POLICY_ALL_ACCESS) failed, trying POLICY_VIEW_LOCAL_INFORMATION\n");
2387
status = LsaOpenPolicy( NULL, &object_attributes, POLICY_VIEW_LOCAL_INFORMATION, &handle);
2388
ok(status == STATUS_SUCCESS, "LsaOpenPolicy(POLICY_VIEW_LOCAL_INFORMATION) returned 0x%08lx\n", status);
2389
}
2390
2391
if (status == STATUS_SUCCESS)
2392
{
2393
PPOLICY_ACCOUNT_DOMAIN_INFO info;
2394
status = LsaQueryInformationPolicy(handle, PolicyAccountDomainInformation, (PVOID*)&info);
2395
ok(status == STATUS_SUCCESS, "LsaQueryInformationPolicy() failed, returned 0x%08lx\n", status);
2396
if (status == STATUS_SUCCESS)
2397
{
2398
ok(info->DomainSid!=0, "LsaQueryInformationPolicy(PolicyAccountDomainInformation) missing SID\n");
2399
if (info->DomainSid)
2400
{
2401
int count = *GetSidSubAuthorityCount(info->DomainSid);
2402
CopySid(GetSidLengthRequired(count), &max_sid, info->DomainSid);
2403
test_sid_str((PSID)&max_sid.sid);
2404
max_sid.sid.SubAuthority[count] = DOMAIN_USER_RID_ADMIN;
2405
max_sid.sid.SubAuthorityCount = count + 1;
2406
test_sid_str((PSID)&max_sid.sid);
2407
max_sid.sid.SubAuthority[count] = DOMAIN_USER_RID_GUEST;
2408
test_sid_str((PSID)&max_sid.sid);
2409
max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_ADMINS;
2410
test_sid_str((PSID)&max_sid.sid);
2411
max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_USERS;
2412
test_sid_str((PSID)&max_sid.sid);
2413
max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_GUESTS;
2414
test_sid_str((PSID)&max_sid.sid);
2415
max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_COMPUTERS;
2416
test_sid_str((PSID)&max_sid.sid);
2417
max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_CONTROLLERS;
2418
test_sid_str((PSID)&max_sid.sid);
2419
max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_CERT_ADMINS;
2420
test_sid_str((PSID)&max_sid.sid);
2421
max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_SCHEMA_ADMINS;
2422
test_sid_str((PSID)&max_sid.sid);
2423
max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_ENTERPRISE_ADMINS;
2424
test_sid_str((PSID)&max_sid.sid);
2425
max_sid.sid.SubAuthority[count] = DOMAIN_GROUP_RID_POLICY_ADMINS;
2426
test_sid_str((PSID)&max_sid.sid);
2427
max_sid.sid.SubAuthority[count] = DOMAIN_ALIAS_RID_RAS_SERVERS;
2428
test_sid_str((PSID)&max_sid.sid);
2429
max_sid.sid.SubAuthority[count] = 1000; /* first user account */
2430
test_sid_str((PSID)&max_sid.sid);
2431
}
2432
2433
LsaFreeMemory(info);
2434
}
2435
2436
status = LsaClose(handle);
2437
ok(status == STATUS_SUCCESS, "LsaClose() failed, returned 0x%08lx\n", status);
2438
}
2439
}
2440
2441
static BOOL get_sid_info(PSID psid, LPSTR *user, LPSTR *dom)
2442
{
2443
static CHAR account[UNLEN + 1];
2444
static CHAR domain[UNLEN + 1];
2445
DWORD size, dom_size;
2446
SID_NAME_USE use;
2447
2448
*user = account;
2449
*dom = domain;
2450
2451
size = dom_size = UNLEN + 1;
2452
account[0] = '\0';
2453
domain[0] = '\0';
2454
SetLastError(0xdeadbeef);
2455
return LookupAccountSidA(NULL, psid, account, &size, domain, &dom_size, &use);
2456
}
2457
2458
static void check_wellknown_name(const char* name, WELL_KNOWN_SID_TYPE result)
2459
{
2460
SID_IDENTIFIER_AUTHORITY ident = { SECURITY_NT_AUTHORITY };
2461
PSID domainsid = NULL;
2462
char wk_sid[SECURITY_MAX_SID_SIZE];
2463
DWORD cb;
2464
2465
DWORD sid_size, domain_size;
2466
SID_NAME_USE sid_use;
2467
LPSTR domain, account, sid_domain, wk_domain, wk_account;
2468
PSID psid;
2469
BOOL ret ,ret2;
2470
2471
sid_size = 0;
2472
domain_size = 0;
2473
ret = LookupAccountNameA(NULL, name, NULL, &sid_size, NULL, &domain_size, &sid_use);
2474
ok(!ret, " %s Should have failed to lookup account name\n", name);
2475
psid = malloc(sid_size);
2476
domain = malloc(domain_size);
2477
ret = LookupAccountNameA(NULL, name, psid, &sid_size, domain, &domain_size, &sid_use);
2478
2479
if (!result)
2480
{
2481
ok(!ret, " %s Should have failed to lookup account name\n",name);
2482
goto cleanup;
2483
}
2484
2485
AllocateAndInitializeSid(&ident, 6, SECURITY_NT_NON_UNIQUE, 12, 23, 34, 45, 56, 0, 0, &domainsid);
2486
cb = sizeof(wk_sid);
2487
if (!CreateWellKnownSid(result, domainsid, wk_sid, &cb))
2488
{
2489
win_skip("SID %i is not available on the system\n",result);
2490
goto cleanup;
2491
}
2492
2493
ret2 = get_sid_info(wk_sid, &wk_account, &wk_domain);
2494
if (!ret2 && GetLastError() == ERROR_NONE_MAPPED)
2495
{
2496
win_skip("CreateWellKnownSid() succeeded but the account '%s' is not present (W2K)\n", name);
2497
goto cleanup;
2498
}
2499
2500
get_sid_info(psid, &account, &sid_domain);
2501
2502
ok(ret, "Failed to lookup account name %s\n",name);
2503
ok(sid_size != 0, "sid_size was zero\n");
2504
2505
ok(EqualSid(psid,wk_sid),"%s Sid %s fails to match well known sid %s!\n",
2506
name, debugstr_sid(psid), debugstr_sid(wk_sid));
2507
2508
ok(!lstrcmpA(account, wk_account), "Expected %s , got %s\n", account, wk_account);
2509
ok(!lstrcmpA(domain, wk_domain), "Expected %s, got %s\n", wk_domain, domain);
2510
ok(sid_use == SidTypeWellKnownGroup , "Expected Use (5), got %d\n", sid_use);
2511
2512
cleanup:
2513
FreeSid(domainsid);
2514
free(psid);
2515
free(domain);
2516
}
2517
2518
static void test_LookupAccountName(void)
2519
{
2520
DWORD sid_size, domain_size, user_size;
2521
DWORD sid_save, domain_save;
2522
CHAR user_name[UNLEN + 1];
2523
CHAR computer_name[UNLEN + 1];
2524
SID_NAME_USE sid_use;
2525
LPSTR domain, account, sid_dom;
2526
PSID psid;
2527
BOOL ret;
2528
2529
/* native crashes if (assuming all other parameters correct):
2530
* - peUse is NULL
2531
* - Sid is NULL and cbSid is > 0
2532
* - cbSid or cchReferencedDomainName are NULL
2533
* - ReferencedDomainName is NULL and cchReferencedDomainName is the correct size
2534
*/
2535
2536
user_size = UNLEN + 1;
2537
SetLastError(0xdeadbeef);
2538
ret = GetUserNameA(user_name, &user_size);
2539
ok(ret, "Failed to get user name : %ld\n", GetLastError());
2540
2541
/* get sizes */
2542
sid_size = 0;
2543
domain_size = 0;
2544
sid_use = 0xcafebabe;
2545
SetLastError(0xdeadbeef);
2546
ret = LookupAccountNameA(NULL, user_name, NULL, &sid_size, NULL, &domain_size, &sid_use);
2547
if(!ret && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
2548
{
2549
win_skip("LookupAccountNameA is not implemented\n");
2550
return;
2551
}
2552
ok(!ret, "Expected 0, got %d\n", ret);
2553
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2554
"Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
2555
ok(sid_size != 0, "Expected non-zero sid size\n");
2556
ok(domain_size != 0, "Expected non-zero domain size\n");
2557
ok(sid_use == (SID_NAME_USE)0xcafebabe, "Expected 0xcafebabe, got %d\n", sid_use);
2558
2559
sid_save = sid_size;
2560
domain_save = domain_size;
2561
2562
psid = malloc(sid_size);
2563
domain = malloc(domain_size);
2564
2565
/* try valid account name */
2566
ret = LookupAccountNameA(NULL, user_name, psid, &sid_size, domain, &domain_size, &sid_use);
2567
get_sid_info(psid, &account, &sid_dom);
2568
ok(ret, "Failed to lookup account name\n");
2569
ok(sid_size == GetLengthSid(psid), "Expected %ld, got %ld\n", GetLengthSid(psid), sid_size);
2570
ok(!lstrcmpA(account, user_name), "Expected %s, got %s\n", user_name, account);
2571
ok(!lstrcmpiA(domain, sid_dom), "Expected %s, got %s\n", sid_dom, domain);
2572
ok(domain_size == domain_save - 1, "Expected %ld, got %ld\n", domain_save - 1, domain_size);
2573
ok(strlen(domain) == domain_size, "Expected %d, got %ld\n", lstrlenA(domain), domain_size);
2574
ok(sid_use == SidTypeUser, "Expected SidTypeUser (%d), got %d\n", SidTypeUser, sid_use);
2575
domain_size = domain_save;
2576
sid_size = sid_save;
2577
2578
if (PRIMARYLANGID(GetSystemDefaultLangID()) != LANG_ENGLISH)
2579
{
2580
skip("Non-English locale (test with hardcoded 'Everyone')\n");
2581
}
2582
else
2583
{
2584
ret = LookupAccountNameA(NULL, "Everyone", psid, &sid_size, domain, &domain_size, &sid_use);
2585
get_sid_info(psid, &account, &sid_dom);
2586
ok(ret, "Failed to lookup account name\n");
2587
ok(sid_size != 0, "sid_size was zero\n");
2588
ok(!lstrcmpA(account, "Everyone"), "Expected Everyone, got %s\n", account);
2589
ok(!lstrcmpiA(domain, sid_dom), "Expected %s, got %s\n", sid_dom, domain);
2590
ok(domain_size == 0, "Expected 0, got %ld\n", domain_size);
2591
ok(strlen(domain) == domain_size, "Expected %d, got %ld\n", lstrlenA(domain), domain_size);
2592
ok(sid_use == SidTypeWellKnownGroup, "Expected SidTypeWellKnownGroup (%d), got %d\n", SidTypeWellKnownGroup, sid_use);
2593
domain_size = domain_save;
2594
}
2595
2596
/* NULL Sid with zero sid size */
2597
SetLastError(0xdeadbeef);
2598
sid_size = 0;
2599
ret = LookupAccountNameA(NULL, user_name, NULL, &sid_size, domain, &domain_size, &sid_use);
2600
ok(!ret, "Expected 0, got %d\n", ret);
2601
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2602
"Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
2603
ok(sid_size == sid_save, "Expected %ld, got %ld\n", sid_save, sid_size);
2604
ok(domain_size == domain_save, "Expected %ld, got %ld\n", domain_save, domain_size);
2605
2606
/* try cchReferencedDomainName - 1 */
2607
SetLastError(0xdeadbeef);
2608
domain_size--;
2609
ret = LookupAccountNameA(NULL, user_name, NULL, &sid_size, domain, &domain_size, &sid_use);
2610
ok(!ret, "Expected 0, got %d\n", ret);
2611
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2612
"Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
2613
ok(sid_size == sid_save, "Expected %ld, got %ld\n", sid_save, sid_size);
2614
ok(domain_size == domain_save, "Expected %ld, got %ld\n", domain_save, domain_size);
2615
2616
/* NULL ReferencedDomainName with zero domain name size */
2617
SetLastError(0xdeadbeef);
2618
domain_size = 0;
2619
ret = LookupAccountNameA(NULL, user_name, psid, &sid_size, NULL, &domain_size, &sid_use);
2620
ok(!ret, "Expected 0, got %d\n", ret);
2621
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2622
"Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
2623
ok(sid_size == sid_save, "Expected %ld, got %ld\n", sid_save, sid_size);
2624
ok(domain_size == domain_save, "Expected %ld, got %ld\n", domain_save, domain_size);
2625
2626
free(psid);
2627
free(domain);
2628
2629
/* get sizes for NULL account name */
2630
sid_size = 0;
2631
domain_size = 0;
2632
sid_use = 0xcafebabe;
2633
SetLastError(0xdeadbeef);
2634
ret = LookupAccountNameA(NULL, NULL, NULL, &sid_size, NULL, &domain_size, &sid_use);
2635
ok(!ret, "Expected 0, got %d\n", ret);
2636
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2637
"Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
2638
ok(sid_size != 0, "Expected non-zero sid size\n");
2639
ok(domain_size != 0, "Expected non-zero domain size\n");
2640
ok(sid_use == (SID_NAME_USE)0xcafebabe, "Expected 0xcafebabe, got %d\n", sid_use);
2641
2642
psid = malloc(sid_size);
2643
domain = malloc(domain_size);
2644
2645
/* try NULL account name */
2646
ret = LookupAccountNameA(NULL, NULL, psid, &sid_size, domain, &domain_size, &sid_use);
2647
get_sid_info(psid, &account, &sid_dom);
2648
ok(ret, "Failed to lookup account name\n");
2649
/* Using a fixed string will not work on different locales */
2650
ok(!lstrcmpiA(account, domain),
2651
"Got %s for account and %s for domain, these should be the same\n", account, domain);
2652
ok(sid_use == SidTypeDomain, "Expected SidTypeDomain (%d), got %d\n", SidTypeDomain, sid_use);
2653
2654
free(psid);
2655
free(domain);
2656
2657
/* try an invalid account name */
2658
SetLastError(0xdeadbeef);
2659
sid_size = 0;
2660
domain_size = 0;
2661
ret = LookupAccountNameA(NULL, "oogabooga", NULL, &sid_size, NULL, &domain_size, &sid_use);
2662
ok(!ret, "Expected 0, got %d\n", ret);
2663
ok(GetLastError() == ERROR_NONE_MAPPED ||
2664
broken(GetLastError() == ERROR_TRUSTED_RELATIONSHIP_FAILURE),
2665
"Expected ERROR_NONE_MAPPED, got %ld\n", GetLastError());
2666
ok(sid_size == 0, "Expected 0, got %ld\n", sid_size);
2667
ok(domain_size == 0, "Expected 0, got %ld\n", domain_size);
2668
2669
/* try an invalid system name */
2670
SetLastError(0xdeadbeef);
2671
sid_size = 0;
2672
domain_size = 0;
2673
ret = LookupAccountNameA("deepthought", NULL, NULL, &sid_size, NULL, &domain_size, &sid_use);
2674
ok(!ret, "Expected 0, got %d\n", ret);
2675
ok(GetLastError() == RPC_S_SERVER_UNAVAILABLE || GetLastError() == RPC_S_INVALID_NET_ADDR /* Vista */,
2676
"Expected RPC_S_SERVER_UNAVAILABLE or RPC_S_INVALID_NET_ADDR, got %ld\n", GetLastError());
2677
ok(sid_size == 0, "Expected 0, got %ld\n", sid_size);
2678
ok(domain_size == 0, "Expected 0, got %ld\n", domain_size);
2679
2680
/* try with the computer name as the account name */
2681
domain_size = sizeof(computer_name);
2682
GetComputerNameA(computer_name, &domain_size);
2683
sid_size = 0;
2684
domain_size = 0;
2685
ret = LookupAccountNameA(NULL, computer_name, NULL, &sid_size, NULL, &domain_size, &sid_use);
2686
ok(!ret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
2687
GetLastError() == ERROR_NONE_MAPPED /* in a domain */ ||
2688
broken(GetLastError() == ERROR_TRUSTED_DOMAIN_FAILURE) ||
2689
broken(GetLastError() == ERROR_TRUSTED_RELATIONSHIP_FAILURE)),
2690
"LookupAccountNameA failed: %ld\n", GetLastError());
2691
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
2692
{
2693
psid = malloc(sid_size);
2694
domain = malloc(domain_size);
2695
ret = LookupAccountNameA(NULL, computer_name, psid, &sid_size, domain, &domain_size, &sid_use);
2696
ok(ret, "LookupAccountNameA failed: %ld\n", GetLastError());
2697
ok(sid_use == SidTypeDomain ||
2698
(sid_use == SidTypeUser && ! strcmp(computer_name, user_name)), "expected SidTypeDomain for %s, got %d\n", computer_name, sid_use);
2699
free(domain);
2700
free(psid);
2701
}
2702
2703
/* Well Known names */
2704
if (PRIMARYLANGID(GetSystemDefaultLangID()) != LANG_ENGLISH)
2705
{
2706
skip("Non-English locale (skipping well known name creation tests)\n");
2707
return;
2708
}
2709
2710
check_wellknown_name("LocalService", WinLocalServiceSid);
2711
check_wellknown_name("Local Service", WinLocalServiceSid);
2712
/* 2 spaces */
2713
check_wellknown_name("Local Service", 0);
2714
check_wellknown_name("NetworkService", WinNetworkServiceSid);
2715
check_wellknown_name("Network Service", WinNetworkServiceSid);
2716
2717
/* example of some names where the spaces are not optional */
2718
check_wellknown_name("Terminal Server User", WinTerminalServerSid);
2719
check_wellknown_name("TerminalServer User", 0);
2720
check_wellknown_name("TerminalServerUser", 0);
2721
check_wellknown_name("Terminal ServerUser", 0);
2722
2723
check_wellknown_name("enterprise domain controllers",WinEnterpriseControllersSid);
2724
check_wellknown_name("enterprisedomain controllers", 0);
2725
check_wellknown_name("enterprise domaincontrollers", 0);
2726
check_wellknown_name("enterprisedomaincontrollers", 0);
2727
2728
/* case insensitivity */
2729
check_wellknown_name("lOCAlServICE", WinLocalServiceSid);
2730
2731
/* fully qualified account names */
2732
check_wellknown_name("NT AUTHORITY\\LocalService", WinLocalServiceSid);
2733
check_wellknown_name("nt authority\\Network Service", WinNetworkServiceSid);
2734
check_wellknown_name("nt authority test\\Network Service", 0);
2735
check_wellknown_name("Dummy\\Network Service", 0);
2736
check_wellknown_name("ntauthority\\Network Service", 0);
2737
}
2738
2739
static void test_security_descriptor(void)
2740
{
2741
SECURITY_DESCRIPTOR sd, *sd_rel, *sd_rel2, *sd_abs;
2742
char buf[8192];
2743
DWORD size, size_dacl, size_sacl, size_owner, size_group;
2744
BOOL isDefault, isPresent, ret;
2745
PACL pacl, dacl, sacl;
2746
PSID psid, owner, group;
2747
2748
SetLastError(0xdeadbeef);
2749
ret = InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
2750
if (ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
2751
{
2752
win_skip("InitializeSecurityDescriptor is not implemented\n");
2753
return;
2754
}
2755
2756
ok(GetSecurityDescriptorOwner(&sd, &psid, &isDefault), "GetSecurityDescriptorOwner failed\n");
2757
expect_eq(psid, NULL, PSID, "%p");
2758
expect_eq(isDefault, FALSE, BOOL, "%d");
2759
sd.Control |= SE_DACL_PRESENT | SE_SACL_PRESENT;
2760
2761
SetLastError(0xdeadbeef);
2762
size = 5;
2763
expect_eq(MakeSelfRelativeSD(&sd, buf, &size), FALSE, BOOL, "%d");
2764
expect_eq(GetLastError(), (DWORD)ERROR_INSUFFICIENT_BUFFER, DWORD, "%lu");
2765
ok(size > 5, "Size not increased\n");
2766
if (size <= 8192)
2767
{
2768
expect_eq(MakeSelfRelativeSD(&sd, buf, &size), TRUE, BOOL, "%d");
2769
ok(GetSecurityDescriptorOwner(&sd, &psid, &isDefault), "GetSecurityDescriptorOwner failed\n");
2770
expect_eq(psid, NULL, PSID, "%p");
2771
expect_eq(isDefault, FALSE, BOOL, "%d");
2772
ok(GetSecurityDescriptorGroup(&sd, &psid, &isDefault), "GetSecurityDescriptorGroup failed\n");
2773
expect_eq(psid, NULL, PSID, "%p");
2774
expect_eq(isDefault, FALSE, BOOL, "%d");
2775
ok(GetSecurityDescriptorDacl(&sd, &isPresent, &pacl, &isDefault), "GetSecurityDescriptorDacl failed\n");
2776
expect_eq(isPresent, TRUE, BOOL, "%d");
2777
expect_eq(psid, NULL, PSID, "%p");
2778
expect_eq(isDefault, FALSE, BOOL, "%d");
2779
ok(GetSecurityDescriptorSacl(&sd, &isPresent, &pacl, &isDefault), "GetSecurityDescriptorSacl failed\n");
2780
expect_eq(isPresent, TRUE, BOOL, "%d");
2781
expect_eq(psid, NULL, PSID, "%p");
2782
expect_eq(isDefault, FALSE, BOOL, "%d");
2783
}
2784
2785
ret = ConvertStringSecurityDescriptorToSecurityDescriptorA(
2786
"O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)"
2787
"(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)"
2788
"(AU;NPSA;0x12019f;;;SU)", SDDL_REVISION_1, (void **)&sd_rel, NULL);
2789
ok(ret, "got %lu\n", GetLastError());
2790
2791
size = 0;
2792
ret = MakeSelfRelativeSD(sd_rel, NULL, &size);
2793
todo_wine ok(!ret && GetLastError() == ERROR_BAD_DESCRIPTOR_FORMAT, "got %lu\n", GetLastError());
2794
2795
/* convert to absolute form */
2796
size = size_dacl = size_sacl = size_owner = size_group = 0;
2797
ret = MakeAbsoluteSD(sd_rel, NULL, &size, NULL, &size_dacl, NULL, &size_sacl, NULL, &size_owner, NULL,
2798
&size_group);
2799
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %lu\n", GetLastError());
2800
2801
sd_abs = malloc(size + size_dacl + size_sacl + size_owner + size_group);
2802
dacl = (PACL)(sd_abs + 1);
2803
sacl = (PACL)((char *)dacl + size_dacl);
2804
owner = (PSID)((char *)sacl + size_sacl);
2805
group = (PSID)((char *)owner + size_owner);
2806
ret = MakeAbsoluteSD(sd_rel, sd_abs, &size, dacl, &size_dacl, sacl, &size_sacl, owner, &size_owner,
2807
group, &size_group);
2808
ok(ret, "got %lu\n", GetLastError());
2809
2810
size = 0;
2811
ret = MakeSelfRelativeSD(sd_abs, NULL, &size);
2812
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %lu\n", GetLastError());
2813
ok(size == 184, "got %lu\n", size);
2814
2815
size += 4;
2816
sd_rel2 = malloc(size);
2817
ret = MakeSelfRelativeSD(sd_abs, sd_rel2, &size);
2818
ok(ret, "got %lu\n", GetLastError());
2819
ok(size == 188, "got %lu\n", size);
2820
2821
free(sd_abs);
2822
free(sd_rel2);
2823
LocalFree(sd_rel);
2824
}
2825
2826
#define TEST_GRANTED_ACCESS(a,b) test_granted_access(a,b,0,__LINE__)
2827
#define TEST_GRANTED_ACCESS2(a,b,c) test_granted_access(a,b,c,__LINE__)
2828
static void test_granted_access(HANDLE handle, ACCESS_MASK access,
2829
ACCESS_MASK alt, int line)
2830
{
2831
OBJECT_BASIC_INFORMATION obj_info;
2832
NTSTATUS status;
2833
2834
status = NtQueryObject( handle, ObjectBasicInformation, &obj_info,
2835
sizeof(obj_info), NULL );
2836
ok_(__FILE__, line)(!status, "NtQueryObject with err: %08lx\n", status);
2837
if (alt)
2838
ok_(__FILE__, line)(obj_info.GrantedAccess == access ||
2839
obj_info.GrantedAccess == alt, "Granted access should be 0x%08lx "
2840
"or 0x%08lx, instead of 0x%08lx\n", access, alt, obj_info.GrantedAccess);
2841
else
2842
ok_(__FILE__, line)(obj_info.GrantedAccess == access, "Granted access should "
2843
"be 0x%08lx, instead of 0x%08lx\n", access, obj_info.GrantedAccess);
2844
}
2845
2846
#define CHECK_SET_SECURITY(o,i,e) \
2847
do{ \
2848
BOOL res_; \
2849
DWORD err; \
2850
SetLastError( 0xdeadbeef ); \
2851
res_ = SetKernelObjectSecurity( o, i, SecurityDescriptor ); \
2852
err = GetLastError(); \
2853
if (e == ERROR_SUCCESS) \
2854
ok(res_, "SetKernelObjectSecurity failed with %ld\n", err); \
2855
else \
2856
ok(!res_ && err == e, "SetKernelObjectSecurity should have failed " \
2857
"with %s, instead of %ld\n", #e, err); \
2858
}while(0)
2859
2860
static void test_process_security(void)
2861
{
2862
BOOL res;
2863
PTOKEN_USER user;
2864
PTOKEN_OWNER owner;
2865
PTOKEN_PRIMARY_GROUP group;
2866
PSID AdminSid = NULL, UsersSid = NULL, UserSid = NULL;
2867
PACL Acl = NULL, ThreadAcl = NULL;
2868
SECURITY_DESCRIPTOR *SecurityDescriptor = NULL, *ThreadSecurityDescriptor = NULL;
2869
char buffer[MAX_PATH], account[MAX_PATH], domain[MAX_PATH];
2870
PROCESS_INFORMATION info;
2871
STARTUPINFOA startup;
2872
SECURITY_ATTRIBUTES psa, tsa;
2873
HANDLE token, event;
2874
DWORD size, acc_size, dom_size, ret;
2875
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
2876
PSID EveryoneSid = NULL;
2877
SID_NAME_USE use;
2878
2879
Acl = malloc(256);
2880
res = InitializeAcl(Acl, 256, ACL_REVISION);
2881
if (!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
2882
{
2883
win_skip("ACLs not implemented - skipping tests\n");
2884
free(Acl);
2885
return;
2886
}
2887
ok(res, "InitializeAcl failed with error %ld\n", GetLastError());
2888
2889
res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid);
2890
ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
2891
2892
/* get owner from the token we might be running as a user not admin */
2893
res = OpenProcessToken( GetCurrentProcess(), MAXIMUM_ALLOWED, &token );
2894
ok(res, "OpenProcessToken failed with error %ld\n", GetLastError());
2895
if (!res)
2896
{
2897
free(Acl);
2898
return;
2899
}
2900
2901
res = GetTokenInformation( token, TokenOwner, NULL, 0, &size );
2902
ok(!res, "Expected failure, got %d\n", res);
2903
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2904
"Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
2905
2906
owner = malloc(size);
2907
res = GetTokenInformation( token, TokenOwner, owner, size, &size );
2908
ok(res, "GetTokenInformation failed with error %ld\n", GetLastError());
2909
AdminSid = owner->Owner;
2910
test_sid_str(AdminSid);
2911
2912
res = GetTokenInformation( token, TokenPrimaryGroup, NULL, 0, &size );
2913
ok(!res, "Expected failure, got %d\n", res);
2914
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2915
"Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
2916
2917
group = malloc(size);
2918
res = GetTokenInformation( token, TokenPrimaryGroup, group, size, &size );
2919
ok(res, "GetTokenInformation failed with error %ld\n", GetLastError());
2920
UsersSid = group->PrimaryGroup;
2921
test_sid_str(UsersSid);
2922
2923
acc_size = sizeof(account);
2924
dom_size = sizeof(domain);
2925
ret = LookupAccountSidA( NULL, UsersSid, account, &acc_size, domain, &dom_size, &use );
2926
ok(ret, "LookupAccountSid failed with %ld\n", ret);
2927
ok(use == SidTypeGroup, "expect SidTypeGroup, got %d\n", use);
2928
if (PRIMARYLANGID(GetSystemDefaultLangID()) != LANG_ENGLISH)
2929
skip("Non-English locale (test with hardcoded 'None')\n");
2930
else
2931
ok(!strcmp(account, "None"), "expect None, got %s\n", account);
2932
2933
res = GetTokenInformation( token, TokenUser, NULL, 0, &size );
2934
ok(!res, "Expected failure, got %d\n", res);
2935
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
2936
"Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
2937
2938
user = malloc(size);
2939
res = GetTokenInformation( token, TokenUser, user, size, &size );
2940
ok(res, "GetTokenInformation failed with error %ld\n", GetLastError());
2941
UserSid = user->User.Sid;
2942
test_sid_str(UserSid);
2943
ok(EqualPrefixSid(UsersSid, UserSid), "TokenPrimaryGroup Sid and TokenUser Sid don't match.\n");
2944
2945
CloseHandle( token );
2946
if (!res)
2947
{
2948
free(group);
2949
free(owner);
2950
free(user);
2951
free(Acl);
2952
return;
2953
}
2954
2955
res = AddAccessDeniedAce(Acl, ACL_REVISION, PROCESS_VM_READ, AdminSid);
2956
ok(res, "AddAccessDeniedAce failed with error %ld\n", GetLastError());
2957
res = AddAccessAllowedAce(Acl, ACL_REVISION, PROCESS_ALL_ACCESS, AdminSid);
2958
ok(res, "AddAccessAllowedAce failed with error %ld\n", GetLastError());
2959
2960
SecurityDescriptor = malloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
2961
res = InitializeSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
2962
ok(res, "InitializeSecurityDescriptor failed with error %ld\n", GetLastError());
2963
2964
event = CreateEventA( NULL, TRUE, TRUE, "test_event" );
2965
ok(event != NULL, "CreateEvent %ld\n", GetLastError());
2966
2967
SecurityDescriptor->Revision = 0;
2968
CHECK_SET_SECURITY( event, OWNER_SECURITY_INFORMATION, ERROR_UNKNOWN_REVISION );
2969
SecurityDescriptor->Revision = SECURITY_DESCRIPTOR_REVISION;
2970
2971
CHECK_SET_SECURITY( event, OWNER_SECURITY_INFORMATION, ERROR_INVALID_SECURITY_DESCR );
2972
CHECK_SET_SECURITY( event, GROUP_SECURITY_INFORMATION, ERROR_INVALID_SECURITY_DESCR );
2973
CHECK_SET_SECURITY( event, SACL_SECURITY_INFORMATION, ERROR_ACCESS_DENIED );
2974
CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS );
2975
/* NULL DACL is valid and means that everyone has access */
2976
SecurityDescriptor->Control |= SE_DACL_PRESENT;
2977
CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS );
2978
2979
/* Set owner and group and dacl */
2980
res = SetSecurityDescriptorOwner(SecurityDescriptor, AdminSid, FALSE);
2981
ok(res, "SetSecurityDescriptorOwner failed with error %ld\n", GetLastError());
2982
CHECK_SET_SECURITY( event, OWNER_SECURITY_INFORMATION, ERROR_SUCCESS );
2983
test_owner_equal( event, AdminSid, __LINE__ );
2984
2985
res = SetSecurityDescriptorGroup(SecurityDescriptor, EveryoneSid, FALSE);
2986
ok(res, "SetSecurityDescriptorGroup failed with error %ld\n", GetLastError());
2987
CHECK_SET_SECURITY( event, GROUP_SECURITY_INFORMATION, ERROR_SUCCESS );
2988
test_group_equal( event, EveryoneSid, __LINE__ );
2989
2990
res = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, Acl, FALSE);
2991
ok(res, "SetSecurityDescriptorDacl failed with error %ld\n", GetLastError());
2992
CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS );
2993
/* setting a dacl should not change the owner or group */
2994
test_owner_equal( event, AdminSid, __LINE__ );
2995
test_group_equal( event, EveryoneSid, __LINE__ );
2996
2997
/* Test again with a different SID in case the previous SID also happens to
2998
* be the one that is incorrectly replacing the group. */
2999
res = SetSecurityDescriptorGroup(SecurityDescriptor, UsersSid, FALSE);
3000
ok(res, "SetSecurityDescriptorGroup failed with error %ld\n", GetLastError());
3001
CHECK_SET_SECURITY( event, GROUP_SECURITY_INFORMATION, ERROR_SUCCESS );
3002
test_group_equal( event, UsersSid, __LINE__ );
3003
3004
res = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, Acl, FALSE);
3005
ok(res, "SetSecurityDescriptorDacl failed with error %ld\n", GetLastError());
3006
CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS );
3007
test_group_equal( event, UsersSid, __LINE__ );
3008
3009
sprintf(buffer, "%s security test", myARGV[0]);
3010
memset(&startup, 0, sizeof(startup));
3011
startup.cb = sizeof(startup);
3012
startup.dwFlags = STARTF_USESHOWWINDOW;
3013
startup.wShowWindow = SW_SHOWNORMAL;
3014
3015
psa.nLength = sizeof(psa);
3016
psa.lpSecurityDescriptor = SecurityDescriptor;
3017
psa.bInheritHandle = TRUE;
3018
3019
ThreadSecurityDescriptor = malloc( SECURITY_DESCRIPTOR_MIN_LENGTH );
3020
res = InitializeSecurityDescriptor( ThreadSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION );
3021
ok(res, "InitializeSecurityDescriptor failed with error %ld\n", GetLastError());
3022
3023
ThreadAcl = malloc( 256 );
3024
res = InitializeAcl( ThreadAcl, 256, ACL_REVISION );
3025
ok(res, "InitializeAcl failed with error %ld\n", GetLastError());
3026
res = AddAccessDeniedAce( ThreadAcl, ACL_REVISION, THREAD_SET_THREAD_TOKEN, AdminSid );
3027
ok(res, "AddAccessDeniedAce failed with error %ld\n", GetLastError() );
3028
res = AddAccessAllowedAce( ThreadAcl, ACL_REVISION, THREAD_ALL_ACCESS, AdminSid );
3029
ok(res, "AddAccessAllowedAce failed with error %ld\n", GetLastError());
3030
3031
res = SetSecurityDescriptorOwner( ThreadSecurityDescriptor, AdminSid, FALSE );
3032
ok(res, "SetSecurityDescriptorOwner failed with error %ld\n", GetLastError());
3033
res = SetSecurityDescriptorGroup( ThreadSecurityDescriptor, UsersSid, FALSE );
3034
ok(res, "SetSecurityDescriptorGroup failed with error %ld\n", GetLastError());
3035
res = SetSecurityDescriptorDacl( ThreadSecurityDescriptor, TRUE, ThreadAcl, FALSE );
3036
ok(res, "SetSecurityDescriptorDacl failed with error %ld\n", GetLastError());
3037
3038
tsa.nLength = sizeof(tsa);
3039
tsa.lpSecurityDescriptor = ThreadSecurityDescriptor;
3040
tsa.bInheritHandle = TRUE;
3041
3042
/* Doesn't matter what ACL say we should get full access for ourselves */
3043
res = CreateProcessA( NULL, buffer, &psa, &tsa, FALSE, 0, NULL, NULL, &startup, &info );
3044
ok(res, "CreateProcess with err:%ld\n", GetLastError());
3045
TEST_GRANTED_ACCESS2( info.hProcess, PROCESS_ALL_ACCESS_NT4,
3046
STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL );
3047
TEST_GRANTED_ACCESS2( info.hThread, THREAD_ALL_ACCESS_NT4,
3048
STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL );
3049
wait_child_process( info.hProcess );
3050
3051
FreeSid(EveryoneSid);
3052
CloseHandle( info.hProcess );
3053
CloseHandle( info.hThread );
3054
CloseHandle( event );
3055
free(group);
3056
free(owner);
3057
free(user);
3058
free(Acl);
3059
free(SecurityDescriptor);
3060
free(ThreadAcl);
3061
free(ThreadSecurityDescriptor);
3062
}
3063
3064
static void test_process_security_child(void)
3065
{
3066
HANDLE handle, handle1;
3067
BOOL ret;
3068
DWORD err;
3069
3070
handle = OpenProcess( PROCESS_TERMINATE, FALSE, GetCurrentProcessId() );
3071
ok(handle != NULL, "OpenProcess(PROCESS_TERMINATE) with err:%ld\n", GetLastError());
3072
TEST_GRANTED_ACCESS( handle, PROCESS_TERMINATE );
3073
3074
ret = DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(),
3075
&handle1, 0, TRUE, DUPLICATE_SAME_ACCESS );
3076
ok(ret, "duplicating handle err:%ld\n", GetLastError());
3077
TEST_GRANTED_ACCESS( handle1, PROCESS_TERMINATE );
3078
3079
CloseHandle( handle1 );
3080
3081
SetLastError( 0xdeadbeef );
3082
ret = DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(),
3083
&handle1, PROCESS_ALL_ACCESS, TRUE, 0 );
3084
err = GetLastError();
3085
ok(!ret && err == ERROR_ACCESS_DENIED, "duplicating handle should have failed "
3086
"with STATUS_ACCESS_DENIED, instead of err:%ld\n", err);
3087
3088
CloseHandle( handle );
3089
3090
/* These two should fail - they are denied by ACL */
3091
handle = OpenProcess( PROCESS_VM_READ, FALSE, GetCurrentProcessId() );
3092
ok(handle == NULL, "OpenProcess(PROCESS_VM_READ) should have failed\n");
3093
handle = OpenProcess( PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId() );
3094
ok(handle == NULL, "OpenProcess(PROCESS_ALL_ACCESS) should have failed\n");
3095
3096
/* Documented privilege elevation */
3097
ret = DuplicateHandle( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
3098
&handle, 0, TRUE, DUPLICATE_SAME_ACCESS );
3099
ok(ret, "duplicating handle err:%ld\n", GetLastError());
3100
TEST_GRANTED_ACCESS2( handle, PROCESS_ALL_ACCESS_NT4,
3101
STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL );
3102
3103
CloseHandle( handle );
3104
3105
/* Same only explicitly asking for all access rights */
3106
ret = DuplicateHandle( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
3107
&handle, PROCESS_ALL_ACCESS, TRUE, 0 );
3108
ok(ret, "duplicating handle err:%ld\n", GetLastError());
3109
TEST_GRANTED_ACCESS2( handle, PROCESS_ALL_ACCESS_NT4,
3110
PROCESS_ALL_ACCESS | PROCESS_QUERY_LIMITED_INFORMATION );
3111
ret = DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(),
3112
&handle1, PROCESS_VM_READ, TRUE, 0 );
3113
ok(ret, "duplicating handle err:%ld\n", GetLastError());
3114
TEST_GRANTED_ACCESS( handle1, PROCESS_VM_READ );
3115
CloseHandle( handle1 );
3116
CloseHandle( handle );
3117
3118
/* Test thread security */
3119
handle = OpenThread( THREAD_TERMINATE, FALSE, GetCurrentThreadId() );
3120
ok(handle != NULL, "OpenThread(THREAD_TERMINATE) with err:%ld\n", GetLastError());
3121
TEST_GRANTED_ACCESS( handle, THREAD_TERMINATE );
3122
CloseHandle( handle );
3123
3124
handle = OpenThread( THREAD_SET_THREAD_TOKEN, FALSE, GetCurrentThreadId() );
3125
ok(handle == NULL, "OpenThread(THREAD_SET_THREAD_TOKEN) should have failed\n");
3126
}
3127
3128
static void test_impersonation_level(void)
3129
{
3130
HANDLE Token, ProcessToken;
3131
HANDLE Token2;
3132
DWORD Size;
3133
TOKEN_PRIVILEGES *Privileges;
3134
TOKEN_USER *User;
3135
PRIVILEGE_SET *PrivilegeSet;
3136
BOOL AccessGranted;
3137
BOOL ret;
3138
HKEY hkey;
3139
DWORD error;
3140
3141
SetLastError(0xdeadbeef);
3142
ret = ImpersonateSelf(SecurityAnonymous);
3143
if(!ret && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
3144
{
3145
win_skip("ImpersonateSelf is not implemented\n");
3146
return;
3147
}
3148
ok(ret, "ImpersonateSelf(SecurityAnonymous) failed with error %ld\n", GetLastError());
3149
ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY_SOURCE | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, TRUE, &Token);
3150
ok(!ret, "OpenThreadToken should have failed\n");
3151
error = GetLastError();
3152
ok(error == ERROR_CANT_OPEN_ANONYMOUS, "OpenThreadToken on anonymous token should have returned ERROR_CANT_OPEN_ANONYMOUS instead of %ld\n", error);
3153
/* can't perform access check when opening object against an anonymous impersonation token */
3154
todo_wine {
3155
error = RegOpenKeyExA(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey);
3156
ok(error == ERROR_INVALID_HANDLE || error == ERROR_CANT_OPEN_ANONYMOUS || error == ERROR_BAD_IMPERSONATION_LEVEL,
3157
"RegOpenKeyEx failed with %ld\n", error);
3158
}
3159
RevertToSelf();
3160
3161
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &ProcessToken);
3162
ok(ret, "OpenProcessToken failed with error %ld\n", GetLastError());
3163
3164
ret = DuplicateTokenEx(ProcessToken,
3165
TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE, NULL,
3166
SecurityAnonymous, TokenImpersonation, &Token);
3167
ok(ret, "DuplicateTokenEx failed with error %ld\n", GetLastError());
3168
/* can't increase the impersonation level */
3169
ret = DuplicateToken(Token, SecurityIdentification, &Token2);
3170
error = GetLastError();
3171
ok(!ret && error == ERROR_BAD_IMPERSONATION_LEVEL,
3172
"Duplicating a token and increasing the impersonation level should have failed with ERROR_BAD_IMPERSONATION_LEVEL instead of %ld\n", error);
3173
/* we can query anything from an anonymous token, including the user */
3174
ret = GetTokenInformation(Token, TokenUser, NULL, 0, &Size);
3175
error = GetLastError();
3176
ok(!ret && error == ERROR_INSUFFICIENT_BUFFER, "GetTokenInformation(TokenUser) should have failed with ERROR_INSUFFICIENT_BUFFER instead of %ld\n", error);
3177
User = malloc(Size);
3178
ret = GetTokenInformation(Token, TokenUser, User, Size, &Size);
3179
ok(ret, "GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError());
3180
free(User);
3181
3182
/* PrivilegeCheck fails with SecurityAnonymous level */
3183
ret = GetTokenInformation(Token, TokenPrivileges, NULL, 0, &Size);
3184
error = GetLastError();
3185
ok(!ret && error == ERROR_INSUFFICIENT_BUFFER, "GetTokenInformation(TokenPrivileges) should have failed with ERROR_INSUFFICIENT_BUFFER instead of %ld\n", error);
3186
Privileges = malloc(Size);
3187
ret = GetTokenInformation(Token, TokenPrivileges, Privileges, Size, &Size);
3188
ok(ret, "GetTokenInformation(TokenPrivileges) failed with error %ld\n", GetLastError());
3189
3190
PrivilegeSet = malloc(FIELD_OFFSET(PRIVILEGE_SET, Privilege[Privileges->PrivilegeCount]));
3191
PrivilegeSet->PrivilegeCount = Privileges->PrivilegeCount;
3192
memcpy(PrivilegeSet->Privilege, Privileges->Privileges, PrivilegeSet->PrivilegeCount * sizeof(PrivilegeSet->Privilege[0]));
3193
PrivilegeSet->Control = PRIVILEGE_SET_ALL_NECESSARY;
3194
free(Privileges);
3195
3196
ret = PrivilegeCheck(Token, PrivilegeSet, &AccessGranted);
3197
error = GetLastError();
3198
ok(!ret && error == ERROR_BAD_IMPERSONATION_LEVEL, "PrivilegeCheck for SecurityAnonymous token should have failed with ERROR_BAD_IMPERSONATION_LEVEL instead of %ld\n", error);
3199
3200
CloseHandle(Token);
3201
3202
ret = ImpersonateSelf(SecurityIdentification);
3203
ok(ret, "ImpersonateSelf(SecurityIdentification) failed with error %ld\n", GetLastError());
3204
ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY_SOURCE | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, TRUE, &Token);
3205
ok(ret, "OpenThreadToken failed with error %ld\n", GetLastError());
3206
3207
/* can't perform access check when opening object against an identification impersonation token */
3208
error = RegOpenKeyExA(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey);
3209
todo_wine {
3210
ok(error == ERROR_INVALID_HANDLE || error == ERROR_BAD_IMPERSONATION_LEVEL || error == ERROR_ACCESS_DENIED,
3211
"RegOpenKeyEx should have failed with ERROR_INVALID_HANDLE, ERROR_BAD_IMPERSONATION_LEVEL or ERROR_ACCESS_DENIED instead of %ld\n", error);
3212
}
3213
ret = PrivilegeCheck(Token, PrivilegeSet, &AccessGranted);
3214
ok(ret, "PrivilegeCheck for SecurityIdentification failed with error %ld\n", GetLastError());
3215
CloseHandle(Token);
3216
RevertToSelf();
3217
3218
ret = ImpersonateSelf(SecurityImpersonation);
3219
ok(ret, "ImpersonateSelf(SecurityImpersonation) failed with error %ld\n", GetLastError());
3220
ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY_SOURCE | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, TRUE, &Token);
3221
ok(ret, "OpenThreadToken failed with error %ld\n", GetLastError());
3222
error = RegOpenKeyExA(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey);
3223
ok(error == ERROR_SUCCESS, "RegOpenKeyEx should have succeeded instead of failing with %ld\n", error);
3224
RegCloseKey(hkey);
3225
ret = PrivilegeCheck(Token, PrivilegeSet, &AccessGranted);
3226
ok(ret, "PrivilegeCheck for SecurityImpersonation failed with error %ld\n", GetLastError());
3227
RevertToSelf();
3228
3229
CloseHandle(Token);
3230
CloseHandle(ProcessToken);
3231
3232
free(PrivilegeSet);
3233
}
3234
3235
static void test_SetEntriesInAclW(void)
3236
{
3237
DWORD res;
3238
PSID EveryoneSid = NULL, UsersSid = NULL;
3239
PACL OldAcl = NULL, NewAcl;
3240
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
3241
SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY };
3242
EXPLICIT_ACCESSW ExplicitAccess;
3243
3244
NewAcl = (PACL)0xdeadbeef;
3245
res = SetEntriesInAclW(0, NULL, NULL, &NewAcl);
3246
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
3247
ok(NewAcl == NULL, "NewAcl=%p, expected NULL\n", NewAcl);
3248
LocalFree(NewAcl);
3249
3250
OldAcl = malloc(256);
3251
res = InitializeAcl(OldAcl, 256, ACL_REVISION);
3252
if(!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
3253
{
3254
win_skip("ACLs not implemented - skipping tests\n");
3255
free(OldAcl);
3256
return;
3257
}
3258
ok(res, "InitializeAcl failed with error %ld\n", GetLastError());
3259
3260
res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid);
3261
ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
3262
3263
res = AllocateAndInitializeSid( &SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
3264
DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &UsersSid);
3265
ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
3266
3267
res = AddAccessAllowedAce(OldAcl, ACL_REVISION, KEY_READ, UsersSid);
3268
ok(res, "AddAccessAllowedAce failed with error %ld\n", GetLastError());
3269
3270
ExplicitAccess.grfAccessPermissions = KEY_WRITE;
3271
ExplicitAccess.grfAccessMode = GRANT_ACCESS;
3272
ExplicitAccess.grfInheritance = NO_INHERITANCE;
3273
ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
3274
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
3275
ExplicitAccess.Trustee.ptstrName = EveryoneSid;
3276
ExplicitAccess.Trustee.MultipleTrusteeOperation = 0xDEADBEEF;
3277
ExplicitAccess.Trustee.pMultipleTrustee = (PVOID)0xDEADBEEF;
3278
res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3279
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
3280
ok(NewAcl != NULL, "returned acl was NULL\n");
3281
LocalFree(NewAcl);
3282
3283
ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3284
ExplicitAccess.Trustee.pMultipleTrustee = NULL;
3285
ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3286
res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3287
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
3288
ok(NewAcl != NULL, "returned acl was NULL\n");
3289
LocalFree(NewAcl);
3290
3291
if (PRIMARYLANGID(GetSystemDefaultLangID()) != LANG_ENGLISH)
3292
{
3293
skip("Non-English locale (test with hardcoded 'Everyone')\n");
3294
}
3295
else
3296
{
3297
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3298
ExplicitAccess.Trustee.ptstrName = (WCHAR *)L"Everyone";
3299
res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3300
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
3301
ok(NewAcl != NULL, "returned acl was NULL\n");
3302
LocalFree(NewAcl);
3303
3304
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_BAD_FORM;
3305
res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3306
ok(res == ERROR_INVALID_PARAMETER,
3307
"SetEntriesInAclW failed: %lu\n", res);
3308
ok(NewAcl == NULL,
3309
"returned acl wasn't NULL: %p\n", NewAcl);
3310
3311
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3312
ExplicitAccess.Trustee.MultipleTrusteeOperation = TRUSTEE_IS_IMPERSONATE;
3313
res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3314
ok(res == ERROR_INVALID_PARAMETER,
3315
"SetEntriesInAclW failed: %lu\n", res);
3316
ok(NewAcl == NULL,
3317
"returned acl wasn't NULL: %p\n", NewAcl);
3318
3319
ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3320
ExplicitAccess.grfAccessMode = SET_ACCESS;
3321
res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3322
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
3323
ok(NewAcl != NULL, "returned acl was NULL\n");
3324
LocalFree(NewAcl);
3325
}
3326
3327
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3328
ExplicitAccess.Trustee.ptstrName = (WCHAR *)L"CURRENT_USER";
3329
res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3330
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
3331
ok(NewAcl != NULL, "returned acl was NULL\n");
3332
LocalFree(NewAcl);
3333
3334
ExplicitAccess.grfAccessMode = REVOKE_ACCESS;
3335
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
3336
ExplicitAccess.Trustee.ptstrName = UsersSid;
3337
res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3338
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
3339
ok(NewAcl != NULL, "returned acl was NULL\n");
3340
LocalFree(NewAcl);
3341
3342
FreeSid(UsersSid);
3343
FreeSid(EveryoneSid);
3344
free(OldAcl);
3345
}
3346
3347
static void test_SetEntriesInAclA(void)
3348
{
3349
DWORD res;
3350
PSID EveryoneSid = NULL, UsersSid = NULL;
3351
PACL OldAcl = NULL, NewAcl;
3352
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
3353
SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY };
3354
EXPLICIT_ACCESSA ExplicitAccess;
3355
3356
NewAcl = (PACL)0xdeadbeef;
3357
res = SetEntriesInAclA(0, NULL, NULL, &NewAcl);
3358
if(res == ERROR_CALL_NOT_IMPLEMENTED)
3359
{
3360
win_skip("SetEntriesInAclA is not implemented\n");
3361
return;
3362
}
3363
ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %lu\n", res);
3364
ok(NewAcl == NULL,
3365
"NewAcl=%p, expected NULL\n", NewAcl);
3366
LocalFree(NewAcl);
3367
3368
OldAcl = malloc(256);
3369
res = InitializeAcl(OldAcl, 256, ACL_REVISION);
3370
if(!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
3371
{
3372
win_skip("ACLs not implemented - skipping tests\n");
3373
free(OldAcl);
3374
return;
3375
}
3376
ok(res, "InitializeAcl failed with error %ld\n", GetLastError());
3377
3378
res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid);
3379
ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
3380
3381
res = AllocateAndInitializeSid( &SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
3382
DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &UsersSid);
3383
ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
3384
3385
res = AddAccessAllowedAce(OldAcl, ACL_REVISION, KEY_READ, UsersSid);
3386
ok(res, "AddAccessAllowedAce failed with error %ld\n", GetLastError());
3387
3388
ExplicitAccess.grfAccessPermissions = KEY_WRITE;
3389
ExplicitAccess.grfAccessMode = GRANT_ACCESS;
3390
ExplicitAccess.grfInheritance = NO_INHERITANCE;
3391
ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
3392
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
3393
ExplicitAccess.Trustee.ptstrName = EveryoneSid;
3394
ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3395
ExplicitAccess.Trustee.pMultipleTrustee = NULL;
3396
res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3397
ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %lu\n", res);
3398
ok(NewAcl != NULL, "returned acl was NULL\n");
3399
LocalFree(NewAcl);
3400
3401
ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3402
ExplicitAccess.Trustee.pMultipleTrustee = NULL;
3403
ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3404
res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3405
ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %lu\n", res);
3406
ok(NewAcl != NULL, "returned acl was NULL\n");
3407
LocalFree(NewAcl);
3408
3409
if (PRIMARYLANGID(GetSystemDefaultLangID()) != LANG_ENGLISH)
3410
{
3411
skip("Non-English locale (test with hardcoded 'Everyone')\n");
3412
}
3413
else
3414
{
3415
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3416
ExplicitAccess.Trustee.ptstrName = (char*)"Everyone";
3417
res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3418
ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %lu\n", res);
3419
ok(NewAcl != NULL, "returned acl was NULL\n");
3420
LocalFree(NewAcl);
3421
3422
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_BAD_FORM;
3423
res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3424
ok(res == ERROR_INVALID_PARAMETER,
3425
"SetEntriesInAclA failed: %lu\n", res);
3426
ok(NewAcl == NULL,
3427
"returned acl wasn't NULL: %p\n", NewAcl);
3428
3429
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3430
ExplicitAccess.Trustee.MultipleTrusteeOperation = TRUSTEE_IS_IMPERSONATE;
3431
res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3432
ok(res == ERROR_INVALID_PARAMETER,
3433
"SetEntriesInAclA failed: %lu\n", res);
3434
ok(NewAcl == NULL,
3435
"returned acl wasn't NULL: %p\n", NewAcl);
3436
3437
ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3438
ExplicitAccess.grfAccessMode = SET_ACCESS;
3439
res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3440
ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %lu\n", res);
3441
ok(NewAcl != NULL, "returned acl was NULL\n");
3442
LocalFree(NewAcl);
3443
}
3444
3445
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3446
ExplicitAccess.Trustee.ptstrName = (char *)"CURRENT_USER";
3447
res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3448
ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %lu\n", res);
3449
ok(NewAcl != NULL, "returned acl was NULL\n");
3450
LocalFree(NewAcl);
3451
3452
ExplicitAccess.grfAccessMode = REVOKE_ACCESS;
3453
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
3454
ExplicitAccess.Trustee.ptstrName = UsersSid;
3455
res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3456
ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %lu\n", res);
3457
ok(NewAcl != NULL, "returned acl was NULL\n");
3458
LocalFree(NewAcl);
3459
3460
FreeSid(UsersSid);
3461
FreeSid(EveryoneSid);
3462
free(OldAcl);
3463
}
3464
3465
/* helper function for test_CreateDirectoryA */
3466
static void get_nt_pathW(const char *name, UNICODE_STRING *nameW)
3467
{
3468
UNICODE_STRING strW;
3469
ANSI_STRING str;
3470
NTSTATUS status;
3471
BOOLEAN ret;
3472
3473
RtlInitAnsiString(&str, name);
3474
3475
status = RtlAnsiStringToUnicodeString(&strW, &str, TRUE);
3476
ok(!status, "RtlAnsiStringToUnicodeString failed with %08lx\n", status);
3477
3478
ret = pRtlDosPathNameToNtPathName_U(strW.Buffer, nameW, NULL, NULL);
3479
ok(ret, "RtlDosPathNameToNtPathName_U failed\n");
3480
3481
RtlFreeUnicodeString(&strW);
3482
}
3483
3484
static void test_inherited_dacl(PACL dacl, PSID admin_sid, PSID user_sid, DWORD flags, DWORD mask,
3485
BOOL todo_count, BOOL todo_sid, BOOL todo_flags, int line)
3486
{
3487
ACL_SIZE_INFORMATION acl_size;
3488
ACCESS_ALLOWED_ACE *ace;
3489
BOOL bret;
3490
3491
bret = GetAclInformation(dacl, &acl_size, sizeof(acl_size), AclSizeInformation);
3492
ok_(__FILE__, line)(bret, "GetAclInformation failed\n");
3493
3494
todo_wine_if (todo_count)
3495
ok_(__FILE__, line)(acl_size.AceCount == 2,
3496
"GetAclInformation returned unexpected entry count (%ld != 2)\n",
3497
acl_size.AceCount);
3498
3499
if (acl_size.AceCount > 0)
3500
{
3501
bret = GetAce(dacl, 0, (VOID **)&ace);
3502
ok_(__FILE__, line)(bret, "Failed to get Current User ACE\n");
3503
3504
bret = EqualSid(&ace->SidStart, user_sid);
3505
todo_wine_if (todo_sid)
3506
ok_(__FILE__, line)(bret, "Current User ACE (%s) != Current User SID (%s)\n", debugstr_sid(&ace->SidStart), debugstr_sid(user_sid));
3507
3508
todo_wine_if (todo_flags)
3509
ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags,
3510
"Current User ACE has unexpected flags (0x%x != 0x%lx)\n",
3511
((ACE_HEADER *)ace)->AceFlags, flags);
3512
3513
ok_(__FILE__, line)(ace->Mask == mask,
3514
"Current User ACE has unexpected mask (0x%lx != 0x%lx)\n",
3515
ace->Mask, mask);
3516
}
3517
if (acl_size.AceCount > 1)
3518
{
3519
bret = GetAce(dacl, 1, (VOID **)&ace);
3520
ok_(__FILE__, line)(bret, "Failed to get Administators Group ACE\n");
3521
3522
bret = EqualSid(&ace->SidStart, admin_sid);
3523
todo_wine_if (todo_sid)
3524
ok_(__FILE__, line)(bret, "Administators Group ACE (%s) != Administators Group SID (%s)\n", debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid));
3525
3526
todo_wine_if (todo_flags)
3527
ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags,
3528
"Administators Group ACE has unexpected flags (0x%x != 0x%lx)\n",
3529
((ACE_HEADER *)ace)->AceFlags, flags);
3530
3531
ok_(__FILE__, line)(ace->Mask == mask,
3532
"Administators Group ACE has unexpected mask (0x%lx != 0x%lx)\n",
3533
ace->Mask, mask);
3534
}
3535
}
3536
3537
static void test_CreateDirectoryA(void)
3538
{
3539
char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], *user;
3540
DWORD sid_size = sizeof(admin_ptr), user_size;
3541
PSID admin_sid = (PSID) admin_ptr, user_sid;
3542
char sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
3543
PSECURITY_DESCRIPTOR pSD = &sd;
3544
ACL_SIZE_INFORMATION acl_size;
3545
UNICODE_STRING tmpfileW;
3546
SECURITY_ATTRIBUTES sa;
3547
OBJECT_ATTRIBUTES attr;
3548
char tmpfile[MAX_PATH];
3549
char tmpdir[MAX_PATH];
3550
HANDLE token, hTemp;
3551
IO_STATUS_BLOCK io;
3552
struct _SID *owner;
3553
BOOL bret = TRUE;
3554
NTSTATUS status;
3555
DWORD error;
3556
PACL pDacl;
3557
3558
if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
3559
{
3560
if (GetLastError() != ERROR_NO_TOKEN) bret = FALSE;
3561
else if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) bret = FALSE;
3562
}
3563
if (!bret)
3564
{
3565
win_skip("Failed to get current user token\n");
3566
return;
3567
}
3568
bret = GetTokenInformation(token, TokenUser, NULL, 0, &user_size);
3569
ok(!bret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
3570
"GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError());
3571
user = malloc(user_size);
3572
bret = GetTokenInformation(token, TokenUser, user, user_size, &user_size);
3573
ok(bret, "GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError());
3574
CloseHandle( token );
3575
user_sid = ((TOKEN_USER *)user)->User.Sid;
3576
3577
sa.nLength = sizeof(sa);
3578
sa.lpSecurityDescriptor = pSD;
3579
sa.bInheritHandle = TRUE;
3580
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
3581
CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size);
3582
pDacl = calloc(1, 100);
3583
bret = InitializeAcl(pDacl, 100, ACL_REVISION);
3584
ok(bret, "Failed to initialize ACL.\n");
3585
bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE,
3586
GENERIC_ALL, user_sid);
3587
ok(bret, "Failed to add Current User to ACL.\n");
3588
bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE,
3589
GENERIC_ALL, admin_sid);
3590
ok(bret, "Failed to add Administrator Group to ACL.\n");
3591
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
3592
ok(bret, "Failed to add ACL to security descriptor.\n");
3593
3594
GetTempPathA(MAX_PATH, tmpdir);
3595
lstrcatA(tmpdir, "Please Remove Me");
3596
bret = CreateDirectoryA(tmpdir, &sa);
3597
ok(bret == TRUE, "CreateDirectoryA(%s) failed err=%ld\n", tmpdir, GetLastError());
3598
free(pDacl);
3599
3600
SetLastError(0xdeadbeef);
3601
error = GetNamedSecurityInfoA(tmpdir, SE_FILE_OBJECT,
3602
OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, (PSID*)&owner,
3603
NULL, &pDacl, NULL, &pSD);
3604
if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
3605
{
3606
win_skip("GetNamedSecurityInfoA is not implemented\n");
3607
goto done;
3608
}
3609
ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error);
3610
test_inherited_dacl(pDacl, admin_sid, user_sid, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE,
3611
0x1f01ff, FALSE, TRUE, FALSE, __LINE__);
3612
LocalFree(pSD);
3613
3614
/* Test inheritance of ACLs in CreateFile without security descriptor */
3615
strcpy(tmpfile, tmpdir);
3616
lstrcatA(tmpfile, "/tmpfile");
3617
3618
hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL,
3619
CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, NULL);
3620
ok(hTemp != INVALID_HANDLE_VALUE, "CreateFile error %lu\n", GetLastError());
3621
3622
error = GetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
3623
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3624
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3625
ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
3626
test_inherited_dacl(pDacl, admin_sid, user_sid, INHERITED_ACE,
3627
0x1f01ff, TRUE, TRUE, TRUE, __LINE__);
3628
LocalFree(pSD);
3629
CloseHandle(hTemp);
3630
3631
/* Test inheritance of ACLs in CreateFile with security descriptor -
3632
* When a security descriptor is set, then inheritance doesn't take effect */
3633
pSD = &sd;
3634
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
3635
pDacl = malloc(sizeof(ACL));
3636
bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
3637
ok(bret, "Failed to initialize ACL\n");
3638
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
3639
ok(bret, "Failed to add ACL to security descriptor\n");
3640
3641
strcpy(tmpfile, tmpdir);
3642
lstrcatA(tmpfile, "/tmpfile");
3643
3644
sa.nLength = sizeof(sa);
3645
sa.lpSecurityDescriptor = pSD;
3646
sa.bInheritHandle = TRUE;
3647
hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, &sa,
3648
CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, NULL);
3649
ok(hTemp != INVALID_HANDLE_VALUE, "CreateFile error %lu\n", GetLastError());
3650
free(pDacl);
3651
3652
error = GetSecurityInfo(hTemp, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3653
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3654
ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %ld\n", error);
3655
bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
3656
ok(bret, "GetAclInformation failed\n");
3657
todo_wine
3658
ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%ld != 0).\n",
3659
acl_size.AceCount);
3660
LocalFree(pSD);
3661
3662
error = GetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
3663
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3664
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3665
todo_wine
3666
ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %ld\n", error);
3667
if (error == ERROR_SUCCESS)
3668
{
3669
bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
3670
ok(bret, "GetAclInformation failed\n");
3671
todo_wine
3672
ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%ld != 0).\n",
3673
acl_size.AceCount);
3674
LocalFree(pSD);
3675
}
3676
CloseHandle(hTemp);
3677
3678
/* Test inheritance of ACLs in NtCreateFile without security descriptor */
3679
strcpy(tmpfile, tmpdir);
3680
lstrcatA(tmpfile, "/tmpfile");
3681
get_nt_pathW(tmpfile, &tmpfileW);
3682
3683
attr.Length = sizeof(attr);
3684
attr.RootDirectory = 0;
3685
attr.ObjectName = &tmpfileW;
3686
attr.Attributes = OBJ_CASE_INSENSITIVE;
3687
attr.SecurityDescriptor = NULL;
3688
attr.SecurityQualityOfService = NULL;
3689
3690
status = NtCreateFile(&hTemp, GENERIC_WRITE | DELETE, &attr, &io, NULL, 0,
3691
FILE_SHARE_READ, FILE_CREATE, FILE_DELETE_ON_CLOSE, NULL, 0);
3692
ok(!status, "NtCreateFile failed with %08lx\n", status);
3693
RtlFreeUnicodeString(&tmpfileW);
3694
3695
error = GetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
3696
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3697
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3698
ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
3699
test_inherited_dacl(pDacl, admin_sid, user_sid, INHERITED_ACE,
3700
0x1f01ff, TRUE, TRUE, TRUE, __LINE__);
3701
LocalFree(pSD);
3702
CloseHandle(hTemp);
3703
3704
/* Test inheritance of ACLs in NtCreateFile with security descriptor -
3705
* When a security descriptor is set, then inheritance doesn't take effect */
3706
pSD = &sd;
3707
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
3708
pDacl = malloc(sizeof(ACL));
3709
bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
3710
ok(bret, "Failed to initialize ACL\n");
3711
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
3712
ok(bret, "Failed to add ACL to security descriptor\n");
3713
3714
strcpy(tmpfile, tmpdir);
3715
lstrcatA(tmpfile, "/tmpfile");
3716
get_nt_pathW(tmpfile, &tmpfileW);
3717
3718
attr.Length = sizeof(attr);
3719
attr.RootDirectory = 0;
3720
attr.ObjectName = &tmpfileW;
3721
attr.Attributes = OBJ_CASE_INSENSITIVE;
3722
attr.SecurityDescriptor = pSD;
3723
attr.SecurityQualityOfService = NULL;
3724
3725
status = NtCreateFile(&hTemp, GENERIC_WRITE | DELETE, &attr, &io, NULL, 0,
3726
FILE_SHARE_READ, FILE_CREATE, FILE_DELETE_ON_CLOSE, NULL, 0);
3727
ok(!status, "NtCreateFile failed with %08lx\n", status);
3728
RtlFreeUnicodeString(&tmpfileW);
3729
free(pDacl);
3730
3731
error = GetSecurityInfo(hTemp, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3732
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3733
ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %ld\n", error);
3734
bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
3735
ok(bret, "GetAclInformation failed\n");
3736
todo_wine
3737
ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%ld != 0).\n",
3738
acl_size.AceCount);
3739
LocalFree(pSD);
3740
3741
error = GetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
3742
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3743
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3744
todo_wine
3745
ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %ld\n", error);
3746
if (error == ERROR_SUCCESS)
3747
{
3748
bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
3749
ok(bret, "GetAclInformation failed\n");
3750
todo_wine
3751
ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%ld != 0).\n",
3752
acl_size.AceCount);
3753
LocalFree(pSD);
3754
}
3755
CloseHandle(hTemp);
3756
3757
done:
3758
free(user);
3759
bret = RemoveDirectoryA(tmpdir);
3760
ok(bret == TRUE, "RemoveDirectoryA should always succeed\n");
3761
}
3762
3763
static void test_GetNamedSecurityInfoA(void)
3764
{
3765
char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], *user;
3766
char system_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES];
3767
char users_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES];
3768
SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY };
3769
PSID admin_sid = (PSID) admin_ptr, users_sid = (PSID) users_ptr;
3770
PSID system_sid = (PSID) system_ptr, user_sid, localsys_sid;
3771
DWORD sid_size = sizeof(admin_ptr), user_size;
3772
char invalid_path[] = "/an invalid file path";
3773
int users_ace_id = -1, admins_ace_id = -1, i;
3774
char software_key[] = "MACHINE\\Software";
3775
char sd[SECURITY_DESCRIPTOR_MIN_LENGTH+sizeof(void*)];
3776
SECURITY_DESCRIPTOR_CONTROL control;
3777
ACL_SIZE_INFORMATION acl_size;
3778
CHAR windows_dir[MAX_PATH];
3779
PSECURITY_DESCRIPTOR pSD;
3780
ACCESS_ALLOWED_ACE *ace;
3781
BOOL bret = TRUE;
3782
char tmpfile[MAX_PATH];
3783
DWORD error, revision;
3784
BOOL owner_defaulted;
3785
BOOL group_defaulted;
3786
BOOL dacl_defaulted;
3787
HANDLE token, hTemp, h;
3788
PSID owner, group;
3789
BOOL dacl_present;
3790
PACL pDacl;
3791
BYTE flags;
3792
NTSTATUS status;
3793
3794
if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
3795
{
3796
if (GetLastError() != ERROR_NO_TOKEN) bret = FALSE;
3797
else if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) bret = FALSE;
3798
}
3799
if (!bret)
3800
{
3801
win_skip("Failed to get current user token\n");
3802
return;
3803
}
3804
bret = GetTokenInformation(token, TokenUser, NULL, 0, &user_size);
3805
ok(!bret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
3806
"GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError());
3807
user = malloc(user_size);
3808
bret = GetTokenInformation(token, TokenUser, user, user_size, &user_size);
3809
ok(bret, "GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError());
3810
CloseHandle( token );
3811
user_sid = ((TOKEN_USER *)user)->User.Sid;
3812
3813
bret = GetWindowsDirectoryA(windows_dir, MAX_PATH);
3814
ok(bret, "GetWindowsDirectory failed with error %ld\n", GetLastError());
3815
3816
SetLastError(0xdeadbeef);
3817
error = GetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,
3818
OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION,
3819
NULL, NULL, NULL, NULL, &pSD);
3820
if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
3821
{
3822
win_skip("GetNamedSecurityInfoA is not implemented\n");
3823
free(user);
3824
return;
3825
}
3826
ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error);
3827
3828
bret = GetSecurityDescriptorControl(pSD, &control, &revision);
3829
ok(bret, "GetSecurityDescriptorControl failed with error %ld\n", GetLastError());
3830
ok((control & (SE_SELF_RELATIVE|SE_DACL_PRESENT)) == (SE_SELF_RELATIVE|SE_DACL_PRESENT),
3831
"control (0x%x) doesn't have (SE_SELF_RELATIVE|SE_DACL_PRESENT) flags set\n", control);
3832
ok(revision == SECURITY_DESCRIPTOR_REVISION1, "revision was %ld instead of 1\n", revision);
3833
3834
bret = GetSecurityDescriptorOwner(pSD, &owner, &owner_defaulted);
3835
ok(bret, "GetSecurityDescriptorOwner failed with error %ld\n", GetLastError());
3836
ok(owner != NULL, "owner should not be NULL\n");
3837
3838
bret = GetSecurityDescriptorGroup(pSD, &group, &group_defaulted);
3839
ok(bret, "GetSecurityDescriptorGroup failed with error %ld\n", GetLastError());
3840
ok(group != NULL, "group should not be NULL\n");
3841
LocalFree(pSD);
3842
3843
3844
/* NULL descriptor tests */
3845
3846
error = GetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,
3847
NULL, NULL, NULL, NULL, NULL);
3848
ok(error==ERROR_INVALID_PARAMETER, "GetNamedSecurityInfo failed with error %ld\n", error);
3849
3850
pDacl = NULL;
3851
error = GetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,
3852
NULL, NULL, &pDacl, NULL, &pSD);
3853
ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error);
3854
ok(pDacl != NULL, "DACL should not be NULL\n");
3855
LocalFree(pSD);
3856
3857
error = GetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,OWNER_SECURITY_INFORMATION,
3858
NULL, NULL, &pDacl, NULL, NULL);
3859
ok(error==ERROR_INVALID_PARAMETER, "GetNamedSecurityInfo failed with error %ld\n", error);
3860
3861
/* Test behavior of SetNamedSecurityInfo with an invalid path */
3862
SetLastError(0xdeadbeef);
3863
error = SetNamedSecurityInfoA(invalid_path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL,
3864
NULL, NULL, NULL);
3865
ok(error == ERROR_FILE_NOT_FOUND, "Unexpected error returned: 0x%lx\n", error);
3866
ok(GetLastError() == 0xdeadbeef, "Expected last error to remain unchanged.\n");
3867
3868
/* Create security descriptor information and test that it comes back the same */
3869
pSD = &sd;
3870
pDacl = malloc(100);
3871
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
3872
CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size);
3873
bret = InitializeAcl(pDacl, 100, ACL_REVISION);
3874
ok(bret, "Failed to initialize ACL.\n");
3875
bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
3876
ok(bret, "Failed to add Current User to ACL.\n");
3877
bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, admin_sid);
3878
ok(bret, "Failed to add Administrator Group to ACL.\n");
3879
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
3880
ok(bret, "Failed to add ACL to security descriptor.\n");
3881
GetTempFileNameA(".", "foo", 0, tmpfile);
3882
hTemp = CreateFileA(tmpfile, WRITE_DAC|GENERIC_WRITE, FILE_SHARE_DELETE|FILE_SHARE_READ,
3883
NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL);
3884
SetLastError(0xdeadbeef);
3885
error = SetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL,
3886
NULL, pDacl, NULL);
3887
free(pDacl);
3888
if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
3889
{
3890
win_skip("SetNamedSecurityInfoA is not implemented\n");
3891
free(user);
3892
CloseHandle(hTemp);
3893
return;
3894
}
3895
ok(!error, "SetNamedSecurityInfoA failed with error %ld\n", error);
3896
SetLastError(0xdeadbeef);
3897
error = GetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
3898
NULL, NULL, &pDacl, NULL, &pSD);
3899
if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
3900
{
3901
win_skip("GetNamedSecurityInfoA is not implemented\n");
3902
free(user);
3903
CloseHandle(hTemp);
3904
return;
3905
}
3906
ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error);
3907
3908
bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
3909
ok(bret, "GetAclInformation failed\n");
3910
if (acl_size.AceCount > 0)
3911
{
3912
bret = GetAce(pDacl, 0, (VOID **)&ace);
3913
ok(bret, "Failed to get Current User ACE.\n");
3914
bret = EqualSid(&ace->SidStart, user_sid);
3915
todo_wine ok(bret, "Current User ACE (%s) != Current User SID (%s).\n",
3916
debugstr_sid(&ace->SidStart), debugstr_sid(user_sid));
3917
ok(((ACE_HEADER *)ace)->AceFlags == 0,
3918
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
3919
ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%lx != 0x1f01ff)\n",
3920
ace->Mask);
3921
}
3922
if (acl_size.AceCount > 1)
3923
{
3924
bret = GetAce(pDacl, 1, (VOID **)&ace);
3925
ok(bret, "Failed to get Administators Group ACE.\n");
3926
bret = EqualSid(&ace->SidStart, admin_sid);
3927
todo_wine ok(bret || broken(!bret) /* win2k */,
3928
"Administators Group ACE (%s) != Administators Group SID (%s).\n",
3929
debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid));
3930
ok(((ACE_HEADER *)ace)->AceFlags == 0,
3931
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
3932
ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */,
3933
"Administators Group ACE has unexpected mask (0x%lx != 0x1f01ff)\n", ace->Mask);
3934
}
3935
LocalFree(pSD);
3936
3937
/* show that setting empty DACL is not removing all file permissions */
3938
pDacl = malloc(sizeof(ACL));
3939
bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
3940
ok(bret, "Failed to initialize ACL.\n");
3941
error = SetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
3942
NULL, NULL, pDacl, NULL);
3943
ok(!error, "SetNamedSecurityInfoA failed with error %ld\n", error);
3944
free(pDacl);
3945
3946
error = GetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
3947
NULL, NULL, &pDacl, NULL, &pSD);
3948
ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error);
3949
3950
bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
3951
ok(bret, "GetAclInformation failed\n");
3952
if (acl_size.AceCount > 0)
3953
{
3954
bret = GetAce(pDacl, 0, (VOID **)&ace);
3955
ok(bret, "Failed to get ACE.\n");
3956
todo_wine ok(((ACE_HEADER *)ace)->AceFlags & INHERITED_ACE,
3957
"ACE has unexpected flags: 0x%x\n", ((ACE_HEADER *)ace)->AceFlags);
3958
}
3959
LocalFree(pSD);
3960
3961
h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
3962
NULL, OPEN_EXISTING, 0, NULL);
3963
ok(h != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
3964
CloseHandle(h);
3965
3966
/* test setting NULL DACL */
3967
error = SetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
3968
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL);
3969
ok(!error, "SetNamedSecurityInfoA failed with error %ld\n", error);
3970
3971
error = GetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
3972
NULL, NULL, &pDacl, NULL, &pSD);
3973
ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error);
3974
todo_wine ok(!pDacl, "pDacl != NULL\n");
3975
LocalFree(pSD);
3976
3977
h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
3978
NULL, OPEN_EXISTING, 0, NULL);
3979
ok(h != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
3980
CloseHandle(h);
3981
3982
/* NtSetSecurityObject doesn't inherit DACL entries */
3983
pSD = sd+sizeof(void*)-((ULONG_PTR)sd)%sizeof(void*);
3984
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
3985
pDacl = malloc(100);
3986
bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
3987
ok(bret, "Failed to initialize ACL.\n");
3988
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
3989
ok(bret, "Failed to add ACL to security descriptor.\n");
3990
status = NtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
3991
ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %lx\n", status);
3992
3993
h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
3994
NULL, OPEN_EXISTING, 0, NULL);
3995
ok(h == INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
3996
CloseHandle(h);
3997
3998
SetSecurityDescriptorControl(pSD, SE_DACL_AUTO_INHERIT_REQ, SE_DACL_AUTO_INHERIT_REQ);
3999
status = NtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
4000
ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %lx\n", status);
4001
4002
h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
4003
NULL, OPEN_EXISTING, 0, NULL);
4004
ok(h == INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
4005
CloseHandle(h);
4006
4007
SetSecurityDescriptorControl(pSD, SE_DACL_AUTO_INHERIT_REQ|SE_DACL_AUTO_INHERITED,
4008
SE_DACL_AUTO_INHERIT_REQ|SE_DACL_AUTO_INHERITED);
4009
status = NtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
4010
ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %lx\n", status);
4011
4012
h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
4013
NULL, OPEN_EXISTING, 0, NULL);
4014
ok(h == INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
4015
CloseHandle(h);
4016
4017
/* test if DACL is properly mapped to permission */
4018
bret = InitializeAcl(pDacl, 100, ACL_REVISION);
4019
ok(bret, "Failed to initialize ACL.\n");
4020
bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
4021
ok(bret, "Failed to add Current User to ACL.\n");
4022
bret = AddAccessDeniedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
4023
ok(bret, "Failed to add Current User to ACL.\n");
4024
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
4025
ok(bret, "Failed to add ACL to security descriptor.\n");
4026
status = NtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
4027
ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %lx\n", status);
4028
4029
h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
4030
NULL, OPEN_EXISTING, 0, NULL);
4031
ok(h != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
4032
CloseHandle(h);
4033
4034
bret = InitializeAcl(pDacl, 100, ACL_REVISION);
4035
ok(bret, "Failed to initialize ACL.\n");
4036
bret = AddAccessDeniedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
4037
ok(bret, "Failed to add Current User to ACL.\n");
4038
bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
4039
ok(bret, "Failed to add Current User to ACL.\n");
4040
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
4041
ok(bret, "Failed to add ACL to security descriptor.\n");
4042
status = NtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
4043
ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %lx\n", status);
4044
4045
h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
4046
NULL, OPEN_EXISTING, 0, NULL);
4047
ok(h == INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
4048
free(pDacl);
4049
free(user);
4050
CloseHandle(hTemp);
4051
4052
/* Test querying the ownership of a built-in registry key */
4053
sid_size = sizeof(system_ptr);
4054
CreateWellKnownSid(WinLocalSystemSid, NULL, system_sid, &sid_size);
4055
error = GetNamedSecurityInfoA(software_key, SE_REGISTRY_KEY,
4056
OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION,
4057
NULL, NULL, NULL, NULL, &pSD);
4058
ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error);
4059
4060
bret = AllocateAndInitializeSid(&SIDAuthNT, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &localsys_sid);
4061
ok(bret, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
4062
4063
bret = GetSecurityDescriptorOwner(pSD, &owner, &owner_defaulted);
4064
ok(bret, "GetSecurityDescriptorOwner failed with error %ld\n", GetLastError());
4065
ok(owner != NULL, "owner should not be NULL\n");
4066
ok(EqualSid(owner, admin_sid) || EqualSid(owner, localsys_sid),
4067
"MACHINE\\Software owner SID (%s) != Administrators SID (%s) or Local System Sid (%s).\n",
4068
debugstr_sid(owner), debugstr_sid(admin_sid), debugstr_sid(localsys_sid));
4069
4070
bret = GetSecurityDescriptorGroup(pSD, &group, &group_defaulted);
4071
ok(bret, "GetSecurityDescriptorGroup failed with error %ld\n", GetLastError());
4072
ok(group != NULL, "group should not be NULL\n");
4073
ok(EqualSid(group, admin_sid) || broken(EqualSid(group, system_sid)) /* before Win7 */
4074
|| broken(((SID*)group)->SubAuthority[0] == SECURITY_NT_NON_UNIQUE) /* Vista */,
4075
"MACHINE\\Software group SID (%s) != Local System SID (%s or %s)\n",
4076
debugstr_sid(group), debugstr_sid(admin_sid), debugstr_sid(system_sid));
4077
LocalFree(pSD);
4078
4079
/* Test querying the DACL of a built-in registry key */
4080
sid_size = sizeof(users_ptr);
4081
CreateWellKnownSid(WinBuiltinUsersSid, NULL, users_sid, &sid_size);
4082
error = GetNamedSecurityInfoA(software_key, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION,
4083
NULL, NULL, NULL, NULL, &pSD);
4084
ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error);
4085
4086
bret = GetSecurityDescriptorDacl(pSD, &dacl_present, &pDacl, &dacl_defaulted);
4087
ok(bret, "GetSecurityDescriptorDacl failed with error %ld\n", GetLastError());
4088
ok(dacl_present, "DACL should be present\n");
4089
ok(pDacl && IsValidAcl(pDacl), "GetSecurityDescriptorDacl returned invalid DACL.\n");
4090
bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
4091
ok(bret, "GetAclInformation failed\n");
4092
ok(acl_size.AceCount != 0, "GetAclInformation returned no ACLs\n");
4093
for (i=0; i<acl_size.AceCount; i++)
4094
{
4095
bret = GetAce(pDacl, i, (VOID **)&ace);
4096
ok(bret, "Failed to get ACE %d.\n", i);
4097
bret = EqualSid(&ace->SidStart, users_sid);
4098
if (bret) users_ace_id = i;
4099
bret = EqualSid(&ace->SidStart, admin_sid);
4100
if (bret) admins_ace_id = i;
4101
}
4102
ok(users_ace_id != -1 || broken(users_ace_id == -1) /* win2k */,
4103
"Builtin Users ACE not found.\n");
4104
if (users_ace_id != -1)
4105
{
4106
bret = GetAce(pDacl, users_ace_id, (VOID **)&ace);
4107
ok(bret, "Failed to get Builtin Users ACE.\n");
4108
flags = ((ACE_HEADER *)ace)->AceFlags;
4109
ok(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE)
4110
|| broken(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE|INHERITED_ACE)) /* w2k8 */
4111
|| broken(flags == (CONTAINER_INHERIT_ACE|INHERITED_ACE)) /* win 10 wow64 */
4112
|| broken(flags == CONTAINER_INHERIT_ACE), /* win 10 */
4113
"Builtin Users ACE has unexpected flags (0x%x != 0x%x)\n", flags,
4114
INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE);
4115
ok(ace->Mask == GENERIC_READ
4116
|| broken(ace->Mask == KEY_READ), /* win 10 */
4117
"Builtin Users ACE has unexpected mask (0x%lx != 0x%x)\n",
4118
ace->Mask, GENERIC_READ);
4119
}
4120
ok(admins_ace_id != -1, "Builtin Admins ACE not found.\n");
4121
if (admins_ace_id != -1)
4122
{
4123
bret = GetAce(pDacl, admins_ace_id, (VOID **)&ace);
4124
ok(bret, "Failed to get Builtin Admins ACE.\n");
4125
flags = ((ACE_HEADER *)ace)->AceFlags;
4126
ok(flags == 0x0
4127
|| broken(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE|INHERITED_ACE)) /* w2k8 */
4128
|| broken(flags == (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE)) /* win7 */
4129
|| broken(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE)) /* win8+ */
4130
|| broken(flags == (CONTAINER_INHERIT_ACE|INHERITED_ACE)) /* win 10 wow64 */
4131
|| broken(flags == CONTAINER_INHERIT_ACE), /* win 10 */
4132
"Builtin Admins ACE has unexpected flags (0x%x != 0x0)\n", flags);
4133
ok(ace->Mask == KEY_ALL_ACCESS || broken(ace->Mask == GENERIC_ALL) /* w2k8 */,
4134
"Builtin Admins ACE has unexpected mask (0x%lx != 0x%x)\n", ace->Mask, KEY_ALL_ACCESS);
4135
}
4136
4137
FreeSid(localsys_sid);
4138
LocalFree(pSD);
4139
}
4140
4141
static void test_ConvertStringSecurityDescriptor(void)
4142
{
4143
BOOL ret;
4144
PSECURITY_DESCRIPTOR pSD;
4145
static const WCHAR Blank[] = { 0 };
4146
unsigned int i;
4147
ULONG size;
4148
ACL *acl;
4149
static const struct
4150
{
4151
const char *sidstring;
4152
DWORD revision;
4153
BOOL ret;
4154
DWORD GLE;
4155
DWORD altGLE;
4156
DWORD ace_Mask;
4157
} cssd[] =
4158
{
4159
{ "D:(A;;GA;;;WD)", 0xdeadbeef, FALSE, ERROR_UNKNOWN_REVISION },
4160
/* test ACE string type */
4161
{ "D:(A;;GA;;;WD)", SDDL_REVISION_1, TRUE },
4162
{ "D:(D;;GA;;;WD)", SDDL_REVISION_1, TRUE },
4163
{ "ERROR:(D;;GA;;;WD)", SDDL_REVISION_1, FALSE, ERROR_INVALID_PARAMETER },
4164
/* test ACE string with spaces */
4165
{ " D:(D;;GA;;;WD)", SDDL_REVISION_1, TRUE },
4166
{ "D: (D;;GA;;;WD)", SDDL_REVISION_1, TRUE },
4167
{ "D:( D;;GA;;;WD)", SDDL_REVISION_1, TRUE },
4168
{ "D:(D ;;GA;;;WD)", SDDL_REVISION_1, FALSE, RPC_S_INVALID_STRING_UUID, ERROR_INVALID_ACL }, /* Vista+ */
4169
{ "D:(D; ;GA;;;WD)", SDDL_REVISION_1, TRUE },
4170
{ "D:(D;; GA;;;WD)", SDDL_REVISION_1, TRUE },
4171
{ "D:(D;;GA ;;;WD)", SDDL_REVISION_1, FALSE, ERROR_INVALID_ACL },
4172
{ "D:(D;;GA; ;;WD)", SDDL_REVISION_1, TRUE },
4173
{ "D:(D;;GA;; ;WD)", SDDL_REVISION_1, TRUE },
4174
{ "D:(D;;GA;;; WD)", SDDL_REVISION_1, TRUE },
4175
{ "D:(D;;GA;;;WD )", SDDL_REVISION_1, TRUE },
4176
/* test ACE string access rights */
4177
{ "D:(A;;GA;;;WD)", SDDL_REVISION_1, TRUE, 0, 0, GENERIC_ALL },
4178
{ "D:(A;;1;;;WD)", SDDL_REVISION_1, TRUE, 0, 0, 1 },
4179
{ "D:(A;;020000000000;;;WD)", SDDL_REVISION_1, TRUE, 0, 0, GENERIC_READ },
4180
{ "D:(A;;0X40000000;;;WD)", SDDL_REVISION_1, TRUE, 0, 0, GENERIC_WRITE },
4181
{ "D:(A;;GRGWGX;;;WD)", SDDL_REVISION_1, TRUE, 0, 0, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE },
4182
{ "D:(A;;RCSDWDWO;;;WD)", SDDL_REVISION_1, TRUE, 0, 0, READ_CONTROL | DELETE | WRITE_DAC | WRITE_OWNER },
4183
{ "D:(A;;RPWPCCDCLCSWLODTCR;;;WD)", SDDL_REVISION_1, TRUE },
4184
{ "D:(A;;FAFRFWFX;;;WD)", SDDL_REVISION_1, TRUE },
4185
{ "D:(A;;KAKRKWKX;;;WD)", SDDL_REVISION_1, TRUE },
4186
{ "D:(A;;0xFFFFFFFF;;;WD)", SDDL_REVISION_1, TRUE },
4187
{ "S:(AU;;0xFFFFFFFF;;;WD)", SDDL_REVISION_1, TRUE },
4188
{ "S:(AU;;0xDeAdBeEf;;;WD)", SDDL_REVISION_1, TRUE },
4189
{ "S:(AU;;GR0xFFFFFFFF;;;WD)", SDDL_REVISION_1, TRUE },
4190
{ "S:(AU;;0xFFFFFFFFGR;;;WD)", SDDL_REVISION_1, TRUE },
4191
{ "S:(AU;;0xFFFFFGR;;;WD)", SDDL_REVISION_1, TRUE },
4192
/* test ACE string access right error case */
4193
{ "D:(A;;ROB;;;WD)", SDDL_REVISION_1, FALSE, ERROR_INVALID_ACL },
4194
/* test behaviour with empty strings */
4195
{ "", SDDL_REVISION_1, TRUE },
4196
/* test ACE string SID */
4197
{ "D:(D;;GA;;;S-1-0-0)", SDDL_REVISION_1, TRUE },
4198
{ "D:(D;;GA;;;WDANDSUCH)", SDDL_REVISION_1, FALSE, ERROR_INVALID_ACL },
4199
{ "D:(D;;GA;;;Nonexistent account)", SDDL_REVISION_1, FALSE, ERROR_INVALID_ACL, ERROR_INVALID_SID }, /* W2K */
4200
};
4201
4202
for (i = 0; i < ARRAY_SIZE(cssd); i++)
4203
{
4204
DWORD GLE;
4205
4206
SetLastError(0xdeadbeef);
4207
ret = ConvertStringSecurityDescriptorToSecurityDescriptorA(
4208
cssd[i].sidstring, cssd[i].revision, &pSD, NULL);
4209
GLE = GetLastError();
4210
ok(ret == cssd[i].ret, "(%02u) Expected %s (%ld)\n", i, cssd[i].ret ? "success" : "failure", GLE);
4211
if (!cssd[i].ret)
4212
ok(GLE == cssd[i].GLE ||
4213
(cssd[i].altGLE && GLE == cssd[i].altGLE),
4214
"(%02u) Unexpected last error %ld\n", i, GLE);
4215
if (ret)
4216
{
4217
if (cssd[i].ace_Mask)
4218
{
4219
ACCESS_ALLOWED_ACE *ace;
4220
4221
acl = (ACL *)((char *)pSD + sizeof(SECURITY_DESCRIPTOR_RELATIVE));
4222
ok(acl->AclRevision == ACL_REVISION, "(%02u) Got %u\n", i, acl->AclRevision);
4223
4224
ace = (ACCESS_ALLOWED_ACE *)(acl + 1);
4225
ok(ace->Mask == cssd[i].ace_Mask, "(%02u) Expected %08lx, got %08lx\n",
4226
i, cssd[i].ace_Mask, ace->Mask);
4227
}
4228
LocalFree(pSD);
4229
}
4230
}
4231
4232
/* test behaviour with NULL parameters */
4233
SetLastError(0xdeadbeef);
4234
ret = ConvertStringSecurityDescriptorToSecurityDescriptorA(
4235
NULL, 0xdeadbeef, &pSD, NULL);
4236
todo_wine
4237
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
4238
"ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %ld\n",
4239
GetLastError());
4240
4241
SetLastError(0xdeadbeef);
4242
ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(
4243
NULL, 0xdeadbeef, &pSD, NULL);
4244
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
4245
"ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %ld\n",
4246
GetLastError());
4247
4248
SetLastError(0xdeadbeef);
4249
ret = ConvertStringSecurityDescriptorToSecurityDescriptorA(
4250
"D:(A;;ROB;;;WD)", 0xdeadbeef, NULL, NULL);
4251
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
4252
"ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %ld\n",
4253
GetLastError());
4254
4255
SetLastError(0xdeadbeef);
4256
ret = ConvertStringSecurityDescriptorToSecurityDescriptorA(
4257
"D:(A;;ROB;;;WD)", SDDL_REVISION_1, NULL, NULL);
4258
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
4259
"ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %ld\n",
4260
GetLastError());
4261
4262
/* test behaviour with empty strings */
4263
SetLastError(0xdeadbeef);
4264
ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(
4265
Blank, SDDL_REVISION_1, &pSD, NULL);
4266
ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %ld\n", GetLastError());
4267
LocalFree(pSD);
4268
4269
SetLastError(0xdeadbeef);
4270
ret = ConvertStringSecurityDescriptorToSecurityDescriptorA(
4271
"D:P(A;;GRGW;;;BA)(A;;GRGW;;;S-1-5-21-0-0-0-1000)S:(ML;;NWNR;;;S-1-16-12288)", SDDL_REVISION_1, &pSD, NULL);
4272
ok(ret || broken(!ret && GetLastError() == ERROR_INVALID_DATATYPE) /* win2k */,
4273
"ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %lu\n", GetLastError());
4274
if (ret) LocalFree(pSD);
4275
4276
/* empty DACL */
4277
size = 0;
4278
SetLastError(0xdeadbeef);
4279
ret = ConvertStringSecurityDescriptorToSecurityDescriptorA("D:", SDDL_REVISION_1, &pSD, &size);
4280
ok(ret, "unexpected error %lu\n", GetLastError());
4281
ok(size == sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sizeof(ACL), "got %lu\n", size);
4282
acl = (ACL *)((char *)pSD + sizeof(SECURITY_DESCRIPTOR_RELATIVE));
4283
ok(acl->AclRevision == ACL_REVISION, "got %u\n", acl->AclRevision);
4284
ok(!acl->Sbz1, "got %u\n", acl->Sbz1);
4285
ok(acl->AclSize == sizeof(*acl), "got %u\n", acl->AclSize);
4286
ok(!acl->AceCount, "got %u\n", acl->AceCount);
4287
ok(!acl->Sbz2, "got %u\n", acl->Sbz2);
4288
LocalFree(pSD);
4289
4290
/* empty SACL */
4291
size = 0;
4292
SetLastError(0xdeadbeef);
4293
ret = ConvertStringSecurityDescriptorToSecurityDescriptorA("S:", SDDL_REVISION_1, &pSD, &size);
4294
ok(ret, "unexpected error %lu\n", GetLastError());
4295
ok(size == sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sizeof(ACL), "got %lu\n", size);
4296
acl = (ACL *)((char *)pSD + sizeof(SECURITY_DESCRIPTOR_RELATIVE));
4297
ok(!acl->Sbz1, "got %u\n", acl->Sbz1);
4298
ok(acl->AclSize == sizeof(*acl), "got %u\n", acl->AclSize);
4299
ok(!acl->AceCount, "got %u\n", acl->AceCount);
4300
ok(!acl->Sbz2, "got %u\n", acl->Sbz2);
4301
LocalFree(pSD);
4302
}
4303
4304
static void test_ConvertSecurityDescriptorToString(void)
4305
{
4306
SECURITY_DESCRIPTOR desc;
4307
SECURITY_INFORMATION sec_info = OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION;
4308
LPSTR string;
4309
DWORD size;
4310
PSID psid, psid2;
4311
PACL pacl;
4312
char sid_buf[256];
4313
char acl_buf[8192];
4314
ULONG len;
4315
4316
/* It seems Windows XP adds an extra character to the length of the string for each ACE in an ACL. We
4317
* don't replicate this feature so we only test len >= strlen+1. */
4318
#define CHECK_RESULT_AND_FREE(exp_str) \
4319
ok(strcmp(string, (exp_str)) == 0, "String mismatch (expected \"%s\", got \"%s\")\n", (exp_str), string); \
4320
ok(len >= (strlen(exp_str) + 1), "Length mismatch (expected %d, got %ld)\n", lstrlenA(exp_str) + 1, len); \
4321
LocalFree(string);
4322
4323
#define CHECK_ONE_OF_AND_FREE(exp_str1, exp_str2) \
4324
ok(strcmp(string, (exp_str1)) == 0 || strcmp(string, (exp_str2)) == 0, "String mismatch (expected\n\"%s\" or\n\"%s\", got\n\"%s\")\n", (exp_str1), (exp_str2), string); \
4325
ok(len >= (strlen(exp_str1) + 1) || len >= (strlen(exp_str2) + 1), "Length mismatch (expected %d or %d, got %ld)\n", lstrlenA(exp_str1) + 1, lstrlenA(exp_str2) + 1, len); \
4326
LocalFree(string);
4327
4328
InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION);
4329
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4330
CHECK_RESULT_AND_FREE("");
4331
4332
size = 4096;
4333
CreateWellKnownSid(WinLocalSid, NULL, sid_buf, &size);
4334
SetSecurityDescriptorOwner(&desc, sid_buf, FALSE);
4335
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4336
CHECK_RESULT_AND_FREE("O:S-1-2-0");
4337
4338
SetSecurityDescriptorOwner(&desc, sid_buf, TRUE);
4339
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4340
CHECK_RESULT_AND_FREE("O:S-1-2-0");
4341
4342
size = sizeof(sid_buf);
4343
CreateWellKnownSid(WinLocalSystemSid, NULL, sid_buf, &size);
4344
SetSecurityDescriptorOwner(&desc, sid_buf, TRUE);
4345
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4346
CHECK_RESULT_AND_FREE("O:SY");
4347
4348
ConvertStringSidToSidA("S-1-5-21-93476-23408-4576", &psid);
4349
SetSecurityDescriptorGroup(&desc, psid, TRUE);
4350
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4351
CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576");
4352
4353
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, GROUP_SECURITY_INFORMATION, &string, &len), "Conversion failed\n");
4354
CHECK_RESULT_AND_FREE("G:S-1-5-21-93476-23408-4576");
4355
4356
pacl = (PACL)acl_buf;
4357
InitializeAcl(pacl, sizeof(acl_buf), ACL_REVISION);
4358
SetSecurityDescriptorDacl(&desc, TRUE, pacl, TRUE);
4359
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4360
CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:");
4361
4362
SetSecurityDescriptorDacl(&desc, TRUE, pacl, FALSE);
4363
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4364
CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:");
4365
4366
ConvertStringSidToSidA("S-1-5-6", &psid2);
4367
AddAccessAllowedAceEx(pacl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, 0xf0000000, psid2);
4368
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4369
CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)");
4370
4371
AddAccessAllowedAceEx(pacl, ACL_REVISION, INHERIT_ONLY_ACE|INHERITED_ACE, 0x00000003, psid2);
4372
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4373
CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)");
4374
4375
AddAccessDeniedAceEx(pacl, ACL_REVISION, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE, 0xffffffff, psid);
4376
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4377
CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)");
4378
4379
4380
pacl = (PACL)acl_buf;
4381
InitializeAcl(pacl, sizeof(acl_buf), ACL_REVISION);
4382
SetSecurityDescriptorSacl(&desc, TRUE, pacl, FALSE);
4383
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4384
CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:S:");
4385
4386
/* fails in win2k */
4387
SetSecurityDescriptorDacl(&desc, TRUE, NULL, FALSE);
4388
AddAuditAccessAceEx(pacl, ACL_REVISION, VALID_INHERIT_FLAGS, KEY_READ|KEY_WRITE, psid2, TRUE, TRUE);
4389
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4390
CHECK_ONE_OF_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)", /* XP */
4391
"O:SYG:S-1-5-21-93476-23408-4576D:NO_ACCESS_CONTROLS:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)" /* Vista */);
4392
4393
/* fails in win2k */
4394
AddAuditAccessAceEx(pacl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, FILE_GENERIC_READ|FILE_GENERIC_WRITE, psid2, TRUE, FALSE);
4395
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4396
CHECK_ONE_OF_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)", /* XP */
4397
"O:SYG:S-1-5-21-93476-23408-4576D:NO_ACCESS_CONTROLS:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)" /* Vista */);
4398
4399
LocalFree(psid2);
4400
LocalFree(psid);
4401
}
4402
4403
static void test_SetSecurityDescriptorControl (PSECURITY_DESCRIPTOR sec)
4404
{
4405
SECURITY_DESCRIPTOR_CONTROL ref;
4406
SECURITY_DESCRIPTOR_CONTROL test;
4407
4408
SECURITY_DESCRIPTOR_CONTROL const mutable
4409
= SE_DACL_AUTO_INHERIT_REQ | SE_SACL_AUTO_INHERIT_REQ
4410
| SE_DACL_AUTO_INHERITED | SE_SACL_AUTO_INHERITED
4411
| SE_DACL_PROTECTED | SE_SACL_PROTECTED
4412
| 0x00000040 | 0x00000080 /* not defined in winnt.h */
4413
;
4414
SECURITY_DESCRIPTOR_CONTROL const immutable
4415
= SE_OWNER_DEFAULTED | SE_GROUP_DEFAULTED
4416
| SE_DACL_PRESENT | SE_DACL_DEFAULTED
4417
| SE_SACL_PRESENT | SE_SACL_DEFAULTED
4418
| SE_RM_CONTROL_VALID | SE_SELF_RELATIVE
4419
;
4420
4421
int bit;
4422
DWORD dwRevision;
4423
LPCSTR fmt = "Expected error %s, got %u\n";
4424
4425
GetSecurityDescriptorControl (sec, &ref, &dwRevision);
4426
4427
/* The mutable bits are mutable regardless of the truth of
4428
SE_DACL_PRESENT and/or SE_SACL_PRESENT */
4429
4430
/* Check call barfs if any bit-of-interest is immutable */
4431
for (bit = 0; bit < 16; ++bit)
4432
{
4433
SECURITY_DESCRIPTOR_CONTROL const bitOfInterest = 1 << bit;
4434
SECURITY_DESCRIPTOR_CONTROL setOrClear = ref & bitOfInterest;
4435
4436
SECURITY_DESCRIPTOR_CONTROL ctrl;
4437
4438
DWORD dwExpect = (bitOfInterest & immutable)
4439
? ERROR_INVALID_PARAMETER : 0xbebecaca;
4440
LPCSTR strExpect = (bitOfInterest & immutable)
4441
? "ERROR_INVALID_PARAMETER" : "0xbebecaca";
4442
4443
ctrl = (bitOfInterest & mutable) ? ref + bitOfInterest : ref;
4444
setOrClear ^= bitOfInterest;
4445
SetLastError (0xbebecaca);
4446
SetSecurityDescriptorControl (sec, bitOfInterest, setOrClear);
4447
ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ());
4448
GetSecurityDescriptorControl(sec, &test, &dwRevision);
4449
expect_eq(test, ctrl, int, "%x");
4450
4451
setOrClear ^= bitOfInterest;
4452
SetLastError (0xbebecaca);
4453
SetSecurityDescriptorControl (sec, bitOfInterest, setOrClear);
4454
ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ());
4455
GetSecurityDescriptorControl (sec, &test, &dwRevision);
4456
expect_eq(test, ref, int, "%x");
4457
}
4458
4459
/* Check call barfs if any bit-to-set is immutable
4460
even when not a bit-of-interest */
4461
for (bit = 0; bit < 16; ++bit)
4462
{
4463
SECURITY_DESCRIPTOR_CONTROL const bitsOfInterest = mutable;
4464
SECURITY_DESCRIPTOR_CONTROL setOrClear = ref & bitsOfInterest;
4465
4466
SECURITY_DESCRIPTOR_CONTROL ctrl;
4467
4468
DWORD dwExpect = ((1 << bit) & immutable)
4469
? ERROR_INVALID_PARAMETER : 0xbebecaca;
4470
LPCSTR strExpect = ((1 << bit) & immutable)
4471
? "ERROR_INVALID_PARAMETER" : "0xbebecaca";
4472
4473
ctrl = ((1 << bit) & immutable) ? test : ref | mutable;
4474
setOrClear ^= bitsOfInterest;
4475
SetLastError (0xbebecaca);
4476
SetSecurityDescriptorControl (sec, bitsOfInterest, setOrClear | (1 << bit));
4477
ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ());
4478
GetSecurityDescriptorControl(sec, &test, &dwRevision);
4479
expect_eq(test, ctrl, int, "%x");
4480
4481
ctrl = ((1 << bit) & immutable) ? test : ref | (1 << bit);
4482
setOrClear ^= bitsOfInterest;
4483
SetLastError (0xbebecaca);
4484
SetSecurityDescriptorControl (sec, bitsOfInterest, setOrClear | (1 << bit));
4485
ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ());
4486
GetSecurityDescriptorControl(sec, &test, &dwRevision);
4487
expect_eq(test, ctrl, int, "%x");
4488
}
4489
}
4490
4491
static void test_PrivateObjectSecurity(void)
4492
{
4493
SECURITY_INFORMATION sec_info = OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION;
4494
SECURITY_DESCRIPTOR_CONTROL ctrl;
4495
PSECURITY_DESCRIPTOR sec;
4496
DWORD dwDescSize;
4497
DWORD dwRevision;
4498
DWORD retSize;
4499
LPSTR string;
4500
ULONG len;
4501
PSECURITY_DESCRIPTOR buf;
4502
BOOL ret;
4503
4504
ok(ConvertStringSecurityDescriptorToSecurityDescriptorA(
4505
"O:SY"
4506
"G:S-1-5-21-93476-23408-4576"
4507
"D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)"
4508
"(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)"
4509
"S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)",
4510
SDDL_REVISION_1, &sec, &dwDescSize), "Creating descriptor failed\n");
4511
4512
test_SetSecurityDescriptorControl(sec);
4513
4514
LocalFree(sec);
4515
4516
ok(ConvertStringSecurityDescriptorToSecurityDescriptorA(
4517
"O:SY"
4518
"G:S-1-5-21-93476-23408-4576",
4519
SDDL_REVISION_1, &sec, &dwDescSize), "Creating descriptor failed\n");
4520
4521
test_SetSecurityDescriptorControl(sec);
4522
4523
LocalFree(sec);
4524
4525
ok(ConvertStringSecurityDescriptorToSecurityDescriptorA(
4526
"O:SY"
4527
"G:S-1-5-21-93476-23408-4576"
4528
"D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)"
4529
"S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)", SDDL_REVISION_1, &sec, &dwDescSize), "Creating descriptor failed\n");
4530
buf = malloc(dwDescSize);
4531
SetSecurityDescriptorControl(sec, SE_DACL_PROTECTED, SE_DACL_PROTECTED);
4532
GetSecurityDescriptorControl(sec, &ctrl, &dwRevision);
4533
expect_eq(ctrl, 0x9014, int, "%x");
4534
4535
ret = GetPrivateObjectSecurity(sec, GROUP_SECURITY_INFORMATION, buf, dwDescSize, &retSize);
4536
ok(ret, "GetPrivateObjectSecurity failed (err=%lu)\n", GetLastError());
4537
ok(retSize <= dwDescSize, "Buffer too small (%ld vs %ld)\n", retSize, dwDescSize);
4538
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4539
CHECK_RESULT_AND_FREE("G:S-1-5-21-93476-23408-4576");
4540
GetSecurityDescriptorControl(buf, &ctrl, &dwRevision);
4541
expect_eq(ctrl, 0x8000, int, "%x");
4542
4543
ret = GetPrivateObjectSecurity(sec, GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, buf, dwDescSize, &retSize);
4544
ok(ret, "GetPrivateObjectSecurity failed (err=%lu)\n", GetLastError());
4545
ok(retSize <= dwDescSize, "Buffer too small (%ld vs %ld)\n", retSize, dwDescSize);
4546
ret = ConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len);
4547
ok(ret, "Conversion failed err=%lu\n", GetLastError());
4548
CHECK_ONE_OF_AND_FREE("G:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)",
4549
"G:S-1-5-21-93476-23408-4576D:P(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)"); /* Win7 */
4550
GetSecurityDescriptorControl(buf, &ctrl, &dwRevision);
4551
expect_eq(ctrl & (~ SE_DACL_PROTECTED), 0x8004, int, "%x");
4552
4553
ret = GetPrivateObjectSecurity(sec, sec_info, buf, dwDescSize, &retSize);
4554
ok(ret, "GetPrivateObjectSecurity failed (err=%lu)\n", GetLastError());
4555
ok(retSize == dwDescSize, "Buffer too small (%ld vs %ld)\n", retSize, dwDescSize);
4556
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4557
CHECK_ONE_OF_AND_FREE("O:SY"
4558
"G:S-1-5-21-93476-23408-4576"
4559
"D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)"
4560
"S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)",
4561
"O:SY"
4562
"G:S-1-5-21-93476-23408-4576"
4563
"D:P(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)"
4564
"S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)"); /* Win7 */
4565
GetSecurityDescriptorControl(buf, &ctrl, &dwRevision);
4566
expect_eq(ctrl & (~ SE_DACL_PROTECTED), 0x8014, int, "%x");
4567
4568
SetLastError(0xdeadbeef);
4569
ok(GetPrivateObjectSecurity(sec, sec_info, buf, 5, &retSize) == FALSE, "GetPrivateObjectSecurity should have failed\n");
4570
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected error ERROR_INSUFFICIENT_BUFFER, got %lu\n", GetLastError());
4571
4572
LocalFree(sec);
4573
free(buf);
4574
}
4575
#undef CHECK_RESULT_AND_FREE
4576
#undef CHECK_ONE_OF_AND_FREE
4577
4578
static void test_InitializeAcl(void)
4579
{
4580
char buffer[256];
4581
PACL pAcl = (PACL)buffer;
4582
BOOL ret;
4583
4584
SetLastError(0xdeadbeef);
4585
ret = InitializeAcl(pAcl, sizeof(ACL) - 1, ACL_REVISION);
4586
if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
4587
{
4588
win_skip("InitializeAcl is not implemented\n");
4589
return;
4590
}
4591
4592
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "InitializeAcl with too small a buffer should have failed with ERROR_INSUFFICIENT_BUFFER instead of %ld\n", GetLastError());
4593
4594
SetLastError(0xdeadbeef);
4595
ret = InitializeAcl(pAcl, 0xffffffff, ACL_REVISION);
4596
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "InitializeAcl with too large a buffer should have failed with ERROR_INVALID_PARAMETER instead of %ld\n", GetLastError());
4597
4598
SetLastError(0xdeadbeef);
4599
ret = InitializeAcl(pAcl, sizeof(buffer), ACL_REVISION1);
4600
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "InitializeAcl(ACL_REVISION1) should have failed with ERROR_INVALID_PARAMETER instead of %ld\n", GetLastError());
4601
4602
ret = InitializeAcl(pAcl, sizeof(buffer), ACL_REVISION2);
4603
ok(ret, "InitializeAcl(ACL_REVISION2) failed with error %ld\n", GetLastError());
4604
4605
ret = IsValidAcl(pAcl);
4606
ok(ret, "IsValidAcl failed with error %ld\n", GetLastError());
4607
4608
ret = InitializeAcl(pAcl, sizeof(buffer), ACL_REVISION3);
4609
ok(ret, "InitializeAcl(ACL_REVISION3) failed with error %ld\n", GetLastError());
4610
4611
ret = IsValidAcl(pAcl);
4612
ok(ret, "IsValidAcl failed with error %ld\n", GetLastError());
4613
4614
SetLastError(0xdeadbeef);
4615
ret = InitializeAcl(pAcl, sizeof(buffer), ACL_REVISION4);
4616
ok(ret, "InitializeAcl(ACL_REVISION4) failed with error %ld\n", GetLastError());
4617
4618
ret = IsValidAcl(pAcl);
4619
ok(ret, "IsValidAcl failed with error %ld\n", GetLastError());
4620
4621
SetLastError(0xdeadbeef);
4622
ret = InitializeAcl(pAcl, sizeof(buffer), -1);
4623
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "InitializeAcl(-1) failed with error %ld\n", GetLastError());
4624
}
4625
4626
static void test_GetSecurityInfo(void)
4627
{
4628
char domain_users_ptr[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
4629
char b[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
4630
char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], dacl[100];
4631
PSID domain_users_sid = (PSID) domain_users_ptr, domain_sid;
4632
SID_IDENTIFIER_AUTHORITY sia = { SECURITY_NT_AUTHORITY };
4633
int domain_users_ace_id = -1, admins_ace_id = -1, i;
4634
DWORD sid_size = sizeof(admin_ptr), l = sizeof(b);
4635
SECURITY_ATTRIBUTES sa = {.nLength = sizeof(sa)};
4636
PSID admin_sid = (PSID) admin_ptr, user_sid;
4637
char sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
4638
BOOL owner_defaulted, group_defaulted;
4639
BOOL dacl_defaulted, dacl_present;
4640
ACL_SIZE_INFORMATION acl_size;
4641
PSECURITY_DESCRIPTOR pSD;
4642
ACCESS_ALLOWED_ACE *ace;
4643
HANDLE token, obj;
4644
PSID owner, group;
4645
BOOL bret = TRUE;
4646
PACL pDacl;
4647
BYTE flags;
4648
DWORD ret;
4649
4650
static const SE_OBJECT_TYPE kernel_types[] =
4651
{
4652
SE_FILE_OBJECT,
4653
SE_KERNEL_OBJECT,
4654
SE_WMIGUID_OBJECT,
4655
};
4656
4657
static const SE_OBJECT_TYPE invalid_types[] =
4658
{
4659
SE_UNKNOWN_OBJECT_TYPE,
4660
SE_DS_OBJECT,
4661
SE_DS_OBJECT_ALL,
4662
SE_PROVIDER_DEFINED_OBJECT,
4663
SE_REGISTRY_WOW64_32KEY,
4664
SE_REGISTRY_WOW64_64KEY,
4665
0xdeadbeef,
4666
};
4667
4668
if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
4669
{
4670
if (GetLastError() != ERROR_NO_TOKEN) bret = FALSE;
4671
else if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) bret = FALSE;
4672
}
4673
if (!bret)
4674
{
4675
win_skip("Failed to get current user token\n");
4676
return;
4677
}
4678
bret = GetTokenInformation(token, TokenUser, b, l, &l);
4679
ok(bret, "GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError());
4680
CloseHandle( token );
4681
user_sid = ((TOKEN_USER *)b)->User.Sid;
4682
4683
/* Create something. Files have lots of associated security info. */
4684
obj = CreateFileA(myARGV[0], GENERIC_READ|WRITE_DAC, FILE_SHARE_READ, NULL,
4685
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
4686
if (obj == INVALID_HANDLE_VALUE)
4687
{
4688
skip("Couldn't create an object for GetSecurityInfo test\n");
4689
return;
4690
}
4691
4692
ret = GetSecurityInfo(obj, SE_FILE_OBJECT,
4693
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
4694
&owner, &group, &pDacl, NULL, &pSD);
4695
if (ret == ERROR_CALL_NOT_IMPLEMENTED)
4696
{
4697
win_skip("GetSecurityInfo is not implemented\n");
4698
CloseHandle(obj);
4699
return;
4700
}
4701
ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %ld\n", ret);
4702
ok(pSD != NULL, "GetSecurityInfo\n");
4703
ok(owner != NULL, "GetSecurityInfo\n");
4704
ok(group != NULL, "GetSecurityInfo\n");
4705
if (pDacl != NULL)
4706
ok(IsValidAcl(pDacl), "GetSecurityInfo\n");
4707
else
4708
win_skip("No ACL information returned\n");
4709
4710
LocalFree(pSD);
4711
4712
/* If we don't ask for the security descriptor, Windows will still give us
4713
the other stuff, leaving us no way to free it. */
4714
ret = GetSecurityInfo(obj, SE_FILE_OBJECT,
4715
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
4716
&owner, &group, &pDacl, NULL, NULL);
4717
ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %ld\n", ret);
4718
ok(owner != NULL, "GetSecurityInfo\n");
4719
ok(group != NULL, "GetSecurityInfo\n");
4720
if (pDacl != NULL)
4721
ok(IsValidAcl(pDacl), "GetSecurityInfo\n");
4722
else
4723
win_skip("No ACL information returned\n");
4724
4725
/* Create security descriptor information and test that it comes back the same */
4726
pSD = &sd;
4727
pDacl = (PACL)&dacl;
4728
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
4729
CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size);
4730
bret = InitializeAcl(pDacl, sizeof(dacl), ACL_REVISION);
4731
ok(bret, "Failed to initialize ACL.\n");
4732
bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
4733
ok(bret, "Failed to add Current User to ACL.\n");
4734
bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, admin_sid);
4735
ok(bret, "Failed to add Administrator Group to ACL.\n");
4736
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
4737
ok(bret, "Failed to add ACL to security descriptor.\n");
4738
ret = SetSecurityInfo(obj, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
4739
NULL, NULL, pDacl, NULL);
4740
ok(ret == ERROR_SUCCESS, "SetSecurityInfo returned %ld\n", ret);
4741
ret = GetSecurityInfo(obj, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
4742
NULL, NULL, &pDacl, NULL, &pSD);
4743
ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %ld\n", ret);
4744
ok(pDacl && IsValidAcl(pDacl), "GetSecurityInfo returned invalid DACL.\n");
4745
bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
4746
ok(bret, "GetAclInformation failed\n");
4747
if (acl_size.AceCount > 0)
4748
{
4749
bret = GetAce(pDacl, 0, (VOID **)&ace);
4750
ok(bret, "Failed to get Current User ACE.\n");
4751
bret = EqualSid(&ace->SidStart, user_sid);
4752
todo_wine ok(bret, "Current User ACE (%s) != Current User SID (%s).\n",
4753
debugstr_sid(&ace->SidStart), debugstr_sid(user_sid));
4754
ok(((ACE_HEADER *)ace)->AceFlags == 0,
4755
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
4756
ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%lx != 0x1f01ff)\n",
4757
ace->Mask);
4758
}
4759
if (acl_size.AceCount > 1)
4760
{
4761
bret = GetAce(pDacl, 1, (VOID **)&ace);
4762
ok(bret, "Failed to get Administators Group ACE.\n");
4763
bret = EqualSid(&ace->SidStart, admin_sid);
4764
todo_wine ok(bret, "Administators Group ACE (%s) != Administators Group SID (%s).\n", debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid));
4765
ok(((ACE_HEADER *)ace)->AceFlags == 0,
4766
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
4767
ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%lx != 0x1f01ff)\n",
4768
ace->Mask);
4769
}
4770
LocalFree(pSD);
4771
CloseHandle(obj);
4772
4773
/* Obtain the "domain users" SID from the user SID */
4774
if (!AllocateAndInitializeSid(&sia, 4, *GetSidSubAuthority(user_sid, 0),
4775
*GetSidSubAuthority(user_sid, 1),
4776
*GetSidSubAuthority(user_sid, 2),
4777
*GetSidSubAuthority(user_sid, 3), 0, 0, 0, 0, &domain_sid))
4778
{
4779
win_skip("Failed to get current domain SID\n");
4780
return;
4781
}
4782
sid_size = sizeof(domain_users_ptr);
4783
CreateWellKnownSid(WinAccountDomainUsersSid, domain_sid, domain_users_sid, &sid_size);
4784
FreeSid(domain_sid);
4785
4786
/* Test querying the ownership of a process */
4787
ret = GetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT,
4788
OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION,
4789
NULL, NULL, NULL, NULL, &pSD);
4790
ok(!ret, "GetNamedSecurityInfo failed with error %ld\n", ret);
4791
4792
bret = GetSecurityDescriptorOwner(pSD, &owner, &owner_defaulted);
4793
ok(bret, "GetSecurityDescriptorOwner failed with error %ld\n", GetLastError());
4794
ok(owner != NULL, "owner should not be NULL\n");
4795
ok(EqualSid(owner, admin_sid) || EqualSid(owner, user_sid),
4796
"Process owner SID != Administrators SID.\n");
4797
4798
bret = GetSecurityDescriptorGroup(pSD, &group, &group_defaulted);
4799
ok(bret, "GetSecurityDescriptorGroup failed with error %ld\n", GetLastError());
4800
ok(group != NULL, "group should not be NULL\n");
4801
ok(EqualSid(group, domain_users_sid), "Process group SID != Domain Users SID.\n");
4802
LocalFree(pSD);
4803
4804
/* Test querying the DACL of a process */
4805
ret = GetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION,
4806
NULL, NULL, NULL, NULL, &pSD);
4807
ok(!ret, "GetSecurityInfo failed with error %ld\n", ret);
4808
4809
bret = GetSecurityDescriptorDacl(pSD, &dacl_present, &pDacl, &dacl_defaulted);
4810
ok(bret, "GetSecurityDescriptorDacl failed with error %ld\n", GetLastError());
4811
ok(dacl_present, "DACL should be present\n");
4812
ok(pDacl && IsValidAcl(pDacl), "GetSecurityDescriptorDacl returned invalid DACL.\n");
4813
bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
4814
ok(bret, "GetAclInformation failed\n");
4815
ok(acl_size.AceCount != 0, "GetAclInformation returned no ACLs\n");
4816
for (i=0; i<acl_size.AceCount; i++)
4817
{
4818
bret = GetAce(pDacl, i, (VOID **)&ace);
4819
ok(bret, "Failed to get ACE %d.\n", i);
4820
bret = EqualSid(&ace->SidStart, domain_users_sid);
4821
if (bret) domain_users_ace_id = i;
4822
bret = EqualSid(&ace->SidStart, admin_sid);
4823
if (bret) admins_ace_id = i;
4824
}
4825
ok(domain_users_ace_id != -1 || broken(domain_users_ace_id == -1) /* win2k */,
4826
"Domain Users ACE not found.\n");
4827
if (domain_users_ace_id != -1)
4828
{
4829
bret = GetAce(pDacl, domain_users_ace_id, (VOID **)&ace);
4830
ok(bret, "Failed to get Domain Users ACE.\n");
4831
flags = ((ACE_HEADER *)ace)->AceFlags;
4832
ok(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE),
4833
"Domain Users ACE has unexpected flags (0x%x != 0x%x)\n", flags,
4834
INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE);
4835
ok(ace->Mask == GENERIC_READ, "Domain Users ACE has unexpected mask (0x%lx != 0x%x)\n",
4836
ace->Mask, GENERIC_READ);
4837
}
4838
ok(admins_ace_id != -1 || broken(admins_ace_id == -1) /* xp */,
4839
"Builtin Admins ACE not found.\n");
4840
if (admins_ace_id != -1)
4841
{
4842
bret = GetAce(pDacl, admins_ace_id, (VOID **)&ace);
4843
ok(bret, "Failed to get Builtin Admins ACE.\n");
4844
flags = ((ACE_HEADER *)ace)->AceFlags;
4845
ok(flags == 0x0, "Builtin Admins ACE has unexpected flags (0x%x != 0x0)\n", flags);
4846
ok(ace->Mask == PROCESS_ALL_ACCESS || broken(ace->Mask == 0x1f0fff) /* win2k */,
4847
"Builtin Admins ACE has unexpected mask (0x%lx != 0x%x)\n", ace->Mask, PROCESS_ALL_ACCESS);
4848
}
4849
LocalFree(pSD);
4850
4851
ret = GetSecurityInfo(NULL, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD);
4852
ok(ret == ERROR_INVALID_HANDLE, "got error %lu\n", ret);
4853
4854
ret = GetSecurityInfo(GetCurrentProcess(), SE_FILE_OBJECT,
4855
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD);
4856
ok(!ret, "got error %lu\n", ret);
4857
LocalFree(pSD);
4858
4859
sa.lpSecurityDescriptor = sd;
4860
obj = CreateEventA(&sa, TRUE, TRUE, NULL);
4861
pDacl = (PACL)&dacl;
4862
4863
for (size_t i = 0; i < ARRAY_SIZE(kernel_types); ++i)
4864
{
4865
winetest_push_context("Type %#x", kernel_types[i]);
4866
4867
ret = GetSecurityInfo(NULL, kernel_types[i],
4868
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD);
4869
ok(ret == ERROR_INVALID_HANDLE, "got error %lu\n", ret);
4870
4871
ret = GetSecurityInfo(GetCurrentProcess(), kernel_types[i],
4872
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD);
4873
ok(!ret, "got error %lu\n", ret);
4874
LocalFree(pSD);
4875
4876
ret = GetSecurityInfo(obj, kernel_types[i],
4877
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD);
4878
ok(!ret, "got error %lu\n", ret);
4879
LocalFree(pSD);
4880
4881
ret = SetSecurityInfo(NULL, kernel_types[i],
4882
DACL_SECURITY_INFORMATION, NULL, NULL, pDacl, NULL);
4883
ok(ret == ERROR_INVALID_HANDLE, "got error %lu\n", ret);
4884
4885
ret = SetSecurityInfo(obj, kernel_types[i],
4886
DACL_SECURITY_INFORMATION, NULL, NULL, pDacl, NULL);
4887
ok(!ret || ret == ERROR_NO_SECURITY_ON_OBJECT /* win 7 */, "got error %lu\n", ret);
4888
4889
winetest_pop_context();
4890
}
4891
4892
ret = GetSecurityInfo(GetCurrentProcess(), SE_REGISTRY_KEY,
4893
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD);
4894
todo_wine ok(ret == ERROR_INVALID_HANDLE, "got error %lu\n", ret);
4895
4896
ret = GetSecurityInfo(obj, SE_REGISTRY_KEY,
4897
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD);
4898
todo_wine ok(ret == ERROR_INVALID_HANDLE, "got error %lu\n", ret);
4899
4900
CloseHandle(obj);
4901
4902
for (size_t i = 0; i < ARRAY_SIZE(invalid_types); ++i)
4903
{
4904
winetest_push_context("Type %#x", invalid_types[i]);
4905
4906
ret = GetSecurityInfo(NULL, invalid_types[i],
4907
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD);
4908
ok(ret == ERROR_INVALID_HANDLE, "got error %lu\n", ret);
4909
4910
ret = GetSecurityInfo((HANDLE)0xdeadbeef, invalid_types[i],
4911
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD);
4912
todo_wine ok(ret == ERROR_INVALID_PARAMETER, "got error %lu\n", ret);
4913
4914
ret = SetSecurityInfo(NULL, invalid_types[i],
4915
DACL_SECURITY_INFORMATION, NULL, NULL, pDacl, NULL);
4916
ok(ret == ERROR_INVALID_HANDLE, "got error %lu\n", ret);
4917
4918
ret = SetSecurityInfo((HANDLE)0xdeadbeef, invalid_types[i],
4919
DACL_SECURITY_INFORMATION, NULL, NULL, pDacl, NULL);
4920
todo_wine ok(ret == ERROR_INVALID_PARAMETER, "got error %lu\n", ret);
4921
4922
winetest_pop_context();
4923
}
4924
}
4925
4926
static void test_GetSidSubAuthority(void)
4927
{
4928
PSID psid = NULL;
4929
4930
/* Note: on windows passing in an invalid index like -1, lets GetSidSubAuthority return 0x05000000 but
4931
still GetLastError returns ERROR_SUCCESS then. We don't test these unlikely cornercases here for now */
4932
ok(ConvertStringSidToSidA("S-1-5-21-93476-23408-4576",&psid),"ConvertStringSidToSidA failed\n");
4933
ok(IsValidSid(psid),"Sid is not valid\n");
4934
SetLastError(0xbebecaca);
4935
ok(*GetSidSubAuthorityCount(psid) == 4,"GetSidSubAuthorityCount gave %d expected 4\n", *GetSidSubAuthorityCount(psid));
4936
ok(GetLastError() == 0,"GetLastError returned %ld instead of 0\n",GetLastError());
4937
SetLastError(0xbebecaca);
4938
ok(*GetSidSubAuthority(psid,0) == 21,"GetSidSubAuthority gave %ld expected 21\n", *GetSidSubAuthority(psid,0));
4939
ok(GetLastError() == 0,"GetLastError returned %ld instead of 0\n",GetLastError());
4940
SetLastError(0xbebecaca);
4941
ok(*GetSidSubAuthority(psid,1) == 93476,"GetSidSubAuthority gave %ld expected 93476\n", *GetSidSubAuthority(psid,1));
4942
ok(GetLastError() == 0,"GetLastError returned %ld instead of 0\n",GetLastError());
4943
SetLastError(0xbebecaca);
4944
ok(GetSidSubAuthority(psid,4) != NULL,"Expected out of bounds GetSidSubAuthority to return a non-NULL pointer\n");
4945
ok(GetLastError() == 0,"GetLastError returned %ld instead of 0\n",GetLastError());
4946
LocalFree(psid);
4947
}
4948
4949
static void test_CheckTokenMembership(void)
4950
{
4951
PTOKEN_GROUPS token_groups;
4952
DWORD size;
4953
HANDLE process_token, token;
4954
BOOL is_member;
4955
BOOL ret;
4956
DWORD i;
4957
4958
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &process_token);
4959
ok(ret, "OpenProcessToken failed with error %ld\n", GetLastError());
4960
4961
ret = DuplicateToken(process_token, SecurityImpersonation, &token);
4962
ok(ret, "DuplicateToken failed with error %ld\n", GetLastError());
4963
4964
/* groups */
4965
ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
4966
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
4967
"GetTokenInformation(TokenGroups) %s with error %ld\n",
4968
ret ? "succeeded" : "failed", GetLastError());
4969
token_groups = malloc(size);
4970
ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
4971
ok(ret, "GetTokenInformation(TokenGroups) failed with error %ld\n", GetLastError());
4972
4973
for (i = 0; i < token_groups->GroupCount; i++)
4974
{
4975
if (token_groups->Groups[i].Attributes & SE_GROUP_ENABLED)
4976
break;
4977
}
4978
4979
if (i == token_groups->GroupCount)
4980
{
4981
free(token_groups);
4982
CloseHandle(token);
4983
skip("user not a member of any group\n");
4984
return;
4985
}
4986
4987
is_member = FALSE;
4988
ret = CheckTokenMembership(token, token_groups->Groups[i].Sid, &is_member);
4989
ok(ret, "CheckTokenMembership failed with error %ld\n", GetLastError());
4990
ok(is_member, "CheckTokenMembership should have detected sid as member\n");
4991
4992
is_member = FALSE;
4993
ret = CheckTokenMembership(NULL, token_groups->Groups[i].Sid, &is_member);
4994
ok(ret, "CheckTokenMembership failed with error %ld\n", GetLastError());
4995
ok(is_member, "CheckTokenMembership should have detected sid as member\n");
4996
4997
is_member = TRUE;
4998
SetLastError(0xdeadbeef);
4999
ret = CheckTokenMembership(process_token, token_groups->Groups[i].Sid, &is_member);
5000
ok(!ret && GetLastError() == ERROR_NO_IMPERSONATION_TOKEN,
5001
"CheckTokenMembership with process token %s with error %ld\n",
5002
ret ? "succeeded" : "failed", GetLastError());
5003
ok(!is_member, "CheckTokenMembership should have cleared is_member\n");
5004
5005
free(token_groups);
5006
CloseHandle(token);
5007
CloseHandle(process_token);
5008
}
5009
5010
static void test_EqualSid(void)
5011
{
5012
PSID sid1, sid2;
5013
BOOL ret;
5014
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
5015
SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY };
5016
5017
SetLastError(0xdeadbeef);
5018
ret = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
5019
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &sid1);
5020
if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
5021
{
5022
win_skip("AllocateAndInitializeSid is not implemented\n");
5023
return;
5024
}
5025
ok(ret, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
5026
ok(GetLastError() == 0xdeadbeef,
5027
"AllocateAndInitializeSid shouldn't have set last error to %ld\n",
5028
GetLastError());
5029
5030
ret = AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID,
5031
0, 0, 0, 0, 0, 0, 0, &sid2);
5032
ok(ret, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
5033
5034
SetLastError(0xdeadbeef);
5035
ret = EqualSid(sid1, sid2);
5036
ok(!ret, "World and domain admins sids shouldn't have been equal\n");
5037
ok(GetLastError() == ERROR_SUCCESS,
5038
"EqualSid should have set last error to ERROR_SUCCESS instead of %ld\n",
5039
GetLastError());
5040
5041
SetLastError(0xdeadbeef);
5042
sid2 = FreeSid(sid2);
5043
ok(!sid2, "FreeSid should have returned NULL instead of %p\n", sid2);
5044
ok(GetLastError() == 0xdeadbeef,
5045
"FreeSid shouldn't have set last error to %ld\n",
5046
GetLastError());
5047
5048
ret = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
5049
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &sid2);
5050
ok(ret, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
5051
5052
SetLastError(0xdeadbeef);
5053
ret = EqualSid(sid1, sid2);
5054
ok(ret, "Same sids should have been equal %s != %s\n",
5055
debugstr_sid(sid1), debugstr_sid(sid2));
5056
ok(GetLastError() == ERROR_SUCCESS,
5057
"EqualSid should have set last error to ERROR_SUCCESS instead of %ld\n",
5058
GetLastError());
5059
5060
((SID *)sid2)->Revision = 2;
5061
SetLastError(0xdeadbeef);
5062
ret = EqualSid(sid1, sid2);
5063
ok(!ret, "EqualSid with invalid sid should have returned FALSE\n");
5064
ok(GetLastError() == ERROR_SUCCESS,
5065
"EqualSid should have set last error to ERROR_SUCCESS instead of %ld\n",
5066
GetLastError());
5067
((SID *)sid2)->Revision = SID_REVISION;
5068
5069
FreeSid(sid1);
5070
FreeSid(sid2);
5071
}
5072
5073
static void test_GetUserNameA(void)
5074
{
5075
char buffer[UNLEN + 1], filler[UNLEN + 1];
5076
DWORD required_len, buffer_len;
5077
BOOL ret;
5078
5079
/* Test crashes on Windows. */
5080
if (0)
5081
{
5082
SetLastError(0xdeadbeef);
5083
GetUserNameA(NULL, NULL);
5084
}
5085
5086
SetLastError(0xdeadbeef);
5087
required_len = 0;
5088
ret = GetUserNameA(NULL, &required_len);
5089
ok(ret == FALSE, "GetUserNameA returned %d\n", ret);
5090
ok(required_len != 0, "Outputted buffer length was %lu\n", required_len);
5091
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError());
5092
5093
SetLastError(0xdeadbeef);
5094
required_len = 1;
5095
ret = GetUserNameA(NULL, &required_len);
5096
ok(ret == FALSE, "GetUserNameA returned %d\n", ret);
5097
ok(required_len != 0 && required_len != 1, "Outputted buffer length was %lu\n", required_len);
5098
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError());
5099
5100
/* Tests crashes on Windows. */
5101
if (0)
5102
{
5103
SetLastError(0xdeadbeef);
5104
required_len = UNLEN + 1;
5105
GetUserNameA(NULL, &required_len);
5106
5107
SetLastError(0xdeadbeef);
5108
GetUserNameA(buffer, NULL);
5109
}
5110
5111
memset(filler, 'x', sizeof(filler));
5112
5113
/* Note that GetUserNameA on XP and newer outputs the number of bytes
5114
* required for a Unicode string, which affects a test in the next block. */
5115
SetLastError(0xdeadbeef);
5116
memcpy(buffer, filler, sizeof(filler));
5117
required_len = 0;
5118
ret = GetUserNameA(buffer, &required_len);
5119
ok(ret == FALSE, "GetUserNameA returned %d\n", ret);
5120
ok(!memcmp(buffer, filler, sizeof(filler)), "Output buffer was altered\n");
5121
ok(required_len != 0, "Outputted buffer length was %lu\n", required_len);
5122
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError());
5123
5124
SetLastError(0xdeadbeef);
5125
memcpy(buffer, filler, sizeof(filler));
5126
buffer_len = required_len;
5127
ret = GetUserNameA(buffer, &buffer_len);
5128
ok(ret == TRUE, "GetUserNameA returned %d, last error %lu\n", ret, GetLastError());
5129
ok(memcmp(buffer, filler, sizeof(filler)) != 0, "Output buffer was untouched\n");
5130
ok(buffer_len == required_len ||
5131
broken(buffer_len == required_len / sizeof(WCHAR)), /* XP+ */
5132
"Outputted buffer length was %lu\n", buffer_len);
5133
ok(GetLastError() == 0xdeadbeef, "Last error was %lu\n", GetLastError());
5134
5135
/* Use the reported buffer size from the last GetUserNameA call and pass
5136
* a length that is one less than the required value. */
5137
SetLastError(0xdeadbeef);
5138
memcpy(buffer, filler, sizeof(filler));
5139
buffer_len--;
5140
ret = GetUserNameA(buffer, &buffer_len);
5141
ok(ret == FALSE, "GetUserNameA returned %d\n", ret);
5142
ok(!memcmp(buffer, filler, sizeof(filler)), "Output buffer was untouched\n");
5143
ok(buffer_len == required_len, "Outputted buffer length was %lu\n", buffer_len);
5144
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError());
5145
}
5146
5147
static void test_GetUserNameW(void)
5148
{
5149
WCHAR buffer[UNLEN + 1], filler[UNLEN + 1];
5150
DWORD required_len, buffer_len;
5151
BOOL ret;
5152
5153
/* Test crashes on Windows. */
5154
if (0)
5155
{
5156
SetLastError(0xdeadbeef);
5157
GetUserNameW(NULL, NULL);
5158
}
5159
5160
SetLastError(0xdeadbeef);
5161
required_len = 0;
5162
ret = GetUserNameW(NULL, &required_len);
5163
ok(ret == FALSE, "GetUserNameW returned %d\n", ret);
5164
ok(required_len != 0, "Outputted buffer length was %lu\n", required_len);
5165
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError());
5166
5167
SetLastError(0xdeadbeef);
5168
required_len = 1;
5169
ret = GetUserNameW(NULL, &required_len);
5170
ok(ret == FALSE, "GetUserNameW returned %d\n", ret);
5171
ok(required_len != 0 && required_len != 1, "Outputted buffer length was %lu\n", required_len);
5172
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError());
5173
5174
/* Tests crash on Windows. */
5175
if (0)
5176
{
5177
SetLastError(0xdeadbeef);
5178
required_len = UNLEN + 1;
5179
GetUserNameW(NULL, &required_len);
5180
5181
SetLastError(0xdeadbeef);
5182
GetUserNameW(buffer, NULL);
5183
}
5184
5185
memset(filler, 'x', sizeof(filler));
5186
5187
SetLastError(0xdeadbeef);
5188
memcpy(buffer, filler, sizeof(filler));
5189
required_len = 0;
5190
ret = GetUserNameW(buffer, &required_len);
5191
ok(ret == FALSE, "GetUserNameW returned %d\n", ret);
5192
ok(!memcmp(buffer, filler, sizeof(filler)), "Output buffer was altered\n");
5193
ok(required_len != 0, "Outputted buffer length was %lu\n", required_len);
5194
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError());
5195
5196
SetLastError(0xdeadbeef);
5197
memcpy(buffer, filler, sizeof(filler));
5198
buffer_len = required_len;
5199
ret = GetUserNameW(buffer, &buffer_len);
5200
ok(ret == TRUE, "GetUserNameW returned %d, last error %lu\n", ret, GetLastError());
5201
ok(memcmp(buffer, filler, sizeof(filler)) != 0, "Output buffer was untouched\n");
5202
ok(buffer_len == required_len, "Outputted buffer length was %lu\n", buffer_len);
5203
ok(GetLastError() == 0xdeadbeef, "Last error was %lu\n", GetLastError());
5204
5205
/* GetUserNameW on XP and newer writes a truncated portion of the username string to the buffer. */
5206
SetLastError(0xdeadbeef);
5207
memcpy(buffer, filler, sizeof(filler));
5208
buffer_len--;
5209
ret = GetUserNameW(buffer, &buffer_len);
5210
ok(ret == FALSE, "GetUserNameW returned %d\n", ret);
5211
ok(!memcmp(buffer, filler, sizeof(filler)) ||
5212
broken(memcmp(buffer, filler, sizeof(filler)) != 0), /* XP+ */
5213
"Output buffer was altered\n");
5214
ok(buffer_len == required_len, "Outputted buffer length was %lu\n", buffer_len);
5215
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError());
5216
}
5217
5218
static void test_CreateRestrictedToken(void)
5219
{
5220
HANDLE process_token, token, r_token;
5221
PTOKEN_GROUPS token_groups, groups2;
5222
LUID_AND_ATTRIBUTES lattr;
5223
SID_AND_ATTRIBUTES sattr;
5224
SECURITY_IMPERSONATION_LEVEL level;
5225
SID *removed_sid = NULL;
5226
char privs_buffer[1000];
5227
TOKEN_PRIVILEGES *privs = (TOKEN_PRIVILEGES *)privs_buffer;
5228
PRIVILEGE_SET priv_set;
5229
TOKEN_TYPE type;
5230
BOOL is_member;
5231
DWORD size;
5232
LUID luid = { 0, 0 };
5233
BOOL ret;
5234
DWORD i;
5235
5236
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &process_token);
5237
ok(ret, "got error %ld\n", GetLastError());
5238
5239
ret = DuplicateTokenEx(process_token, TOKEN_DUPLICATE|TOKEN_ADJUST_GROUPS|TOKEN_QUERY,
5240
NULL, SecurityImpersonation, TokenImpersonation, &token);
5241
ok(ret, "got error %ld\n", GetLastError());
5242
5243
ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
5244
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
5245
"got %d with error %ld\n", ret, GetLastError());
5246
token_groups = malloc(size);
5247
ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
5248
ok(ret, "got error %ld\n", GetLastError());
5249
5250
for (i = 0; i < token_groups->GroupCount; i++)
5251
{
5252
if (token_groups->Groups[i].Attributes & SE_GROUP_ENABLED)
5253
{
5254
removed_sid = token_groups->Groups[i].Sid;
5255
break;
5256
}
5257
}
5258
ok(!!removed_sid, "user is not a member of any group\n");
5259
5260
is_member = FALSE;
5261
ret = CheckTokenMembership(token, removed_sid, &is_member);
5262
ok(ret, "got error %ld\n", GetLastError());
5263
ok(is_member, "not a member\n");
5264
5265
sattr.Sid = removed_sid;
5266
sattr.Attributes = 0;
5267
r_token = NULL;
5268
ret = CreateRestrictedToken(token, 0, 1, &sattr, 0, NULL, 0, NULL, &r_token);
5269
ok(ret, "got error %ld\n", GetLastError());
5270
5271
is_member = TRUE;
5272
ret = CheckTokenMembership(r_token, removed_sid, &is_member);
5273
ok(ret, "got error %ld\n", GetLastError());
5274
ok(!is_member, "not a member\n");
5275
5276
ret = GetTokenInformation(r_token, TokenGroups, NULL, 0, &size);
5277
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %ld\n",
5278
ret, GetLastError());
5279
groups2 = malloc(size);
5280
ret = GetTokenInformation(r_token, TokenGroups, groups2, size, &size);
5281
ok(ret, "got error %ld\n", GetLastError());
5282
5283
for (i = 0; i < groups2->GroupCount; i++)
5284
{
5285
if (EqualSid(groups2->Groups[i].Sid, removed_sid))
5286
{
5287
DWORD attr = groups2->Groups[i].Attributes;
5288
ok(attr & SE_GROUP_USE_FOR_DENY_ONLY, "got wrong attributes %#lx\n", attr);
5289
ok(!(attr & SE_GROUP_ENABLED), "got wrong attributes %#lx\n", attr);
5290
break;
5291
}
5292
}
5293
5294
free(groups2);
5295
5296
size = sizeof(type);
5297
ret = GetTokenInformation(r_token, TokenType, &type, size, &size);
5298
ok(ret, "got error %ld\n", GetLastError());
5299
ok(type == TokenImpersonation, "got type %u\n", type);
5300
5301
size = sizeof(level);
5302
ret = GetTokenInformation(r_token, TokenImpersonationLevel, &level, size, &size);
5303
ok(ret, "got error %ld\n", GetLastError());
5304
ok(level == SecurityImpersonation, "got level %u\n", type);
5305
5306
CloseHandle(r_token);
5307
5308
r_token = NULL;
5309
ret = CreateRestrictedToken(process_token, 0, 1, &sattr, 0, NULL, 0, NULL, &r_token);
5310
ok(ret, "got error %lu\n", GetLastError());
5311
5312
size = sizeof(type);
5313
ret = GetTokenInformation(r_token, TokenType, &type, size, &size);
5314
ok(ret, "got error %lu\n", GetLastError());
5315
ok(type == TokenPrimary, "got type %u\n", type);
5316
5317
CloseHandle(r_token);
5318
5319
ret = GetTokenInformation(token, TokenPrivileges, privs, sizeof(privs_buffer), &size);
5320
ok(ret, "got error %lu\n", GetLastError());
5321
5322
for (i = 0; i < privs->PrivilegeCount; i++)
5323
{
5324
if (privs->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED)
5325
{
5326
luid = privs->Privileges[i].Luid;
5327
break;
5328
}
5329
}
5330
ok(i < privs->PrivilegeCount, "user has no privileges\n");
5331
5332
lattr.Luid = luid;
5333
lattr.Attributes = 0;
5334
r_token = NULL;
5335
ret = CreateRestrictedToken(token, 0, 0, NULL, 1, &lattr, 0, NULL, &r_token);
5336
ok(ret, "got error %lu\n", GetLastError());
5337
5338
priv_set.PrivilegeCount = 1;
5339
priv_set.Control = 0;
5340
priv_set.Privilege[0].Luid = luid;
5341
priv_set.Privilege[0].Attributes = 0;
5342
ret = PrivilegeCheck(r_token, &priv_set, &is_member);
5343
ok(ret, "got error %lu\n", GetLastError());
5344
ok(!is_member, "privilege should not be enabled\n");
5345
5346
ret = GetTokenInformation(r_token, TokenPrivileges, privs, sizeof(privs_buffer), &size);
5347
ok(ret, "got error %lu\n", GetLastError());
5348
5349
is_member = FALSE;
5350
for (i = 0; i < privs->PrivilegeCount; i++)
5351
{
5352
if (!memcmp(&privs->Privileges[i].Luid, &luid, sizeof(luid)))
5353
is_member = TRUE;
5354
}
5355
ok(!is_member, "disabled privilege should not be present\n");
5356
5357
CloseHandle(r_token);
5358
5359
removed_sid->SubAuthority[0] = 0xdeadbeef;
5360
lattr.Luid.LowPart = 0xdeadbeef;
5361
r_token = NULL;
5362
ret = CreateRestrictedToken(token, 0, 1, &sattr, 1, &lattr, 0, NULL, &r_token);
5363
ok(ret, "got error %lu\n", GetLastError());
5364
CloseHandle(r_token);
5365
5366
free(token_groups);
5367
CloseHandle(token);
5368
CloseHandle(process_token);
5369
}
5370
5371
static void validate_default_security_descriptor(SECURITY_DESCRIPTOR *sd)
5372
{
5373
BOOL ret, present, defaulted;
5374
ACL *acl;
5375
void *sid;
5376
5377
ret = IsValidSecurityDescriptor(sd);
5378
ok(ret, "security descriptor is not valid\n");
5379
5380
present = -1;
5381
defaulted = -1;
5382
acl = (void *)0xdeadbeef;
5383
SetLastError(0xdeadbeef);
5384
ret = GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted);
5385
ok(ret, "GetSecurityDescriptorDacl error %ld\n", GetLastError());
5386
todo_wine
5387
ok(present == 1, "acl is not present\n");
5388
todo_wine
5389
ok(acl != (void *)0xdeadbeef && acl != NULL, "acl pointer is not set\n");
5390
ok(defaulted == 0, "defaulted is set to TRUE\n");
5391
5392
defaulted = -1;
5393
sid = (void *)0xdeadbeef;
5394
SetLastError(0xdeadbeef);
5395
ret = GetSecurityDescriptorOwner(sd, &sid, &defaulted);
5396
ok(ret, "GetSecurityDescriptorOwner error %ld\n", GetLastError());
5397
todo_wine
5398
ok(sid != (void *)0xdeadbeef && sid != NULL, "sid pointer is not set\n");
5399
ok(defaulted == 0, "defaulted is set to TRUE\n");
5400
5401
defaulted = -1;
5402
sid = (void *)0xdeadbeef;
5403
SetLastError(0xdeadbeef);
5404
ret = GetSecurityDescriptorGroup(sd, &sid, &defaulted);
5405
ok(ret, "GetSecurityDescriptorGroup error %ld\n", GetLastError());
5406
todo_wine
5407
ok(sid != (void *)0xdeadbeef && sid != NULL, "sid pointer is not set\n");
5408
ok(defaulted == 0, "defaulted is set to TRUE\n");
5409
}
5410
5411
static void test_default_handle_security(HANDLE token, HANDLE handle, GENERIC_MAPPING *mapping)
5412
{
5413
DWORD ret, granted, priv_set_len;
5414
BOOL status;
5415
PRIVILEGE_SET priv_set;
5416
SECURITY_DESCRIPTOR *sd;
5417
5418
sd = test_get_security_descriptor(handle, __LINE__);
5419
validate_default_security_descriptor(sd);
5420
5421
priv_set_len = sizeof(priv_set);
5422
granted = 0xdeadbeef;
5423
status = 0xdeadbeef;
5424
SetLastError(0xdeadbeef);
5425
ret = AccessCheck(sd, token, MAXIMUM_ALLOWED, mapping, &priv_set, &priv_set_len, &granted, &status);
5426
todo_wine {
5427
ok(ret, "AccessCheck error %ld\n", GetLastError());
5428
ok(status == 1, "expected 1, got %d\n", status);
5429
ok(granted == mapping->GenericAll, "expected all access %#lx, got %#lx\n", mapping->GenericAll, granted);
5430
}
5431
priv_set_len = sizeof(priv_set);
5432
granted = 0xdeadbeef;
5433
status = 0xdeadbeef;
5434
SetLastError(0xdeadbeef);
5435
ret = AccessCheck(sd, token, 0, mapping, &priv_set, &priv_set_len, &granted, &status);
5436
todo_wine {
5437
ok(ret, "AccessCheck error %ld\n", GetLastError());
5438
ok(status == 0, "expected 0, got %d\n", status);
5439
ok(granted == 0, "expected 0, got %#lx\n", granted);
5440
}
5441
priv_set_len = sizeof(priv_set);
5442
granted = 0xdeadbeef;
5443
status = 0xdeadbeef;
5444
SetLastError(0xdeadbeef);
5445
ret = AccessCheck(sd, token, ACCESS_SYSTEM_SECURITY, mapping, &priv_set, &priv_set_len, &granted, &status);
5446
todo_wine {
5447
ok(ret, "AccessCheck error %ld\n", GetLastError());
5448
ok(status == 0, "expected 0, got %d\n", status);
5449
ok(granted == 0, "expected 0, got %#lx\n", granted);
5450
}
5451
priv_set_len = sizeof(priv_set);
5452
granted = 0xdeadbeef;
5453
status = 0xdeadbeef;
5454
SetLastError(0xdeadbeef);
5455
ret = AccessCheck(sd, token, mapping->GenericRead, mapping, &priv_set, &priv_set_len, &granted, &status);
5456
todo_wine {
5457
ok(ret, "AccessCheck error %ld\n", GetLastError());
5458
ok(status == 1, "expected 1, got %d\n", status);
5459
ok(granted == mapping->GenericRead, "expected read access %#lx, got %#lx\n", mapping->GenericRead, granted);
5460
}
5461
priv_set_len = sizeof(priv_set);
5462
granted = 0xdeadbeef;
5463
status = 0xdeadbeef;
5464
SetLastError(0xdeadbeef);
5465
ret = AccessCheck(sd, token, mapping->GenericWrite, mapping, &priv_set, &priv_set_len, &granted, &status);
5466
todo_wine {
5467
ok(ret, "AccessCheck error %ld\n", GetLastError());
5468
ok(status == 1, "expected 1, got %d\n", status);
5469
ok(granted == mapping->GenericWrite, "expected write access %#lx, got %#lx\n", mapping->GenericWrite, granted);
5470
}
5471
priv_set_len = sizeof(priv_set);
5472
granted = 0xdeadbeef;
5473
status = 0xdeadbeef;
5474
SetLastError(0xdeadbeef);
5475
ret = AccessCheck(sd, token, mapping->GenericExecute, mapping, &priv_set, &priv_set_len, &granted, &status);
5476
todo_wine {
5477
ok(ret, "AccessCheck error %ld\n", GetLastError());
5478
ok(status == 1, "expected 1, got %d\n", status);
5479
ok(granted == mapping->GenericExecute, "expected execute access %#lx, got %#lx\n", mapping->GenericExecute, granted);
5480
}
5481
free(sd);
5482
}
5483
5484
static ACCESS_MASK get_obj_access(HANDLE obj)
5485
{
5486
OBJECT_BASIC_INFORMATION info;
5487
NTSTATUS status;
5488
5489
status = NtQueryObject(obj, ObjectBasicInformation, &info, sizeof(info), NULL);
5490
ok(!status, "NtQueryObject error %#lx\n", status);
5491
5492
return info.GrantedAccess;
5493
}
5494
5495
static void test_mutex_security(HANDLE token)
5496
{
5497
DWORD ret, i, access;
5498
HANDLE mutex, dup;
5499
GENERIC_MAPPING mapping = { STANDARD_RIGHTS_READ | MUTANT_QUERY_STATE | SYNCHRONIZE,
5500
STANDARD_RIGHTS_WRITE | MUTEX_MODIFY_STATE | SYNCHRONIZE,
5501
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
5502
STANDARD_RIGHTS_ALL | MUTEX_ALL_ACCESS };
5503
static const struct
5504
{
5505
int generic, mapped;
5506
} map[] =
5507
{
5508
{ 0, 0 },
5509
{ GENERIC_READ, STANDARD_RIGHTS_READ | MUTANT_QUERY_STATE },
5510
{ GENERIC_WRITE, STANDARD_RIGHTS_WRITE },
5511
{ GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE },
5512
{ GENERIC_ALL, STANDARD_RIGHTS_ALL | MUTANT_QUERY_STATE }
5513
};
5514
5515
SetLastError(0xdeadbeef);
5516
mutex = OpenMutexA(0, FALSE, "WineTestMutex");
5517
ok(!mutex, "mutex should not exist\n");
5518
ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %lu\n", GetLastError());
5519
5520
SetLastError(0xdeadbeef);
5521
mutex = CreateMutexA(NULL, FALSE, "WineTestMutex");
5522
ok(mutex != 0, "CreateMutex error %ld\n", GetLastError());
5523
5524
access = get_obj_access(mutex);
5525
ok(access == MUTANT_ALL_ACCESS, "expected MUTANT_ALL_ACCESS, got %#lx\n", access);
5526
5527
for (i = 0; i < ARRAY_SIZE(map); i++)
5528
{
5529
SetLastError( 0xdeadbeef );
5530
ret = DuplicateHandle(GetCurrentProcess(), mutex, GetCurrentProcess(), &dup,
5531
map[i].generic, FALSE, 0);
5532
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
5533
5534
access = get_obj_access(dup);
5535
ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
5536
5537
CloseHandle(dup);
5538
5539
SetLastError(0xdeadbeef);
5540
dup = OpenMutexA(0, FALSE, "WineTestMutex");
5541
ok(!dup, "OpenMutex should fail\n");
5542
ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %lu\n", GetLastError());
5543
}
5544
5545
test_default_handle_security(token, mutex, &mapping);
5546
5547
CloseHandle (mutex);
5548
}
5549
5550
static void test_event_security(HANDLE token)
5551
{
5552
DWORD ret, i, access;
5553
HANDLE event, dup;
5554
GENERIC_MAPPING mapping = { STANDARD_RIGHTS_READ | EVENT_QUERY_STATE | SYNCHRONIZE,
5555
STANDARD_RIGHTS_WRITE | EVENT_MODIFY_STATE | SYNCHRONIZE,
5556
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
5557
STANDARD_RIGHTS_ALL | EVENT_ALL_ACCESS };
5558
static const struct
5559
{
5560
int generic, mapped;
5561
} map[] =
5562
{
5563
{ 0, 0 },
5564
{ GENERIC_READ, STANDARD_RIGHTS_READ | EVENT_QUERY_STATE },
5565
{ GENERIC_WRITE, STANDARD_RIGHTS_WRITE | EVENT_MODIFY_STATE },
5566
{ GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE },
5567
{ GENERIC_ALL, STANDARD_RIGHTS_ALL | EVENT_QUERY_STATE | EVENT_MODIFY_STATE }
5568
};
5569
5570
SetLastError(0xdeadbeef);
5571
event = OpenEventA(0, FALSE, "WineTestEvent");
5572
ok(!event, "event should not exist\n");
5573
ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %lu\n", GetLastError());
5574
5575
SetLastError(0xdeadbeef);
5576
event = CreateEventA(NULL, FALSE, FALSE, "WineTestEvent");
5577
ok(event != 0, "CreateEvent error %ld\n", GetLastError());
5578
5579
access = get_obj_access(event);
5580
ok(access == EVENT_ALL_ACCESS, "expected EVENT_ALL_ACCESS, got %#lx\n", access);
5581
5582
for (i = 0; i < ARRAY_SIZE(map); i++)
5583
{
5584
SetLastError( 0xdeadbeef );
5585
ret = DuplicateHandle(GetCurrentProcess(), event, GetCurrentProcess(), &dup,
5586
map[i].generic, FALSE, 0);
5587
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
5588
5589
access = get_obj_access(dup);
5590
ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
5591
5592
CloseHandle(dup);
5593
5594
SetLastError(0xdeadbeef);
5595
dup = OpenEventA(0, FALSE, "WineTestEvent");
5596
ok(!dup, "OpenEvent should fail\n");
5597
ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %lu\n", GetLastError());
5598
}
5599
5600
test_default_handle_security(token, event, &mapping);
5601
5602
CloseHandle(event);
5603
}
5604
5605
static void test_semaphore_security(HANDLE token)
5606
{
5607
DWORD ret, i, access;
5608
HANDLE sem, dup;
5609
GENERIC_MAPPING mapping = { STANDARD_RIGHTS_READ | SEMAPHORE_QUERY_STATE,
5610
STANDARD_RIGHTS_WRITE | SEMAPHORE_MODIFY_STATE,
5611
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
5612
STANDARD_RIGHTS_ALL | SEMAPHORE_ALL_ACCESS };
5613
static const struct
5614
{
5615
int generic, mapped;
5616
} map[] =
5617
{
5618
{ 0, 0 },
5619
{ GENERIC_READ, STANDARD_RIGHTS_READ | SEMAPHORE_QUERY_STATE },
5620
{ GENERIC_WRITE, STANDARD_RIGHTS_WRITE | SEMAPHORE_MODIFY_STATE },
5621
{ GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE },
5622
{ GENERIC_ALL, STANDARD_RIGHTS_ALL | SEMAPHORE_QUERY_STATE | SEMAPHORE_MODIFY_STATE }
5623
};
5624
5625
SetLastError(0xdeadbeef);
5626
sem = OpenSemaphoreA(0, FALSE, "WineTestSemaphore");
5627
ok(!sem, "semaphore should not exist\n");
5628
ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %lu\n", GetLastError());
5629
5630
SetLastError(0xdeadbeef);
5631
sem = CreateSemaphoreA(NULL, 0, 10, "WineTestSemaphore");
5632
ok(sem != 0, "CreateSemaphore error %ld\n", GetLastError());
5633
5634
access = get_obj_access(sem);
5635
ok(access == SEMAPHORE_ALL_ACCESS, "expected SEMAPHORE_ALL_ACCESS, got %#lx\n", access);
5636
5637
for (i = 0; i < ARRAY_SIZE(map); i++)
5638
{
5639
SetLastError( 0xdeadbeef );
5640
ret = DuplicateHandle(GetCurrentProcess(), sem, GetCurrentProcess(), &dup,
5641
map[i].generic, FALSE, 0);
5642
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
5643
5644
access = get_obj_access(dup);
5645
ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
5646
5647
CloseHandle(dup);
5648
}
5649
5650
test_default_handle_security(token, sem, &mapping);
5651
5652
CloseHandle(sem);
5653
}
5654
5655
#define WINE_TEST_PIPE "\\\\.\\pipe\\WineTestPipe"
5656
static void test_named_pipe_security(HANDLE token)
5657
{
5658
DWORD ret, i, access;
5659
HANDLE pipe, file, dup;
5660
GENERIC_MAPPING mapping = { FILE_GENERIC_READ,
5661
FILE_GENERIC_WRITE,
5662
FILE_GENERIC_EXECUTE,
5663
STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS };
5664
static const struct
5665
{
5666
int generic, mapped;
5667
} map[] =
5668
{
5669
{ 0, 0 },
5670
{ GENERIC_READ, FILE_GENERIC_READ },
5671
{ GENERIC_WRITE, FILE_GENERIC_WRITE },
5672
{ GENERIC_EXECUTE, FILE_GENERIC_EXECUTE },
5673
{ GENERIC_ALL, STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS }
5674
};
5675
static const struct
5676
{
5677
DWORD open_mode;
5678
DWORD access;
5679
} creation_access[] =
5680
{
5681
{ PIPE_ACCESS_INBOUND, FILE_GENERIC_READ },
5682
{ PIPE_ACCESS_OUTBOUND, FILE_GENERIC_WRITE },
5683
{ PIPE_ACCESS_DUPLEX, FILE_GENERIC_READ|FILE_GENERIC_WRITE },
5684
{ PIPE_ACCESS_INBOUND|WRITE_DAC, FILE_GENERIC_READ|WRITE_DAC },
5685
{ PIPE_ACCESS_INBOUND|WRITE_OWNER, FILE_GENERIC_READ|WRITE_OWNER }
5686
/* ACCESS_SYSTEM_SECURITY is also valid, but will fail with ERROR_PRIVILEGE_NOT_HELD */
5687
};
5688
5689
/* Test the different security access options for pipes */
5690
for (i = 0; i < ARRAY_SIZE(creation_access); i++)
5691
{
5692
SetLastError(0xdeadbeef);
5693
pipe = CreateNamedPipeA(WINE_TEST_PIPE, creation_access[i].open_mode,
5694
PIPE_TYPE_BYTE | PIPE_NOWAIT, PIPE_UNLIMITED_INSTANCES, 0, 0,
5695
NMPWAIT_USE_DEFAULT_WAIT, NULL);
5696
ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe(0x%lx) error %ld\n",
5697
creation_access[i].open_mode, GetLastError());
5698
access = get_obj_access(pipe);
5699
ok(access == creation_access[i].access,
5700
"CreateNamedPipeA(0x%lx) pipe expected access 0x%lx (got 0x%lx)\n",
5701
creation_access[i].open_mode, creation_access[i].access, access);
5702
CloseHandle(pipe);
5703
}
5704
5705
SetLastError(0xdeadbeef);
5706
pipe = CreateNamedPipeA(WINE_TEST_PIPE, PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
5707
PIPE_TYPE_BYTE | PIPE_NOWAIT, PIPE_UNLIMITED_INSTANCES,
5708
0, 0, NMPWAIT_USE_DEFAULT_WAIT, NULL);
5709
ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe error %ld\n", GetLastError());
5710
5711
test_default_handle_security(token, pipe, &mapping);
5712
5713
SetLastError(0xdeadbeef);
5714
file = CreateFileA(WINE_TEST_PIPE, FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING, 0, 0);
5715
ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
5716
5717
access = get_obj_access(file);
5718
ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#lx\n", access);
5719
5720
for (i = 0; i < ARRAY_SIZE(map); i++)
5721
{
5722
SetLastError( 0xdeadbeef );
5723
ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup,
5724
map[i].generic, FALSE, 0);
5725
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
5726
5727
access = get_obj_access(dup);
5728
ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
5729
5730
CloseHandle(dup);
5731
}
5732
5733
CloseHandle(file);
5734
CloseHandle(pipe);
5735
5736
SetLastError(0xdeadbeef);
5737
file = CreateFileA("\\\\.\\pipe\\", FILE_ALL_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
5738
ok(file != INVALID_HANDLE_VALUE || broken(file == INVALID_HANDLE_VALUE) /* before Vista */, "CreateFile error %ld\n", GetLastError());
5739
5740
if (file != INVALID_HANDLE_VALUE)
5741
{
5742
access = get_obj_access(file);
5743
ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#lx\n", access);
5744
5745
for (i = 0; i < ARRAY_SIZE(map); i++)
5746
{
5747
SetLastError( 0xdeadbeef );
5748
ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup,
5749
map[i].generic, FALSE, 0);
5750
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
5751
5752
access = get_obj_access(dup);
5753
ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
5754
CloseHandle(dup);
5755
}
5756
}
5757
5758
CloseHandle(file);
5759
}
5760
5761
static void test_file_security(HANDLE token)
5762
{
5763
DWORD ret, i, access, bytes;
5764
HANDLE file, dup;
5765
static const struct
5766
{
5767
int generic, mapped;
5768
} map[] =
5769
{
5770
{ 0, 0 },
5771
{ GENERIC_READ, FILE_GENERIC_READ },
5772
{ GENERIC_WRITE, FILE_GENERIC_WRITE },
5773
{ GENERIC_EXECUTE, FILE_GENERIC_EXECUTE },
5774
{ GENERIC_ALL, STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS }
5775
};
5776
char temp_path[MAX_PATH];
5777
char file_name[MAX_PATH];
5778
char buf[16];
5779
5780
GetTempPathA(MAX_PATH, temp_path);
5781
GetTempFileNameA(temp_path, "tmp", 0, file_name);
5782
5783
/* file */
5784
SetLastError(0xdeadbeef);
5785
file = CreateFileA(file_name, GENERIC_ALL, 0, NULL, CREATE_ALWAYS, 0, NULL);
5786
ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
5787
5788
access = get_obj_access(file);
5789
ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#lx\n", access);
5790
5791
for (i = 0; i < ARRAY_SIZE(map); i++)
5792
{
5793
SetLastError( 0xdeadbeef );
5794
ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup,
5795
map[i].generic, FALSE, 0);
5796
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
5797
5798
access = get_obj_access(dup);
5799
ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
5800
5801
CloseHandle(dup);
5802
}
5803
5804
CloseHandle(file);
5805
5806
SetLastError(0xdeadbeef);
5807
file = CreateFileA(file_name, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
5808
ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
5809
5810
access = get_obj_access(file);
5811
ok(access == (FILE_READ_ATTRIBUTES | SYNCHRONIZE), "expected FILE_READ_ATTRIBUTES | SYNCHRONIZE, got %#lx\n", access);
5812
5813
bytes = 0xdeadbeef;
5814
SetLastError(0xdeadbeef);
5815
ret = ReadFile(file, buf, sizeof(buf), &bytes, NULL);
5816
ok(!ret, "ReadFile should fail\n");
5817
ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
5818
ok(bytes == 0, "expected 0, got %lu\n", bytes);
5819
5820
CloseHandle(file);
5821
5822
SetLastError(0xdeadbeef);
5823
file = CreateFileA(file_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
5824
ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
5825
5826
access = get_obj_access(file);
5827
ok(access == (FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES), "expected FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES, got %#lx\n", access);
5828
5829
bytes = 0xdeadbeef;
5830
SetLastError(0xdeadbeef);
5831
ret = ReadFile(file, buf, sizeof(buf), &bytes, NULL);
5832
ok(!ret, "ReadFile should fail\n");
5833
ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
5834
ok(bytes == 0, "expected 0, got %lu\n", bytes);
5835
5836
CloseHandle(file);
5837
DeleteFileA(file_name);
5838
5839
/* directory */
5840
SetLastError(0xdeadbeef);
5841
file = CreateFileA(temp_path, GENERIC_ALL, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
5842
ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
5843
5844
access = get_obj_access(file);
5845
ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#lx\n", access);
5846
5847
for (i = 0; i < ARRAY_SIZE(map); i++)
5848
{
5849
SetLastError( 0xdeadbeef );
5850
ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup,
5851
map[i].generic, FALSE, 0);
5852
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
5853
5854
access = get_obj_access(dup);
5855
ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
5856
5857
CloseHandle(dup);
5858
}
5859
5860
CloseHandle(file);
5861
5862
SetLastError(0xdeadbeef);
5863
file = CreateFileA(temp_path, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
5864
ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
5865
5866
access = get_obj_access(file);
5867
ok(access == (FILE_READ_ATTRIBUTES | SYNCHRONIZE), "expected FILE_READ_ATTRIBUTES | SYNCHRONIZE, got %#lx\n", access);
5868
5869
CloseHandle(file);
5870
5871
SetLastError(0xdeadbeef);
5872
file = CreateFileA(temp_path, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
5873
ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
5874
5875
access = get_obj_access(file);
5876
ok(access == (FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES), "expected FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES, got %#lx\n", access);
5877
5878
CloseHandle(file);
5879
}
5880
5881
static void test_filemap_security(void)
5882
{
5883
char temp_path[MAX_PATH];
5884
char file_name[MAX_PATH];
5885
DWORD ret, i, access;
5886
HANDLE file, mapping, dup, created_mapping;
5887
static const struct
5888
{
5889
int generic, mapped;
5890
BOOL open_only;
5891
} map[] =
5892
{
5893
{ 0, 0 },
5894
{ GENERIC_READ, STANDARD_RIGHTS_READ | SECTION_QUERY | SECTION_MAP_READ },
5895
{ GENERIC_WRITE, STANDARD_RIGHTS_WRITE | SECTION_MAP_WRITE },
5896
{ GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SECTION_MAP_EXECUTE },
5897
{ GENERIC_ALL, STANDARD_RIGHTS_REQUIRED | SECTION_ALL_ACCESS },
5898
{ SECTION_MAP_READ | SECTION_MAP_WRITE, SECTION_MAP_READ | SECTION_MAP_WRITE },
5899
{ SECTION_MAP_WRITE, SECTION_MAP_WRITE },
5900
{ SECTION_MAP_READ | SECTION_QUERY, SECTION_MAP_READ | SECTION_QUERY },
5901
{ SECTION_QUERY, SECTION_MAP_READ, TRUE },
5902
{ SECTION_QUERY | SECTION_MAP_READ, SECTION_QUERY | SECTION_MAP_READ }
5903
};
5904
static const struct
5905
{
5906
int prot, mapped;
5907
} prot_map[] =
5908
{
5909
{ 0, 0 },
5910
{ PAGE_NOACCESS, 0 },
5911
{ PAGE_READONLY, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ },
5912
{ PAGE_READWRITE, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE },
5913
{ PAGE_WRITECOPY, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ },
5914
{ PAGE_EXECUTE, 0 },
5915
{ PAGE_EXECUTE_READ, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_EXECUTE },
5916
{ PAGE_EXECUTE_READWRITE, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE },
5917
{ PAGE_EXECUTE_WRITECOPY, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_EXECUTE }
5918
};
5919
5920
GetTempPathA(MAX_PATH, temp_path);
5921
GetTempFileNameA(temp_path, "tmp", 0, file_name);
5922
5923
SetLastError(0xdeadbeef);
5924
file = CreateFileA(file_name, GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE, 0, NULL, CREATE_ALWAYS, 0, 0);
5925
ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
5926
SetFilePointer(file, 4096, NULL, FILE_BEGIN);
5927
SetEndOfFile(file);
5928
5929
for (i = 0; i < ARRAY_SIZE(prot_map); i++)
5930
{
5931
if (map[i].open_only) continue;
5932
5933
SetLastError(0xdeadbeef);
5934
mapping = CreateFileMappingW(file, NULL, prot_map[i].prot, 0, 4096, NULL);
5935
if (prot_map[i].mapped)
5936
{
5937
ok(mapping != 0, "CreateFileMapping(%04x) error %ld\n", prot_map[i].prot, GetLastError());
5938
}
5939
else
5940
{
5941
ok(!mapping, "CreateFileMapping(%04x) should fail\n", prot_map[i].prot);
5942
ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
5943
continue;
5944
}
5945
5946
access = get_obj_access(mapping);
5947
ok(access == prot_map[i].mapped, "%ld: expected %#x, got %#lx\n", i, prot_map[i].mapped, access);
5948
5949
CloseHandle(mapping);
5950
}
5951
5952
SetLastError(0xdeadbeef);
5953
mapping = CreateFileMappingW(file, NULL, PAGE_EXECUTE_READWRITE, 0, 4096, NULL);
5954
ok(mapping != 0, "CreateFileMapping error %ld\n", GetLastError());
5955
5956
access = get_obj_access(mapping);
5957
ok(access == (STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE),
5958
"expected STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE, got %#lx\n", access);
5959
5960
for (i = 0; i < ARRAY_SIZE(map); i++)
5961
{
5962
if (map[i].open_only) continue;
5963
5964
SetLastError( 0xdeadbeef );
5965
ret = DuplicateHandle(GetCurrentProcess(), mapping, GetCurrentProcess(), &dup,
5966
map[i].generic, FALSE, 0);
5967
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
5968
5969
access = get_obj_access(dup);
5970
ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
5971
5972
CloseHandle(dup);
5973
}
5974
5975
CloseHandle(mapping);
5976
CloseHandle(file);
5977
DeleteFileA(file_name);
5978
5979
created_mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 0x1000,
5980
"Wine Test Open Mapping");
5981
ok(created_mapping != NULL, "CreateFileMapping failed with error %lu\n", GetLastError());
5982
5983
for (i = 0; i < ARRAY_SIZE(map); i++)
5984
{
5985
if (!map[i].generic) continue;
5986
5987
mapping = OpenFileMappingA(map[i].generic, FALSE, "Wine Test Open Mapping");
5988
ok(mapping != NULL, "OpenFileMapping failed with error %ld\n", GetLastError());
5989
access = get_obj_access(mapping);
5990
ok(access == map[i].mapped, "%ld: unexpected access flags %#lx, expected %#x\n",
5991
i, access, map[i].mapped);
5992
CloseHandle(mapping);
5993
}
5994
5995
CloseHandle(created_mapping);
5996
}
5997
5998
static void test_thread_security(void)
5999
{
6000
DWORD ret, i, access;
6001
HANDLE thread, dup;
6002
static const struct
6003
{
6004
int generic, mapped;
6005
} map[] =
6006
{
6007
{ 0, 0 },
6008
{ GENERIC_READ, STANDARD_RIGHTS_READ | THREAD_QUERY_INFORMATION | THREAD_GET_CONTEXT },
6009
{ GENERIC_WRITE, STANDARD_RIGHTS_WRITE | THREAD_SET_INFORMATION | THREAD_SET_CONTEXT | THREAD_TERMINATE | THREAD_SUSPEND_RESUME | 0x4 },
6010
{ GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE },
6011
{ GENERIC_ALL, THREAD_ALL_ACCESS_NT4 }
6012
};
6013
6014
SetLastError(0xdeadbeef);
6015
thread = CreateThread(NULL, 0, (void *)0xdeadbeef, NULL, CREATE_SUSPENDED, &ret);
6016
ok(thread != 0, "CreateThread error %ld\n", GetLastError());
6017
6018
access = get_obj_access(thread);
6019
ok(access == THREAD_ALL_ACCESS_NT4 || access == THREAD_ALL_ACCESS_VISTA, "expected THREAD_ALL_ACCESS, got %#lx\n", access);
6020
6021
for (i = 0; i < ARRAY_SIZE(map); i++)
6022
{
6023
SetLastError( 0xdeadbeef );
6024
ret = DuplicateHandle(GetCurrentProcess(), thread, GetCurrentProcess(), &dup,
6025
map[i].generic, FALSE, 0);
6026
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
6027
6028
access = get_obj_access(dup);
6029
switch (map[i].generic)
6030
{
6031
case GENERIC_READ:
6032
case GENERIC_EXECUTE:
6033
ok(access == map[i].mapped ||
6034
access == (map[i].mapped | THREAD_QUERY_LIMITED_INFORMATION) /* Vista+ */ ||
6035
access == (map[i].mapped | THREAD_QUERY_LIMITED_INFORMATION | THREAD_RESUME) /* win8 */,
6036
"%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
6037
break;
6038
case GENERIC_WRITE:
6039
ok(access == map[i].mapped ||
6040
access == (map[i].mapped | THREAD_SET_LIMITED_INFORMATION) /* Vista+ */ ||
6041
access == (map[i].mapped | THREAD_SET_LIMITED_INFORMATION | THREAD_RESUME) /* win8 */,
6042
"%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
6043
break;
6044
case GENERIC_ALL:
6045
ok(access == map[i].mapped || access == THREAD_ALL_ACCESS_VISTA,
6046
"%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
6047
break;
6048
default:
6049
ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
6050
break;
6051
}
6052
6053
CloseHandle(dup);
6054
}
6055
6056
SetLastError( 0xdeadbeef );
6057
ret = DuplicateHandle(GetCurrentProcess(), thread, GetCurrentProcess(), &dup,
6058
THREAD_QUERY_INFORMATION, FALSE, 0);
6059
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
6060
access = get_obj_access(dup);
6061
ok(access == (THREAD_QUERY_INFORMATION | THREAD_QUERY_LIMITED_INFORMATION) /* Vista+ */ ||
6062
access == THREAD_QUERY_INFORMATION /* before Vista */,
6063
"expected THREAD_QUERY_INFORMATION|THREAD_QUERY_LIMITED_INFORMATION, got %#lx\n", access);
6064
CloseHandle(dup);
6065
6066
TerminateThread(thread, 0);
6067
CloseHandle(thread);
6068
}
6069
6070
static void test_process_access(void)
6071
{
6072
DWORD ret, i, access;
6073
HANDLE process, dup;
6074
STARTUPINFOA sti;
6075
PROCESS_INFORMATION pi;
6076
char cmdline[] = "winver.exe";
6077
static const struct
6078
{
6079
int generic, mapped;
6080
} map[] =
6081
{
6082
{ 0, 0 },
6083
{ GENERIC_READ, STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ },
6084
{ GENERIC_WRITE, STANDARD_RIGHTS_WRITE | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION | PROCESS_SUSPEND_RESUME |
6085
PROCESS_VM_WRITE | PROCESS_DUP_HANDLE | PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION },
6086
{ GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE },
6087
{ GENERIC_ALL, PROCESS_ALL_ACCESS_NT4 }
6088
};
6089
6090
memset(&sti, 0, sizeof(sti));
6091
sti.cb = sizeof(sti);
6092
SetLastError(0xdeadbeef);
6093
ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &sti, &pi);
6094
ok(ret, "CreateProcess() error %ld\n", GetLastError());
6095
6096
CloseHandle(pi.hThread);
6097
process = pi.hProcess;
6098
6099
access = get_obj_access(process);
6100
ok(access == PROCESS_ALL_ACCESS_NT4 || access == PROCESS_ALL_ACCESS_VISTA, "expected PROCESS_ALL_ACCESS, got %#lx\n", access);
6101
6102
for (i = 0; i < ARRAY_SIZE(map); i++)
6103
{
6104
SetLastError( 0xdeadbeef );
6105
ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup,
6106
map[i].generic, FALSE, 0);
6107
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
6108
6109
access = get_obj_access(dup);
6110
switch (map[i].generic)
6111
{
6112
case GENERIC_READ:
6113
ok(access == map[i].mapped || access == (map[i].mapped | PROCESS_QUERY_LIMITED_INFORMATION) /* Vista+ */,
6114
"%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
6115
break;
6116
case GENERIC_WRITE:
6117
ok(access == map[i].mapped ||
6118
access == (map[i].mapped | PROCESS_TERMINATE) /* before Vista */ ||
6119
access == (map[i].mapped | PROCESS_SET_LIMITED_INFORMATION) /* win8 */ ||
6120
access == (map[i].mapped | PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_SET_LIMITED_INFORMATION) /* Win10 Anniversary Update */,
6121
"%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
6122
break;
6123
case GENERIC_EXECUTE:
6124
ok(access == map[i].mapped || access == (map[i].mapped | PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_TERMINATE) /* Vista+ */,
6125
"%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
6126
break;
6127
case GENERIC_ALL:
6128
ok(access == map[i].mapped || access == PROCESS_ALL_ACCESS_VISTA,
6129
"%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
6130
break;
6131
default:
6132
ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
6133
break;
6134
}
6135
6136
CloseHandle(dup);
6137
}
6138
6139
SetLastError( 0xdeadbeef );
6140
ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup,
6141
PROCESS_QUERY_INFORMATION, FALSE, 0);
6142
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
6143
access = get_obj_access(dup);
6144
ok(access == (PROCESS_QUERY_INFORMATION | PROCESS_QUERY_LIMITED_INFORMATION) /* Vista+ */ ||
6145
access == PROCESS_QUERY_INFORMATION /* before Vista */,
6146
"expected PROCESS_QUERY_INFORMATION|PROCESS_QUERY_LIMITED_INFORMATION, got %#lx\n", access);
6147
CloseHandle(dup);
6148
6149
SetLastError( 0xdeadbeef );
6150
ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup,
6151
PROCESS_VM_OPERATION, FALSE, 0);
6152
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
6153
access = get_obj_access(dup);
6154
ok(access == PROCESS_VM_OPERATION, "unexpected access right %lx\n", access);
6155
CloseHandle(dup);
6156
6157
SetLastError( 0xdeadbeef );
6158
ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup,
6159
PROCESS_VM_WRITE, FALSE, 0);
6160
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
6161
access = get_obj_access(dup);
6162
ok(access == PROCESS_VM_WRITE, "unexpected access right %lx\n", access);
6163
CloseHandle(dup);
6164
6165
SetLastError( 0xdeadbeef );
6166
ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup,
6167
PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, 0);
6168
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
6169
access = get_obj_access(dup);
6170
ok(access == (PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_QUERY_LIMITED_INFORMATION) ||
6171
broken(access == (PROCESS_VM_OPERATION | PROCESS_VM_WRITE)) /* Win8 and before */,
6172
"expected PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_QUERY_LIMITED_INFORMATION, got %#lx\n", access);
6173
CloseHandle(dup);
6174
6175
SetLastError( 0xdeadbeef );
6176
ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup,
6177
PROCESS_VM_OPERATION | PROCESS_VM_READ, FALSE, 0);
6178
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
6179
access = get_obj_access(dup);
6180
ok(access == (PROCESS_VM_OPERATION | PROCESS_VM_READ), "unexpected access right %lx\n", access);
6181
CloseHandle(dup);
6182
6183
TerminateProcess(process, 0);
6184
CloseHandle(process);
6185
}
6186
6187
static BOOL validate_impersonation_token(HANDLE token, DWORD *token_type)
6188
{
6189
DWORD ret, needed;
6190
TOKEN_TYPE type;
6191
SECURITY_IMPERSONATION_LEVEL sil;
6192
6193
type = 0xdeadbeef;
6194
needed = 0;
6195
SetLastError(0xdeadbeef);
6196
ret = GetTokenInformation(token, TokenType, &type, sizeof(type), &needed);
6197
ok(ret, "GetTokenInformation error %ld\n", GetLastError());
6198
ok(needed == sizeof(type), "GetTokenInformation should return required buffer length\n");
6199
ok(type == TokenPrimary || type == TokenImpersonation, "expected TokenPrimary or TokenImpersonation, got %d\n", type);
6200
6201
*token_type = type;
6202
if (type != TokenImpersonation) return FALSE;
6203
6204
needed = 0;
6205
SetLastError(0xdeadbeef);
6206
ret = GetTokenInformation(token, TokenImpersonationLevel, &sil, sizeof(sil), &needed);
6207
ok(ret, "GetTokenInformation error %ld\n", GetLastError());
6208
ok(needed == sizeof(sil), "GetTokenInformation should return required buffer length\n");
6209
ok(sil == SecurityImpersonation, "expected SecurityImpersonation, got %d\n", sil);
6210
6211
needed = 0xdeadbeef;
6212
SetLastError(0xdeadbeef);
6213
ret = GetTokenInformation(token, TokenDefaultDacl, NULL, 0, &needed);
6214
ok(!ret, "GetTokenInformation should fail\n");
6215
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
6216
ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n");
6217
ok(needed > sizeof(TOKEN_DEFAULT_DACL), "GetTokenInformation returned empty default DACL\n");
6218
6219
needed = 0xdeadbeef;
6220
SetLastError(0xdeadbeef);
6221
ret = GetTokenInformation(token, TokenOwner, NULL, 0, &needed);
6222
ok(!ret, "GetTokenInformation should fail\n");
6223
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
6224
ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n");
6225
ok(needed > sizeof(TOKEN_OWNER), "GetTokenInformation returned empty token owner\n");
6226
6227
needed = 0xdeadbeef;
6228
SetLastError(0xdeadbeef);
6229
ret = GetTokenInformation(token, TokenPrimaryGroup, NULL, 0, &needed);
6230
ok(!ret, "GetTokenInformation should fail\n");
6231
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
6232
ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n");
6233
ok(needed > sizeof(TOKEN_PRIMARY_GROUP), "GetTokenInformation returned empty token primary group\n");
6234
6235
return TRUE;
6236
}
6237
6238
static void test_kernel_objects_security(void)
6239
{
6240
HANDLE token, process_token;
6241
DWORD ret, token_type;
6242
6243
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &process_token);
6244
ok(ret, "OpenProcessToken error %ld\n", GetLastError());
6245
6246
ret = validate_impersonation_token(process_token, &token_type);
6247
ok(token_type == TokenPrimary, "expected TokenPrimary, got %ld\n", token_type);
6248
ok(!ret, "access token should not be an impersonation token\n");
6249
6250
ret = DuplicateToken(process_token, SecurityImpersonation, &token);
6251
ok(ret, "DuplicateToken error %ld\n", GetLastError());
6252
6253
ret = validate_impersonation_token(token, &token_type);
6254
ok(ret, "access token should be a valid impersonation token\n");
6255
ok(token_type == TokenImpersonation, "expected TokenImpersonation, got %ld\n", token_type);
6256
6257
test_mutex_security(token);
6258
test_event_security(token);
6259
test_named_pipe_security(token);
6260
test_semaphore_security(token);
6261
test_file_security(token);
6262
test_filemap_security();
6263
test_thread_security();
6264
test_process_access();
6265
/* FIXME: test other kernel object types */
6266
6267
CloseHandle(process_token);
6268
CloseHandle(token);
6269
}
6270
6271
static void test_TokenIntegrityLevel(void)
6272
{
6273
TOKEN_MANDATORY_LABEL *tml;
6274
BYTE buffer[64]; /* using max. 28 byte in win7 x64 */
6275
HANDLE token;
6276
DWORD size;
6277
DWORD res;
6278
static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
6279
{SECURITY_MANDATORY_HIGH_RID}};
6280
static SID high_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
6281
{SECURITY_MANDATORY_MEDIUM_RID}};
6282
6283
SetLastError(0xdeadbeef);
6284
res = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
6285
ok(res, "got %ld with %ld (expected TRUE)\n", res, GetLastError());
6286
6287
SetLastError(0xdeadbeef);
6288
res = GetTokenInformation(token, TokenIntegrityLevel, buffer, sizeof(buffer), &size);
6289
6290
/* not supported before Vista */
6291
if (!res && ((GetLastError() == ERROR_INVALID_PARAMETER) || GetLastError() == ERROR_INVALID_FUNCTION))
6292
{
6293
win_skip("TokenIntegrityLevel not supported\n");
6294
CloseHandle(token);
6295
return;
6296
}
6297
6298
ok(res, "got %lu with %lu (expected TRUE)\n", res, GetLastError());
6299
if (!res)
6300
{
6301
CloseHandle(token);
6302
return;
6303
}
6304
6305
tml = (TOKEN_MANDATORY_LABEL*) buffer;
6306
ok(tml->Label.Attributes == (SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED),
6307
"got 0x%lx (expected 0x%x)\n", tml->Label.Attributes, (SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED));
6308
6309
ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level),
6310
"got %s (expected %s or %s)\n", debugstr_sid(tml->Label.Sid),
6311
debugstr_sid(&medium_level), debugstr_sid(&high_level));
6312
6313
CloseHandle(token);
6314
}
6315
6316
static void test_default_dacl_owner_group_sid(void)
6317
{
6318
TOKEN_USER *token_user;
6319
TOKEN_OWNER *token_owner;
6320
TOKEN_PRIMARY_GROUP *token_primary_group;
6321
HANDLE handle, token;
6322
BOOL ret, defaulted, present, found;
6323
DWORD size, index;
6324
SECURITY_DESCRIPTOR *sd;
6325
SECURITY_ATTRIBUTES sa;
6326
PSID owner, group;
6327
ACL *dacl;
6328
ACCESS_ALLOWED_ACE *ace;
6329
6330
ret = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &token );
6331
ok(ret, "OpenProcessToken failed with error %ld\n", GetLastError());
6332
6333
token_user = get_alloc_token_user( token );
6334
token_owner = get_alloc_token_owner( token );
6335
token_primary_group = get_alloc_token_primary_group( token );
6336
6337
CloseHandle( token );
6338
6339
sd = malloc( SECURITY_DESCRIPTOR_MIN_LENGTH );
6340
ret = InitializeSecurityDescriptor( sd, SECURITY_DESCRIPTOR_REVISION );
6341
ok( ret, "error %lu\n", GetLastError() );
6342
6343
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
6344
sa.lpSecurityDescriptor = sd;
6345
sa.bInheritHandle = FALSE;
6346
handle = CreateEventA( &sa, TRUE, TRUE, "test_event" );
6347
ok( handle != NULL, "error %lu\n", GetLastError() );
6348
6349
size = 0;
6350
ret = GetKernelObjectSecurity( handle, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, NULL, 0, &size );
6351
ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "error %lu\n", GetLastError() );
6352
6353
sd = malloc( size );
6354
ret = GetKernelObjectSecurity( handle, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, sd, size, &size );
6355
ok( ret, "error %lu\n", GetLastError() );
6356
6357
owner = (void *)0xdeadbeef;
6358
defaulted = TRUE;
6359
ret = GetSecurityDescriptorOwner( sd, &owner, &defaulted );
6360
ok( ret, "error %lu\n", GetLastError() );
6361
ok( owner != (void *)0xdeadbeef, "owner not set\n" );
6362
ok( !defaulted, "owner defaulted\n" );
6363
ok( EqualSid( owner, token_owner->Owner ), "owner shall equal token owner\n" );
6364
6365
group = (void *)0xdeadbeef;
6366
defaulted = TRUE;
6367
ret = GetSecurityDescriptorGroup( sd, &group, &defaulted );
6368
ok( ret, "error %lu\n", GetLastError() );
6369
ok( group != (void *)0xdeadbeef, "group not set\n" );
6370
ok( !defaulted, "group defaulted\n" );
6371
ok( EqualSid( group, token_primary_group->PrimaryGroup ), "group shall equal token primary group\n" );
6372
6373
dacl = (void *)0xdeadbeef;
6374
present = FALSE;
6375
defaulted = TRUE;
6376
ret = GetSecurityDescriptorDacl( sd, &present, &dacl, &defaulted );
6377
ok( ret, "error %lu\n", GetLastError() );
6378
ok( present, "dacl not present\n" );
6379
ok( dacl != (void *)0xdeadbeef, "dacl not set\n" );
6380
ok( !defaulted, "dacl defaulted\n" );
6381
6382
index = 0;
6383
found = FALSE;
6384
while (GetAce( dacl, index++, (void **)&ace ))
6385
{
6386
ok( ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE,
6387
"expected ACCESS_ALLOWED_ACE_TYPE, got %d\n", ace->Header.AceType );
6388
if (EqualSid( &ace->SidStart, owner )) found = TRUE;
6389
}
6390
ok( found, "owner sid not found in dacl\n" );
6391
6392
if (!EqualSid( token_user->User.Sid, token_owner->Owner ))
6393
{
6394
index = 0;
6395
found = FALSE;
6396
while (GetAce( dacl, index++, (void **)&ace ))
6397
{
6398
ok( ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE,
6399
"expected ACCESS_ALLOWED_ACE_TYPE, got %d\n", ace->Header.AceType );
6400
if (EqualSid( &ace->SidStart, token_user->User.Sid )) found = TRUE;
6401
}
6402
ok( !found, "DACL shall not reference token user if it is different from token owner\n" );
6403
}
6404
6405
free( sa.lpSecurityDescriptor );
6406
free( sd );
6407
CloseHandle( handle );
6408
6409
free( token_primary_group );
6410
free( token_owner );
6411
free( token_user );
6412
}
6413
6414
static void test_AdjustTokenPrivileges(void)
6415
{
6416
TOKEN_PRIVILEGES tp;
6417
HANDLE token;
6418
DWORD len;
6419
LUID luid;
6420
BOOL ret;
6421
6422
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
6423
return;
6424
6425
if (!LookupPrivilegeValueA(NULL, SE_BACKUP_NAME, &luid))
6426
{
6427
CloseHandle(token);
6428
return;
6429
}
6430
6431
tp.PrivilegeCount = 1;
6432
tp.Privileges[0].Luid = luid;
6433
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
6434
6435
len = 0xdeadbeef;
6436
ret = AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, &len);
6437
ok(ret, "got %d\n", ret);
6438
ok(len == 0xdeadbeef, "got length %ld\n", len);
6439
6440
/* revert */
6441
tp.PrivilegeCount = 1;
6442
tp.Privileges[0].Luid = luid;
6443
tp.Privileges[0].Attributes = 0;
6444
ret = AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
6445
ok(ret, "got %d\n", ret);
6446
6447
CloseHandle(token);
6448
}
6449
6450
static void test_AddAce(void)
6451
{
6452
static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
6453
6454
char acl_buf[1024], ace_buf[256];
6455
ACCESS_ALLOWED_ACE *ace = (ACCESS_ALLOWED_ACE*)ace_buf;
6456
PACL acl = (PACL)acl_buf;
6457
BOOL ret;
6458
6459
memset(ace, 0, sizeof(ace_buf));
6460
ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
6461
ace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD)+sizeof(SID);
6462
memcpy(&ace->SidStart, &sidWorld, sizeof(sidWorld));
6463
6464
ret = InitializeAcl(acl, sizeof(acl_buf), ACL_REVISION2);
6465
ok(ret, "InitializeAcl failed: %ld\n", GetLastError());
6466
6467
ret = AddAce(acl, ACL_REVISION1, MAXDWORD, ace, ace->Header.AceSize);
6468
ok(ret, "AddAce failed: %ld\n", GetLastError());
6469
ret = AddAce(acl, ACL_REVISION2, MAXDWORD, ace, ace->Header.AceSize);
6470
ok(ret, "AddAce failed: %ld\n", GetLastError());
6471
ret = AddAce(acl, ACL_REVISION3, MAXDWORD, ace, ace->Header.AceSize);
6472
ok(ret, "AddAce failed: %ld\n", GetLastError());
6473
ok(acl->AclRevision == ACL_REVISION3, "acl->AclRevision = %d\n", acl->AclRevision);
6474
ret = AddAce(acl, ACL_REVISION4, MAXDWORD, ace, ace->Header.AceSize);
6475
ok(ret, "AddAce failed: %ld\n", GetLastError());
6476
ok(acl->AclRevision == ACL_REVISION4, "acl->AclRevision = %d\n", acl->AclRevision);
6477
ret = AddAce(acl, ACL_REVISION1, MAXDWORD, ace, ace->Header.AceSize);
6478
ok(ret, "AddAce failed: %ld\n", GetLastError());
6479
ok(acl->AclRevision == ACL_REVISION4, "acl->AclRevision = %d\n", acl->AclRevision);
6480
ret = AddAce(acl, ACL_REVISION2, MAXDWORD, ace, ace->Header.AceSize);
6481
ok(ret, "AddAce failed: %ld\n", GetLastError());
6482
6483
ret = AddAce(acl, MIN_ACL_REVISION-1, MAXDWORD, ace, ace->Header.AceSize);
6484
ok(ret, "AddAce failed: %ld\n", GetLastError());
6485
/* next test succeededs but corrupts ACL */
6486
ret = AddAce(acl, MAX_ACL_REVISION+1, MAXDWORD, ace, ace->Header.AceSize);
6487
ok(ret, "AddAce failed: %ld\n", GetLastError());
6488
ok(acl->AclRevision == MAX_ACL_REVISION+1, "acl->AclRevision = %d\n", acl->AclRevision);
6489
SetLastError(0xdeadbeef);
6490
ret = AddAce(acl, ACL_REVISION1, MAXDWORD, ace, ace->Header.AceSize);
6491
ok(!ret, "AddAce succeeded\n");
6492
ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError() = %ld\n", GetLastError());
6493
}
6494
6495
static void test_AddMandatoryAce(void)
6496
{
6497
static SID low_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
6498
{SECURITY_MANDATORY_LOW_RID}};
6499
static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
6500
{SECURITY_MANDATORY_MEDIUM_RID}};
6501
static SID_IDENTIFIER_AUTHORITY sia_world = {SECURITY_WORLD_SID_AUTHORITY};
6502
char buffer_sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
6503
SECURITY_DESCRIPTOR *sd2, *sd = (SECURITY_DESCRIPTOR *)&buffer_sd;
6504
BOOL defaulted, present, ret;
6505
ACL_SIZE_INFORMATION acl_size_info;
6506
SYSTEM_MANDATORY_LABEL_ACE *ace;
6507
char buffer_acl[256];
6508
ACL *acl = (ACL *)&buffer_acl;
6509
SECURITY_ATTRIBUTES sa;
6510
DWORD size;
6511
HANDLE handle;
6512
SID *everyone;
6513
ACL *sacl;
6514
6515
if (!pAddMandatoryAce)
6516
{
6517
win_skip("AddMandatoryAce not supported, skipping test\n");
6518
return;
6519
}
6520
6521
ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
6522
ok(ret, "InitializeSecurityDescriptor failed with error %lu\n", GetLastError());
6523
6524
sa.nLength = sizeof(sa);
6525
sa.lpSecurityDescriptor = sd;
6526
sa.bInheritHandle = FALSE;
6527
6528
handle = CreateEventA(&sa, TRUE, TRUE, "test_event");
6529
ok(handle != NULL, "CreateEventA failed with error %lu\n", GetLastError());
6530
6531
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
6532
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
6533
"Unexpected GetKernelObjectSecurity return value %u, error %lu\n", ret, GetLastError());
6534
6535
sd2 = malloc(size);
6536
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
6537
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
6538
6539
sacl = (void *)0xdeadbeef;
6540
present = TRUE;
6541
ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted);
6542
ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
6543
ok(!present, "SACL is present\n");
6544
ok(sacl == (void *)0xdeadbeef, "SACL is set\n");
6545
6546
free(sd2);
6547
CloseHandle(handle);
6548
6549
memset(buffer_acl, 0, sizeof(buffer_acl));
6550
ret = InitializeAcl(acl, 256, ACL_REVISION);
6551
ok(ret, "InitializeAcl failed with %lu\n", GetLastError());
6552
6553
SetLastError(0xdeadbeef);
6554
ret = pAddMandatoryAce(acl, ACL_REVISION, 0, 0x1234, &low_level);
6555
ok(!ret, "AddMandatoryAce succeeded\n");
6556
ok(GetLastError() == ERROR_INVALID_PARAMETER,
6557
"Expected ERROR_INVALID_PARAMETER got %lu\n", GetLastError());
6558
6559
ret = pAddMandatoryAce(acl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, &low_level);
6560
ok(ret, "AddMandatoryAce failed with %lu\n", GetLastError());
6561
6562
ret = GetAce(acl, 0, (void **)&ace);
6563
ok(ret, "got error %lu\n", GetLastError());
6564
ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, "got type %#x\n", ace->Header.AceType);
6565
ok(!ace->Header.AceFlags, "got flags %#x\n", ace->Header.AceFlags);
6566
ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, "got mask %#lx\n", ace->Mask);
6567
ok(EqualSid(&ace->SidStart, &low_level), "wrong sid\n");
6568
6569
SetLastError(0xdeadbeef);
6570
ret = GetAce(acl, 1, (void **)&ace);
6571
ok(!ret, "expected failure\n");
6572
ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError());
6573
6574
ret = SetSecurityDescriptorSacl(sd, TRUE, acl, FALSE);
6575
ok(ret, "SetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
6576
6577
handle = CreateEventA(&sa, TRUE, TRUE, "test_event");
6578
ok(handle != NULL, "CreateEventA failed with error %lu\n", GetLastError());
6579
6580
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
6581
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
6582
"Unexpected GetKernelObjectSecurity return value %u, error %lu\n", ret, GetLastError());
6583
6584
sd2 = malloc(size);
6585
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
6586
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
6587
6588
sacl = (void *)0xdeadbeef;
6589
present = FALSE;
6590
defaulted = TRUE;
6591
ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted);
6592
ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
6593
ok(present, "SACL not present\n");
6594
ok(sacl != (void *)0xdeadbeef, "SACL not set\n");
6595
ok(!defaulted, "SACL defaulted\n");
6596
ret = GetAclInformation(sacl, &acl_size_info, sizeof(acl_size_info), AclSizeInformation);
6597
ok(ret, "GetAclInformation failed with error %lu\n", GetLastError());
6598
ok(acl_size_info.AceCount == 1, "SACL contains an unexpected ACE count %lu\n", acl_size_info.AceCount);
6599
6600
ret = GetAce(sacl, 0, (void **)&ace);
6601
ok(ret, "GetAce failed with error %lu\n", GetLastError());
6602
ok (ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, "Unexpected ACE type %#x\n", ace->Header.AceType);
6603
ok(!ace->Header.AceFlags, "Unexpected ACE flags %#x\n", ace->Header.AceFlags);
6604
ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, "Unexpected ACE mask %#lx\n", ace->Mask);
6605
ok(EqualSid(&ace->SidStart, &low_level), "Expected low integrity level\n");
6606
6607
free(sd2);
6608
6609
ret = pAddMandatoryAce(acl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP, &medium_level);
6610
ok(ret, "AddMandatoryAce failed with error %lu\n", GetLastError());
6611
6612
ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd);
6613
ok(ret, "SetKernelObjectSecurity failed with error %lu\n", GetLastError());
6614
6615
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
6616
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
6617
"Unexpected GetKernelObjectSecurity return value %u, error %lu\n", ret, GetLastError());
6618
6619
sd2 = malloc(size);
6620
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
6621
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
6622
6623
sacl = (void *)0xdeadbeef;
6624
present = FALSE;
6625
defaulted = TRUE;
6626
ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted);
6627
ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
6628
ok(present, "SACL not present\n");
6629
ok(sacl != (void *)0xdeadbeef, "SACL not set\n");
6630
ok(sacl->AceCount == 2, "Expected 2 ACEs, got %d\n", sacl->AceCount);
6631
ok(!defaulted, "SACL defaulted\n");
6632
6633
ret = GetAce(acl, 0, (void **)&ace);
6634
ok(ret, "got error %lu\n", GetLastError());
6635
ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, "got type %#x\n", ace->Header.AceType);
6636
ok(!ace->Header.AceFlags, "got flags %#x\n", ace->Header.AceFlags);
6637
ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, "got mask %#lx\n", ace->Mask);
6638
ok(EqualSid(&ace->SidStart, &low_level), "wrong sid\n");
6639
6640
ret = GetAce(acl, 1, (void **)&ace);
6641
ok(ret, "got error %lu\n", GetLastError());
6642
ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, "got type %#x\n", ace->Header.AceType);
6643
ok(!ace->Header.AceFlags, "got flags %#x\n", ace->Header.AceFlags);
6644
ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP, "got mask %#lx\n", ace->Mask);
6645
ok(EqualSid(&ace->SidStart, &medium_level), "wrong sid\n");
6646
6647
SetLastError(0xdeadbeef);
6648
ret = GetAce(acl, 2, (void **)&ace);
6649
ok(!ret, "expected failure\n");
6650
ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError());
6651
6652
free(sd2);
6653
6654
ret = SetSecurityDescriptorSacl(sd, FALSE, NULL, FALSE);
6655
ok(ret, "SetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
6656
6657
ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd);
6658
ok(ret, "SetKernelObjectSecurity failed with error %lu\n", GetLastError());
6659
6660
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
6661
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
6662
"Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError());
6663
6664
sd2 = malloc(size);
6665
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
6666
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
6667
6668
sacl = (void *)0xdeadbeef;
6669
present = FALSE;
6670
defaulted = TRUE;
6671
ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted);
6672
ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
6673
ok(present, "SACL not present\n");
6674
ok(sacl && sacl != (void *)0xdeadbeef, "SACL not set\n");
6675
ok(!defaulted, "SACL defaulted\n");
6676
ok(!sacl->AceCount, "SACL contains an unexpected ACE count %u\n", sacl->AceCount);
6677
6678
free(sd2);
6679
6680
ret = InitializeAcl(acl, 256, ACL_REVISION);
6681
ok(ret, "InitializeAcl failed with error %lu\n", GetLastError());
6682
6683
ret = pAddMandatoryAce(acl, ACL_REVISION3, 0, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP, &medium_level);
6684
ok(ret, "AddMandatoryAce failed with error %lu\n", GetLastError());
6685
6686
ret = SetSecurityDescriptorSacl(sd, TRUE, acl, FALSE);
6687
ok(ret, "SetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
6688
6689
ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd);
6690
ok(ret, "SetKernelObjectSecurity failed with error %lu\n", GetLastError());
6691
6692
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
6693
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
6694
"Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError());
6695
6696
sd2 = malloc(size);
6697
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
6698
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
6699
6700
sacl = (void *)0xdeadbeef;
6701
present = FALSE;
6702
defaulted = TRUE;
6703
ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted);
6704
ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
6705
ok(present, "SACL not present\n");
6706
ok(sacl != (void *)0xdeadbeef, "SACL not set\n");
6707
ok(sacl->AclRevision == ACL_REVISION3, "Expected revision 3, got %d\n", sacl->AclRevision);
6708
ok(!defaulted, "SACL defaulted\n");
6709
6710
free(sd2);
6711
6712
ret = InitializeAcl(acl, 256, ACL_REVISION);
6713
ok(ret, "InitializeAcl failed with error %lu\n", GetLastError());
6714
6715
ret = AllocateAndInitializeSid(&sia_world, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, (void **)&everyone);
6716
ok(ret, "AllocateAndInitializeSid failed with error %lu\n", GetLastError());
6717
6718
ret = AddAccessAllowedAce(acl, ACL_REVISION, KEY_READ, everyone);
6719
ok(ret, "AddAccessAllowedAce failed with error %lu\n", GetLastError());
6720
6721
ret = SetSecurityDescriptorSacl(sd, TRUE, acl, FALSE);
6722
ok(ret, "SetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
6723
6724
ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd);
6725
ok(ret, "SetKernelObjectSecurity failed with error %lu\n", GetLastError());
6726
6727
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
6728
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
6729
"Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError());
6730
6731
sd2 = malloc(size);
6732
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
6733
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
6734
6735
sacl = (void *)0xdeadbeef;
6736
present = FALSE;
6737
defaulted = TRUE;
6738
ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted);
6739
ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
6740
ok(present, "SACL not present\n");
6741
ok(sacl && sacl != (void *)0xdeadbeef, "SACL not set\n");
6742
ok(!defaulted, "SACL defaulted\n");
6743
ok(!sacl->AceCount, "SACL contains an unexpected ACE count %u\n", sacl->AceCount);
6744
6745
FreeSid(everyone);
6746
free(sd2);
6747
CloseHandle(handle);
6748
}
6749
6750
static void test_system_security_access(void)
6751
{
6752
static const WCHAR testkeyW[] = L"SOFTWARE\\Wine\\SACLtest";
6753
LONG res;
6754
HKEY hkey;
6755
PSECURITY_DESCRIPTOR sd;
6756
ACL *sacl;
6757
DWORD err, len = 128;
6758
TOKEN_PRIVILEGES priv, *priv_prev;
6759
HANDLE token;
6760
LUID luid;
6761
BOOL ret;
6762
6763
if (!OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &token )) return;
6764
if (!LookupPrivilegeValueA( NULL, SE_SECURITY_NAME, &luid ))
6765
{
6766
CloseHandle( token );
6767
return;
6768
}
6769
6770
/* ACCESS_SYSTEM_SECURITY requires special privilege */
6771
res = RegCreateKeyExW( HKEY_LOCAL_MACHINE, testkeyW, 0, NULL, 0, KEY_READ|ACCESS_SYSTEM_SECURITY, NULL, &hkey, NULL );
6772
if (res == ERROR_ACCESS_DENIED)
6773
{
6774
skip( "unprivileged user\n" );
6775
CloseHandle( token );
6776
return;
6777
}
6778
todo_wine ok( res == ERROR_PRIVILEGE_NOT_HELD, "got %ld\n", res );
6779
6780
priv.PrivilegeCount = 1;
6781
priv.Privileges[0].Luid = luid;
6782
priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
6783
6784
priv_prev = malloc( len );
6785
ret = AdjustTokenPrivileges( token, FALSE, &priv, len, priv_prev, &len );
6786
ok( ret, "got %lu\n", GetLastError());
6787
6788
res = RegCreateKeyExW( HKEY_LOCAL_MACHINE, testkeyW, 0, NULL, 0, KEY_READ|ACCESS_SYSTEM_SECURITY, NULL, &hkey, NULL );
6789
if (res == ERROR_PRIVILEGE_NOT_HELD)
6790
{
6791
win_skip( "privilege not held\n" );
6792
free( priv_prev );
6793
CloseHandle( token );
6794
return;
6795
}
6796
ok( !res, "got %ld\n", res );
6797
6798
/* restore privileges */
6799
ret = AdjustTokenPrivileges( token, FALSE, priv_prev, 0, NULL, NULL );
6800
ok( ret, "got %lu\n", GetLastError() );
6801
free( priv_prev );
6802
6803
/* privilege is checked on access */
6804
err = GetSecurityInfo( hkey, SE_REGISTRY_KEY, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, &sacl, &sd );
6805
todo_wine ok( err == ERROR_PRIVILEGE_NOT_HELD || err == ERROR_ACCESS_DENIED, "got %lu\n", err );
6806
if (err == ERROR_SUCCESS)
6807
LocalFree( sd );
6808
6809
priv.PrivilegeCount = 1;
6810
priv.Privileges[0].Luid = luid;
6811
priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
6812
6813
priv_prev = malloc( len );
6814
ret = AdjustTokenPrivileges( token, FALSE, &priv, len, priv_prev, &len );
6815
ok( ret, "got %lu\n", GetLastError());
6816
6817
err = GetSecurityInfo( hkey, SE_REGISTRY_KEY, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, &sacl, &sd );
6818
ok( err == ERROR_SUCCESS, "got %lu\n", err );
6819
RegCloseKey( hkey );
6820
LocalFree( sd );
6821
6822
/* handle created without ACCESS_SYSTEM_SECURITY, privilege held */
6823
res = RegCreateKeyExW( HKEY_LOCAL_MACHINE, testkeyW, 0, NULL, 0, KEY_READ, NULL, &hkey, NULL );
6824
ok( res == ERROR_SUCCESS, "got %ld\n", res );
6825
6826
sd = NULL;
6827
err = GetSecurityInfo( hkey, SE_REGISTRY_KEY, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, &sacl, &sd );
6828
todo_wine ok( err == ERROR_SUCCESS, "got %lu\n", err );
6829
RegCloseKey( hkey );
6830
LocalFree( sd );
6831
6832
/* restore privileges */
6833
ret = AdjustTokenPrivileges( token, FALSE, priv_prev, 0, NULL, NULL );
6834
ok( ret, "got %lu\n", GetLastError() );
6835
free( priv_prev );
6836
6837
/* handle created without ACCESS_SYSTEM_SECURITY, privilege not held */
6838
res = RegCreateKeyExW( HKEY_LOCAL_MACHINE, testkeyW, 0, NULL, 0, KEY_READ, NULL, &hkey, NULL );
6839
ok( res == ERROR_SUCCESS, "got %ld\n", res );
6840
6841
err = GetSecurityInfo( hkey, SE_REGISTRY_KEY, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, &sacl, &sd );
6842
ok( err == ERROR_PRIVILEGE_NOT_HELD || err == ERROR_ACCESS_DENIED, "got %lu\n", err );
6843
RegCloseKey( hkey );
6844
6845
res = RegDeleteKeyW( HKEY_LOCAL_MACHINE, testkeyW );
6846
ok( !res, "got %ld\n", res );
6847
CloseHandle( token );
6848
}
6849
6850
static void test_GetWindowsAccountDomainSid(void)
6851
{
6852
char *user, buffer1[SECURITY_MAX_SID_SIZE], buffer2[SECURITY_MAX_SID_SIZE];
6853
SID_IDENTIFIER_AUTHORITY domain_ident = { SECURITY_NT_AUTHORITY };
6854
PSID domain_sid = (PSID *)&buffer1;
6855
PSID domain_sid2 = (PSID *)&buffer2;
6856
DWORD sid_size;
6857
PSID user_sid;
6858
HANDLE token;
6859
BOOL bret = TRUE;
6860
int i;
6861
6862
if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
6863
{
6864
if (GetLastError() != ERROR_NO_TOKEN) bret = FALSE;
6865
else if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) bret = FALSE;
6866
}
6867
if (!bret)
6868
{
6869
win_skip("Failed to get current user token\n");
6870
return;
6871
}
6872
6873
bret = GetTokenInformation(token, TokenUser, NULL, 0, &sid_size);
6874
ok(!bret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
6875
"GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError());
6876
user = malloc(sid_size);
6877
bret = GetTokenInformation(token, TokenUser, user, sid_size, &sid_size);
6878
ok(bret, "GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError());
6879
CloseHandle(token);
6880
user_sid = ((TOKEN_USER *)user)->User.Sid;
6881
6882
SetLastError(0xdeadbeef);
6883
bret = GetWindowsAccountDomainSid(0, 0, 0);
6884
ok(!bret, "GetWindowsAccountDomainSid succeeded\n");
6885
ok(GetLastError() == ERROR_INVALID_SID, "expected ERROR_INVALID_SID, got %ld\n", GetLastError());
6886
6887
SetLastError(0xdeadbeef);
6888
bret = GetWindowsAccountDomainSid(user_sid, 0, 0);
6889
ok(!bret, "GetWindowsAccountDomainSid succeeded\n");
6890
ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
6891
6892
sid_size = SECURITY_MAX_SID_SIZE;
6893
SetLastError(0xdeadbeef);
6894
bret = GetWindowsAccountDomainSid(user_sid, 0, &sid_size);
6895
ok(!bret, "GetWindowsAccountDomainSid succeeded\n");
6896
ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
6897
ok(sid_size == GetSidLengthRequired(4), "expected size %ld, got %ld\n", GetSidLengthRequired(4), sid_size);
6898
6899
SetLastError(0xdeadbeef);
6900
bret = GetWindowsAccountDomainSid(user_sid, domain_sid, 0);
6901
ok(!bret, "GetWindowsAccountDomainSid succeeded\n");
6902
ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
6903
6904
sid_size = 1;
6905
SetLastError(0xdeadbeef);
6906
bret = GetWindowsAccountDomainSid(user_sid, domain_sid, &sid_size);
6907
ok(!bret, "GetWindowsAccountDomainSid succeeded\n");
6908
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
6909
ok(sid_size == GetSidLengthRequired(4), "expected size %ld, got %ld\n", GetSidLengthRequired(4), sid_size);
6910
6911
sid_size = SECURITY_MAX_SID_SIZE;
6912
bret = GetWindowsAccountDomainSid(user_sid, domain_sid, &sid_size);
6913
ok(bret, "GetWindowsAccountDomainSid failed with error %ld\n", GetLastError());
6914
ok(sid_size == GetSidLengthRequired(4), "expected size %ld, got %ld\n", GetSidLengthRequired(4), sid_size);
6915
InitializeSid(domain_sid2, &domain_ident, 4);
6916
for (i = 0; i < 4; i++)
6917
*GetSidSubAuthority(domain_sid2, i) = *GetSidSubAuthority(user_sid, i);
6918
ok(EqualSid(domain_sid, domain_sid2), "unexpected domain sid %s != %s\n",
6919
debugstr_sid(domain_sid), debugstr_sid(domain_sid2));
6920
6921
free(user);
6922
}
6923
6924
static void test_GetSidIdentifierAuthority(void)
6925
{
6926
char buffer[SECURITY_MAX_SID_SIZE];
6927
PSID authority_sid = (PSID *)buffer;
6928
PSID_IDENTIFIER_AUTHORITY id;
6929
BOOL ret;
6930
6931
memset(buffer, 0xcc, sizeof(buffer));
6932
ret = IsValidSid(authority_sid);
6933
ok(!ret, "expected FALSE, got %u\n", ret);
6934
6935
SetLastError(0xdeadbeef);
6936
id = GetSidIdentifierAuthority(authority_sid);
6937
ok(id != NULL, "got NULL pointer as identifier authority\n");
6938
ok(GetLastError() == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", GetLastError());
6939
6940
SetLastError(0xdeadbeef);
6941
id = GetSidIdentifierAuthority(NULL);
6942
ok(id != NULL, "got NULL pointer as identifier authority\n");
6943
ok(GetLastError() == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", GetLastError());
6944
}
6945
6946
static void test_pseudo_tokens(void)
6947
{
6948
TOKEN_STATISTICS statistics1, statistics2;
6949
HANDLE token;
6950
DWORD retlen;
6951
BOOL ret;
6952
6953
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
6954
ok(ret, "OpenProcessToken failed with error %lu\n", GetLastError());
6955
memset(&statistics1, 0x11, sizeof(statistics1));
6956
ret = GetTokenInformation(token, TokenStatistics, &statistics1, sizeof(statistics1), &retlen);
6957
ok(ret, "GetTokenInformation failed with %lu\n", GetLastError());
6958
CloseHandle(token);
6959
6960
/* test GetCurrentProcessToken() */
6961
SetLastError(0xdeadbeef);
6962
memset(&statistics2, 0x22, sizeof(statistics2));
6963
ret = GetTokenInformation(GetCurrentProcessToken(), TokenStatistics,
6964
&statistics2, sizeof(statistics2), &retlen);
6965
ok(ret || broken(GetLastError() == ERROR_INVALID_HANDLE),
6966
"GetTokenInformation failed with %lu\n", GetLastError());
6967
if (ret)
6968
ok(!memcmp(&statistics1, &statistics2, sizeof(statistics1)), "Token statistics do not match\n");
6969
else
6970
win_skip("CurrentProcessToken not supported, skipping test\n");
6971
6972
/* test GetCurrentThreadEffectiveToken() */
6973
SetLastError(0xdeadbeef);
6974
memset(&statistics2, 0x22, sizeof(statistics2));
6975
ret = GetTokenInformation(GetCurrentThreadEffectiveToken(), TokenStatistics,
6976
&statistics2, sizeof(statistics2), &retlen);
6977
ok(ret || broken(GetLastError() == ERROR_INVALID_HANDLE),
6978
"GetTokenInformation failed with %lu\n", GetLastError());
6979
if (ret)
6980
ok(!memcmp(&statistics1, &statistics2, sizeof(statistics1)), "Token statistics do not match\n");
6981
else
6982
win_skip("CurrentThreadEffectiveToken not supported, skipping test\n");
6983
6984
SetLastError(0xdeadbeef);
6985
ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &token);
6986
ok(!ret, "OpenThreadToken should have failed\n");
6987
ok(GetLastError() == ERROR_NO_TOKEN, "Expected ERROR_NO_TOKEN, got %lu\n", GetLastError());
6988
6989
/* test GetCurrentThreadToken() */
6990
SetLastError(0xdeadbeef);
6991
ret = GetTokenInformation(GetCurrentThreadToken(), TokenStatistics,
6992
&statistics2, sizeof(statistics2), &retlen);
6993
todo_wine ok(GetLastError() == ERROR_NO_TOKEN || broken(GetLastError() == ERROR_INVALID_HANDLE),
6994
"Expected ERROR_NO_TOKEN, got %lu\n", GetLastError());
6995
}
6996
6997
static void test_maximum_allowed(void)
6998
{
6999
HANDLE (WINAPI *pCreateEventExA)(SECURITY_ATTRIBUTES *, LPCSTR, DWORD, DWORD);
7000
char buffer_sd[SECURITY_DESCRIPTOR_MIN_LENGTH], buffer_acl[256];
7001
SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *)&buffer_sd;
7002
SECURITY_ATTRIBUTES sa;
7003
ACL *acl = (ACL *)&buffer_acl;
7004
HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
7005
ACCESS_MASK mask;
7006
HANDLE handle;
7007
BOOL ret;
7008
7009
pCreateEventExA = (void *)GetProcAddress(hkernel32, "CreateEventExA");
7010
if (!pCreateEventExA)
7011
{
7012
win_skip("CreateEventExA is not available\n");
7013
return;
7014
}
7015
7016
ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
7017
ok(ret, "InitializeSecurityDescriptor failed with %lu\n", GetLastError());
7018
memset(buffer_acl, 0, sizeof(buffer_acl));
7019
ret = InitializeAcl(acl, 256, ACL_REVISION);
7020
ok(ret, "InitializeAcl failed with %lu\n", GetLastError());
7021
ret = SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE);
7022
ok(ret, "SetSecurityDescriptorDacl failed with %lu\n", GetLastError());
7023
7024
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
7025
sa.lpSecurityDescriptor = sd;
7026
sa.bInheritHandle = FALSE;
7027
7028
handle = pCreateEventExA(&sa, NULL, 0, MAXIMUM_ALLOWED | 0x4);
7029
ok(handle != NULL, "CreateEventExA failed with error %lu\n", GetLastError());
7030
mask = get_obj_access(handle);
7031
ok(mask == EVENT_ALL_ACCESS, "Expected %x, got %lx\n", EVENT_ALL_ACCESS, mask);
7032
CloseHandle(handle);
7033
}
7034
7035
static void check_token_label(HANDLE token, DWORD *level, BOOL sacl_inherited)
7036
{
7037
static SID medium_sid = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
7038
{SECURITY_MANDATORY_MEDIUM_RID}};
7039
static SID high_sid = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
7040
{SECURITY_MANDATORY_HIGH_RID}};
7041
SECURITY_DESCRIPTOR_CONTROL control;
7042
SYSTEM_MANDATORY_LABEL_ACE *ace;
7043
BOOL ret, present, defaulted;
7044
SECURITY_DESCRIPTOR *sd;
7045
ACL *sacl = NULL, *dacl;
7046
DWORD size, revision;
7047
char *str;
7048
SID *sid;
7049
7050
ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
7051
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7052
"Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError());
7053
7054
sd = malloc(size);
7055
ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd, size, &size);
7056
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
7057
7058
ret = GetSecurityDescriptorControl(sd, &control, &revision);
7059
ok(ret, "GetSecurityDescriptorControl failed with error %lu\n", GetLastError());
7060
if (sacl_inherited)
7061
todo_wine ok(control == (SE_SELF_RELATIVE | SE_SACL_AUTO_INHERITED | SE_SACL_PRESENT),
7062
"Unexpected security descriptor control %#x\n", control);
7063
else
7064
todo_wine ok(control == (SE_SELF_RELATIVE | SE_SACL_PRESENT),
7065
"Unexpected security descriptor control %#x\n", control);
7066
ok(revision == 1, "Unexpected security descriptor revision %lu\n", revision);
7067
7068
sid = (void *)0xdeadbeef;
7069
defaulted = TRUE;
7070
ret = GetSecurityDescriptorOwner(sd, (void **)&sid, &defaulted);
7071
ok(ret, "GetSecurityDescriptorOwner failed with error %lu\n", GetLastError());
7072
ok(!sid, "Owner present\n");
7073
ok(!defaulted, "Owner defaulted\n");
7074
7075
sid = (void *)0xdeadbeef;
7076
defaulted = TRUE;
7077
ret = GetSecurityDescriptorGroup(sd, (void **)&sid, &defaulted);
7078
ok(ret, "GetSecurityDescriptorGroup failed with error %lu\n", GetLastError());
7079
ok(!sid, "Group present\n");
7080
ok(!defaulted, "Group defaulted\n");
7081
7082
ret = GetSecurityDescriptorSacl(sd, &present, &sacl, &defaulted);
7083
ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
7084
ok(present, "No SACL in the security descriptor\n");
7085
ok(!!sacl, "NULL SACL in the security descriptor\n");
7086
ok(!defaulted, "SACL defaulted\n");
7087
ok(sacl->AceCount == 1, "SACL contains an unexpected ACE count %u\n", sacl->AceCount);
7088
7089
ret = GetAce(sacl, 0, (void **)&ace);
7090
ok(ret, "GetAce failed with error %lu\n", GetLastError());
7091
7092
ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE,
7093
"Unexpected ACE type %#x\n", ace->Header.AceType);
7094
ok(!ace->Header.AceFlags, "Unexpected ACE flags %#x\n", ace->Header.AceFlags);
7095
ok(ace->Header.AceSize, "Unexpected ACE size %u\n", ace->Header.AceSize);
7096
ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, "Unexpected ACE mask %#lx\n", ace->Mask);
7097
7098
sid = (SID *)&ace->SidStart;
7099
ConvertSidToStringSidA(sid, &str);
7100
ok(EqualSid(sid, &medium_sid) || EqualSid(sid, &high_sid), "Got unexpected SID %s\n", str);
7101
*level = sid->SubAuthority[0];
7102
LocalFree(str);
7103
7104
ret = GetSecurityDescriptorDacl(sd, &present, &dacl, &defaulted);
7105
ok(ret, "GetSecurityDescriptorDacl failed with error %lu\n", GetLastError());
7106
todo_wine ok(!present, "DACL present\n");
7107
7108
free(sd);
7109
}
7110
7111
static void test_token_label(void)
7112
{
7113
SID low_sid = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
7114
{SECURITY_MANDATORY_LOW_RID}};
7115
char sacl_buffer[50];
7116
SECURITY_ATTRIBUTES attr = {.nLength = sizeof(SECURITY_ATTRIBUTES)};
7117
ACL *sacl = (ACL *)sacl_buffer;
7118
TOKEN_LINKED_TOKEN linked;
7119
DWORD level, level2, size;
7120
PSECURITY_DESCRIPTOR sd;
7121
HANDLE token, token2;
7122
BOOL ret;
7123
7124
if (!pAddMandatoryAce)
7125
{
7126
win_skip("Mandatory integrity control is not supported.\n");
7127
return;
7128
}
7129
7130
ret = OpenProcessToken(GetCurrentProcess(), READ_CONTROL | TOKEN_QUERY | TOKEN_DUPLICATE, &token);
7131
ok(ret, "OpenProcessToken failed with error %lu\n", GetLastError());
7132
7133
check_token_label(token, &level, TRUE);
7134
7135
ret = DuplicateTokenEx(token, READ_CONTROL, NULL, SecurityAnonymous, TokenPrimary, &token2);
7136
ok(ret, "Failed to duplicate token, error %lu\n", GetLastError());
7137
7138
check_token_label(token2, &level2, TRUE);
7139
ok(level2 == level, "Expected level %#lx, got %#lx.\n", level, level2);
7140
7141
CloseHandle(token2);
7142
7143
ret = DuplicateTokenEx(token, READ_CONTROL, NULL, SecurityImpersonation, TokenImpersonation, &token2);
7144
ok(ret, "Failed to duplicate token, error %lu\n", GetLastError());
7145
7146
check_token_label(token2, &level2, TRUE);
7147
ok(level2 == level, "Expected level %#lx, got %#lx.\n", level, level2);
7148
7149
CloseHandle(token2);
7150
7151
/* Any label set in the SD when calling DuplicateTokenEx() is ignored. */
7152
7153
ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
7154
ok(!ret, "expected failure\n");
7155
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got error %lu\n", GetLastError());
7156
7157
sd = malloc(size);
7158
ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd, size, &size);
7159
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
7160
7161
InitializeAcl(sacl, sizeof(sacl_buffer), ACL_REVISION);
7162
AddMandatoryAce(sacl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, &low_sid);
7163
SetSecurityDescriptorSacl(sd, TRUE, sacl, FALSE);
7164
7165
attr.lpSecurityDescriptor = sd;
7166
ret = DuplicateTokenEx(token, TOKEN_ALL_ACCESS, &attr, SecurityImpersonation, TokenImpersonation, &token2);
7167
ok(ret, "Failed to duplicate token, error %lu\n", GetLastError());
7168
7169
check_token_label(token2, &level2, TRUE);
7170
ok(level2 == level, "Expected level %#lx, got %#lx.\n", level, level2);
7171
7172
/* Trying to set a SD on the token also claims success but has no effect. */
7173
7174
ret = SetKernelObjectSecurity(token2, LABEL_SECURITY_INFORMATION, sd);
7175
ok(ret, "Failed to set SD, error %lu\n", GetLastError());
7176
7177
check_token_label(token2, &level2, FALSE);
7178
ok(level2 == level, "Expected level %#lx, got %#lx.\n", level, level2);
7179
7180
free(sd);
7181
7182
/* Test the linked token. */
7183
7184
ret = GetTokenInformation(token, TokenLinkedToken, &linked, sizeof(linked), &size);
7185
ok(ret, "Failed to get linked token, error %lu\n", GetLastError());
7186
7187
check_token_label(linked.LinkedToken, &level2, TRUE);
7188
ok(level2 == level, "Expected level %#lx, got %#lx.\n", level, level2);
7189
7190
CloseHandle(linked.LinkedToken);
7191
7192
CloseHandle(token);
7193
}
7194
7195
static void test_token_security_descriptor(void)
7196
{
7197
static SID low_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
7198
{SECURITY_MANDATORY_LOW_RID}};
7199
char buffer_sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
7200
SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *)&buffer_sd, *sd2;
7201
char buffer_acl[256], buffer[MAX_PATH];
7202
ACL *acl = (ACL *)&buffer_acl, *acl2, *acl_child;
7203
BOOL defaulted, present, ret, found;
7204
HANDLE token, token2, token3;
7205
EXPLICIT_ACCESSW exp_access;
7206
PROCESS_INFORMATION info;
7207
DWORD size, index, retd;
7208
ACCESS_ALLOWED_ACE *ace;
7209
SECURITY_ATTRIBUTES sa;
7210
STARTUPINFOA startup;
7211
PSID psid;
7212
7213
/* Test whether we can create tokens with security descriptors */
7214
ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token);
7215
ok(ret, "OpenProcessToken failed with error %lu\n", GetLastError());
7216
7217
ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
7218
ok(ret, "InitializeSecurityDescriptor failed with error %lu\n", GetLastError());
7219
7220
memset(buffer_acl, 0, sizeof(buffer_acl));
7221
ret = InitializeAcl(acl, 256, ACL_REVISION);
7222
ok(ret, "InitializeAcl failed with error %lu\n", GetLastError());
7223
7224
ret = ConvertStringSidToSidA("S-1-5-6", &psid);
7225
ok(ret, "ConvertStringSidToSidA failed with error %lu\n", GetLastError());
7226
7227
ret = AddAccessAllowedAceEx(acl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, GENERIC_ALL, psid);
7228
ok(ret, "AddAccessAllowedAceEx failed with error %lu\n", GetLastError());
7229
7230
ret = SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE);
7231
ok(ret, "SetSecurityDescriptorDacl failed with error %lu\n", GetLastError());
7232
7233
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
7234
sa.lpSecurityDescriptor = sd;
7235
sa.bInheritHandle = FALSE;
7236
7237
ret = DuplicateTokenEx(token, MAXIMUM_ALLOWED, &sa, SecurityImpersonation, TokenImpersonation, &token2);
7238
ok(ret, "DuplicateTokenEx failed with error %lu\n", GetLastError());
7239
7240
ret = GetKernelObjectSecurity(token2, DACL_SECURITY_INFORMATION, NULL, 0, &size);
7241
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7242
"Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError());
7243
7244
sd2 = malloc(size);
7245
ret = GetKernelObjectSecurity(token2, DACL_SECURITY_INFORMATION, sd2, size, &size);
7246
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
7247
7248
acl2 = (void *)0xdeadbeef;
7249
present = FALSE;
7250
defaulted = TRUE;
7251
ret = GetSecurityDescriptorDacl(sd2, &present, &acl2, &defaulted);
7252
ok(ret, "GetSecurityDescriptorDacl failed with error %lu\n", GetLastError());
7253
ok(present, "acl2 not present\n");
7254
ok(acl2 != (void *)0xdeadbeef, "acl2 not set\n");
7255
ok(acl2->AceCount == 1, "Expected 1 ACE, got %d\n", acl2->AceCount);
7256
ok(!defaulted, "acl2 defaulted\n");
7257
7258
ret = GetAce(acl2, 0, (void **)&ace);
7259
ok(ret, "GetAce failed with error %lu\n", GetLastError());
7260
ok(ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE, "Unexpected ACE type %#x\n", ace->Header.AceType);
7261
ok(EqualSid(&ace->SidStart, psid), "Expected access allowed ACE\n");
7262
ok(ace->Header.AceFlags == NO_PROPAGATE_INHERIT_ACE,
7263
"Expected NO_PROPAGATE_INHERIT_ACE as flags, got %x\n", ace->Header.AceFlags);
7264
7265
free(sd2);
7266
7267
/* Duplicate token without security attributes.
7268
* Tokens do not inherit the security descriptor in DuplicateToken. */
7269
ret = DuplicateTokenEx(token2, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenImpersonation, &token3);
7270
ok(ret, "DuplicateTokenEx failed with error %lu\n", GetLastError());
7271
7272
ret = GetKernelObjectSecurity(token3, DACL_SECURITY_INFORMATION, NULL, 0, &size);
7273
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7274
"Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError());
7275
7276
sd2 = malloc(size);
7277
ret = GetKernelObjectSecurity(token3, DACL_SECURITY_INFORMATION, sd2, size, &size);
7278
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
7279
7280
acl2 = (void *)0xdeadbeef;
7281
present = FALSE;
7282
defaulted = TRUE;
7283
ret = GetSecurityDescriptorDacl(sd2, &present, &acl2, &defaulted);
7284
ok(ret, "GetSecurityDescriptorDacl failed with error %lu\n", GetLastError());
7285
ok(present, "DACL not present\n");
7286
7287
ok(acl2 != (void *)0xdeadbeef, "DACL not set\n");
7288
ok(!defaulted, "DACL defaulted\n");
7289
7290
index = 0;
7291
found = FALSE;
7292
while (GetAce(acl2, index++, (void **)&ace))
7293
{
7294
if (ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE && EqualSid(&ace->SidStart, psid))
7295
found = TRUE;
7296
}
7297
ok(!found, "Access allowed ACE was inherited\n");
7298
7299
free(sd2);
7300
7301
/* When creating a child process, the process does inherit the token of
7302
* the parent but not the DACL of the token */
7303
ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, NULL, 0, &size);
7304
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7305
"Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError());
7306
7307
sd2 = malloc(size);
7308
ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, sd2, size, &size);
7309
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
7310
7311
acl2 = (void *)0xdeadbeef;
7312
present = FALSE;
7313
defaulted = TRUE;
7314
ret = GetSecurityDescriptorDacl(sd2, &present, &acl2, &defaulted);
7315
ok(ret, "GetSecurityDescriptorDacl failed with error %lu\n", GetLastError());
7316
ok(present, "DACL not present\n");
7317
ok(acl2 != (void *)0xdeadbeef, "DACL not set\n");
7318
ok(!defaulted, "DACL defaulted\n");
7319
7320
exp_access.grfAccessPermissions = GENERIC_ALL;
7321
exp_access.grfAccessMode = GRANT_ACCESS;
7322
exp_access.grfInheritance = NO_PROPAGATE_INHERIT_ACE;
7323
exp_access.Trustee.pMultipleTrustee = NULL;
7324
exp_access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
7325
exp_access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
7326
exp_access.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
7327
exp_access.Trustee.ptstrName = (void*)psid;
7328
7329
retd = SetEntriesInAclW(1, &exp_access, acl2, &acl_child);
7330
ok(retd == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", retd);
7331
7332
memset(sd, 0, sizeof(buffer_sd));
7333
ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
7334
ok(ret, "InitializeSecurityDescriptor failed with error %lu\n", GetLastError());
7335
7336
ret = SetSecurityDescriptorDacl(sd, TRUE, acl_child, FALSE);
7337
ok(ret, "SetSecurityDescriptorDacl failed with error %lu\n", GetLastError());
7338
7339
ret = SetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, sd);
7340
ok(ret, "SetKernelObjectSecurity failed with error %lu\n", GetLastError());
7341
7342
/* The security label is also not inherited */
7343
if (pAddMandatoryAce)
7344
{
7345
ret = InitializeAcl(acl, 256, ACL_REVISION);
7346
ok(ret, "InitializeAcl failed with error %lu\n", GetLastError());
7347
7348
ret = pAddMandatoryAce(acl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, &low_level);
7349
ok(ret, "AddMandatoryAce failed with error %lu\n", GetLastError());
7350
7351
memset(sd, 0, sizeof(buffer_sd));
7352
ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
7353
ok(ret, "InitializeSecurityDescriptor failed with error %lu\n", GetLastError());
7354
7355
ret = SetSecurityDescriptorSacl(sd, TRUE, acl, FALSE);
7356
ok(ret, "SetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
7357
7358
ret = SetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd);
7359
ok(ret, "SetKernelObjectSecurity failed with error %lu\n", GetLastError());
7360
}
7361
else
7362
win_skip("SYSTEM_MANDATORY_LABEL not supported\n");
7363
7364
/* Start child process with our modified token */
7365
memset(&startup, 0, sizeof(startup));
7366
startup.cb = sizeof(startup);
7367
startup.dwFlags = STARTF_USESHOWWINDOW;
7368
startup.wShowWindow = SW_SHOWNORMAL;
7369
7370
sprintf(buffer, "%s security test_token_sd", myARGV[0]);
7371
ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info);
7372
ok(ret, "CreateProcess failed with error %lu\n", GetLastError());
7373
wait_child_process(info.hProcess);
7374
CloseHandle(info.hProcess);
7375
CloseHandle(info.hThread);
7376
7377
LocalFree(acl_child);
7378
free(sd2);
7379
LocalFree(psid);
7380
7381
CloseHandle(token3);
7382
CloseHandle(token2);
7383
CloseHandle(token);
7384
}
7385
7386
static void test_child_token_sd(void)
7387
{
7388
static SID low_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
7389
{SECURITY_MANDATORY_LOW_RID}};
7390
SYSTEM_MANDATORY_LABEL_ACE *ace_label;
7391
BOOL ret, present, defaulted;
7392
ACCESS_ALLOWED_ACE *acc_ace;
7393
SECURITY_DESCRIPTOR *sd;
7394
DWORD size, i;
7395
HANDLE token;
7396
PSID psid;
7397
ACL *acl;
7398
7399
ret = ConvertStringSidToSidA("S-1-5-6", &psid);
7400
ok(ret, "ConvertStringSidToSidA failed with error %lu\n", GetLastError());
7401
7402
ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token);
7403
ok(ret, "OpenProcessToken failed with error %lu\n", GetLastError());
7404
7405
ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, NULL, 0, &size);
7406
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7407
"Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError());
7408
7409
sd = malloc(size);
7410
ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, sd, size, &size);
7411
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
7412
7413
acl = NULL;
7414
present = FALSE;
7415
defaulted = TRUE;
7416
ret = GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted);
7417
ok(ret, "GetSecurityDescriptorDacl failed with error %lu\n", GetLastError());
7418
ok(present, "DACL not present\n");
7419
ok(acl && acl != (void *)0xdeadbeef, "Got invalid DACL\n");
7420
ok(!defaulted, "DACL defaulted\n");
7421
7422
ok(acl->AceCount, "Expected at least one ACE\n");
7423
for (i = 0; i < acl->AceCount; i++)
7424
{
7425
ret = GetAce(acl, i, (void **)&acc_ace);
7426
ok(ret, "GetAce failed with error %lu\n", GetLastError());
7427
ok(acc_ace->Header.AceType != ACCESS_ALLOWED_ACE_TYPE || !EqualSid(&acc_ace->SidStart, psid),
7428
"ACE inherited from the parent\n");
7429
}
7430
7431
LocalFree(psid);
7432
free(sd);
7433
7434
if (!pAddMandatoryAce)
7435
{
7436
win_skip("SYSTEM_MANDATORY_LABEL not supported\n");
7437
return;
7438
}
7439
7440
ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
7441
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7442
"Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError());
7443
7444
sd = malloc(size);
7445
ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd, size, &size);
7446
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
7447
7448
acl = NULL;
7449
present = FALSE;
7450
defaulted = TRUE;
7451
ret = GetSecurityDescriptorSacl(sd, &present, &acl, &defaulted);
7452
ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
7453
ok(present, "SACL not present\n");
7454
ok(acl && acl != (void *)0xdeadbeef, "Got invalid SACL\n");
7455
ok(!defaulted, "SACL defaulted\n");
7456
ok(acl->AceCount == 1, "Expected exactly one ACE\n");
7457
ret = GetAce(acl, 0, (void **)&ace_label);
7458
ok(ret, "GetAce failed with error %lu\n", GetLastError());
7459
ok(ace_label->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE,
7460
"Unexpected ACE type %#x\n", ace_label->Header.AceType);
7461
ok(!EqualSid(&ace_label->SidStart, &low_level),
7462
"Low integrity level should not have been inherited\n");
7463
7464
free(sd);
7465
}
7466
7467
static void test_GetExplicitEntriesFromAclW(void)
7468
{
7469
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
7470
SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY };
7471
PSID everyone_sid = NULL, users_sid = NULL;
7472
EXPLICIT_ACCESSW access;
7473
EXPLICIT_ACCESSW *access2;
7474
PACL new_acl, old_acl = NULL;
7475
ULONG count;
7476
DWORD res;
7477
7478
old_acl = malloc(256);
7479
res = InitializeAcl(old_acl, 256, ACL_REVISION);
7480
ok(res, "InitializeAcl failed with error %ld\n", GetLastError());
7481
7482
res = AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &everyone_sid);
7483
ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
7484
7485
res = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
7486
DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &users_sid);
7487
ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
7488
7489
res = AddAccessAllowedAce(old_acl, ACL_REVISION, KEY_READ, users_sid);
7490
ok(res, "AddAccessAllowedAce failed with error %ld\n", GetLastError());
7491
7492
access2 = NULL;
7493
res = GetExplicitEntriesFromAclW(old_acl, &count, &access2);
7494
ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %ld\n", GetLastError());
7495
ok(count == 1, "Expected count == 1, got %ld\n", count);
7496
ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode);
7497
ok(access2[0].grfAccessPermissions == KEY_READ, "Expected KEY_READ, got %ld\n", access2[0].grfAccessPermissions);
7498
ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm);
7499
ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %lx\n", access2[0].grfInheritance);
7500
ok(EqualSid(access2[0].Trustee.ptstrName, users_sid), "Expected equal SIDs\n");
7501
LocalFree(access2);
7502
7503
access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
7504
access.Trustee.pMultipleTrustee = NULL;
7505
7506
access.grfAccessPermissions = KEY_WRITE;
7507
access.grfAccessMode = GRANT_ACCESS;
7508
access.grfInheritance = NO_INHERITANCE;
7509
access.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
7510
access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
7511
access.Trustee.ptstrName = everyone_sid;
7512
res = SetEntriesInAclW(1, &access, old_acl, &new_acl);
7513
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
7514
ok(new_acl != NULL, "returned acl was NULL\n");
7515
7516
access2 = NULL;
7517
res = GetExplicitEntriesFromAclW(new_acl, &count, &access2);
7518
ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %ld\n", GetLastError());
7519
ok(count == 2, "Expected count == 2, got %ld\n", count);
7520
ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode);
7521
ok(access2[0].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %ld\n", access2[0].grfAccessPermissions);
7522
ok(access2[0].Trustee.TrusteeType == TRUSTEE_IS_UNKNOWN,
7523
"Expected TRUSTEE_IS_UNKNOWN trustee type, got %d\n", access2[0].Trustee.TrusteeType);
7524
ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm);
7525
ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %lx\n", access2[0].grfInheritance);
7526
ok(EqualSid(access2[0].Trustee.ptstrName, everyone_sid), "Expected equal SIDs\n");
7527
LocalFree(access2);
7528
LocalFree(new_acl);
7529
7530
access.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
7531
res = SetEntriesInAclW(1, &access, old_acl, &new_acl);
7532
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
7533
ok(new_acl != NULL, "returned acl was NULL\n");
7534
7535
access2 = NULL;
7536
res = GetExplicitEntriesFromAclW(new_acl, &count, &access2);
7537
ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %ld\n", GetLastError());
7538
ok(count == 2, "Expected count == 2, got %ld\n", count);
7539
ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode);
7540
ok(access2[0].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %ld\n", access2[0].grfAccessPermissions);
7541
ok(access2[0].Trustee.TrusteeType == TRUSTEE_IS_UNKNOWN,
7542
"Expected TRUSTEE_IS_UNKNOWN trustee type, got %d\n", access2[0].Trustee.TrusteeType);
7543
ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm);
7544
ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %lx\n", access2[0].grfInheritance);
7545
ok(EqualSid(access2[0].Trustee.ptstrName, everyone_sid), "Expected equal SIDs\n");
7546
LocalFree(access2);
7547
LocalFree(new_acl);
7548
7549
access.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
7550
access.Trustee.ptstrName = (WCHAR *)L"CURRENT_USER";
7551
res = SetEntriesInAclW(1, &access, old_acl, &new_acl);
7552
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
7553
ok(new_acl != NULL, "returned acl was NULL\n");
7554
7555
access2 = NULL;
7556
res = GetExplicitEntriesFromAclW(new_acl, &count, &access2);
7557
ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %ld\n", GetLastError());
7558
ok(count == 2, "Expected count == 2, got %ld\n", count);
7559
ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode);
7560
ok(access2[0].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %ld\n", access2[0].grfAccessPermissions);
7561
ok(access2[0].Trustee.TrusteeType == TRUSTEE_IS_UNKNOWN,
7562
"Expected TRUSTEE_IS_UNKNOWN trustee type, got %d\n", access2[0].Trustee.TrusteeType);
7563
ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm);
7564
ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %lx\n", access2[0].grfInheritance);
7565
LocalFree(access2);
7566
LocalFree(new_acl);
7567
7568
access.grfAccessMode = REVOKE_ACCESS;
7569
access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
7570
access.Trustee.ptstrName = users_sid;
7571
res = SetEntriesInAclW(1, &access, old_acl, &new_acl);
7572
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
7573
ok(new_acl != NULL, "returned acl was NULL\n");
7574
7575
access2 = (void *)0xdeadbeef;
7576
res = GetExplicitEntriesFromAclW(new_acl, &count, &access2);
7577
ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %ld\n", GetLastError());
7578
ok(count == 0, "Expected count == 0, got %ld\n", count);
7579
ok(access2 == NULL, "access2 was not NULL\n");
7580
LocalFree(new_acl);
7581
7582
/* Make the ACL both Allow and Deny Everyone. */
7583
res = AddAccessAllowedAce(old_acl, ACL_REVISION, KEY_READ, everyone_sid);
7584
ok(res, "AddAccessAllowedAce failed with error %ld\n", GetLastError());
7585
res = AddAccessDeniedAce(old_acl, ACL_REVISION, KEY_WRITE, everyone_sid);
7586
ok(res, "AddAccessDeniedAce failed with error %ld\n", GetLastError());
7587
/* Revoke Everyone. */
7588
access.Trustee.ptstrName = everyone_sid;
7589
access.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
7590
access.grfAccessPermissions = 0;
7591
new_acl = NULL;
7592
res = SetEntriesInAclW(1, &access, old_acl, &new_acl);
7593
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
7594
ok(new_acl != NULL, "returned acl was NULL\n");
7595
/* Deny Everyone should remain (along with Grant Users from earlier). */
7596
access2 = NULL;
7597
res = GetExplicitEntriesFromAclW(new_acl, &count, &access2);
7598
ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %ld\n", GetLastError());
7599
ok(count == 2, "Expected count == 2, got %ld\n", count);
7600
ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode);
7601
ok(access2[0].grfAccessPermissions == KEY_READ , "Expected KEY_READ, got %ld\n", access2[0].grfAccessPermissions);
7602
ok(EqualSid(access2[0].Trustee.ptstrName, users_sid), "Expected equal SIDs\n");
7603
ok(access2[1].grfAccessMode == DENY_ACCESS, "Expected DENY_ACCESS, got %d\n", access2[1].grfAccessMode);
7604
ok(access2[1].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %ld\n", access2[1].grfAccessPermissions);
7605
ok(EqualSid(access2[1].Trustee.ptstrName, everyone_sid), "Expected equal SIDs\n");
7606
LocalFree(access2);
7607
7608
FreeSid(users_sid);
7609
FreeSid(everyone_sid);
7610
free(old_acl);
7611
}
7612
7613
static void test_BuildSecurityDescriptorW(void)
7614
{
7615
SECURITY_DESCRIPTOR old_sd, *new_sd, *rel_sd;
7616
ULONG new_sd_size;
7617
DWORD buf_size;
7618
char buf[1024];
7619
BOOL success;
7620
DWORD ret;
7621
7622
InitializeSecurityDescriptor(&old_sd, SECURITY_DESCRIPTOR_REVISION);
7623
7624
buf_size = sizeof(buf);
7625
rel_sd = (SECURITY_DESCRIPTOR *)buf;
7626
success = MakeSelfRelativeSD(&old_sd, rel_sd, &buf_size);
7627
ok(success, "MakeSelfRelativeSD failed with %lu\n", GetLastError());
7628
7629
new_sd = NULL;
7630
new_sd_size = 0;
7631
ret = BuildSecurityDescriptorW(NULL, NULL, 0, NULL, 0, NULL, NULL, &new_sd_size, (void **)&new_sd);
7632
ok(ret == ERROR_SUCCESS, "BuildSecurityDescriptor failed with %lu\n", ret);
7633
ok(new_sd != NULL, "expected new_sd != NULL\n");
7634
LocalFree(new_sd);
7635
7636
new_sd = (void *)0xdeadbeef;
7637
ret = BuildSecurityDescriptorW(NULL, NULL, 0, NULL, 0, NULL, &old_sd, &new_sd_size, (void **)&new_sd);
7638
ok(ret == ERROR_INVALID_SECURITY_DESCR, "expected ERROR_INVALID_SECURITY_DESCR, got %lu\n", ret);
7639
ok(new_sd == (void *)0xdeadbeef, "expected new_sd == 0xdeadbeef, got %p\n", new_sd);
7640
7641
new_sd = NULL;
7642
new_sd_size = 0;
7643
ret = BuildSecurityDescriptorW(NULL, NULL, 0, NULL, 0, NULL, rel_sd, &new_sd_size, (void **)&new_sd);
7644
ok(ret == ERROR_SUCCESS, "BuildSecurityDescriptor failed with %lu\n", ret);
7645
ok(new_sd != NULL, "expected new_sd != NULL\n");
7646
LocalFree(new_sd);
7647
}
7648
7649
static void test_EqualDomainSid(void)
7650
{
7651
SID_IDENTIFIER_AUTHORITY ident = { SECURITY_NT_AUTHORITY };
7652
char sid_buffer[SECURITY_MAX_SID_SIZE], sid_buffer2[SECURITY_MAX_SID_SIZE];
7653
PSID domainsid, sid = sid_buffer, sid2 = sid_buffer2;
7654
DWORD size;
7655
BOOL ret, equal;
7656
unsigned int i;
7657
7658
ret = AllocateAndInitializeSid(&ident, 6, SECURITY_NT_NON_UNIQUE, 12, 23, 34, 45, 56, 0, 0, &domainsid);
7659
ok(ret, "AllocateAndInitializeSid error %lu\n", GetLastError());
7660
7661
SetLastError(0xdeadbeef);
7662
ret = EqualDomainSid(NULL, NULL, NULL);
7663
ok(!ret, "got %d\n", ret);
7664
ok(GetLastError() == ERROR_INVALID_SID, "got %lu\n", GetLastError());
7665
7666
SetLastError(0xdeadbeef);
7667
ret = EqualDomainSid(domainsid, domainsid, NULL);
7668
ok(!ret, "got %d\n", ret);
7669
ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError());
7670
7671
for (i = 0; i < ARRAY_SIZE(well_known_sid_values); i++)
7672
{
7673
SID *pisid = sid;
7674
7675
size = sizeof(sid_buffer);
7676
if (!CreateWellKnownSid(i, NULL, sid, &size))
7677
{
7678
trace("Well known SID %u not supported\n", i);
7679
continue;
7680
}
7681
7682
equal = 0xdeadbeef;
7683
SetLastError(0xdeadbeef);
7684
ret = EqualDomainSid(sid, domainsid, &equal);
7685
if (pisid->SubAuthority[0] != SECURITY_BUILTIN_DOMAIN_RID)
7686
{
7687
ok(!ret, "%u: got %d\n", i, ret);
7688
ok(GetLastError() == ERROR_NON_DOMAIN_SID, "%u: got %lu\n", i, GetLastError());
7689
ok(equal == 0xdeadbeef, "%u: got %d\n", i, equal);
7690
continue;
7691
}
7692
7693
ok(ret, "%u: got %d\n", i, ret);
7694
ok(GetLastError() == 0, "%u: got %lu\n", i, GetLastError());
7695
ok(equal == 0, "%u: got %d\n", i, equal);
7696
7697
size = sizeof(sid_buffer2);
7698
ret = CreateWellKnownSid(i, well_known_sid_values[i].without_domain ? NULL : domainsid, sid2, &size);
7699
ok(ret, "%u: CreateWellKnownSid error %lu\n", i, GetLastError());
7700
7701
equal = 0xdeadbeef;
7702
SetLastError(0xdeadbeef);
7703
ret = EqualDomainSid(sid, sid2, &equal);
7704
ok(ret, "%u: got %d\n", i, ret);
7705
ok(GetLastError() == 0, "%u: got %lu\n", i, GetLastError());
7706
ok(equal == 1, "%u: got %d\n", i, equal);
7707
}
7708
7709
FreeSid(domainsid);
7710
}
7711
7712
static DWORD WINAPI duplicate_handle_access_thread(void *arg)
7713
{
7714
HANDLE event = arg, event2;
7715
BOOL ret;
7716
7717
event2 = OpenEventA(SYNCHRONIZE, FALSE, "test_dup");
7718
ok(!!event2, "got error %lu\n", GetLastError());
7719
CloseHandle(event2);
7720
7721
event2 = OpenEventA(EVENT_MODIFY_STATE, FALSE, "test_dup");
7722
ok(!!event2, "got error %lu\n", GetLastError());
7723
CloseHandle(event2);
7724
7725
ret = DuplicateHandle(GetCurrentProcess(), event, GetCurrentProcess(),
7726
&event2, EVENT_MODIFY_STATE, FALSE, 0);
7727
ok(ret, "got error %lu\n", GetLastError());
7728
CloseHandle(event2);
7729
7730
return 0;
7731
}
7732
7733
static void test_duplicate_handle_access(void)
7734
{
7735
char acl_buffer[200], everyone_sid_buffer[100], local_sid_buffer[100], cmdline[300];
7736
HANDLE token, restricted, impersonation, all_event, sync_event, event2, thread;
7737
SECURITY_ATTRIBUTES sa = {.nLength = sizeof(sa)};
7738
SID *everyone_sid = (SID *)everyone_sid_buffer;
7739
SID *local_sid = (SID *)local_sid_buffer;
7740
ACL *acl = (ACL *)acl_buffer;
7741
SID_AND_ATTRIBUTES sid_attr;
7742
SECURITY_DESCRIPTOR sd;
7743
PROCESS_INFORMATION pi;
7744
STARTUPINFOA si = {0};
7745
DWORD size;
7746
BOOL ret;
7747
7748
/* DuplicateHandle() validates access against the calling thread's token and
7749
* the target process's token. It does *not* validate access against the
7750
* calling process's token, even if the calling thread is not impersonating.
7751
*/
7752
7753
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, &token);
7754
ok(ret, "got error %lu\n", GetLastError());
7755
7756
size = sizeof(everyone_sid_buffer);
7757
ret = CreateWellKnownSid(WinWorldSid, NULL, everyone_sid, &size);
7758
ok(ret, "got error %lu\n", GetLastError());
7759
size = sizeof(local_sid_buffer);
7760
ret = CreateWellKnownSid(WinLocalSid, NULL, local_sid, &size);
7761
ok(ret, "got error %lu\n", GetLastError());
7762
7763
InitializeAcl(acl, sizeof(acl_buffer), ACL_REVISION);
7764
ret = AddAccessAllowedAce(acl, ACL_REVISION, SYNCHRONIZE, everyone_sid);
7765
ok(ret, "got error %lu\n", GetLastError());
7766
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
7767
ret = AddAccessAllowedAce(acl, ACL_REVISION, EVENT_MODIFY_STATE, local_sid);
7768
ok(ret, "got error %lu\n", GetLastError());
7769
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
7770
ret = SetSecurityDescriptorDacl(&sd, TRUE, acl, FALSE);
7771
ok(ret, "got error %lu\n", GetLastError());
7772
sa.lpSecurityDescriptor = &sd;
7773
7774
sid_attr.Sid = local_sid;
7775
sid_attr.Attributes = 0;
7776
ret = CreateRestrictedToken(token, 0, 1, &sid_attr, 0, NULL, 0, NULL, &restricted);
7777
ok(ret, "got error %lu\n", GetLastError());
7778
ret = DuplicateTokenEx(restricted, TOKEN_IMPERSONATE, NULL,
7779
SecurityImpersonation, TokenImpersonation, &impersonation);
7780
ok(ret, "got error %lu\n", GetLastError());
7781
7782
all_event = CreateEventA(&sa, TRUE, TRUE, "test_dup");
7783
ok(!!all_event, "got error %lu\n", GetLastError());
7784
sync_event = OpenEventA(SYNCHRONIZE, FALSE, "test_dup");
7785
ok(!!sync_event, "got error %lu\n", GetLastError());
7786
7787
event2 = OpenEventA(SYNCHRONIZE, FALSE, "test_dup");
7788
ok(!!event2, "got error %lu\n", GetLastError());
7789
CloseHandle(event2);
7790
7791
event2 = OpenEventA(EVENT_MODIFY_STATE, FALSE, "test_dup");
7792
ok(!!event2, "got error %lu\n", GetLastError());
7793
CloseHandle(event2);
7794
7795
ret = DuplicateHandle(GetCurrentProcess(), all_event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0);
7796
ok(ret, "got error %lu\n", GetLastError());
7797
CloseHandle(event2);
7798
7799
ret = DuplicateHandle(GetCurrentProcess(), sync_event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0);
7800
ok(ret, "got error %lu\n", GetLastError());
7801
CloseHandle(event2);
7802
7803
ret = SetThreadToken(NULL, impersonation);
7804
ok(ret, "got error %lu\n", GetLastError());
7805
7806
thread = CreateThread(NULL, 0, duplicate_handle_access_thread, sync_event, 0, NULL);
7807
ret = WaitForSingleObject(thread, 1000);
7808
ok(!ret, "wait failed\n");
7809
7810
event2 = OpenEventA(SYNCHRONIZE, FALSE, "test_dup");
7811
ok(!!event2, "got error %lu\n", GetLastError());
7812
CloseHandle(event2);
7813
7814
SetLastError(0xdeadbeef);
7815
event2 = OpenEventA(EVENT_MODIFY_STATE, FALSE, "test_dup");
7816
ok(!event2, "expected failure\n");
7817
ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
7818
7819
ret = DuplicateHandle(GetCurrentProcess(), all_event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0);
7820
ok(ret, "got error %lu\n", GetLastError());
7821
CloseHandle(event2);
7822
7823
SetLastError(0xdeadbeef);
7824
ret = DuplicateHandle(GetCurrentProcess(), sync_event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0);
7825
ok(!ret, "expected failure\n");
7826
ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
7827
7828
ret = RevertToSelf();
7829
ok(ret, "got error %lu\n", GetLastError());
7830
7831
sprintf(cmdline, "%s security duplicate %Iu %lu %Iu", myARGV[0],
7832
(ULONG_PTR)sync_event, GetCurrentProcessId(), (ULONG_PTR)impersonation );
7833
ret = CreateProcessAsUserA(restricted, NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
7834
ok(ret, "got error %lu\n", GetLastError());
7835
7836
ret = DuplicateHandle(GetCurrentProcess(), all_event, pi.hProcess, &event2, EVENT_MODIFY_STATE, FALSE, 0);
7837
ok(ret, "got error %lu\n", GetLastError());
7838
7839
SetLastError(0xdeadbeef);
7840
ret = DuplicateHandle(GetCurrentProcess(), sync_event, pi.hProcess, &event2, EVENT_MODIFY_STATE, FALSE, 0);
7841
ok(!ret, "expected failure\n");
7842
ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
7843
7844
ret = WaitForSingleObject(pi.hProcess, 1000);
7845
ok(!ret, "wait failed\n");
7846
7847
CloseHandle(impersonation);
7848
CloseHandle(restricted);
7849
CloseHandle(token);
7850
CloseHandle(sync_event);
7851
CloseHandle(all_event);
7852
}
7853
7854
static void test_duplicate_handle_access_child(void)
7855
{
7856
HANDLE event, event2, process, token;
7857
BOOL ret;
7858
7859
event = (HANDLE)(ULONG_PTR)_atoi64(myARGV[3]);
7860
process = OpenProcess(PROCESS_DUP_HANDLE, FALSE, atoi(myARGV[4]));
7861
ok(!!process, "failed to open process, error %lu\n", GetLastError());
7862
7863
event2 = OpenEventA(SYNCHRONIZE, FALSE, "test_dup");
7864
ok(!!event2, "got error %lu\n", GetLastError());
7865
CloseHandle(event2);
7866
7867
SetLastError(0xdeadbeef);
7868
event2 = OpenEventA(EVENT_MODIFY_STATE, FALSE, "test_dup");
7869
ok(!event2, "expected failure\n");
7870
ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
7871
7872
ret = DuplicateHandle(process, event, process, &event2, EVENT_MODIFY_STATE, FALSE, 0);
7873
ok(ret, "got error %lu\n", GetLastError());
7874
7875
SetLastError(0xdeadbeef);
7876
ret = DuplicateHandle(process, event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0);
7877
ok(!ret, "expected failure\n");
7878
ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
7879
7880
ret = DuplicateHandle(process, (HANDLE)(ULONG_PTR)_atoi64(myARGV[5]),
7881
GetCurrentProcess(), &token, 0, FALSE, DUPLICATE_SAME_ACCESS);
7882
ok(ret, "failed to retrieve token, error %lu\n", GetLastError());
7883
ret = SetThreadToken(NULL, token);
7884
ok(ret, "failed to set thread token, error %lu\n", GetLastError());
7885
7886
SetLastError(0xdeadbeef);
7887
ret = DuplicateHandle(process, event, process, &event2, EVENT_MODIFY_STATE, FALSE, 0);
7888
ok(!ret, "expected failure\n");
7889
ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
7890
7891
SetLastError(0xdeadbeef);
7892
ret = DuplicateHandle(process, event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0);
7893
ok(!ret, "expected failure\n");
7894
ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
7895
7896
ret = RevertToSelf();
7897
ok(ret, "failed to revert, error %lu\n", GetLastError());
7898
CloseHandle(token);
7899
CloseHandle(process);
7900
}
7901
7902
#define join_process(a) join_process_(__LINE__, a)
7903
static void join_process_(int line, const PROCESS_INFORMATION *pi)
7904
{
7905
DWORD ret = WaitForSingleObject(pi->hProcess, 1000);
7906
ok_(__FILE__, line)(!ret, "wait failed\n");
7907
CloseHandle(pi->hProcess);
7908
CloseHandle(pi->hThread);
7909
}
7910
7911
static void test_create_process_token(void)
7912
{
7913
char cmdline[300], acl_buffer[200], sid_buffer[100];
7914
SECURITY_ATTRIBUTES sa = {.nLength = sizeof(sa)};
7915
ACL *acl = (ACL *)acl_buffer;
7916
SID *sid = (SID *)sid_buffer;
7917
SID_AND_ATTRIBUTES sid_attr;
7918
HANDLE event, token, token2;
7919
PROCESS_INFORMATION pi;
7920
SECURITY_DESCRIPTOR sd;
7921
STARTUPINFOA si = {0};
7922
DWORD size;
7923
BOOL ret;
7924
7925
size = sizeof(sid_buffer);
7926
ret = CreateWellKnownSid(WinLocalSid, NULL, sid, &size);
7927
ok(ret, "got error %lu\n", GetLastError());
7928
ret = InitializeAcl(acl, sizeof(acl_buffer), ACL_REVISION);
7929
ok(ret, "got error %lu\n", GetLastError());
7930
ret = AddAccessAllowedAce(acl, ACL_REVISION, EVENT_MODIFY_STATE, sid);
7931
ok(ret, "got error %lu\n", GetLastError());
7932
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
7933
ret = SetSecurityDescriptorDacl(&sd, TRUE, acl, FALSE);
7934
ok(ret, "got error %lu\n", GetLastError());
7935
sa.lpSecurityDescriptor = &sd;
7936
event = CreateEventA(&sa, TRUE, TRUE, "test_event");
7937
ok(!!event, "got error %lu\n", GetLastError());
7938
7939
sprintf(cmdline, "%s security restricted 0", myARGV[0]);
7940
7941
ret = CreateProcessAsUserA(NULL, NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
7942
ok(ret, "got error %lu\n", GetLastError());
7943
join_process(&pi);
7944
7945
ret = CreateProcessAsUserA(GetCurrentProcessToken(), NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
7946
todo_wine ok(!ret, "expected failure\n");
7947
todo_wine ok(GetLastError() == ERROR_INVALID_HANDLE, "got error %lu\n", GetLastError());
7948
if (ret) join_process(&pi);
7949
7950
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, &token);
7951
ok(ret, "got error %lu\n", GetLastError());
7952
ret = CreateProcessAsUserA(token, NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
7953
ok(ret || broken(GetLastError() == ERROR_ACCESS_DENIED) /* < 7 */, "got error %lu\n", GetLastError());
7954
if (ret) join_process(&pi);
7955
CloseHandle(token);
7956
7957
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
7958
ok(ret, "got error %lu\n", GetLastError());
7959
ret = CreateProcessAsUserA(token, NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
7960
ok(!ret, "expected failure\n");
7961
ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
7962
CloseHandle(token);
7963
7964
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_ASSIGN_PRIMARY, &token);
7965
ok(ret, "got error %lu\n", GetLastError());
7966
ret = CreateProcessAsUserA(token, NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
7967
ok(!ret, "expected failure\n");
7968
ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
7969
CloseHandle(token);
7970
7971
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE, &token);
7972
ok(ret, "got error %lu\n", GetLastError());
7973
7974
ret = DuplicateTokenEx(token, TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, NULL,
7975
SecurityImpersonation, TokenImpersonation, &token2);
7976
ok(ret, "got error %lu\n", GetLastError());
7977
ret = CreateProcessAsUserA(token2, NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
7978
ok(ret || broken(GetLastError() == ERROR_BAD_TOKEN_TYPE) /* < 7 */, "got error %lu\n", GetLastError());
7979
if (ret) join_process(&pi);
7980
CloseHandle(token2);
7981
7982
sprintf(cmdline, "%s security restricted 1", myARGV[0]);
7983
sid_attr.Sid = sid;
7984
sid_attr.Attributes = 0;
7985
ret = CreateRestrictedToken(token, 0, 1, &sid_attr, 0, NULL, 0, NULL, &token2);
7986
ok(ret, "got error %lu\n", GetLastError());
7987
ret = CreateProcessAsUserA(token2, NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
7988
ok(ret, "got error %lu\n", GetLastError());
7989
join_process(&pi);
7990
CloseHandle(token2);
7991
7992
CloseHandle(token);
7993
7994
CloseHandle(event);
7995
}
7996
7997
static void test_create_process_token_child(void)
7998
{
7999
HANDLE event;
8000
8001
SetLastError(0xdeadbeef);
8002
event = OpenEventA(EVENT_MODIFY_STATE, FALSE, "test_event");
8003
if (!atoi(myARGV[3]))
8004
{
8005
ok(!!event, "got error %lu\n", GetLastError());
8006
CloseHandle(event);
8007
}
8008
else
8009
{
8010
ok(!event, "expected failure\n");
8011
ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
8012
}
8013
}
8014
8015
static void test_pseudo_handle_security(void)
8016
{
8017
char buffer[200];
8018
PSECURITY_DESCRIPTOR sd = buffer, sd_ptr;
8019
unsigned int i;
8020
DWORD size;
8021
BOOL ret;
8022
8023
static const HKEY keys[] =
8024
{
8025
HKEY_CLASSES_ROOT,
8026
HKEY_CURRENT_USER,
8027
HKEY_LOCAL_MACHINE,
8028
HKEY_USERS,
8029
HKEY_PERFORMANCE_DATA,
8030
HKEY_CURRENT_CONFIG,
8031
HKEY_DYN_DATA,
8032
};
8033
8034
ret = GetKernelObjectSecurity(GetCurrentProcess(), OWNER_SECURITY_INFORMATION, &sd, sizeof(buffer), &size);
8035
ok(ret, "got error %lu\n", GetLastError());
8036
8037
ret = GetKernelObjectSecurity(GetCurrentThread(), OWNER_SECURITY_INFORMATION, &sd, sizeof(buffer), &size);
8038
ok(ret, "got error %lu\n", GetLastError());
8039
8040
for (i = 0; i < ARRAY_SIZE(keys); ++i)
8041
{
8042
SetLastError(0xdeadbeef);
8043
ret = GetKernelObjectSecurity(keys[i], OWNER_SECURITY_INFORMATION, &sd, sizeof(buffer), &size);
8044
ok(!ret, "key %p: expected failure\n", keys[i]);
8045
ok(GetLastError() == ERROR_INVALID_HANDLE, "key %p: got error %lu\n", keys[i], GetLastError());
8046
8047
ret = GetSecurityInfo(keys[i], SE_REGISTRY_KEY,
8048
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &sd_ptr);
8049
if (keys[i] == HKEY_PERFORMANCE_DATA)
8050
ok(ret == ERROR_INVALID_HANDLE, "key %p: got error %u\n", keys[i], ret);
8051
else if (keys[i] == HKEY_DYN_DATA)
8052
todo_wine ok(ret == ERROR_CALL_NOT_IMPLEMENTED || broken(ret == ERROR_INVALID_HANDLE) /* <7 */,
8053
"key %p: got error %u\n", keys[i], ret);
8054
else
8055
ok(!ret, "key %p: got error %u\n", keys[i], ret);
8056
if (!ret) LocalFree(sd_ptr);
8057
8058
ret = GetSecurityInfo(keys[i], SE_KERNEL_OBJECT,
8059
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &sd_ptr);
8060
ok(ret == ERROR_INVALID_HANDLE, "key %p: got error %u\n", keys[i], ret);
8061
}
8062
}
8063
8064
static const LUID_AND_ATTRIBUTES *find_privilege(const TOKEN_PRIVILEGES *privs, const LUID *luid)
8065
{
8066
DWORD i;
8067
8068
for (i = 0; i < privs->PrivilegeCount; ++i)
8069
{
8070
if (!memcmp(luid, &privs->Privileges[i].Luid, sizeof(LUID)))
8071
return &privs->Privileges[i];
8072
}
8073
8074
return NULL;
8075
}
8076
8077
static void test_duplicate_token(void)
8078
{
8079
const DWORD orig_access = TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT | TOKEN_ADJUST_PRIVILEGES;
8080
char prev_privs_buffer[128], ret_privs_buffer[1024];
8081
TOKEN_PRIVILEGES *prev_privs = (void *)prev_privs_buffer;
8082
TOKEN_PRIVILEGES *ret_privs = (void *)ret_privs_buffer;
8083
const LUID_AND_ATTRIBUTES *priv;
8084
TOKEN_PRIVILEGES privs;
8085
SECURITY_QUALITY_OF_SERVICE qos = {.Length = sizeof(qos)};
8086
OBJECT_ATTRIBUTES attr = {.Length = sizeof(attr)};
8087
SECURITY_IMPERSONATION_LEVEL level;
8088
HANDLE token, token2;
8089
DWORD size;
8090
BOOL ret;
8091
8092
ret = OpenProcessToken(GetCurrentProcess(), orig_access, &token);
8093
ok(ret, "got error %lu\n", GetLastError());
8094
8095
/* Disable a privilege, to see if that privilege modification is preserved
8096
* in the duplicated tokens. */
8097
privs.PrivilegeCount = 1;
8098
ret = LookupPrivilegeValueA(NULL, "SeChangeNotifyPrivilege", &privs.Privileges[0].Luid);
8099
ok(ret, "got error %lu\n", GetLastError());
8100
privs.Privileges[0].Attributes = 0;
8101
ret = AdjustTokenPrivileges(token, FALSE, &privs, sizeof(prev_privs_buffer), prev_privs, &size);
8102
ok(ret, "got error %lu\n", GetLastError());
8103
8104
ret = DuplicateToken(token, SecurityAnonymous, &token2);
8105
ok(ret, "got error %lu\n", GetLastError());
8106
TEST_GRANTED_ACCESS(token2, TOKEN_QUERY | TOKEN_IMPERSONATE);
8107
ret = GetTokenInformation(token2, TokenImpersonationLevel, &level, sizeof(level), &size);
8108
ok(ret, "got error %lu\n", GetLastError());
8109
ok(level == SecurityAnonymous, "got impersonation level %#x\n", level);
8110
ret = GetTokenInformation(token2, TokenPrivileges, ret_privs, sizeof(ret_privs_buffer), &size);
8111
ok(ret, "got error %lu\n", GetLastError());
8112
priv = find_privilege(ret_privs, &privs.Privileges[0].Luid);
8113
ok(!!priv, "Privilege should exist\n");
8114
todo_wine ok(priv->Attributes == SE_GROUP_MANDATORY, "Got attributes %#lx\n", priv->Attributes);
8115
CloseHandle(token2);
8116
8117
ret = DuplicateTokenEx(token, 0, NULL, SecurityAnonymous, TokenPrimary, &token2);
8118
ok(ret, "got error %lu\n", GetLastError());
8119
TEST_GRANTED_ACCESS(token2, orig_access);
8120
ret = GetTokenInformation(token2, TokenImpersonationLevel, &level, sizeof(level), &size);
8121
ok(!ret, "expected failure\n");
8122
ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got error %lu.\n", GetLastError());
8123
ret = GetTokenInformation(token2, TokenPrivileges, ret_privs, sizeof(ret_privs_buffer), &size);
8124
ok(ret, "got error %lu\n", GetLastError());
8125
priv = find_privilege(ret_privs, &privs.Privileges[0].Luid);
8126
ok(!!priv, "Privilege should exist\n");
8127
todo_wine ok(priv->Attributes == SE_GROUP_MANDATORY, "Got attributes %#lx\n", priv->Attributes);
8128
CloseHandle(token2);
8129
8130
ret = DuplicateTokenEx(token, MAXIMUM_ALLOWED, NULL, SecurityAnonymous, TokenPrimary, &token2);
8131
ok(ret, "got error %lu\n", GetLastError());
8132
TEST_GRANTED_ACCESS(token2, TOKEN_ALL_ACCESS);
8133
CloseHandle(token2);
8134
8135
ret = DuplicateTokenEx(token, TOKEN_QUERY_SOURCE, NULL, SecurityAnonymous, TokenPrimary, &token2);
8136
ok(ret, "got error %lu\n", GetLastError());
8137
TEST_GRANTED_ACCESS(token2, TOKEN_QUERY_SOURCE);
8138
CloseHandle(token2);
8139
8140
ret = DuplicateTokenEx(token, 0, NULL, SecurityIdentification, TokenImpersonation, &token2);
8141
ok(ret, "got error %lu\n", GetLastError());
8142
TEST_GRANTED_ACCESS(token2, orig_access);
8143
ret = GetTokenInformation(token2, TokenImpersonationLevel, &level, sizeof(level), &size);
8144
ok(ret, "got error %lu\n", GetLastError());
8145
ok(level == SecurityIdentification, "got impersonation level %#x\n", level);
8146
ret = GetTokenInformation(token2, TokenPrivileges, ret_privs, sizeof(ret_privs_buffer), &size);
8147
ok(ret, "got error %lu\n", GetLastError());
8148
priv = find_privilege(ret_privs, &privs.Privileges[0].Luid);
8149
ok(!!priv, "Privilege should exist\n");
8150
todo_wine ok(priv->Attributes == SE_GROUP_MANDATORY, "Got attributes %#lx\n", priv->Attributes);
8151
CloseHandle(token2);
8152
8153
ret = NtDuplicateToken(token, 0, &attr, FALSE, TokenImpersonation, &token2);
8154
ok(ret == STATUS_SUCCESS, "Got status %#x.\n", ret);
8155
TEST_GRANTED_ACCESS(token2, orig_access);
8156
ret = GetTokenInformation(token2, TokenImpersonationLevel, &level, sizeof(level), &size);
8157
ok(ret, "got error %lu\n", GetLastError());
8158
ok(level == SecurityAnonymous, "got impersonation level %#x\n", level);
8159
ret = GetTokenInformation(token2, TokenPrivileges, ret_privs, sizeof(ret_privs_buffer), &size);
8160
ok(ret, "got error %lu\n", GetLastError());
8161
priv = find_privilege(ret_privs, &privs.Privileges[0].Luid);
8162
ok(!!priv, "Privilege should exist\n");
8163
todo_wine ok(priv->Attributes == SE_GROUP_MANDATORY, "Got attributes %#lx\n", priv->Attributes);
8164
CloseHandle(token2);
8165
8166
ret = NtDuplicateToken(token, 0, &attr, TRUE, TokenImpersonation, &token2);
8167
ok(ret == STATUS_SUCCESS, "Got status %#x.\n", ret);
8168
TEST_GRANTED_ACCESS(token2, orig_access);
8169
ret = GetTokenInformation(token2, TokenPrivileges, ret_privs, sizeof(ret_privs_buffer), &size);
8170
ok(ret, "got error %lu\n", GetLastError());
8171
priv = find_privilege(ret_privs, &privs.Privileges[0].Luid);
8172
todo_wine ok(!priv, "Privilege shouldn't exist\n");
8173
CloseHandle(token2);
8174
8175
qos.ImpersonationLevel = SecurityIdentification;
8176
qos.ContextTrackingMode = SECURITY_STATIC_TRACKING;
8177
qos.EffectiveOnly = FALSE;
8178
attr.SecurityQualityOfService = &qos;
8179
ret = NtDuplicateToken(token, 0, &attr, FALSE, TokenImpersonation, &token2);
8180
ok(ret == STATUS_SUCCESS, "Got status %#x.\n", ret);
8181
TEST_GRANTED_ACCESS(token2, orig_access);
8182
ret = GetTokenInformation(token2, TokenImpersonationLevel, &level, sizeof(level), &size);
8183
ok(ret, "got error %lu\n", GetLastError());
8184
ok(level == SecurityIdentification, "got impersonation level %#x\n", level);
8185
CloseHandle(token2);
8186
8187
privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
8188
ret = AdjustTokenPrivileges(token, FALSE, &privs, sizeof(prev_privs_buffer), prev_privs, &size);
8189
ok(ret, "got error %lu\n", GetLastError());
8190
8191
CloseHandle(token);
8192
}
8193
8194
static void test_GetKernelObjectSecurity(void)
8195
{
8196
/* Basic tests for parameter validation. */
8197
8198
SECURITY_DESCRIPTOR_CONTROL control;
8199
DWORD size, ret_size, revision;
8200
BOOL ret, present, defaulted;
8201
PSECURITY_DESCRIPTOR sd;
8202
PSID sid;
8203
ACL *acl;
8204
8205
SetLastError(0xdeadbeef);
8206
size = 0xdeadbeef;
8207
ret = GetKernelObjectSecurity(NULL, OWNER_SECURITY_INFORMATION, NULL, 0, &size);
8208
ok(!ret, "expected failure\n");
8209
ok(GetLastError() == ERROR_INVALID_HANDLE, "got error %lu\n", GetLastError());
8210
ok(size == 0xdeadbeef, "got size %lu\n", size);
8211
8212
SetLastError(0xdeadbeef);
8213
ret = GetKernelObjectSecurity(GetCurrentProcess(), OWNER_SECURITY_INFORMATION, NULL, 0, NULL);
8214
ok(!ret, "expected failure\n");
8215
ok(GetLastError() == ERROR_NOACCESS, "got error %lu\n", GetLastError());
8216
8217
SetLastError(0xdeadbeef);
8218
size = 0xdeadbeef;
8219
ret = GetKernelObjectSecurity(GetCurrentProcess(), OWNER_SECURITY_INFORMATION, NULL, 0, &size);
8220
ok(!ret, "expected failure\n");
8221
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got error %lu\n", GetLastError());
8222
ok(size > 0 && size != 0xdeadbeef, "got size 0\n");
8223
8224
sd = malloc(size + 1);
8225
8226
SetLastError(0xdeadbeef);
8227
ret = GetKernelObjectSecurity(GetCurrentProcess(), OWNER_SECURITY_INFORMATION, sd, size - 1, &ret_size);
8228
ok(!ret, "expected failure\n");
8229
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got error %lu\n", GetLastError());
8230
ok(ret_size == size, "expected size %lu, got %lu\n", size, ret_size);
8231
8232
SetLastError(0xdeadbeef);
8233
ret = GetKernelObjectSecurity(GetCurrentProcess(), OWNER_SECURITY_INFORMATION, sd, size + 1, &ret_size);
8234
ok(ret, "expected success\n");
8235
ok(GetLastError() == 0xdeadbeef, "got error %lu\n", GetLastError());
8236
ok(ret_size == size, "expected size %lu, got %lu\n", size, ret_size);
8237
8238
free(sd);
8239
8240
/* Calling the function with flags not defined succeeds and yields an empty
8241
* descriptor. */
8242
8243
SetLastError(0xdeadbeef);
8244
ret = GetKernelObjectSecurity(GetCurrentProcess(), 0x100000, NULL, 0, &size);
8245
ok(!ret, "expected failure\n");
8246
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got error %lu\n", GetLastError());
8247
8248
sd = malloc(size);
8249
SetLastError(0xdeadbeef);
8250
ret = GetKernelObjectSecurity(GetCurrentProcess(), 0x100000, sd, size, &ret_size);
8251
ok(ret, "expected success\n");
8252
ok(GetLastError() == 0xdeadbeef, "got error %lu\n", GetLastError());
8253
ok(ret_size == size, "expected size %lu, got %lu\n", size, ret_size);
8254
8255
ret = GetSecurityDescriptorControl(sd, &control, &revision);
8256
ok(ret, "got error %lu\n", GetLastError());
8257
todo_wine ok(control == SE_SELF_RELATIVE, "got control %#x\n", control);
8258
ok(revision == SECURITY_DESCRIPTOR_REVISION1, "got revision %lu\n", revision);
8259
8260
ret = GetSecurityDescriptorOwner(sd, &sid, &defaulted);
8261
ok(ret, "got error %lu\n", GetLastError());
8262
ok(!sid, "expected no owner SID\n");
8263
ok(!defaulted, "expected owner not defaulted\n");
8264
8265
ret = GetSecurityDescriptorGroup(sd, &sid, &defaulted);
8266
ok(ret, "got error %lu\n", GetLastError());
8267
ok(!sid, "expected no group SID\n");
8268
ok(!defaulted, "expected group not defaulted\n");
8269
8270
ret = GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted);
8271
ok(ret, "got error %lu\n", GetLastError());
8272
todo_wine ok(!present, "expected no DACL present\n");
8273
/* the descriptor is defaulted only on Windows >= 7 */
8274
8275
ret = GetSecurityDescriptorSacl(sd, &present, &acl, &defaulted);
8276
ok(ret, "got error %lu\n", GetLastError());
8277
ok(!present, "expected no SACL present\n");
8278
/* the descriptor is defaulted only on Windows >= 7 */
8279
8280
free(sd);
8281
}
8282
8283
static void check_different_token(HANDLE token1, HANDLE token2)
8284
{
8285
TOKEN_STATISTICS stats1, stats2;
8286
DWORD size;
8287
BOOL ret;
8288
8289
ret = GetTokenInformation(token1, TokenStatistics, &stats1, sizeof(stats1), &size);
8290
ok(ret, "got error %lu\n", GetLastError());
8291
ret = GetTokenInformation(token2, TokenStatistics, &stats2, sizeof(stats2), &size);
8292
ok(ret, "got error %lu\n", GetLastError());
8293
8294
ok(memcmp(&stats1.TokenId, &stats2.TokenId, sizeof(LUID)), "expected different IDs\n");
8295
}
8296
8297
static void test_elevation(void)
8298
{
8299
TOKEN_LINKED_TOKEN linked, linked2;
8300
DWORD orig_type, type, size;
8301
TOKEN_ELEVATION elevation;
8302
HANDLE token, token2;
8303
BOOL ret;
8304
8305
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | READ_CONTROL | TOKEN_DUPLICATE
8306
| TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_DEFAULT, &token);
8307
ok(ret, "got error %lu\n", GetLastError());
8308
8309
ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
8310
ok(ret, "got error %lu\n", GetLastError());
8311
orig_type = type;
8312
ret = GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &size);
8313
ok(ret, "got error %lu\n", GetLastError());
8314
ret = GetTokenInformation(token, TokenLinkedToken, &linked, sizeof(linked), &size);
8315
if (!ret && GetLastError() == ERROR_NO_SUCH_LOGON_SESSION) /* fails on w2008s64 */
8316
{
8317
win_skip("Failed to get linked token.\n");
8318
CloseHandle(token);
8319
return;
8320
}
8321
ok(ret, "got error %lu\n", GetLastError());
8322
8323
if (type == TokenElevationTypeDefault)
8324
{
8325
ok(elevation.TokenIsElevated == FALSE, "got elevation %#lx\n", elevation.TokenIsElevated);
8326
ok(!linked.LinkedToken, "expected no linked token\n");
8327
}
8328
else if (type == TokenElevationTypeLimited)
8329
{
8330
ok(elevation.TokenIsElevated == FALSE, "got elevation %#lx\n", elevation.TokenIsElevated);
8331
ok(!!linked.LinkedToken, "expected a linked token\n");
8332
8333
TEST_GRANTED_ACCESS(linked.LinkedToken, TOKEN_ALL_ACCESS);
8334
ret = GetTokenInformation(linked.LinkedToken, TokenElevationType, &type, sizeof(type), &size);
8335
ok(ret, "got error %lu\n", GetLastError());
8336
ok(type == TokenElevationTypeFull, "got type %#lx\n", type);
8337
ret = GetTokenInformation(linked.LinkedToken, TokenElevation, &elevation, sizeof(elevation), &size);
8338
ok(ret, "got error %lu\n", GetLastError());
8339
ok(elevation.TokenIsElevated == TRUE, "got elevation %#lx\n", elevation.TokenIsElevated);
8340
ret = GetTokenInformation(linked.LinkedToken, TokenType, &type, sizeof(type), &size);
8341
ok(ret, "got error %lu\n", GetLastError());
8342
ok(type == TokenImpersonation, "got type %#lx\n", type);
8343
ret = GetTokenInformation(linked.LinkedToken, TokenImpersonationLevel, &type, sizeof(type), &size);
8344
ok(ret, "got error %lu\n", GetLastError());
8345
ok(type == SecurityIdentification, "got impersonation level %#lx\n", type);
8346
8347
/* Asking for the linked token again gives us a different token. */
8348
ret = GetTokenInformation(token, TokenLinkedToken, &linked2, sizeof(linked2), &size);
8349
ok(ret, "got error %lu\n", GetLastError());
8350
8351
ret = GetTokenInformation(linked2.LinkedToken, TokenElevationType, &type, sizeof(type), &size);
8352
ok(ret, "got error %lu\n", GetLastError());
8353
ok(type == TokenElevationTypeFull, "got type %#lx\n", type);
8354
ret = GetTokenInformation(linked2.LinkedToken, TokenElevation, &elevation, sizeof(elevation), &size);
8355
ok(ret, "got error %lu\n", GetLastError());
8356
ok(elevation.TokenIsElevated == TRUE, "got elevation %#lx\n", elevation.TokenIsElevated);
8357
8358
check_different_token(linked.LinkedToken, linked2.LinkedToken);
8359
8360
CloseHandle(linked2.LinkedToken);
8361
8362
/* Asking for the linked token's linked token gives us a new limited token. */
8363
ret = GetTokenInformation(linked.LinkedToken, TokenLinkedToken, &linked2, sizeof(linked2), &size);
8364
ok(ret, "got error %lu\n", GetLastError());
8365
8366
ret = GetTokenInformation(linked2.LinkedToken, TokenElevationType, &type, sizeof(type), &size);
8367
ok(ret, "got error %lu\n", GetLastError());
8368
ok(type == TokenElevationTypeLimited, "got type %#lx\n", type);
8369
ret = GetTokenInformation(linked2.LinkedToken, TokenElevation, &elevation, sizeof(elevation), &size);
8370
ok(ret, "got error %lu\n", GetLastError());
8371
ok(elevation.TokenIsElevated == FALSE, "got elevation %#lx\n", elevation.TokenIsElevated);
8372
8373
check_different_token(token, linked2.LinkedToken);
8374
8375
CloseHandle(linked2.LinkedToken);
8376
8377
CloseHandle(linked.LinkedToken);
8378
8379
type = TokenElevationTypeLimited;
8380
ret = SetTokenInformation(token, TokenElevationType, &type, sizeof(type));
8381
ok(!ret, "expected failure\n");
8382
todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError());
8383
8384
elevation.TokenIsElevated = FALSE;
8385
ret = SetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation));
8386
ok(!ret, "expected failure\n");
8387
todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError());
8388
}
8389
else
8390
{
8391
ok(elevation.TokenIsElevated == TRUE, "got elevation %#lx\n", elevation.TokenIsElevated);
8392
ok(!!linked.LinkedToken, "expected a linked token\n");
8393
8394
TEST_GRANTED_ACCESS(linked.LinkedToken, TOKEN_ALL_ACCESS);
8395
ret = GetTokenInformation(linked.LinkedToken, TokenElevationType, &type, sizeof(type), &size);
8396
ok(ret, "got error %lu\n", GetLastError());
8397
ok(type == TokenElevationTypeLimited, "got type %#lx\n", type);
8398
ret = GetTokenInformation(linked.LinkedToken, TokenElevation, &elevation, sizeof(elevation), &size);
8399
ok(ret, "got error %lu\n", GetLastError());
8400
ok(elevation.TokenIsElevated == FALSE, "got elevation %#lx\n", elevation.TokenIsElevated);
8401
ret = GetTokenInformation(linked.LinkedToken, TokenType, &type, sizeof(type), &size);
8402
ok(ret, "got error %lu\n", GetLastError());
8403
ok(type == TokenImpersonation, "got type %#lx\n", type);
8404
ret = GetTokenInformation(linked.LinkedToken, TokenImpersonationLevel, &type, sizeof(type), &size);
8405
ok(ret, "got error %lu\n", GetLastError());
8406
ok(type == SecurityIdentification, "got impersonation level %#lx\n", type);
8407
8408
/* Asking for the linked token again gives us a different token. */
8409
ret = GetTokenInformation(token, TokenLinkedToken, &linked2, sizeof(linked2), &size);
8410
ok(ret, "got error %lu\n", GetLastError());
8411
8412
ret = GetTokenInformation(linked2.LinkedToken, TokenElevationType, &type, sizeof(type), &size);
8413
ok(ret, "got error %lu\n", GetLastError());
8414
ok(type == TokenElevationTypeLimited, "got type %#lx\n", type);
8415
ret = GetTokenInformation(linked2.LinkedToken, TokenElevation, &elevation, sizeof(elevation), &size);
8416
ok(ret, "got error %lu\n", GetLastError());
8417
ok(elevation.TokenIsElevated == FALSE, "got elevation %#lx\n", elevation.TokenIsElevated);
8418
8419
check_different_token(linked.LinkedToken, linked2.LinkedToken);
8420
8421
CloseHandle(linked2.LinkedToken);
8422
8423
/* Asking for the linked token's linked token gives us a new elevated token. */
8424
ret = GetTokenInformation(linked.LinkedToken, TokenLinkedToken, &linked2, sizeof(linked2), &size);
8425
ok(ret, "got error %lu\n", GetLastError());
8426
8427
ret = GetTokenInformation(linked2.LinkedToken, TokenElevationType, &type, sizeof(type), &size);
8428
ok(ret, "got error %lu\n", GetLastError());
8429
ok(type == TokenElevationTypeFull, "got type %#lx\n", type);
8430
ret = GetTokenInformation(linked2.LinkedToken, TokenElevation, &elevation, sizeof(elevation), &size);
8431
ok(ret, "got error %lu\n", GetLastError());
8432
ok(elevation.TokenIsElevated == TRUE, "got elevation %#lx\n", elevation.TokenIsElevated);
8433
8434
check_different_token(token, linked2.LinkedToken);
8435
8436
CloseHandle(linked2.LinkedToken);
8437
8438
CloseHandle(linked.LinkedToken);
8439
8440
type = TokenElevationTypeLimited;
8441
ret = SetTokenInformation(token, TokenElevationType, &type, sizeof(type));
8442
ok(!ret, "expected failure\n");
8443
todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError());
8444
8445
elevation.TokenIsElevated = FALSE;
8446
ret = SetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation));
8447
ok(!ret, "expected failure\n");
8448
todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError());
8449
}
8450
8451
ret = DuplicateTokenEx(token, TOKEN_ALL_ACCESS, NULL, SecurityAnonymous, TokenPrimary, &token2);
8452
ok(ret, "got error %lu\n", GetLastError());
8453
ret = GetTokenInformation(token2, TokenElevationType, &type, sizeof(type), &size);
8454
ok(ret, "got error %lu\n", GetLastError());
8455
ok(type == orig_type, "expected same type\n");
8456
ret = GetTokenInformation(token2, TokenElevation, &elevation, sizeof(elevation), &size);
8457
ok(ret, "got error %lu\n", GetLastError());
8458
ok(elevation.TokenIsElevated == (type == TokenElevationTypeFull), "got elevation %#lx\n", elevation.TokenIsElevated);
8459
ret = GetTokenInformation(token2, TokenLinkedToken, &linked, sizeof(linked), &size);
8460
ok(ret, "got error %lu\n", GetLastError());
8461
if (type == TokenElevationTypeDefault)
8462
{
8463
ok(!linked.LinkedToken, "expected no linked token\n");
8464
ret = GetTokenInformation(linked.LinkedToken, TokenType, &type, sizeof(type), &size);
8465
ok(ret, "got error %lu\n", GetLastError());
8466
ok(type == TokenImpersonation, "got type %#lx\n", type);
8467
ret = GetTokenInformation(linked.LinkedToken, TokenImpersonationLevel, &type, sizeof(type), &size);
8468
ok(ret, "got error %lu\n", GetLastError());
8469
ok(type == SecurityIdentification, "got impersonation level %#lx\n", type);
8470
CloseHandle(linked.LinkedToken);
8471
}
8472
else
8473
ok(!!linked.LinkedToken, "expected a linked token\n");
8474
CloseHandle(token2);
8475
8476
ret = CreateRestrictedToken(token, 0, 0, NULL, 0, NULL, 0, NULL, &token2);
8477
ok(ret, "got error %lu\n", GetLastError());
8478
ret = GetTokenInformation(token2, TokenElevationType, &type, sizeof(type), &size);
8479
ok(ret, "got error %lu\n", GetLastError());
8480
ok(type == orig_type, "expected same type\n");
8481
ret = GetTokenInformation(token2, TokenElevation, &elevation, sizeof(elevation), &size);
8482
ok(ret, "got error %lu\n", GetLastError());
8483
ok(elevation.TokenIsElevated == (type == TokenElevationTypeFull), "got elevation %#lx\n", elevation.TokenIsElevated);
8484
ret = GetTokenInformation(token2, TokenLinkedToken, &linked, sizeof(linked), &size);
8485
ok(ret, "got error %lu\n", GetLastError());
8486
if (type == TokenElevationTypeDefault)
8487
ok(!linked.LinkedToken, "expected no linked token\n");
8488
else
8489
ok(!!linked.LinkedToken, "expected a linked token\n");
8490
CloseHandle(linked.LinkedToken);
8491
CloseHandle(token2);
8492
8493
if (type != TokenElevationTypeDefault)
8494
{
8495
char prev_privs_buffer[128], acl_buffer[256], prev_acl_buffer[256];
8496
TOKEN_PRIVILEGES privs, *prev_privs = (TOKEN_PRIVILEGES *)prev_privs_buffer;
8497
TOKEN_DEFAULT_DACL *prev_acl = (TOKEN_DEFAULT_DACL *)prev_acl_buffer;
8498
TOKEN_DEFAULT_DACL *ret_acl = (TOKEN_DEFAULT_DACL *)acl_buffer;
8499
TOKEN_DEFAULT_DACL default_acl;
8500
PRIVILEGE_SET priv_set;
8501
BOOL ret, is_member;
8502
DWORD size;
8503
ACL acl;
8504
8505
/* Linked tokens do not preserve privilege modifications. */
8506
8507
privs.PrivilegeCount = 1;
8508
ret = LookupPrivilegeValueA(NULL, "SeChangeNotifyPrivilege", &privs.Privileges[0].Luid);
8509
ok(ret, "got error %lu\n", GetLastError());
8510
privs.Privileges[0].Attributes = SE_PRIVILEGE_REMOVED;
8511
ret = AdjustTokenPrivileges(token, FALSE, &privs, sizeof(prev_privs_buffer), prev_privs, &size);
8512
ok(ret, "got error %lu\n", GetLastError());
8513
8514
priv_set.PrivilegeCount = 1;
8515
priv_set.Control = 0;
8516
priv_set.Privilege[0] = privs.Privileges[0];
8517
ret = PrivilegeCheck(token, &priv_set, &is_member);
8518
ok(ret, "got error %lu\n", GetLastError());
8519
ok(!is_member, "not a member\n");
8520
8521
ret = GetTokenInformation(token, TokenLinkedToken, &linked, sizeof(linked), &size);
8522
ok(ret, "got error %lu\n", GetLastError());
8523
8524
ret = PrivilegeCheck(linked.LinkedToken, &priv_set, &is_member);
8525
ok(ret, "got error %lu\n", GetLastError());
8526
ok(is_member, "not a member\n");
8527
8528
CloseHandle(linked.LinkedToken);
8529
8530
ret = AdjustTokenPrivileges(token, FALSE, prev_privs, 0, NULL, NULL);
8531
ok(ret, "got error %lu\n", GetLastError());
8532
8533
/* Linked tokens do not preserve default DACL modifications. */
8534
8535
ret = GetTokenInformation(token, TokenDefaultDacl, prev_acl, sizeof(prev_acl_buffer), &size);
8536
ok(ret, "got error %lu\n", GetLastError());
8537
ok(prev_acl->DefaultDacl->AceCount, "expected non-empty default DACL\n");
8538
8539
InitializeAcl(&acl, sizeof(acl), ACL_REVISION);
8540
default_acl.DefaultDacl = &acl;
8541
ret = SetTokenInformation(token, TokenDefaultDacl, &default_acl, sizeof(default_acl));
8542
ok(ret, "got error %lu\n", GetLastError());
8543
8544
ret = GetTokenInformation(token, TokenDefaultDacl, ret_acl, sizeof(acl_buffer), &size);
8545
ok(ret, "got error %lu\n", GetLastError());
8546
ok(!ret_acl->DefaultDacl->AceCount, "expected empty default DACL\n");
8547
8548
ret = GetTokenInformation(token, TokenLinkedToken, &linked, sizeof(linked), &size);
8549
ok(ret, "got error %lu\n", GetLastError());
8550
8551
ret = GetTokenInformation(linked.LinkedToken, TokenDefaultDacl, ret_acl, sizeof(acl_buffer), &size);
8552
ok(ret, "got error %lu\n", GetLastError());
8553
ok(ret_acl->DefaultDacl->AceCount, "expected non-empty default DACL\n");
8554
8555
CloseHandle(linked.LinkedToken);
8556
8557
ret = SetTokenInformation(token, TokenDefaultDacl, prev_acl, sizeof(*prev_acl));
8558
ok(ret, "got error %lu\n", GetLastError());
8559
}
8560
8561
CloseHandle(token);
8562
}
8563
8564
static void test_admin_elevation(void)
8565
{
8566
/* Tokens with elevation type TokenElevationTypeDefault should still come
8567
back as elevated from a TokenElevation query if they belong to the admin
8568
group. The owner of the desktop window should have such a token. */
8569
DWORD tid, pid;
8570
HANDLE hproc, htok;
8571
TOKEN_ELEVATION_TYPE elevation_type;
8572
TOKEN_ELEVATION elevation;
8573
DWORD size;
8574
BOOL ret;
8575
8576
tid = GetWindowThreadProcessId(GetDesktopWindow(), &pid);
8577
ok(tid, "got error %lu\n", GetLastError());
8578
8579
hproc = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
8580
if (!hproc)
8581
{
8582
skip("could not open process, error %lu\n", GetLastError());
8583
return;
8584
}
8585
8586
ret = OpenProcessToken(hproc, TOKEN_READ, &htok);
8587
ok(ret, "got error %lu\n", GetLastError());
8588
8589
CloseHandle(hproc);
8590
8591
size = sizeof(elevation_type);
8592
ret = GetTokenInformation(htok, TokenElevationType, &elevation_type, size, &size);
8593
ok(ret, "got error %lu\n", GetLastError());
8594
ok(elevation_type == TokenElevationTypeDefault, "unexpected elevation type %d\n", elevation_type);
8595
8596
size = sizeof(elevation);
8597
ret = GetTokenInformation(htok, TokenElevation, &elevation, size, &size);
8598
ok(ret, "got error %lu\n", GetLastError());
8599
ok(elevation.TokenIsElevated, "expected token to be elevated\n");
8600
8601
CloseHandle(htok);
8602
}
8603
8604
static void test_group_as_file_owner(void)
8605
{
8606
char sd_buffer[200], sid_buffer[100];
8607
SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *)sd_buffer;
8608
char temp_path[MAX_PATH], path[MAX_PATH];
8609
SID *admin_sid = (SID *)sid_buffer;
8610
BOOL ret, present, defaulted;
8611
SECURITY_DESCRIPTOR new_sd;
8612
HANDLE file;
8613
DWORD size;
8614
ACL *dacl;
8615
8616
/* The EA Origin client sets the SD owner of a directory to Administrators,
8617
* while using the default DACL, and subsequently tries to create
8618
* subdirectories. */
8619
8620
size = sizeof(sid_buffer);
8621
CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &size);
8622
8623
ret = CheckTokenMembership(NULL, admin_sid, &present);
8624
ok(ret, "got error %lu\n", GetLastError());
8625
if (!present)
8626
{
8627
skip("user is not an administrator\n");
8628
return;
8629
}
8630
8631
GetTempPathA(ARRAY_SIZE(temp_path), temp_path);
8632
sprintf(path, "%s\\testdir", temp_path);
8633
8634
ret = CreateDirectoryA(path, NULL);
8635
ok(ret, "got error %lu\n", GetLastError());
8636
8637
file = CreateFileA(path, FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
8638
ok(file != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError());
8639
8640
ret = GetKernelObjectSecurity(file, DACL_SECURITY_INFORMATION, sd_buffer, sizeof(sd_buffer), &size);
8641
ok(ret, "got error %lu\n", GetLastError());
8642
ret = GetSecurityDescriptorDacl(sd, &present, &dacl, &defaulted);
8643
ok(ret, "got error %lu\n", GetLastError());
8644
8645
InitializeSecurityDescriptor(&new_sd, SECURITY_DESCRIPTOR_REVISION);
8646
8647
ret = SetSecurityDescriptorOwner(&new_sd, admin_sid, FALSE);
8648
ok(ret, "got error %lu\n", GetLastError());
8649
8650
ret = GetSecurityDescriptorDacl(sd, &present, &dacl, &defaulted);
8651
ok(ret, "got error %lu\n", GetLastError());
8652
8653
ret = SetSecurityDescriptorDacl(&new_sd, present, dacl, defaulted);
8654
ok(ret, "got error %lu\n", GetLastError());
8655
8656
ret = SetKernelObjectSecurity(file, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, &new_sd);
8657
ok(ret, "got error %lu\n", GetLastError());
8658
8659
CloseHandle(file);
8660
8661
sprintf(path, "%s\\testdir\\subdir", temp_path);
8662
ret = CreateDirectoryA(path, NULL);
8663
ok(ret, "got error %lu\n", GetLastError());
8664
8665
ret = RemoveDirectoryA(path);
8666
ok(ret, "got error %lu\n", GetLastError());
8667
sprintf(path, "%s\\testdir", temp_path);
8668
ret = RemoveDirectoryA(path);
8669
ok(ret, "got error %lu\n", GetLastError());
8670
}
8671
8672
static void test_IsValidSecurityDescriptor(void)
8673
{
8674
SECURITY_DESCRIPTOR *sd;
8675
BOOL ret;
8676
8677
SetLastError(0xdeadbeef);
8678
ret = IsValidSecurityDescriptor(NULL);
8679
ok(!ret, "Unexpected return value %d.\n", ret);
8680
ok(GetLastError() == ERROR_INVALID_SECURITY_DESCR, "Unexpected error %ld.\n", GetLastError());
8681
8682
sd = calloc(1, SECURITY_DESCRIPTOR_MIN_LENGTH);
8683
8684
SetLastError(0xdeadbeef);
8685
ret = IsValidSecurityDescriptor(sd);
8686
ok(!ret, "Unexpected return value %d.\n", ret);
8687
ok(GetLastError() == ERROR_INVALID_SECURITY_DESCR, "Unexpected error %ld.\n", GetLastError());
8688
8689
ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
8690
ok(ret, "Unexpected return value %d, error %ld.\n", ret, GetLastError());
8691
8692
SetLastError(0xdeadbeef);
8693
ret = IsValidSecurityDescriptor(sd);
8694
ok(ret, "Unexpected return value %d.\n", ret);
8695
ok(GetLastError() == 0xdeadbeef, "Unexpected error %ld.\n", GetLastError());
8696
8697
free(sd);
8698
}
8699
8700
static void test_window_security(void)
8701
{
8702
PSECURITY_DESCRIPTOR sd;
8703
BOOL present, defaulted;
8704
HDESK desktop;
8705
DWORD ret;
8706
ACL *dacl;
8707
8708
desktop = GetThreadDesktop(GetCurrentThreadId());
8709
8710
ret = GetSecurityInfo(desktop, SE_WINDOW_OBJECT,
8711
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &sd);
8712
ok(!ret, "got error %lu\n", ret);
8713
8714
ret = GetSecurityDescriptorDacl(sd, &present, &dacl, &defaulted);
8715
ok(ret == TRUE, "got error %lu\n", GetLastError());
8716
todo_wine ok(present == TRUE, "got present %d\n", present);
8717
ok(defaulted == FALSE, "got defaulted %d\n", defaulted);
8718
8719
LocalFree(sd);
8720
}
8721
8722
START_TEST(security)
8723
{
8724
init();
8725
if (!hmod) return;
8726
8727
if (myARGC >= 3)
8728
{
8729
if (!strcmp(myARGV[2], "test_token_sd"))
8730
test_child_token_sd();
8731
else if (!strcmp(myARGV[2], "test"))
8732
test_process_security_child();
8733
else if (!strcmp(myARGV[2], "duplicate"))
8734
test_duplicate_handle_access_child();
8735
else if (!strcmp(myARGV[2], "restricted"))
8736
test_create_process_token_child();
8737
return;
8738
}
8739
test_kernel_objects_security();
8740
test_ConvertStringSidToSid();
8741
test_trustee();
8742
test_allocateLuid();
8743
test_lookupPrivilegeName();
8744
test_lookupPrivilegeValue();
8745
test_CreateWellKnownSid();
8746
test_FileSecurity();
8747
test_AccessCheck();
8748
test_token_attr();
8749
test_GetTokenInformation();
8750
test_LookupAccountSid();
8751
test_LookupAccountName();
8752
test_security_descriptor();
8753
test_process_security();
8754
test_impersonation_level();
8755
test_SetEntriesInAclW();
8756
test_SetEntriesInAclA();
8757
test_CreateDirectoryA();
8758
test_GetNamedSecurityInfoA();
8759
test_ConvertStringSecurityDescriptor();
8760
test_ConvertSecurityDescriptorToString();
8761
test_PrivateObjectSecurity();
8762
test_InitializeAcl();
8763
test_GetWindowsAccountDomainSid();
8764
test_EqualDomainSid();
8765
test_GetSecurityInfo();
8766
test_GetSidSubAuthority();
8767
test_CheckTokenMembership();
8768
test_EqualSid();
8769
test_GetUserNameA();
8770
test_GetUserNameW();
8771
test_CreateRestrictedToken();
8772
test_TokenIntegrityLevel();
8773
test_default_dacl_owner_group_sid();
8774
test_AdjustTokenPrivileges();
8775
test_AddAce();
8776
test_AddMandatoryAce();
8777
test_system_security_access();
8778
test_GetSidIdentifierAuthority();
8779
test_pseudo_tokens();
8780
test_maximum_allowed();
8781
test_token_label();
8782
test_GetExplicitEntriesFromAclW();
8783
test_BuildSecurityDescriptorW();
8784
test_duplicate_handle_access();
8785
test_create_process_token();
8786
test_pseudo_handle_security();
8787
test_duplicate_token();
8788
test_GetKernelObjectSecurity();
8789
test_elevation();
8790
test_admin_elevation();
8791
test_group_as_file_owner();
8792
test_IsValidSecurityDescriptor();
8793
test_window_security();
8794
8795
/* Must be the last test, modifies process token */
8796
test_token_security_descriptor();
8797
}
8798
8799