Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/advapi32/tests/security.c
8712 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 );
3050
3051
FreeSid(EveryoneSid);
3052
CloseHandle( event );
3053
free(group);
3054
free(owner);
3055
free(user);
3056
free(Acl);
3057
free(SecurityDescriptor);
3058
free(ThreadAcl);
3059
free(ThreadSecurityDescriptor);
3060
}
3061
3062
static void test_process_security_child(void)
3063
{
3064
HANDLE handle, handle1;
3065
BOOL ret;
3066
DWORD err;
3067
3068
handle = OpenProcess( PROCESS_TERMINATE, FALSE, GetCurrentProcessId() );
3069
ok(handle != NULL, "OpenProcess(PROCESS_TERMINATE) with err:%ld\n", GetLastError());
3070
TEST_GRANTED_ACCESS( handle, PROCESS_TERMINATE );
3071
3072
ret = DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(),
3073
&handle1, 0, TRUE, DUPLICATE_SAME_ACCESS );
3074
ok(ret, "duplicating handle err:%ld\n", GetLastError());
3075
TEST_GRANTED_ACCESS( handle1, PROCESS_TERMINATE );
3076
3077
CloseHandle( handle1 );
3078
3079
SetLastError( 0xdeadbeef );
3080
ret = DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(),
3081
&handle1, PROCESS_ALL_ACCESS, TRUE, 0 );
3082
err = GetLastError();
3083
ok(!ret && err == ERROR_ACCESS_DENIED, "duplicating handle should have failed "
3084
"with STATUS_ACCESS_DENIED, instead of err:%ld\n", err);
3085
3086
CloseHandle( handle );
3087
3088
/* These two should fail - they are denied by ACL */
3089
handle = OpenProcess( PROCESS_VM_READ, FALSE, GetCurrentProcessId() );
3090
ok(handle == NULL, "OpenProcess(PROCESS_VM_READ) should have failed\n");
3091
handle = OpenProcess( PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId() );
3092
ok(handle == NULL, "OpenProcess(PROCESS_ALL_ACCESS) should have failed\n");
3093
3094
/* Documented privilege elevation */
3095
ret = DuplicateHandle( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
3096
&handle, 0, TRUE, DUPLICATE_SAME_ACCESS );
3097
ok(ret, "duplicating handle err:%ld\n", GetLastError());
3098
TEST_GRANTED_ACCESS2( handle, PROCESS_ALL_ACCESS_NT4,
3099
STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL );
3100
3101
CloseHandle( handle );
3102
3103
/* Same only explicitly asking for all access rights */
3104
ret = DuplicateHandle( GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(),
3105
&handle, PROCESS_ALL_ACCESS, TRUE, 0 );
3106
ok(ret, "duplicating handle err:%ld\n", GetLastError());
3107
TEST_GRANTED_ACCESS2( handle, PROCESS_ALL_ACCESS_NT4,
3108
PROCESS_ALL_ACCESS | PROCESS_QUERY_LIMITED_INFORMATION );
3109
ret = DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(),
3110
&handle1, PROCESS_VM_READ, TRUE, 0 );
3111
ok(ret, "duplicating handle err:%ld\n", GetLastError());
3112
TEST_GRANTED_ACCESS( handle1, PROCESS_VM_READ );
3113
CloseHandle( handle1 );
3114
CloseHandle( handle );
3115
3116
/* Test thread security */
3117
handle = OpenThread( THREAD_TERMINATE, FALSE, GetCurrentThreadId() );
3118
ok(handle != NULL, "OpenThread(THREAD_TERMINATE) with err:%ld\n", GetLastError());
3119
TEST_GRANTED_ACCESS( handle, THREAD_TERMINATE );
3120
CloseHandle( handle );
3121
3122
handle = OpenThread( THREAD_SET_THREAD_TOKEN, FALSE, GetCurrentThreadId() );
3123
ok(handle == NULL, "OpenThread(THREAD_SET_THREAD_TOKEN) should have failed\n");
3124
}
3125
3126
static void test_impersonation_level(void)
3127
{
3128
HANDLE Token, ProcessToken;
3129
HANDLE Token2;
3130
DWORD Size;
3131
TOKEN_PRIVILEGES *Privileges;
3132
TOKEN_USER *User;
3133
PRIVILEGE_SET *PrivilegeSet;
3134
BOOL AccessGranted;
3135
BOOL ret;
3136
HKEY hkey;
3137
DWORD error;
3138
3139
SetLastError(0xdeadbeef);
3140
ret = ImpersonateSelf(SecurityAnonymous);
3141
if(!ret && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
3142
{
3143
win_skip("ImpersonateSelf is not implemented\n");
3144
return;
3145
}
3146
ok(ret, "ImpersonateSelf(SecurityAnonymous) failed with error %ld\n", GetLastError());
3147
ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY_SOURCE | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, TRUE, &Token);
3148
ok(!ret, "OpenThreadToken should have failed\n");
3149
error = GetLastError();
3150
ok(error == ERROR_CANT_OPEN_ANONYMOUS, "OpenThreadToken on anonymous token should have returned ERROR_CANT_OPEN_ANONYMOUS instead of %ld\n", error);
3151
/* can't perform access check when opening object against an anonymous impersonation token */
3152
todo_wine {
3153
error = RegOpenKeyExA(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey);
3154
ok(error == ERROR_INVALID_HANDLE || error == ERROR_CANT_OPEN_ANONYMOUS || error == ERROR_BAD_IMPERSONATION_LEVEL,
3155
"RegOpenKeyEx failed with %ld\n", error);
3156
}
3157
RevertToSelf();
3158
3159
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &ProcessToken);
3160
ok(ret, "OpenProcessToken failed with error %ld\n", GetLastError());
3161
3162
ret = DuplicateTokenEx(ProcessToken,
3163
TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE, NULL,
3164
SecurityAnonymous, TokenImpersonation, &Token);
3165
ok(ret, "DuplicateTokenEx failed with error %ld\n", GetLastError());
3166
/* can't increase the impersonation level */
3167
ret = DuplicateToken(Token, SecurityIdentification, &Token2);
3168
error = GetLastError();
3169
ok(!ret && error == ERROR_BAD_IMPERSONATION_LEVEL,
3170
"Duplicating a token and increasing the impersonation level should have failed with ERROR_BAD_IMPERSONATION_LEVEL instead of %ld\n", error);
3171
/* we can query anything from an anonymous token, including the user */
3172
ret = GetTokenInformation(Token, TokenUser, NULL, 0, &Size);
3173
error = GetLastError();
3174
ok(!ret && error == ERROR_INSUFFICIENT_BUFFER, "GetTokenInformation(TokenUser) should have failed with ERROR_INSUFFICIENT_BUFFER instead of %ld\n", error);
3175
User = malloc(Size);
3176
ret = GetTokenInformation(Token, TokenUser, User, Size, &Size);
3177
ok(ret, "GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError());
3178
free(User);
3179
3180
/* PrivilegeCheck fails with SecurityAnonymous level */
3181
ret = GetTokenInformation(Token, TokenPrivileges, NULL, 0, &Size);
3182
error = GetLastError();
3183
ok(!ret && error == ERROR_INSUFFICIENT_BUFFER, "GetTokenInformation(TokenPrivileges) should have failed with ERROR_INSUFFICIENT_BUFFER instead of %ld\n", error);
3184
Privileges = malloc(Size);
3185
ret = GetTokenInformation(Token, TokenPrivileges, Privileges, Size, &Size);
3186
ok(ret, "GetTokenInformation(TokenPrivileges) failed with error %ld\n", GetLastError());
3187
3188
PrivilegeSet = malloc(FIELD_OFFSET(PRIVILEGE_SET, Privilege[Privileges->PrivilegeCount]));
3189
PrivilegeSet->PrivilegeCount = Privileges->PrivilegeCount;
3190
memcpy(PrivilegeSet->Privilege, Privileges->Privileges, PrivilegeSet->PrivilegeCount * sizeof(PrivilegeSet->Privilege[0]));
3191
PrivilegeSet->Control = PRIVILEGE_SET_ALL_NECESSARY;
3192
free(Privileges);
3193
3194
ret = PrivilegeCheck(Token, PrivilegeSet, &AccessGranted);
3195
error = GetLastError();
3196
ok(!ret && error == ERROR_BAD_IMPERSONATION_LEVEL, "PrivilegeCheck for SecurityAnonymous token should have failed with ERROR_BAD_IMPERSONATION_LEVEL instead of %ld\n", error);
3197
3198
CloseHandle(Token);
3199
3200
ret = ImpersonateSelf(SecurityIdentification);
3201
ok(ret, "ImpersonateSelf(SecurityIdentification) failed with error %ld\n", GetLastError());
3202
ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY_SOURCE | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, TRUE, &Token);
3203
ok(ret, "OpenThreadToken failed with error %ld\n", GetLastError());
3204
3205
/* can't perform access check when opening object against an identification impersonation token */
3206
error = RegOpenKeyExA(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey);
3207
todo_wine {
3208
ok(error == ERROR_INVALID_HANDLE || error == ERROR_BAD_IMPERSONATION_LEVEL || error == ERROR_ACCESS_DENIED,
3209
"RegOpenKeyEx should have failed with ERROR_INVALID_HANDLE, ERROR_BAD_IMPERSONATION_LEVEL or ERROR_ACCESS_DENIED instead of %ld\n", error);
3210
}
3211
ret = PrivilegeCheck(Token, PrivilegeSet, &AccessGranted);
3212
ok(ret, "PrivilegeCheck for SecurityIdentification failed with error %ld\n", GetLastError());
3213
CloseHandle(Token);
3214
RevertToSelf();
3215
3216
ret = ImpersonateSelf(SecurityImpersonation);
3217
ok(ret, "ImpersonateSelf(SecurityImpersonation) failed with error %ld\n", GetLastError());
3218
ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY_SOURCE | TOKEN_IMPERSONATE | TOKEN_ADJUST_DEFAULT, TRUE, &Token);
3219
ok(ret, "OpenThreadToken failed with error %ld\n", GetLastError());
3220
error = RegOpenKeyExA(HKEY_CURRENT_USER, "Software", 0, KEY_READ, &hkey);
3221
ok(error == ERROR_SUCCESS, "RegOpenKeyEx should have succeeded instead of failing with %ld\n", error);
3222
RegCloseKey(hkey);
3223
ret = PrivilegeCheck(Token, PrivilegeSet, &AccessGranted);
3224
ok(ret, "PrivilegeCheck for SecurityImpersonation failed with error %ld\n", GetLastError());
3225
RevertToSelf();
3226
3227
CloseHandle(Token);
3228
CloseHandle(ProcessToken);
3229
3230
free(PrivilegeSet);
3231
}
3232
3233
static void test_SetEntriesInAclW(void)
3234
{
3235
DWORD res;
3236
PSID EveryoneSid = NULL, UsersSid = NULL;
3237
PACL OldAcl = NULL, NewAcl;
3238
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
3239
SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY };
3240
EXPLICIT_ACCESSW ExplicitAccess;
3241
3242
NewAcl = (PACL)0xdeadbeef;
3243
res = SetEntriesInAclW(0, NULL, NULL, &NewAcl);
3244
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
3245
ok(NewAcl == NULL, "NewAcl=%p, expected NULL\n", NewAcl);
3246
LocalFree(NewAcl);
3247
3248
OldAcl = malloc(256);
3249
res = InitializeAcl(OldAcl, 256, ACL_REVISION);
3250
if(!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
3251
{
3252
win_skip("ACLs not implemented - skipping tests\n");
3253
free(OldAcl);
3254
return;
3255
}
3256
ok(res, "InitializeAcl failed with error %ld\n", GetLastError());
3257
3258
res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid);
3259
ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
3260
3261
res = AllocateAndInitializeSid( &SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
3262
DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &UsersSid);
3263
ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
3264
3265
res = AddAccessAllowedAce(OldAcl, ACL_REVISION, KEY_READ, UsersSid);
3266
ok(res, "AddAccessAllowedAce failed with error %ld\n", GetLastError());
3267
3268
ExplicitAccess.grfAccessPermissions = KEY_WRITE;
3269
ExplicitAccess.grfAccessMode = GRANT_ACCESS;
3270
ExplicitAccess.grfInheritance = NO_INHERITANCE;
3271
ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
3272
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
3273
ExplicitAccess.Trustee.ptstrName = EveryoneSid;
3274
ExplicitAccess.Trustee.MultipleTrusteeOperation = 0xDEADBEEF;
3275
ExplicitAccess.Trustee.pMultipleTrustee = (PVOID)0xDEADBEEF;
3276
res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3277
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
3278
ok(NewAcl != NULL, "returned acl was NULL\n");
3279
LocalFree(NewAcl);
3280
3281
ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3282
ExplicitAccess.Trustee.pMultipleTrustee = NULL;
3283
ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3284
res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3285
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
3286
ok(NewAcl != NULL, "returned acl was NULL\n");
3287
LocalFree(NewAcl);
3288
3289
if (PRIMARYLANGID(GetSystemDefaultLangID()) != LANG_ENGLISH)
3290
{
3291
skip("Non-English locale (test with hardcoded 'Everyone')\n");
3292
}
3293
else
3294
{
3295
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3296
ExplicitAccess.Trustee.ptstrName = (WCHAR *)L"Everyone";
3297
res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3298
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
3299
ok(NewAcl != NULL, "returned acl was NULL\n");
3300
LocalFree(NewAcl);
3301
3302
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_BAD_FORM;
3303
res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3304
ok(res == ERROR_INVALID_PARAMETER,
3305
"SetEntriesInAclW failed: %lu\n", res);
3306
ok(NewAcl == NULL,
3307
"returned acl wasn't NULL: %p\n", NewAcl);
3308
3309
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3310
ExplicitAccess.Trustee.MultipleTrusteeOperation = TRUSTEE_IS_IMPERSONATE;
3311
res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3312
ok(res == ERROR_INVALID_PARAMETER,
3313
"SetEntriesInAclW failed: %lu\n", res);
3314
ok(NewAcl == NULL,
3315
"returned acl wasn't NULL: %p\n", NewAcl);
3316
3317
ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3318
ExplicitAccess.grfAccessMode = SET_ACCESS;
3319
res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3320
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
3321
ok(NewAcl != NULL, "returned acl was NULL\n");
3322
LocalFree(NewAcl);
3323
}
3324
3325
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3326
ExplicitAccess.Trustee.ptstrName = (WCHAR *)L"CURRENT_USER";
3327
res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3328
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
3329
ok(NewAcl != NULL, "returned acl was NULL\n");
3330
LocalFree(NewAcl);
3331
3332
ExplicitAccess.grfAccessMode = REVOKE_ACCESS;
3333
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
3334
ExplicitAccess.Trustee.ptstrName = UsersSid;
3335
res = SetEntriesInAclW(1, &ExplicitAccess, OldAcl, &NewAcl);
3336
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
3337
ok(NewAcl != NULL, "returned acl was NULL\n");
3338
LocalFree(NewAcl);
3339
3340
FreeSid(UsersSid);
3341
FreeSid(EveryoneSid);
3342
free(OldAcl);
3343
}
3344
3345
static void test_SetEntriesInAclA(void)
3346
{
3347
DWORD res;
3348
PSID EveryoneSid = NULL, UsersSid = NULL;
3349
PACL OldAcl = NULL, NewAcl;
3350
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
3351
SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY };
3352
EXPLICIT_ACCESSA ExplicitAccess;
3353
3354
NewAcl = (PACL)0xdeadbeef;
3355
res = SetEntriesInAclA(0, NULL, NULL, &NewAcl);
3356
if(res == ERROR_CALL_NOT_IMPLEMENTED)
3357
{
3358
win_skip("SetEntriesInAclA is not implemented\n");
3359
return;
3360
}
3361
ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %lu\n", res);
3362
ok(NewAcl == NULL,
3363
"NewAcl=%p, expected NULL\n", NewAcl);
3364
LocalFree(NewAcl);
3365
3366
OldAcl = malloc(256);
3367
res = InitializeAcl(OldAcl, 256, ACL_REVISION);
3368
if(!res && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
3369
{
3370
win_skip("ACLs not implemented - skipping tests\n");
3371
free(OldAcl);
3372
return;
3373
}
3374
ok(res, "InitializeAcl failed with error %ld\n", GetLastError());
3375
3376
res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid);
3377
ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
3378
3379
res = AllocateAndInitializeSid( &SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
3380
DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &UsersSid);
3381
ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
3382
3383
res = AddAccessAllowedAce(OldAcl, ACL_REVISION, KEY_READ, UsersSid);
3384
ok(res, "AddAccessAllowedAce failed with error %ld\n", GetLastError());
3385
3386
ExplicitAccess.grfAccessPermissions = KEY_WRITE;
3387
ExplicitAccess.grfAccessMode = GRANT_ACCESS;
3388
ExplicitAccess.grfInheritance = NO_INHERITANCE;
3389
ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
3390
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
3391
ExplicitAccess.Trustee.ptstrName = EveryoneSid;
3392
ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3393
ExplicitAccess.Trustee.pMultipleTrustee = NULL;
3394
res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3395
ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %lu\n", res);
3396
ok(NewAcl != NULL, "returned acl was NULL\n");
3397
LocalFree(NewAcl);
3398
3399
ExplicitAccess.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3400
ExplicitAccess.Trustee.pMultipleTrustee = NULL;
3401
ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3402
res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3403
ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %lu\n", res);
3404
ok(NewAcl != NULL, "returned acl was NULL\n");
3405
LocalFree(NewAcl);
3406
3407
if (PRIMARYLANGID(GetSystemDefaultLangID()) != LANG_ENGLISH)
3408
{
3409
skip("Non-English locale (test with hardcoded 'Everyone')\n");
3410
}
3411
else
3412
{
3413
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3414
ExplicitAccess.Trustee.ptstrName = (char*)"Everyone";
3415
res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3416
ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %lu\n", res);
3417
ok(NewAcl != NULL, "returned acl was NULL\n");
3418
LocalFree(NewAcl);
3419
3420
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_BAD_FORM;
3421
res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3422
ok(res == ERROR_INVALID_PARAMETER,
3423
"SetEntriesInAclA failed: %lu\n", res);
3424
ok(NewAcl == NULL,
3425
"returned acl wasn't NULL: %p\n", NewAcl);
3426
3427
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3428
ExplicitAccess.Trustee.MultipleTrusteeOperation = TRUSTEE_IS_IMPERSONATE;
3429
res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3430
ok(res == ERROR_INVALID_PARAMETER,
3431
"SetEntriesInAclA failed: %lu\n", res);
3432
ok(NewAcl == NULL,
3433
"returned acl wasn't NULL: %p\n", NewAcl);
3434
3435
ExplicitAccess.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3436
ExplicitAccess.grfAccessMode = SET_ACCESS;
3437
res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3438
ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %lu\n", res);
3439
ok(NewAcl != NULL, "returned acl was NULL\n");
3440
LocalFree(NewAcl);
3441
}
3442
3443
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3444
ExplicitAccess.Trustee.ptstrName = (char *)"CURRENT_USER";
3445
res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3446
ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %lu\n", res);
3447
ok(NewAcl != NULL, "returned acl was NULL\n");
3448
LocalFree(NewAcl);
3449
3450
ExplicitAccess.grfAccessMode = REVOKE_ACCESS;
3451
ExplicitAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
3452
ExplicitAccess.Trustee.ptstrName = UsersSid;
3453
res = SetEntriesInAclA(1, &ExplicitAccess, OldAcl, &NewAcl);
3454
ok(res == ERROR_SUCCESS, "SetEntriesInAclA failed: %lu\n", res);
3455
ok(NewAcl != NULL, "returned acl was NULL\n");
3456
LocalFree(NewAcl);
3457
3458
FreeSid(UsersSid);
3459
FreeSid(EveryoneSid);
3460
free(OldAcl);
3461
}
3462
3463
/* helper function for test_CreateDirectoryA */
3464
static void get_nt_pathW(const char *name, UNICODE_STRING *nameW)
3465
{
3466
UNICODE_STRING strW;
3467
ANSI_STRING str;
3468
NTSTATUS status;
3469
BOOLEAN ret;
3470
3471
RtlInitAnsiString(&str, name);
3472
3473
status = RtlAnsiStringToUnicodeString(&strW, &str, TRUE);
3474
ok(!status, "RtlAnsiStringToUnicodeString failed with %08lx\n", status);
3475
3476
ret = pRtlDosPathNameToNtPathName_U(strW.Buffer, nameW, NULL, NULL);
3477
ok(ret, "RtlDosPathNameToNtPathName_U failed\n");
3478
3479
RtlFreeUnicodeString(&strW);
3480
}
3481
3482
static void test_inherited_dacl(PACL dacl, PSID admin_sid, PSID user_sid, DWORD flags, DWORD mask,
3483
BOOL todo_count, BOOL todo_sid, BOOL todo_flags, int line)
3484
{
3485
ACL_SIZE_INFORMATION acl_size;
3486
ACCESS_ALLOWED_ACE *ace;
3487
BOOL bret;
3488
3489
bret = GetAclInformation(dacl, &acl_size, sizeof(acl_size), AclSizeInformation);
3490
ok_(__FILE__, line)(bret, "GetAclInformation failed\n");
3491
3492
todo_wine_if (todo_count)
3493
ok_(__FILE__, line)(acl_size.AceCount == 2,
3494
"GetAclInformation returned unexpected entry count (%ld != 2)\n",
3495
acl_size.AceCount);
3496
3497
if (acl_size.AceCount > 0)
3498
{
3499
bret = GetAce(dacl, 0, (VOID **)&ace);
3500
ok_(__FILE__, line)(bret, "Failed to get Current User ACE\n");
3501
3502
bret = EqualSid(&ace->SidStart, user_sid);
3503
todo_wine_if (todo_sid)
3504
ok_(__FILE__, line)(bret, "Current User ACE (%s) != Current User SID (%s)\n", debugstr_sid(&ace->SidStart), debugstr_sid(user_sid));
3505
3506
todo_wine_if (todo_flags)
3507
ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags,
3508
"Current User ACE has unexpected flags (0x%x != 0x%lx)\n",
3509
((ACE_HEADER *)ace)->AceFlags, flags);
3510
3511
ok_(__FILE__, line)(ace->Mask == mask,
3512
"Current User ACE has unexpected mask (0x%lx != 0x%lx)\n",
3513
ace->Mask, mask);
3514
}
3515
if (acl_size.AceCount > 1)
3516
{
3517
bret = GetAce(dacl, 1, (VOID **)&ace);
3518
ok_(__FILE__, line)(bret, "Failed to get Administators Group ACE\n");
3519
3520
bret = EqualSid(&ace->SidStart, admin_sid);
3521
todo_wine_if (todo_sid)
3522
ok_(__FILE__, line)(bret, "Administators Group ACE (%s) != Administators Group SID (%s)\n", debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid));
3523
3524
todo_wine_if (todo_flags)
3525
ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags,
3526
"Administators Group ACE has unexpected flags (0x%x != 0x%lx)\n",
3527
((ACE_HEADER *)ace)->AceFlags, flags);
3528
3529
ok_(__FILE__, line)(ace->Mask == mask,
3530
"Administators Group ACE has unexpected mask (0x%lx != 0x%lx)\n",
3531
ace->Mask, mask);
3532
}
3533
}
3534
3535
static void test_CreateDirectoryA(void)
3536
{
3537
char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], *user;
3538
DWORD sid_size = sizeof(admin_ptr), user_size;
3539
PSID admin_sid = (PSID) admin_ptr, user_sid;
3540
char sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
3541
PSECURITY_DESCRIPTOR pSD = &sd;
3542
ACL_SIZE_INFORMATION acl_size;
3543
UNICODE_STRING tmpfileW;
3544
SECURITY_ATTRIBUTES sa;
3545
OBJECT_ATTRIBUTES attr;
3546
char tmpfile[MAX_PATH];
3547
char tmpdir[MAX_PATH];
3548
HANDLE token, hTemp;
3549
IO_STATUS_BLOCK io;
3550
struct _SID *owner;
3551
BOOL bret = TRUE;
3552
NTSTATUS status;
3553
DWORD error;
3554
PACL pDacl;
3555
3556
if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
3557
{
3558
if (GetLastError() != ERROR_NO_TOKEN) bret = FALSE;
3559
else if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) bret = FALSE;
3560
}
3561
if (!bret)
3562
{
3563
win_skip("Failed to get current user token\n");
3564
return;
3565
}
3566
bret = GetTokenInformation(token, TokenUser, NULL, 0, &user_size);
3567
ok(!bret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
3568
"GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError());
3569
user = malloc(user_size);
3570
bret = GetTokenInformation(token, TokenUser, user, user_size, &user_size);
3571
ok(bret, "GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError());
3572
CloseHandle( token );
3573
user_sid = ((TOKEN_USER *)user)->User.Sid;
3574
3575
sa.nLength = sizeof(sa);
3576
sa.lpSecurityDescriptor = pSD;
3577
sa.bInheritHandle = TRUE;
3578
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
3579
CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size);
3580
pDacl = calloc(1, 100);
3581
bret = InitializeAcl(pDacl, 100, ACL_REVISION);
3582
ok(bret, "Failed to initialize ACL.\n");
3583
bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE,
3584
GENERIC_ALL, user_sid);
3585
ok(bret, "Failed to add Current User to ACL.\n");
3586
bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE,
3587
GENERIC_ALL, admin_sid);
3588
ok(bret, "Failed to add Administrator Group to ACL.\n");
3589
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
3590
ok(bret, "Failed to add ACL to security descriptor.\n");
3591
3592
GetTempPathA(MAX_PATH, tmpdir);
3593
lstrcatA(tmpdir, "Please Remove Me");
3594
bret = CreateDirectoryA(tmpdir, &sa);
3595
ok(bret == TRUE, "CreateDirectoryA(%s) failed err=%ld\n", tmpdir, GetLastError());
3596
free(pDacl);
3597
3598
SetLastError(0xdeadbeef);
3599
error = GetNamedSecurityInfoA(tmpdir, SE_FILE_OBJECT,
3600
OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, (PSID*)&owner,
3601
NULL, &pDacl, NULL, &pSD);
3602
if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
3603
{
3604
win_skip("GetNamedSecurityInfoA is not implemented\n");
3605
goto done;
3606
}
3607
ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error);
3608
test_inherited_dacl(pDacl, admin_sid, user_sid, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE,
3609
0x1f01ff, FALSE, TRUE, FALSE, __LINE__);
3610
LocalFree(pSD);
3611
3612
/* Test inheritance of ACLs in CreateFile without security descriptor */
3613
strcpy(tmpfile, tmpdir);
3614
lstrcatA(tmpfile, "/tmpfile");
3615
3616
hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL,
3617
CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, NULL);
3618
ok(hTemp != INVALID_HANDLE_VALUE, "CreateFile error %lu\n", GetLastError());
3619
3620
error = GetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
3621
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3622
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3623
ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
3624
test_inherited_dacl(pDacl, admin_sid, user_sid, INHERITED_ACE,
3625
0x1f01ff, TRUE, TRUE, TRUE, __LINE__);
3626
LocalFree(pSD);
3627
CloseHandle(hTemp);
3628
3629
/* Test inheritance of ACLs in CreateFile with security descriptor -
3630
* When a security descriptor is set, then inheritance doesn't take effect */
3631
pSD = &sd;
3632
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
3633
pDacl = malloc(sizeof(ACL));
3634
bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
3635
ok(bret, "Failed to initialize ACL\n");
3636
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
3637
ok(bret, "Failed to add ACL to security descriptor\n");
3638
3639
strcpy(tmpfile, tmpdir);
3640
lstrcatA(tmpfile, "/tmpfile");
3641
3642
sa.nLength = sizeof(sa);
3643
sa.lpSecurityDescriptor = pSD;
3644
sa.bInheritHandle = TRUE;
3645
hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, &sa,
3646
CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, NULL);
3647
ok(hTemp != INVALID_HANDLE_VALUE, "CreateFile error %lu\n", GetLastError());
3648
free(pDacl);
3649
3650
error = GetSecurityInfo(hTemp, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3651
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3652
ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %ld\n", error);
3653
bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
3654
ok(bret, "GetAclInformation failed\n");
3655
todo_wine
3656
ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%ld != 0).\n",
3657
acl_size.AceCount);
3658
LocalFree(pSD);
3659
3660
error = GetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
3661
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3662
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3663
todo_wine
3664
ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %ld\n", error);
3665
if (error == ERROR_SUCCESS)
3666
{
3667
bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
3668
ok(bret, "GetAclInformation failed\n");
3669
todo_wine
3670
ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%ld != 0).\n",
3671
acl_size.AceCount);
3672
LocalFree(pSD);
3673
}
3674
CloseHandle(hTemp);
3675
3676
/* Test inheritance of ACLs in NtCreateFile without security descriptor */
3677
strcpy(tmpfile, tmpdir);
3678
lstrcatA(tmpfile, "/tmpfile");
3679
get_nt_pathW(tmpfile, &tmpfileW);
3680
3681
attr.Length = sizeof(attr);
3682
attr.RootDirectory = 0;
3683
attr.ObjectName = &tmpfileW;
3684
attr.Attributes = OBJ_CASE_INSENSITIVE;
3685
attr.SecurityDescriptor = NULL;
3686
attr.SecurityQualityOfService = NULL;
3687
3688
status = NtCreateFile(&hTemp, GENERIC_WRITE | DELETE, &attr, &io, NULL, 0,
3689
FILE_SHARE_READ, FILE_CREATE, FILE_DELETE_ON_CLOSE, NULL, 0);
3690
ok(!status, "NtCreateFile failed with %08lx\n", status);
3691
RtlFreeUnicodeString(&tmpfileW);
3692
3693
error = GetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
3694
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3695
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3696
ok(error == ERROR_SUCCESS, "Failed to get permissions on file\n");
3697
test_inherited_dacl(pDacl, admin_sid, user_sid, INHERITED_ACE,
3698
0x1f01ff, TRUE, TRUE, TRUE, __LINE__);
3699
LocalFree(pSD);
3700
CloseHandle(hTemp);
3701
3702
/* Test inheritance of ACLs in NtCreateFile with security descriptor -
3703
* When a security descriptor is set, then inheritance doesn't take effect */
3704
pSD = &sd;
3705
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
3706
pDacl = malloc(sizeof(ACL));
3707
bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
3708
ok(bret, "Failed to initialize ACL\n");
3709
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
3710
ok(bret, "Failed to add ACL to security descriptor\n");
3711
3712
strcpy(tmpfile, tmpdir);
3713
lstrcatA(tmpfile, "/tmpfile");
3714
get_nt_pathW(tmpfile, &tmpfileW);
3715
3716
attr.Length = sizeof(attr);
3717
attr.RootDirectory = 0;
3718
attr.ObjectName = &tmpfileW;
3719
attr.Attributes = OBJ_CASE_INSENSITIVE;
3720
attr.SecurityDescriptor = pSD;
3721
attr.SecurityQualityOfService = NULL;
3722
3723
status = NtCreateFile(&hTemp, GENERIC_WRITE | DELETE, &attr, &io, NULL, 0,
3724
FILE_SHARE_READ, FILE_CREATE, FILE_DELETE_ON_CLOSE, NULL, 0);
3725
ok(!status, "NtCreateFile failed with %08lx\n", status);
3726
RtlFreeUnicodeString(&tmpfileW);
3727
free(pDacl);
3728
3729
error = GetSecurityInfo(hTemp, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3730
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3731
ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %ld\n", error);
3732
bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
3733
ok(bret, "GetAclInformation failed\n");
3734
todo_wine
3735
ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%ld != 0).\n",
3736
acl_size.AceCount);
3737
LocalFree(pSD);
3738
3739
error = GetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
3740
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
3741
(PSID *)&owner, NULL, &pDacl, NULL, &pSD);
3742
todo_wine
3743
ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %ld\n", error);
3744
if (error == ERROR_SUCCESS)
3745
{
3746
bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
3747
ok(bret, "GetAclInformation failed\n");
3748
todo_wine
3749
ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%ld != 0).\n",
3750
acl_size.AceCount);
3751
LocalFree(pSD);
3752
}
3753
CloseHandle(hTemp);
3754
3755
done:
3756
free(user);
3757
bret = RemoveDirectoryA(tmpdir);
3758
ok(bret == TRUE, "RemoveDirectoryA should always succeed\n");
3759
}
3760
3761
static void test_GetNamedSecurityInfoA(void)
3762
{
3763
char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], *user;
3764
char system_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES];
3765
char users_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES];
3766
SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY };
3767
PSID admin_sid = (PSID) admin_ptr, users_sid = (PSID) users_ptr;
3768
PSID system_sid = (PSID) system_ptr, user_sid, localsys_sid;
3769
DWORD sid_size = sizeof(admin_ptr), user_size;
3770
char invalid_path[] = "/an invalid file path";
3771
int users_ace_id = -1, admins_ace_id = -1, i;
3772
char software_key[] = "MACHINE\\Software";
3773
char sd[SECURITY_DESCRIPTOR_MIN_LENGTH+sizeof(void*)];
3774
SECURITY_DESCRIPTOR_CONTROL control;
3775
ACL_SIZE_INFORMATION acl_size;
3776
CHAR windows_dir[MAX_PATH];
3777
PSECURITY_DESCRIPTOR pSD;
3778
ACCESS_ALLOWED_ACE *ace;
3779
BOOL bret = TRUE;
3780
char tmpfile[MAX_PATH];
3781
DWORD error, revision;
3782
BOOL owner_defaulted;
3783
BOOL group_defaulted;
3784
BOOL dacl_defaulted;
3785
HANDLE token, hTemp, h;
3786
PSID owner, group;
3787
BOOL dacl_present;
3788
PACL pDacl;
3789
BYTE flags;
3790
NTSTATUS status;
3791
3792
if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
3793
{
3794
if (GetLastError() != ERROR_NO_TOKEN) bret = FALSE;
3795
else if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) bret = FALSE;
3796
}
3797
if (!bret)
3798
{
3799
win_skip("Failed to get current user token\n");
3800
return;
3801
}
3802
bret = GetTokenInformation(token, TokenUser, NULL, 0, &user_size);
3803
ok(!bret && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
3804
"GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError());
3805
user = malloc(user_size);
3806
bret = GetTokenInformation(token, TokenUser, user, user_size, &user_size);
3807
ok(bret, "GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError());
3808
CloseHandle( token );
3809
user_sid = ((TOKEN_USER *)user)->User.Sid;
3810
3811
bret = GetWindowsDirectoryA(windows_dir, MAX_PATH);
3812
ok(bret, "GetWindowsDirectory failed with error %ld\n", GetLastError());
3813
3814
SetLastError(0xdeadbeef);
3815
error = GetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,
3816
OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION,
3817
NULL, NULL, NULL, NULL, &pSD);
3818
if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
3819
{
3820
win_skip("GetNamedSecurityInfoA is not implemented\n");
3821
free(user);
3822
return;
3823
}
3824
ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error);
3825
3826
bret = GetSecurityDescriptorControl(pSD, &control, &revision);
3827
ok(bret, "GetSecurityDescriptorControl failed with error %ld\n", GetLastError());
3828
ok((control & (SE_SELF_RELATIVE|SE_DACL_PRESENT)) == (SE_SELF_RELATIVE|SE_DACL_PRESENT),
3829
"control (0x%x) doesn't have (SE_SELF_RELATIVE|SE_DACL_PRESENT) flags set\n", control);
3830
ok(revision == SECURITY_DESCRIPTOR_REVISION1, "revision was %ld instead of 1\n", revision);
3831
3832
bret = GetSecurityDescriptorOwner(pSD, &owner, &owner_defaulted);
3833
ok(bret, "GetSecurityDescriptorOwner failed with error %ld\n", GetLastError());
3834
ok(owner != NULL, "owner should not be NULL\n");
3835
3836
bret = GetSecurityDescriptorGroup(pSD, &group, &group_defaulted);
3837
ok(bret, "GetSecurityDescriptorGroup failed with error %ld\n", GetLastError());
3838
ok(group != NULL, "group should not be NULL\n");
3839
LocalFree(pSD);
3840
3841
3842
/* NULL descriptor tests */
3843
3844
error = GetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,
3845
NULL, NULL, NULL, NULL, NULL);
3846
ok(error==ERROR_INVALID_PARAMETER, "GetNamedSecurityInfo failed with error %ld\n", error);
3847
3848
pDacl = NULL;
3849
error = GetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,
3850
NULL, NULL, &pDacl, NULL, &pSD);
3851
ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error);
3852
ok(pDacl != NULL, "DACL should not be NULL\n");
3853
LocalFree(pSD);
3854
3855
error = GetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,OWNER_SECURITY_INFORMATION,
3856
NULL, NULL, &pDacl, NULL, NULL);
3857
ok(error==ERROR_INVALID_PARAMETER, "GetNamedSecurityInfo failed with error %ld\n", error);
3858
3859
/* Test behavior of SetNamedSecurityInfo with an invalid path */
3860
SetLastError(0xdeadbeef);
3861
error = SetNamedSecurityInfoA(invalid_path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL,
3862
NULL, NULL, NULL);
3863
ok(error == ERROR_FILE_NOT_FOUND, "Unexpected error returned: 0x%lx\n", error);
3864
ok(GetLastError() == 0xdeadbeef, "Expected last error to remain unchanged.\n");
3865
3866
/* Create security descriptor information and test that it comes back the same */
3867
pSD = &sd;
3868
pDacl = malloc(100);
3869
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
3870
CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size);
3871
bret = InitializeAcl(pDacl, 100, ACL_REVISION);
3872
ok(bret, "Failed to initialize ACL.\n");
3873
bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
3874
ok(bret, "Failed to add Current User to ACL.\n");
3875
bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, admin_sid);
3876
ok(bret, "Failed to add Administrator Group to ACL.\n");
3877
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
3878
ok(bret, "Failed to add ACL to security descriptor.\n");
3879
GetTempFileNameA(".", "foo", 0, tmpfile);
3880
hTemp = CreateFileA(tmpfile, WRITE_DAC|GENERIC_WRITE, FILE_SHARE_DELETE|FILE_SHARE_READ,
3881
NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL);
3882
SetLastError(0xdeadbeef);
3883
error = SetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL,
3884
NULL, pDacl, NULL);
3885
free(pDacl);
3886
if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
3887
{
3888
win_skip("SetNamedSecurityInfoA is not implemented\n");
3889
free(user);
3890
CloseHandle(hTemp);
3891
return;
3892
}
3893
ok(!error, "SetNamedSecurityInfoA failed with error %ld\n", error);
3894
SetLastError(0xdeadbeef);
3895
error = GetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
3896
NULL, NULL, &pDacl, NULL, &pSD);
3897
if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
3898
{
3899
win_skip("GetNamedSecurityInfoA is not implemented\n");
3900
free(user);
3901
CloseHandle(hTemp);
3902
return;
3903
}
3904
ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error);
3905
3906
bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
3907
ok(bret, "GetAclInformation failed\n");
3908
if (acl_size.AceCount > 0)
3909
{
3910
bret = GetAce(pDacl, 0, (VOID **)&ace);
3911
ok(bret, "Failed to get Current User ACE.\n");
3912
bret = EqualSid(&ace->SidStart, user_sid);
3913
todo_wine ok(bret, "Current User ACE (%s) != Current User SID (%s).\n",
3914
debugstr_sid(&ace->SidStart), debugstr_sid(user_sid));
3915
ok(((ACE_HEADER *)ace)->AceFlags == 0,
3916
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
3917
ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%lx != 0x1f01ff)\n",
3918
ace->Mask);
3919
}
3920
if (acl_size.AceCount > 1)
3921
{
3922
bret = GetAce(pDacl, 1, (VOID **)&ace);
3923
ok(bret, "Failed to get Administators Group ACE.\n");
3924
bret = EqualSid(&ace->SidStart, admin_sid);
3925
todo_wine ok(bret || broken(!bret) /* win2k */,
3926
"Administators Group ACE (%s) != Administators Group SID (%s).\n",
3927
debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid));
3928
ok(((ACE_HEADER *)ace)->AceFlags == 0,
3929
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
3930
ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */,
3931
"Administators Group ACE has unexpected mask (0x%lx != 0x1f01ff)\n", ace->Mask);
3932
}
3933
LocalFree(pSD);
3934
3935
/* show that setting empty DACL is not removing all file permissions */
3936
pDacl = malloc(sizeof(ACL));
3937
bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
3938
ok(bret, "Failed to initialize ACL.\n");
3939
error = SetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
3940
NULL, NULL, pDacl, NULL);
3941
ok(!error, "SetNamedSecurityInfoA failed with error %ld\n", error);
3942
free(pDacl);
3943
3944
error = GetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
3945
NULL, NULL, &pDacl, NULL, &pSD);
3946
ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error);
3947
3948
bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
3949
ok(bret, "GetAclInformation failed\n");
3950
if (acl_size.AceCount > 0)
3951
{
3952
bret = GetAce(pDacl, 0, (VOID **)&ace);
3953
ok(bret, "Failed to get ACE.\n");
3954
todo_wine ok(((ACE_HEADER *)ace)->AceFlags & INHERITED_ACE,
3955
"ACE has unexpected flags: 0x%x\n", ((ACE_HEADER *)ace)->AceFlags);
3956
}
3957
LocalFree(pSD);
3958
3959
h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
3960
NULL, OPEN_EXISTING, 0, NULL);
3961
ok(h != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
3962
CloseHandle(h);
3963
3964
/* test setting NULL DACL */
3965
error = SetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT,
3966
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL);
3967
ok(!error, "SetNamedSecurityInfoA failed with error %ld\n", error);
3968
3969
error = GetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
3970
NULL, NULL, &pDacl, NULL, &pSD);
3971
ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error);
3972
todo_wine ok(!pDacl, "pDacl != NULL\n");
3973
LocalFree(pSD);
3974
3975
h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
3976
NULL, OPEN_EXISTING, 0, NULL);
3977
ok(h != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
3978
CloseHandle(h);
3979
3980
/* NtSetSecurityObject doesn't inherit DACL entries */
3981
pSD = sd+sizeof(void*)-((ULONG_PTR)sd)%sizeof(void*);
3982
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
3983
pDacl = malloc(100);
3984
bret = InitializeAcl(pDacl, sizeof(ACL), ACL_REVISION);
3985
ok(bret, "Failed to initialize ACL.\n");
3986
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
3987
ok(bret, "Failed to add ACL to security descriptor.\n");
3988
status = NtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
3989
ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %lx\n", status);
3990
3991
h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
3992
NULL, OPEN_EXISTING, 0, NULL);
3993
ok(h == INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
3994
CloseHandle(h);
3995
3996
SetSecurityDescriptorControl(pSD, SE_DACL_AUTO_INHERIT_REQ, SE_DACL_AUTO_INHERIT_REQ);
3997
status = NtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
3998
ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %lx\n", status);
3999
4000
h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
4001
NULL, OPEN_EXISTING, 0, NULL);
4002
ok(h == INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
4003
CloseHandle(h);
4004
4005
SetSecurityDescriptorControl(pSD, SE_DACL_AUTO_INHERIT_REQ|SE_DACL_AUTO_INHERITED,
4006
SE_DACL_AUTO_INHERIT_REQ|SE_DACL_AUTO_INHERITED);
4007
status = NtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
4008
ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %lx\n", status);
4009
4010
h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
4011
NULL, OPEN_EXISTING, 0, NULL);
4012
ok(h == INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
4013
CloseHandle(h);
4014
4015
/* test if DACL is properly mapped to permission */
4016
bret = InitializeAcl(pDacl, 100, ACL_REVISION);
4017
ok(bret, "Failed to initialize ACL.\n");
4018
bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
4019
ok(bret, "Failed to add Current User to ACL.\n");
4020
bret = AddAccessDeniedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
4021
ok(bret, "Failed to add Current User to ACL.\n");
4022
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
4023
ok(bret, "Failed to add ACL to security descriptor.\n");
4024
status = NtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
4025
ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %lx\n", status);
4026
4027
h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
4028
NULL, OPEN_EXISTING, 0, NULL);
4029
ok(h != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
4030
CloseHandle(h);
4031
4032
bret = InitializeAcl(pDacl, 100, ACL_REVISION);
4033
ok(bret, "Failed to initialize ACL.\n");
4034
bret = AddAccessDeniedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
4035
ok(bret, "Failed to add Current User to ACL.\n");
4036
bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
4037
ok(bret, "Failed to add Current User to ACL.\n");
4038
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
4039
ok(bret, "Failed to add ACL to security descriptor.\n");
4040
status = NtSetSecurityObject(hTemp, DACL_SECURITY_INFORMATION, pSD);
4041
ok(status == ERROR_SUCCESS, "NtSetSecurityObject returned %lx\n", status);
4042
4043
h = CreateFileA(tmpfile, GENERIC_READ, FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ,
4044
NULL, OPEN_EXISTING, 0, NULL);
4045
ok(h == INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
4046
free(pDacl);
4047
free(user);
4048
CloseHandle(hTemp);
4049
4050
/* Test querying the ownership of a built-in registry key */
4051
sid_size = sizeof(system_ptr);
4052
CreateWellKnownSid(WinLocalSystemSid, NULL, system_sid, &sid_size);
4053
error = GetNamedSecurityInfoA(software_key, SE_REGISTRY_KEY,
4054
OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION,
4055
NULL, NULL, NULL, NULL, &pSD);
4056
ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error);
4057
4058
bret = AllocateAndInitializeSid(&SIDAuthNT, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &localsys_sid);
4059
ok(bret, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
4060
4061
bret = GetSecurityDescriptorOwner(pSD, &owner, &owner_defaulted);
4062
ok(bret, "GetSecurityDescriptorOwner failed with error %ld\n", GetLastError());
4063
ok(owner != NULL, "owner should not be NULL\n");
4064
ok(EqualSid(owner, admin_sid) || EqualSid(owner, localsys_sid),
4065
"MACHINE\\Software owner SID (%s) != Administrators SID (%s) or Local System Sid (%s).\n",
4066
debugstr_sid(owner), debugstr_sid(admin_sid), debugstr_sid(localsys_sid));
4067
4068
bret = GetSecurityDescriptorGroup(pSD, &group, &group_defaulted);
4069
ok(bret, "GetSecurityDescriptorGroup failed with error %ld\n", GetLastError());
4070
ok(group != NULL, "group should not be NULL\n");
4071
ok(EqualSid(group, admin_sid) || broken(EqualSid(group, system_sid)) /* before Win7 */
4072
|| broken(((SID*)group)->SubAuthority[0] == SECURITY_NT_NON_UNIQUE) /* Vista */,
4073
"MACHINE\\Software group SID (%s) != Local System SID (%s or %s)\n",
4074
debugstr_sid(group), debugstr_sid(admin_sid), debugstr_sid(system_sid));
4075
LocalFree(pSD);
4076
4077
/* Test querying the DACL of a built-in registry key */
4078
sid_size = sizeof(users_ptr);
4079
CreateWellKnownSid(WinBuiltinUsersSid, NULL, users_sid, &sid_size);
4080
error = GetNamedSecurityInfoA(software_key, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION,
4081
NULL, NULL, NULL, NULL, &pSD);
4082
ok(!error, "GetNamedSecurityInfo failed with error %ld\n", error);
4083
4084
bret = GetSecurityDescriptorDacl(pSD, &dacl_present, &pDacl, &dacl_defaulted);
4085
ok(bret, "GetSecurityDescriptorDacl failed with error %ld\n", GetLastError());
4086
ok(dacl_present, "DACL should be present\n");
4087
ok(pDacl && IsValidAcl(pDacl), "GetSecurityDescriptorDacl returned invalid DACL.\n");
4088
bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
4089
ok(bret, "GetAclInformation failed\n");
4090
ok(acl_size.AceCount != 0, "GetAclInformation returned no ACLs\n");
4091
for (i=0; i<acl_size.AceCount; i++)
4092
{
4093
bret = GetAce(pDacl, i, (VOID **)&ace);
4094
ok(bret, "Failed to get ACE %d.\n", i);
4095
bret = EqualSid(&ace->SidStart, users_sid);
4096
if (bret) users_ace_id = i;
4097
bret = EqualSid(&ace->SidStart, admin_sid);
4098
if (bret) admins_ace_id = i;
4099
}
4100
ok(users_ace_id != -1 || broken(users_ace_id == -1) /* win2k */,
4101
"Builtin Users ACE not found.\n");
4102
if (users_ace_id != -1)
4103
{
4104
bret = GetAce(pDacl, users_ace_id, (VOID **)&ace);
4105
ok(bret, "Failed to get Builtin Users ACE.\n");
4106
flags = ((ACE_HEADER *)ace)->AceFlags;
4107
ok(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE)
4108
|| broken(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE|INHERITED_ACE)) /* w2k8 */
4109
|| broken(flags == (CONTAINER_INHERIT_ACE|INHERITED_ACE)) /* win 10 wow64 */
4110
|| broken(flags == CONTAINER_INHERIT_ACE), /* win 10 */
4111
"Builtin Users ACE has unexpected flags (0x%x != 0x%x)\n", flags,
4112
INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE);
4113
ok(ace->Mask == GENERIC_READ
4114
|| broken(ace->Mask == KEY_READ), /* win 10 */
4115
"Builtin Users ACE has unexpected mask (0x%lx != 0x%x)\n",
4116
ace->Mask, GENERIC_READ);
4117
}
4118
ok(admins_ace_id != -1, "Builtin Admins ACE not found.\n");
4119
if (admins_ace_id != -1)
4120
{
4121
bret = GetAce(pDacl, admins_ace_id, (VOID **)&ace);
4122
ok(bret, "Failed to get Builtin Admins ACE.\n");
4123
flags = ((ACE_HEADER *)ace)->AceFlags;
4124
ok(flags == 0x0
4125
|| broken(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE|INHERITED_ACE)) /* w2k8 */
4126
|| broken(flags == (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE)) /* win7 */
4127
|| broken(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE)) /* win8+ */
4128
|| broken(flags == (CONTAINER_INHERIT_ACE|INHERITED_ACE)) /* win 10 wow64 */
4129
|| broken(flags == CONTAINER_INHERIT_ACE), /* win 10 */
4130
"Builtin Admins ACE has unexpected flags (0x%x != 0x0)\n", flags);
4131
ok(ace->Mask == KEY_ALL_ACCESS || broken(ace->Mask == GENERIC_ALL) /* w2k8 */,
4132
"Builtin Admins ACE has unexpected mask (0x%lx != 0x%x)\n", ace->Mask, KEY_ALL_ACCESS);
4133
}
4134
4135
FreeSid(localsys_sid);
4136
LocalFree(pSD);
4137
}
4138
4139
static void test_ConvertStringSecurityDescriptor(void)
4140
{
4141
BOOL ret;
4142
PSECURITY_DESCRIPTOR pSD;
4143
static const WCHAR Blank[] = { 0 };
4144
unsigned int i;
4145
ULONG size;
4146
ACL *acl;
4147
static const struct
4148
{
4149
const char *sidstring;
4150
DWORD revision;
4151
BOOL ret;
4152
DWORD GLE;
4153
DWORD altGLE;
4154
DWORD ace_Mask;
4155
} cssd[] =
4156
{
4157
{ "D:(A;;GA;;;WD)", 0xdeadbeef, FALSE, ERROR_UNKNOWN_REVISION },
4158
/* test ACE string type */
4159
{ "D:(A;;GA;;;WD)", SDDL_REVISION_1, TRUE },
4160
{ "D:(D;;GA;;;WD)", SDDL_REVISION_1, TRUE },
4161
{ "ERROR:(D;;GA;;;WD)", SDDL_REVISION_1, FALSE, ERROR_INVALID_PARAMETER },
4162
/* test ACE string with spaces */
4163
{ " D:(D;;GA;;;WD)", SDDL_REVISION_1, TRUE },
4164
{ "D: (D;;GA;;;WD)", SDDL_REVISION_1, TRUE },
4165
{ "D:( D;;GA;;;WD)", SDDL_REVISION_1, TRUE },
4166
{ "D:(D ;;GA;;;WD)", SDDL_REVISION_1, FALSE, RPC_S_INVALID_STRING_UUID, ERROR_INVALID_ACL }, /* Vista+ */
4167
{ "D:(D; ;GA;;;WD)", SDDL_REVISION_1, TRUE },
4168
{ "D:(D;; GA;;;WD)", SDDL_REVISION_1, TRUE },
4169
{ "D:(D;;GA ;;;WD)", SDDL_REVISION_1, FALSE, ERROR_INVALID_ACL },
4170
{ "D:(D;;GA; ;;WD)", SDDL_REVISION_1, TRUE },
4171
{ "D:(D;;GA;; ;WD)", SDDL_REVISION_1, TRUE },
4172
{ "D:(D;;GA;;; WD)", SDDL_REVISION_1, TRUE },
4173
{ "D:(D;;GA;;;WD )", SDDL_REVISION_1, TRUE },
4174
/* test ACE string access rights */
4175
{ "D:(A;;GA;;;WD)", SDDL_REVISION_1, TRUE, 0, 0, GENERIC_ALL },
4176
{ "D:(A;;1;;;WD)", SDDL_REVISION_1, TRUE, 0, 0, 1 },
4177
{ "D:(A;;020000000000;;;WD)", SDDL_REVISION_1, TRUE, 0, 0, GENERIC_READ },
4178
{ "D:(A;;0X40000000;;;WD)", SDDL_REVISION_1, TRUE, 0, 0, GENERIC_WRITE },
4179
{ "D:(A;;GRGWGX;;;WD)", SDDL_REVISION_1, TRUE, 0, 0, GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE },
4180
{ "D:(A;;RCSDWDWO;;;WD)", SDDL_REVISION_1, TRUE, 0, 0, READ_CONTROL | DELETE | WRITE_DAC | WRITE_OWNER },
4181
{ "D:(A;;RPWPCCDCLCSWLODTCR;;;WD)", SDDL_REVISION_1, TRUE },
4182
{ "D:(A;;FAFRFWFX;;;WD)", SDDL_REVISION_1, TRUE },
4183
{ "D:(A;;KAKRKWKX;;;WD)", SDDL_REVISION_1, TRUE },
4184
{ "D:(A;;0xFFFFFFFF;;;WD)", SDDL_REVISION_1, TRUE },
4185
{ "S:(AU;;0xFFFFFFFF;;;WD)", SDDL_REVISION_1, TRUE },
4186
{ "S:(AU;;0xDeAdBeEf;;;WD)", SDDL_REVISION_1, TRUE },
4187
{ "S:(AU;;GR0xFFFFFFFF;;;WD)", SDDL_REVISION_1, TRUE },
4188
{ "S:(AU;;0xFFFFFFFFGR;;;WD)", SDDL_REVISION_1, TRUE },
4189
{ "S:(AU;;0xFFFFFGR;;;WD)", SDDL_REVISION_1, TRUE },
4190
/* test ACE string access right error case */
4191
{ "D:(A;;ROB;;;WD)", SDDL_REVISION_1, FALSE, ERROR_INVALID_ACL },
4192
/* test behaviour with empty strings */
4193
{ "", SDDL_REVISION_1, TRUE },
4194
/* test ACE string SID */
4195
{ "D:(D;;GA;;;S-1-0-0)", SDDL_REVISION_1, TRUE },
4196
{ "D:(D;;GA;;;WDANDSUCH)", SDDL_REVISION_1, FALSE, ERROR_INVALID_ACL },
4197
{ "D:(D;;GA;;;Nonexistent account)", SDDL_REVISION_1, FALSE, ERROR_INVALID_ACL, ERROR_INVALID_SID }, /* W2K */
4198
};
4199
4200
for (i = 0; i < ARRAY_SIZE(cssd); i++)
4201
{
4202
DWORD GLE;
4203
4204
SetLastError(0xdeadbeef);
4205
ret = ConvertStringSecurityDescriptorToSecurityDescriptorA(
4206
cssd[i].sidstring, cssd[i].revision, &pSD, NULL);
4207
GLE = GetLastError();
4208
ok(ret == cssd[i].ret, "(%02u) Expected %s (%ld)\n", i, cssd[i].ret ? "success" : "failure", GLE);
4209
if (!cssd[i].ret)
4210
ok(GLE == cssd[i].GLE ||
4211
(cssd[i].altGLE && GLE == cssd[i].altGLE),
4212
"(%02u) Unexpected last error %ld\n", i, GLE);
4213
if (ret)
4214
{
4215
if (cssd[i].ace_Mask)
4216
{
4217
ACCESS_ALLOWED_ACE *ace;
4218
4219
acl = (ACL *)((char *)pSD + sizeof(SECURITY_DESCRIPTOR_RELATIVE));
4220
ok(acl->AclRevision == ACL_REVISION, "(%02u) Got %u\n", i, acl->AclRevision);
4221
4222
ace = (ACCESS_ALLOWED_ACE *)(acl + 1);
4223
ok(ace->Mask == cssd[i].ace_Mask, "(%02u) Expected %08lx, got %08lx\n",
4224
i, cssd[i].ace_Mask, ace->Mask);
4225
}
4226
LocalFree(pSD);
4227
}
4228
}
4229
4230
/* test behaviour with NULL parameters */
4231
SetLastError(0xdeadbeef);
4232
ret = ConvertStringSecurityDescriptorToSecurityDescriptorA(
4233
NULL, 0xdeadbeef, &pSD, NULL);
4234
todo_wine
4235
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
4236
"ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %ld\n",
4237
GetLastError());
4238
4239
SetLastError(0xdeadbeef);
4240
ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(
4241
NULL, 0xdeadbeef, &pSD, NULL);
4242
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
4243
"ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %ld\n",
4244
GetLastError());
4245
4246
SetLastError(0xdeadbeef);
4247
ret = ConvertStringSecurityDescriptorToSecurityDescriptorA(
4248
"D:(A;;ROB;;;WD)", 0xdeadbeef, NULL, NULL);
4249
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
4250
"ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %ld\n",
4251
GetLastError());
4252
4253
SetLastError(0xdeadbeef);
4254
ret = ConvertStringSecurityDescriptorToSecurityDescriptorA(
4255
"D:(A;;ROB;;;WD)", SDDL_REVISION_1, NULL, NULL);
4256
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
4257
"ConvertStringSecurityDescriptorToSecurityDescriptor should have failed with ERROR_INVALID_PARAMETER instead of %ld\n",
4258
GetLastError());
4259
4260
/* test behaviour with empty strings */
4261
SetLastError(0xdeadbeef);
4262
ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(
4263
Blank, SDDL_REVISION_1, &pSD, NULL);
4264
ok(ret, "ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %ld\n", GetLastError());
4265
LocalFree(pSD);
4266
4267
SetLastError(0xdeadbeef);
4268
ret = ConvertStringSecurityDescriptorToSecurityDescriptorA(
4269
"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);
4270
ok(ret || broken(!ret && GetLastError() == ERROR_INVALID_DATATYPE) /* win2k */,
4271
"ConvertStringSecurityDescriptorToSecurityDescriptor failed with error %lu\n", GetLastError());
4272
if (ret) LocalFree(pSD);
4273
4274
/* empty DACL */
4275
size = 0;
4276
SetLastError(0xdeadbeef);
4277
ret = ConvertStringSecurityDescriptorToSecurityDescriptorA("D:", SDDL_REVISION_1, &pSD, &size);
4278
ok(ret, "unexpected error %lu\n", GetLastError());
4279
ok(size == sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sizeof(ACL), "got %lu\n", size);
4280
acl = (ACL *)((char *)pSD + sizeof(SECURITY_DESCRIPTOR_RELATIVE));
4281
ok(acl->AclRevision == ACL_REVISION, "got %u\n", acl->AclRevision);
4282
ok(!acl->Sbz1, "got %u\n", acl->Sbz1);
4283
ok(acl->AclSize == sizeof(*acl), "got %u\n", acl->AclSize);
4284
ok(!acl->AceCount, "got %u\n", acl->AceCount);
4285
ok(!acl->Sbz2, "got %u\n", acl->Sbz2);
4286
LocalFree(pSD);
4287
4288
/* empty SACL */
4289
size = 0;
4290
SetLastError(0xdeadbeef);
4291
ret = ConvertStringSecurityDescriptorToSecurityDescriptorA("S:", SDDL_REVISION_1, &pSD, &size);
4292
ok(ret, "unexpected error %lu\n", GetLastError());
4293
ok(size == sizeof(SECURITY_DESCRIPTOR_RELATIVE) + sizeof(ACL), "got %lu\n", size);
4294
acl = (ACL *)((char *)pSD + sizeof(SECURITY_DESCRIPTOR_RELATIVE));
4295
ok(!acl->Sbz1, "got %u\n", acl->Sbz1);
4296
ok(acl->AclSize == sizeof(*acl), "got %u\n", acl->AclSize);
4297
ok(!acl->AceCount, "got %u\n", acl->AceCount);
4298
ok(!acl->Sbz2, "got %u\n", acl->Sbz2);
4299
LocalFree(pSD);
4300
}
4301
4302
static void test_ConvertSecurityDescriptorToString(void)
4303
{
4304
SECURITY_DESCRIPTOR desc;
4305
SECURITY_INFORMATION sec_info = OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION;
4306
LPSTR string;
4307
DWORD size;
4308
PSID psid, psid2;
4309
PACL pacl;
4310
char sid_buf[256];
4311
char acl_buf[8192];
4312
ULONG len;
4313
4314
/* It seems Windows XP adds an extra character to the length of the string for each ACE in an ACL. We
4315
* don't replicate this feature so we only test len >= strlen+1. */
4316
#define CHECK_RESULT_AND_FREE(exp_str) \
4317
ok(strcmp(string, (exp_str)) == 0, "String mismatch (expected \"%s\", got \"%s\")\n", (exp_str), string); \
4318
ok(len >= (strlen(exp_str) + 1), "Length mismatch (expected %d, got %ld)\n", lstrlenA(exp_str) + 1, len); \
4319
LocalFree(string);
4320
4321
#define CHECK_ONE_OF_AND_FREE(exp_str1, exp_str2) \
4322
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); \
4323
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); \
4324
LocalFree(string);
4325
4326
InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION);
4327
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4328
CHECK_RESULT_AND_FREE("");
4329
4330
size = 4096;
4331
CreateWellKnownSid(WinLocalSid, NULL, sid_buf, &size);
4332
SetSecurityDescriptorOwner(&desc, sid_buf, FALSE);
4333
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4334
CHECK_RESULT_AND_FREE("O:S-1-2-0");
4335
4336
SetSecurityDescriptorOwner(&desc, sid_buf, TRUE);
4337
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4338
CHECK_RESULT_AND_FREE("O:S-1-2-0");
4339
4340
size = sizeof(sid_buf);
4341
CreateWellKnownSid(WinLocalSystemSid, NULL, sid_buf, &size);
4342
SetSecurityDescriptorOwner(&desc, sid_buf, TRUE);
4343
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4344
CHECK_RESULT_AND_FREE("O:SY");
4345
4346
ConvertStringSidToSidA("S-1-5-21-93476-23408-4576", &psid);
4347
SetSecurityDescriptorGroup(&desc, psid, TRUE);
4348
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4349
CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576");
4350
4351
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, GROUP_SECURITY_INFORMATION, &string, &len), "Conversion failed\n");
4352
CHECK_RESULT_AND_FREE("G:S-1-5-21-93476-23408-4576");
4353
4354
pacl = (PACL)acl_buf;
4355
InitializeAcl(pacl, sizeof(acl_buf), ACL_REVISION);
4356
SetSecurityDescriptorDacl(&desc, TRUE, pacl, TRUE);
4357
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4358
CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:");
4359
4360
SetSecurityDescriptorDacl(&desc, TRUE, pacl, FALSE);
4361
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4362
CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:");
4363
4364
ConvertStringSidToSidA("S-1-5-6", &psid2);
4365
AddAccessAllowedAceEx(pacl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, 0xf0000000, psid2);
4366
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4367
CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)");
4368
4369
AddAccessAllowedAceEx(pacl, ACL_REVISION, INHERIT_ONLY_ACE|INHERITED_ACE, 0x00000003, psid2);
4370
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4371
CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)");
4372
4373
AddAccessDeniedAceEx(pacl, ACL_REVISION, OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE, 0xffffffff, psid);
4374
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4375
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)");
4376
4377
4378
pacl = (PACL)acl_buf;
4379
InitializeAcl(pacl, sizeof(acl_buf), ACL_REVISION);
4380
SetSecurityDescriptorSacl(&desc, TRUE, pacl, FALSE);
4381
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4382
CHECK_RESULT_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:S:");
4383
4384
/* fails in win2k */
4385
SetSecurityDescriptorDacl(&desc, TRUE, NULL, FALSE);
4386
AddAuditAccessAceEx(pacl, ACL_REVISION, VALID_INHERIT_FLAGS, KEY_READ|KEY_WRITE, psid2, TRUE, TRUE);
4387
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4388
CHECK_ONE_OF_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)", /* XP */
4389
"O:SYG:S-1-5-21-93476-23408-4576D:NO_ACCESS_CONTROLS:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)" /* Vista */);
4390
4391
/* fails in win2k */
4392
AddAuditAccessAceEx(pacl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, FILE_GENERIC_READ|FILE_GENERIC_WRITE, psid2, TRUE, FALSE);
4393
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(&desc, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4394
CHECK_ONE_OF_AND_FREE("O:SYG:S-1-5-21-93476-23408-4576D:S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)", /* XP */
4395
"O:SYG:S-1-5-21-93476-23408-4576D:NO_ACCESS_CONTROLS:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)" /* Vista */);
4396
4397
LocalFree(psid2);
4398
LocalFree(psid);
4399
}
4400
4401
static void test_SetSecurityDescriptorControl (PSECURITY_DESCRIPTOR sec)
4402
{
4403
SECURITY_DESCRIPTOR_CONTROL ref;
4404
SECURITY_DESCRIPTOR_CONTROL test;
4405
4406
SECURITY_DESCRIPTOR_CONTROL const mutable
4407
= SE_DACL_AUTO_INHERIT_REQ | SE_SACL_AUTO_INHERIT_REQ
4408
| SE_DACL_AUTO_INHERITED | SE_SACL_AUTO_INHERITED
4409
| SE_DACL_PROTECTED | SE_SACL_PROTECTED
4410
| 0x00000040 | 0x00000080 /* not defined in winnt.h */
4411
;
4412
SECURITY_DESCRIPTOR_CONTROL const immutable
4413
= SE_OWNER_DEFAULTED | SE_GROUP_DEFAULTED
4414
| SE_DACL_PRESENT | SE_DACL_DEFAULTED
4415
| SE_SACL_PRESENT | SE_SACL_DEFAULTED
4416
| SE_RM_CONTROL_VALID | SE_SELF_RELATIVE
4417
;
4418
4419
int bit;
4420
DWORD dwRevision;
4421
LPCSTR fmt = "Expected error %s, got %u\n";
4422
4423
GetSecurityDescriptorControl (sec, &ref, &dwRevision);
4424
4425
/* The mutable bits are mutable regardless of the truth of
4426
SE_DACL_PRESENT and/or SE_SACL_PRESENT */
4427
4428
/* Check call barfs if any bit-of-interest is immutable */
4429
for (bit = 0; bit < 16; ++bit)
4430
{
4431
SECURITY_DESCRIPTOR_CONTROL const bitOfInterest = 1 << bit;
4432
SECURITY_DESCRIPTOR_CONTROL setOrClear = ref & bitOfInterest;
4433
4434
SECURITY_DESCRIPTOR_CONTROL ctrl;
4435
4436
DWORD dwExpect = (bitOfInterest & immutable)
4437
? ERROR_INVALID_PARAMETER : 0xbebecaca;
4438
LPCSTR strExpect = (bitOfInterest & immutable)
4439
? "ERROR_INVALID_PARAMETER" : "0xbebecaca";
4440
4441
ctrl = (bitOfInterest & mutable) ? ref + bitOfInterest : ref;
4442
setOrClear ^= bitOfInterest;
4443
SetLastError (0xbebecaca);
4444
SetSecurityDescriptorControl (sec, bitOfInterest, setOrClear);
4445
ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ());
4446
GetSecurityDescriptorControl(sec, &test, &dwRevision);
4447
expect_eq(test, ctrl, int, "%x");
4448
4449
setOrClear ^= bitOfInterest;
4450
SetLastError (0xbebecaca);
4451
SetSecurityDescriptorControl (sec, bitOfInterest, setOrClear);
4452
ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ());
4453
GetSecurityDescriptorControl (sec, &test, &dwRevision);
4454
expect_eq(test, ref, int, "%x");
4455
}
4456
4457
/* Check call barfs if any bit-to-set is immutable
4458
even when not a bit-of-interest */
4459
for (bit = 0; bit < 16; ++bit)
4460
{
4461
SECURITY_DESCRIPTOR_CONTROL const bitsOfInterest = mutable;
4462
SECURITY_DESCRIPTOR_CONTROL setOrClear = ref & bitsOfInterest;
4463
4464
SECURITY_DESCRIPTOR_CONTROL ctrl;
4465
4466
DWORD dwExpect = ((1 << bit) & immutable)
4467
? ERROR_INVALID_PARAMETER : 0xbebecaca;
4468
LPCSTR strExpect = ((1 << bit) & immutable)
4469
? "ERROR_INVALID_PARAMETER" : "0xbebecaca";
4470
4471
ctrl = ((1 << bit) & immutable) ? test : ref | mutable;
4472
setOrClear ^= bitsOfInterest;
4473
SetLastError (0xbebecaca);
4474
SetSecurityDescriptorControl (sec, bitsOfInterest, setOrClear | (1 << bit));
4475
ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ());
4476
GetSecurityDescriptorControl(sec, &test, &dwRevision);
4477
expect_eq(test, ctrl, int, "%x");
4478
4479
ctrl = ((1 << bit) & immutable) ? test : ref | (1 << bit);
4480
setOrClear ^= bitsOfInterest;
4481
SetLastError (0xbebecaca);
4482
SetSecurityDescriptorControl (sec, bitsOfInterest, setOrClear | (1 << bit));
4483
ok (GetLastError () == dwExpect, fmt, strExpect, GetLastError ());
4484
GetSecurityDescriptorControl(sec, &test, &dwRevision);
4485
expect_eq(test, ctrl, int, "%x");
4486
}
4487
}
4488
4489
static void test_PrivateObjectSecurity(void)
4490
{
4491
SECURITY_INFORMATION sec_info = OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION;
4492
SECURITY_DESCRIPTOR_CONTROL ctrl;
4493
PSECURITY_DESCRIPTOR sec;
4494
DWORD dwDescSize;
4495
DWORD dwRevision;
4496
DWORD retSize;
4497
LPSTR string;
4498
ULONG len;
4499
PSECURITY_DESCRIPTOR buf;
4500
BOOL ret;
4501
4502
ok(ConvertStringSecurityDescriptorToSecurityDescriptorA(
4503
"O:SY"
4504
"G:S-1-5-21-93476-23408-4576"
4505
"D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)"
4506
"(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)"
4507
"S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)",
4508
SDDL_REVISION_1, &sec, &dwDescSize), "Creating descriptor failed\n");
4509
4510
test_SetSecurityDescriptorControl(sec);
4511
4512
LocalFree(sec);
4513
4514
ok(ConvertStringSecurityDescriptorToSecurityDescriptorA(
4515
"O:SY"
4516
"G:S-1-5-21-93476-23408-4576",
4517
SDDL_REVISION_1, &sec, &dwDescSize), "Creating descriptor failed\n");
4518
4519
test_SetSecurityDescriptorControl(sec);
4520
4521
LocalFree(sec);
4522
4523
ok(ConvertStringSecurityDescriptorToSecurityDescriptorA(
4524
"O:SY"
4525
"G:S-1-5-21-93476-23408-4576"
4526
"D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)"
4527
"S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)", SDDL_REVISION_1, &sec, &dwDescSize), "Creating descriptor failed\n");
4528
buf = malloc(dwDescSize);
4529
SetSecurityDescriptorControl(sec, SE_DACL_PROTECTED, SE_DACL_PROTECTED);
4530
GetSecurityDescriptorControl(sec, &ctrl, &dwRevision);
4531
expect_eq(ctrl, 0x9014, int, "%x");
4532
4533
ret = GetPrivateObjectSecurity(sec, GROUP_SECURITY_INFORMATION, buf, dwDescSize, &retSize);
4534
ok(ret, "GetPrivateObjectSecurity failed (err=%lu)\n", GetLastError());
4535
ok(retSize <= dwDescSize, "Buffer too small (%ld vs %ld)\n", retSize, dwDescSize);
4536
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4537
CHECK_RESULT_AND_FREE("G:S-1-5-21-93476-23408-4576");
4538
GetSecurityDescriptorControl(buf, &ctrl, &dwRevision);
4539
expect_eq(ctrl, 0x8000, int, "%x");
4540
4541
ret = GetPrivateObjectSecurity(sec, GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, buf, dwDescSize, &retSize);
4542
ok(ret, "GetPrivateObjectSecurity failed (err=%lu)\n", GetLastError());
4543
ok(retSize <= dwDescSize, "Buffer too small (%ld vs %ld)\n", retSize, dwDescSize);
4544
ret = ConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len);
4545
ok(ret, "Conversion failed err=%lu\n", GetLastError());
4546
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)",
4547
"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 */
4548
GetSecurityDescriptorControl(buf, &ctrl, &dwRevision);
4549
expect_eq(ctrl & (~ SE_DACL_PROTECTED), 0x8004, int, "%x");
4550
4551
ret = GetPrivateObjectSecurity(sec, sec_info, buf, dwDescSize, &retSize);
4552
ok(ret, "GetPrivateObjectSecurity failed (err=%lu)\n", GetLastError());
4553
ok(retSize == dwDescSize, "Buffer too small (%ld vs %ld)\n", retSize, dwDescSize);
4554
ok(ConvertSecurityDescriptorToStringSecurityDescriptorA(buf, SDDL_REVISION_1, sec_info, &string, &len), "Conversion failed\n");
4555
CHECK_ONE_OF_AND_FREE("O:SY"
4556
"G:S-1-5-21-93476-23408-4576"
4557
"D:(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)"
4558
"S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)",
4559
"O:SY"
4560
"G:S-1-5-21-93476-23408-4576"
4561
"D:P(A;NP;GAGXGWGR;;;SU)(A;IOID;CCDC;;;SU)(D;OICI;0xffffffff;;;S-1-5-21-93476-23408-4576)"
4562
"S:(AU;OICINPIOIDSAFA;CCDCLCSWRPRC;;;SU)(AU;NPSA;0x12019f;;;SU)"); /* Win7 */
4563
GetSecurityDescriptorControl(buf, &ctrl, &dwRevision);
4564
expect_eq(ctrl & (~ SE_DACL_PROTECTED), 0x8014, int, "%x");
4565
4566
SetLastError(0xdeadbeef);
4567
ok(GetPrivateObjectSecurity(sec, sec_info, buf, 5, &retSize) == FALSE, "GetPrivateObjectSecurity should have failed\n");
4568
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected error ERROR_INSUFFICIENT_BUFFER, got %lu\n", GetLastError());
4569
4570
LocalFree(sec);
4571
free(buf);
4572
}
4573
#undef CHECK_RESULT_AND_FREE
4574
#undef CHECK_ONE_OF_AND_FREE
4575
4576
static void test_InitializeAcl(void)
4577
{
4578
char buffer[256];
4579
PACL pAcl = (PACL)buffer;
4580
BOOL ret;
4581
4582
SetLastError(0xdeadbeef);
4583
ret = InitializeAcl(pAcl, sizeof(ACL) - 1, ACL_REVISION);
4584
if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
4585
{
4586
win_skip("InitializeAcl is not implemented\n");
4587
return;
4588
}
4589
4590
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "InitializeAcl with too small a buffer should have failed with ERROR_INSUFFICIENT_BUFFER instead of %ld\n", GetLastError());
4591
4592
SetLastError(0xdeadbeef);
4593
ret = InitializeAcl(pAcl, 0xffffffff, ACL_REVISION);
4594
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "InitializeAcl with too large a buffer should have failed with ERROR_INVALID_PARAMETER instead of %ld\n", GetLastError());
4595
4596
SetLastError(0xdeadbeef);
4597
ret = InitializeAcl(pAcl, sizeof(buffer), ACL_REVISION1);
4598
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "InitializeAcl(ACL_REVISION1) should have failed with ERROR_INVALID_PARAMETER instead of %ld\n", GetLastError());
4599
4600
ret = InitializeAcl(pAcl, sizeof(buffer), ACL_REVISION2);
4601
ok(ret, "InitializeAcl(ACL_REVISION2) failed with error %ld\n", GetLastError());
4602
4603
ret = IsValidAcl(pAcl);
4604
ok(ret, "IsValidAcl failed with error %ld\n", GetLastError());
4605
4606
ret = InitializeAcl(pAcl, sizeof(buffer), ACL_REVISION3);
4607
ok(ret, "InitializeAcl(ACL_REVISION3) failed with error %ld\n", GetLastError());
4608
4609
ret = IsValidAcl(pAcl);
4610
ok(ret, "IsValidAcl failed with error %ld\n", GetLastError());
4611
4612
SetLastError(0xdeadbeef);
4613
ret = InitializeAcl(pAcl, sizeof(buffer), ACL_REVISION4);
4614
ok(ret, "InitializeAcl(ACL_REVISION4) failed with error %ld\n", GetLastError());
4615
4616
ret = IsValidAcl(pAcl);
4617
ok(ret, "IsValidAcl failed with error %ld\n", GetLastError());
4618
4619
SetLastError(0xdeadbeef);
4620
ret = InitializeAcl(pAcl, sizeof(buffer), -1);
4621
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "InitializeAcl(-1) failed with error %ld\n", GetLastError());
4622
}
4623
4624
static void test_GetSecurityInfo(void)
4625
{
4626
char domain_users_ptr[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
4627
char b[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
4628
char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], dacl[100];
4629
PSID domain_users_sid = (PSID) domain_users_ptr, domain_sid;
4630
SID_IDENTIFIER_AUTHORITY sia = { SECURITY_NT_AUTHORITY };
4631
int domain_users_ace_id = -1, admins_ace_id = -1, i;
4632
DWORD sid_size = sizeof(admin_ptr), l = sizeof(b);
4633
SECURITY_ATTRIBUTES sa = {.nLength = sizeof(sa)};
4634
PSID admin_sid = (PSID) admin_ptr, user_sid;
4635
char sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
4636
BOOL owner_defaulted, group_defaulted;
4637
BOOL dacl_defaulted, dacl_present;
4638
ACL_SIZE_INFORMATION acl_size;
4639
PSECURITY_DESCRIPTOR pSD;
4640
ACCESS_ALLOWED_ACE *ace;
4641
HANDLE token, obj;
4642
PSID owner, group;
4643
BOOL bret = TRUE;
4644
PACL pDacl;
4645
BYTE flags;
4646
DWORD ret;
4647
4648
static const SE_OBJECT_TYPE kernel_types[] =
4649
{
4650
SE_FILE_OBJECT,
4651
SE_KERNEL_OBJECT,
4652
SE_WMIGUID_OBJECT,
4653
};
4654
4655
static const SE_OBJECT_TYPE invalid_types[] =
4656
{
4657
SE_UNKNOWN_OBJECT_TYPE,
4658
SE_DS_OBJECT,
4659
SE_DS_OBJECT_ALL,
4660
SE_PROVIDER_DEFINED_OBJECT,
4661
SE_REGISTRY_WOW64_32KEY,
4662
SE_REGISTRY_WOW64_64KEY,
4663
0xdeadbeef,
4664
};
4665
4666
if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
4667
{
4668
if (GetLastError() != ERROR_NO_TOKEN) bret = FALSE;
4669
else if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) bret = FALSE;
4670
}
4671
if (!bret)
4672
{
4673
win_skip("Failed to get current user token\n");
4674
return;
4675
}
4676
bret = GetTokenInformation(token, TokenUser, b, l, &l);
4677
ok(bret, "GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError());
4678
CloseHandle( token );
4679
user_sid = ((TOKEN_USER *)b)->User.Sid;
4680
4681
/* Create something. Files have lots of associated security info. */
4682
obj = CreateFileA(myARGV[0], GENERIC_READ|WRITE_DAC, FILE_SHARE_READ, NULL,
4683
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
4684
if (obj == INVALID_HANDLE_VALUE)
4685
{
4686
skip("Couldn't create an object for GetSecurityInfo test\n");
4687
return;
4688
}
4689
4690
ret = GetSecurityInfo(obj, SE_FILE_OBJECT,
4691
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
4692
&owner, &group, &pDacl, NULL, &pSD);
4693
if (ret == ERROR_CALL_NOT_IMPLEMENTED)
4694
{
4695
win_skip("GetSecurityInfo is not implemented\n");
4696
CloseHandle(obj);
4697
return;
4698
}
4699
ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %ld\n", ret);
4700
ok(pSD != NULL, "GetSecurityInfo\n");
4701
ok(owner != NULL, "GetSecurityInfo\n");
4702
ok(group != NULL, "GetSecurityInfo\n");
4703
if (pDacl != NULL)
4704
ok(IsValidAcl(pDacl), "GetSecurityInfo\n");
4705
else
4706
win_skip("No ACL information returned\n");
4707
4708
LocalFree(pSD);
4709
4710
/* If we don't ask for the security descriptor, Windows will still give us
4711
the other stuff, leaving us no way to free it. */
4712
ret = GetSecurityInfo(obj, SE_FILE_OBJECT,
4713
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
4714
&owner, &group, &pDacl, NULL, NULL);
4715
ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %ld\n", ret);
4716
ok(owner != NULL, "GetSecurityInfo\n");
4717
ok(group != NULL, "GetSecurityInfo\n");
4718
if (pDacl != NULL)
4719
ok(IsValidAcl(pDacl), "GetSecurityInfo\n");
4720
else
4721
win_skip("No ACL information returned\n");
4722
4723
/* Create security descriptor information and test that it comes back the same */
4724
pSD = &sd;
4725
pDacl = (PACL)&dacl;
4726
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
4727
CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size);
4728
bret = InitializeAcl(pDacl, sizeof(dacl), ACL_REVISION);
4729
ok(bret, "Failed to initialize ACL.\n");
4730
bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
4731
ok(bret, "Failed to add Current User to ACL.\n");
4732
bret = AddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, admin_sid);
4733
ok(bret, "Failed to add Administrator Group to ACL.\n");
4734
bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE);
4735
ok(bret, "Failed to add ACL to security descriptor.\n");
4736
ret = SetSecurityInfo(obj, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
4737
NULL, NULL, pDacl, NULL);
4738
ok(ret == ERROR_SUCCESS, "SetSecurityInfo returned %ld\n", ret);
4739
ret = GetSecurityInfo(obj, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
4740
NULL, NULL, &pDacl, NULL, &pSD);
4741
ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %ld\n", ret);
4742
ok(pDacl && IsValidAcl(pDacl), "GetSecurityInfo returned invalid DACL.\n");
4743
bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
4744
ok(bret, "GetAclInformation failed\n");
4745
if (acl_size.AceCount > 0)
4746
{
4747
bret = GetAce(pDacl, 0, (VOID **)&ace);
4748
ok(bret, "Failed to get Current User ACE.\n");
4749
bret = EqualSid(&ace->SidStart, user_sid);
4750
todo_wine ok(bret, "Current User ACE (%s) != Current User SID (%s).\n",
4751
debugstr_sid(&ace->SidStart), debugstr_sid(user_sid));
4752
ok(((ACE_HEADER *)ace)->AceFlags == 0,
4753
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
4754
ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%lx != 0x1f01ff)\n",
4755
ace->Mask);
4756
}
4757
if (acl_size.AceCount > 1)
4758
{
4759
bret = GetAce(pDacl, 1, (VOID **)&ace);
4760
ok(bret, "Failed to get Administators Group ACE.\n");
4761
bret = EqualSid(&ace->SidStart, admin_sid);
4762
todo_wine ok(bret, "Administators Group ACE (%s) != Administators Group SID (%s).\n", debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid));
4763
ok(((ACE_HEADER *)ace)->AceFlags == 0,
4764
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
4765
ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%lx != 0x1f01ff)\n",
4766
ace->Mask);
4767
}
4768
LocalFree(pSD);
4769
CloseHandle(obj);
4770
4771
/* Obtain the "domain users" SID from the user SID */
4772
if (!AllocateAndInitializeSid(&sia, 4, *GetSidSubAuthority(user_sid, 0),
4773
*GetSidSubAuthority(user_sid, 1),
4774
*GetSidSubAuthority(user_sid, 2),
4775
*GetSidSubAuthority(user_sid, 3), 0, 0, 0, 0, &domain_sid))
4776
{
4777
win_skip("Failed to get current domain SID\n");
4778
return;
4779
}
4780
sid_size = sizeof(domain_users_ptr);
4781
CreateWellKnownSid(WinAccountDomainUsersSid, domain_sid, domain_users_sid, &sid_size);
4782
FreeSid(domain_sid);
4783
4784
/* Test querying the ownership of a process */
4785
ret = GetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT,
4786
OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION,
4787
NULL, NULL, NULL, NULL, &pSD);
4788
ok(!ret, "GetNamedSecurityInfo failed with error %ld\n", ret);
4789
4790
bret = GetSecurityDescriptorOwner(pSD, &owner, &owner_defaulted);
4791
ok(bret, "GetSecurityDescriptorOwner failed with error %ld\n", GetLastError());
4792
ok(owner != NULL, "owner should not be NULL\n");
4793
ok(EqualSid(owner, admin_sid) || EqualSid(owner, user_sid),
4794
"Process owner SID != Administrators SID.\n");
4795
4796
bret = GetSecurityDescriptorGroup(pSD, &group, &group_defaulted);
4797
ok(bret, "GetSecurityDescriptorGroup failed with error %ld\n", GetLastError());
4798
ok(group != NULL, "group should not be NULL\n");
4799
ok(EqualSid(group, domain_users_sid), "Process group SID != Domain Users SID.\n");
4800
LocalFree(pSD);
4801
4802
/* Test querying the DACL of a process */
4803
ret = GetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION,
4804
NULL, NULL, NULL, NULL, &pSD);
4805
ok(!ret, "GetSecurityInfo failed with error %ld\n", ret);
4806
4807
bret = GetSecurityDescriptorDacl(pSD, &dacl_present, &pDacl, &dacl_defaulted);
4808
ok(bret, "GetSecurityDescriptorDacl failed with error %ld\n", GetLastError());
4809
ok(dacl_present, "DACL should be present\n");
4810
ok(pDacl && IsValidAcl(pDacl), "GetSecurityDescriptorDacl returned invalid DACL.\n");
4811
bret = GetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
4812
ok(bret, "GetAclInformation failed\n");
4813
ok(acl_size.AceCount != 0, "GetAclInformation returned no ACLs\n");
4814
for (i=0; i<acl_size.AceCount; i++)
4815
{
4816
bret = GetAce(pDacl, i, (VOID **)&ace);
4817
ok(bret, "Failed to get ACE %d.\n", i);
4818
bret = EqualSid(&ace->SidStart, domain_users_sid);
4819
if (bret) domain_users_ace_id = i;
4820
bret = EqualSid(&ace->SidStart, admin_sid);
4821
if (bret) admins_ace_id = i;
4822
}
4823
ok(domain_users_ace_id != -1 || broken(domain_users_ace_id == -1) /* win2k */,
4824
"Domain Users ACE not found.\n");
4825
if (domain_users_ace_id != -1)
4826
{
4827
bret = GetAce(pDacl, domain_users_ace_id, (VOID **)&ace);
4828
ok(bret, "Failed to get Domain Users ACE.\n");
4829
flags = ((ACE_HEADER *)ace)->AceFlags;
4830
ok(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE),
4831
"Domain Users ACE has unexpected flags (0x%x != 0x%x)\n", flags,
4832
INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE);
4833
ok(ace->Mask == GENERIC_READ, "Domain Users ACE has unexpected mask (0x%lx != 0x%x)\n",
4834
ace->Mask, GENERIC_READ);
4835
}
4836
ok(admins_ace_id != -1 || broken(admins_ace_id == -1) /* xp */,
4837
"Builtin Admins ACE not found.\n");
4838
if (admins_ace_id != -1)
4839
{
4840
bret = GetAce(pDacl, admins_ace_id, (VOID **)&ace);
4841
ok(bret, "Failed to get Builtin Admins ACE.\n");
4842
flags = ((ACE_HEADER *)ace)->AceFlags;
4843
ok(flags == 0x0, "Builtin Admins ACE has unexpected flags (0x%x != 0x0)\n", flags);
4844
ok(ace->Mask == PROCESS_ALL_ACCESS || broken(ace->Mask == 0x1f0fff) /* win2k */,
4845
"Builtin Admins ACE has unexpected mask (0x%lx != 0x%x)\n", ace->Mask, PROCESS_ALL_ACCESS);
4846
}
4847
LocalFree(pSD);
4848
4849
ret = GetSecurityInfo(NULL, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD);
4850
ok(ret == ERROR_INVALID_HANDLE, "got error %lu\n", ret);
4851
4852
ret = GetSecurityInfo(GetCurrentProcess(), SE_FILE_OBJECT,
4853
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD);
4854
ok(!ret, "got error %lu\n", ret);
4855
LocalFree(pSD);
4856
4857
sa.lpSecurityDescriptor = sd;
4858
obj = CreateEventA(&sa, TRUE, TRUE, NULL);
4859
pDacl = (PACL)&dacl;
4860
4861
for (size_t i = 0; i < ARRAY_SIZE(kernel_types); ++i)
4862
{
4863
winetest_push_context("Type %#x", kernel_types[i]);
4864
4865
ret = GetSecurityInfo(NULL, kernel_types[i],
4866
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD);
4867
ok(ret == ERROR_INVALID_HANDLE, "got error %lu\n", ret);
4868
4869
ret = GetSecurityInfo(GetCurrentProcess(), kernel_types[i],
4870
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD);
4871
ok(!ret, "got error %lu\n", ret);
4872
LocalFree(pSD);
4873
4874
ret = GetSecurityInfo(obj, kernel_types[i],
4875
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD);
4876
ok(!ret, "got error %lu\n", ret);
4877
LocalFree(pSD);
4878
4879
ret = SetSecurityInfo(NULL, kernel_types[i],
4880
DACL_SECURITY_INFORMATION, NULL, NULL, pDacl, NULL);
4881
ok(ret == ERROR_INVALID_HANDLE, "got error %lu\n", ret);
4882
4883
ret = SetSecurityInfo(obj, kernel_types[i],
4884
DACL_SECURITY_INFORMATION, NULL, NULL, pDacl, NULL);
4885
ok(!ret || ret == ERROR_NO_SECURITY_ON_OBJECT /* win 7 */, "got error %lu\n", ret);
4886
4887
winetest_pop_context();
4888
}
4889
4890
ret = GetSecurityInfo(GetCurrentProcess(), SE_REGISTRY_KEY,
4891
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD);
4892
todo_wine ok(ret == ERROR_INVALID_HANDLE, "got error %lu\n", ret);
4893
4894
ret = GetSecurityInfo(obj, SE_REGISTRY_KEY,
4895
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD);
4896
todo_wine ok(ret == ERROR_INVALID_HANDLE, "got error %lu\n", ret);
4897
4898
CloseHandle(obj);
4899
4900
for (size_t i = 0; i < ARRAY_SIZE(invalid_types); ++i)
4901
{
4902
winetest_push_context("Type %#x", invalid_types[i]);
4903
4904
ret = GetSecurityInfo(NULL, invalid_types[i],
4905
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD);
4906
ok(ret == ERROR_INVALID_HANDLE, "got error %lu\n", ret);
4907
4908
ret = GetSecurityInfo((HANDLE)0xdeadbeef, invalid_types[i],
4909
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD);
4910
todo_wine ok(ret == ERROR_INVALID_PARAMETER, "got error %lu\n", ret);
4911
4912
ret = SetSecurityInfo(NULL, invalid_types[i],
4913
DACL_SECURITY_INFORMATION, NULL, NULL, pDacl, NULL);
4914
ok(ret == ERROR_INVALID_HANDLE, "got error %lu\n", ret);
4915
4916
ret = SetSecurityInfo((HANDLE)0xdeadbeef, invalid_types[i],
4917
DACL_SECURITY_INFORMATION, NULL, NULL, pDacl, NULL);
4918
todo_wine ok(ret == ERROR_INVALID_PARAMETER, "got error %lu\n", ret);
4919
4920
winetest_pop_context();
4921
}
4922
}
4923
4924
static void test_GetSidSubAuthority(void)
4925
{
4926
PSID psid = NULL;
4927
4928
/* Note: on windows passing in an invalid index like -1, lets GetSidSubAuthority return 0x05000000 but
4929
still GetLastError returns ERROR_SUCCESS then. We don't test these unlikely cornercases here for now */
4930
ok(ConvertStringSidToSidA("S-1-5-21-93476-23408-4576",&psid),"ConvertStringSidToSidA failed\n");
4931
ok(IsValidSid(psid),"Sid is not valid\n");
4932
SetLastError(0xbebecaca);
4933
ok(*GetSidSubAuthorityCount(psid) == 4,"GetSidSubAuthorityCount gave %d expected 4\n", *GetSidSubAuthorityCount(psid));
4934
ok(GetLastError() == 0,"GetLastError returned %ld instead of 0\n",GetLastError());
4935
SetLastError(0xbebecaca);
4936
ok(*GetSidSubAuthority(psid,0) == 21,"GetSidSubAuthority gave %ld expected 21\n", *GetSidSubAuthority(psid,0));
4937
ok(GetLastError() == 0,"GetLastError returned %ld instead of 0\n",GetLastError());
4938
SetLastError(0xbebecaca);
4939
ok(*GetSidSubAuthority(psid,1) == 93476,"GetSidSubAuthority gave %ld expected 93476\n", *GetSidSubAuthority(psid,1));
4940
ok(GetLastError() == 0,"GetLastError returned %ld instead of 0\n",GetLastError());
4941
SetLastError(0xbebecaca);
4942
ok(GetSidSubAuthority(psid,4) != NULL,"Expected out of bounds GetSidSubAuthority to return a non-NULL pointer\n");
4943
ok(GetLastError() == 0,"GetLastError returned %ld instead of 0\n",GetLastError());
4944
LocalFree(psid);
4945
}
4946
4947
static void test_CheckTokenMembership(void)
4948
{
4949
PTOKEN_GROUPS token_groups;
4950
DWORD size;
4951
HANDLE process_token, token;
4952
BOOL is_member;
4953
BOOL ret;
4954
DWORD i;
4955
4956
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &process_token);
4957
ok(ret, "OpenProcessToken failed with error %ld\n", GetLastError());
4958
4959
ret = DuplicateToken(process_token, SecurityImpersonation, &token);
4960
ok(ret, "DuplicateToken failed with error %ld\n", GetLastError());
4961
4962
/* groups */
4963
ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
4964
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
4965
"GetTokenInformation(TokenGroups) %s with error %ld\n",
4966
ret ? "succeeded" : "failed", GetLastError());
4967
token_groups = malloc(size);
4968
ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
4969
ok(ret, "GetTokenInformation(TokenGroups) failed with error %ld\n", GetLastError());
4970
4971
for (i = 0; i < token_groups->GroupCount; i++)
4972
{
4973
if (token_groups->Groups[i].Attributes & SE_GROUP_ENABLED)
4974
break;
4975
}
4976
4977
if (i == token_groups->GroupCount)
4978
{
4979
free(token_groups);
4980
CloseHandle(token);
4981
skip("user not a member of any group\n");
4982
return;
4983
}
4984
4985
is_member = FALSE;
4986
ret = CheckTokenMembership(token, token_groups->Groups[i].Sid, &is_member);
4987
ok(ret, "CheckTokenMembership failed with error %ld\n", GetLastError());
4988
ok(is_member, "CheckTokenMembership should have detected sid as member\n");
4989
4990
is_member = FALSE;
4991
ret = CheckTokenMembership(NULL, token_groups->Groups[i].Sid, &is_member);
4992
ok(ret, "CheckTokenMembership failed with error %ld\n", GetLastError());
4993
ok(is_member, "CheckTokenMembership should have detected sid as member\n");
4994
4995
is_member = TRUE;
4996
SetLastError(0xdeadbeef);
4997
ret = CheckTokenMembership(process_token, token_groups->Groups[i].Sid, &is_member);
4998
ok(!ret && GetLastError() == ERROR_NO_IMPERSONATION_TOKEN,
4999
"CheckTokenMembership with process token %s with error %ld\n",
5000
ret ? "succeeded" : "failed", GetLastError());
5001
ok(!is_member, "CheckTokenMembership should have cleared is_member\n");
5002
5003
free(token_groups);
5004
CloseHandle(token);
5005
CloseHandle(process_token);
5006
}
5007
5008
static void test_EqualSid(void)
5009
{
5010
PSID sid1, sid2;
5011
BOOL ret;
5012
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
5013
SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY };
5014
5015
SetLastError(0xdeadbeef);
5016
ret = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
5017
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &sid1);
5018
if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
5019
{
5020
win_skip("AllocateAndInitializeSid is not implemented\n");
5021
return;
5022
}
5023
ok(ret, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
5024
ok(GetLastError() == 0xdeadbeef,
5025
"AllocateAndInitializeSid shouldn't have set last error to %ld\n",
5026
GetLastError());
5027
5028
ret = AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID,
5029
0, 0, 0, 0, 0, 0, 0, &sid2);
5030
ok(ret, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
5031
5032
SetLastError(0xdeadbeef);
5033
ret = EqualSid(sid1, sid2);
5034
ok(!ret, "World and domain admins sids shouldn't have been equal\n");
5035
ok(GetLastError() == ERROR_SUCCESS,
5036
"EqualSid should have set last error to ERROR_SUCCESS instead of %ld\n",
5037
GetLastError());
5038
5039
SetLastError(0xdeadbeef);
5040
sid2 = FreeSid(sid2);
5041
ok(!sid2, "FreeSid should have returned NULL instead of %p\n", sid2);
5042
ok(GetLastError() == 0xdeadbeef,
5043
"FreeSid shouldn't have set last error to %ld\n",
5044
GetLastError());
5045
5046
ret = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
5047
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &sid2);
5048
ok(ret, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
5049
5050
SetLastError(0xdeadbeef);
5051
ret = EqualSid(sid1, sid2);
5052
ok(ret, "Same sids should have been equal %s != %s\n",
5053
debugstr_sid(sid1), debugstr_sid(sid2));
5054
ok(GetLastError() == ERROR_SUCCESS,
5055
"EqualSid should have set last error to ERROR_SUCCESS instead of %ld\n",
5056
GetLastError());
5057
5058
((SID *)sid2)->Revision = 2;
5059
SetLastError(0xdeadbeef);
5060
ret = EqualSid(sid1, sid2);
5061
ok(!ret, "EqualSid with invalid sid should have returned FALSE\n");
5062
ok(GetLastError() == ERROR_SUCCESS,
5063
"EqualSid should have set last error to ERROR_SUCCESS instead of %ld\n",
5064
GetLastError());
5065
((SID *)sid2)->Revision = SID_REVISION;
5066
5067
FreeSid(sid1);
5068
FreeSid(sid2);
5069
}
5070
5071
static void test_GetUserNameA(void)
5072
{
5073
char buffer[UNLEN + 1], filler[UNLEN + 1];
5074
DWORD required_len, buffer_len;
5075
BOOL ret;
5076
5077
/* Test crashes on Windows. */
5078
if (0)
5079
{
5080
SetLastError(0xdeadbeef);
5081
GetUserNameA(NULL, NULL);
5082
}
5083
5084
SetLastError(0xdeadbeef);
5085
required_len = 0;
5086
ret = GetUserNameA(NULL, &required_len);
5087
ok(ret == FALSE, "GetUserNameA returned %d\n", ret);
5088
ok(required_len != 0, "Outputted buffer length was %lu\n", required_len);
5089
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError());
5090
5091
SetLastError(0xdeadbeef);
5092
required_len = 1;
5093
ret = GetUserNameA(NULL, &required_len);
5094
ok(ret == FALSE, "GetUserNameA returned %d\n", ret);
5095
ok(required_len != 0 && required_len != 1, "Outputted buffer length was %lu\n", required_len);
5096
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError());
5097
5098
/* Tests crashes on Windows. */
5099
if (0)
5100
{
5101
SetLastError(0xdeadbeef);
5102
required_len = UNLEN + 1;
5103
GetUserNameA(NULL, &required_len);
5104
5105
SetLastError(0xdeadbeef);
5106
GetUserNameA(buffer, NULL);
5107
}
5108
5109
memset(filler, 'x', sizeof(filler));
5110
5111
/* Note that GetUserNameA on XP and newer outputs the number of bytes
5112
* required for a Unicode string, which affects a test in the next block. */
5113
SetLastError(0xdeadbeef);
5114
memcpy(buffer, filler, sizeof(filler));
5115
required_len = 0;
5116
ret = GetUserNameA(buffer, &required_len);
5117
ok(ret == FALSE, "GetUserNameA returned %d\n", ret);
5118
ok(!memcmp(buffer, filler, sizeof(filler)), "Output buffer was altered\n");
5119
ok(required_len != 0, "Outputted buffer length was %lu\n", required_len);
5120
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError());
5121
5122
SetLastError(0xdeadbeef);
5123
memcpy(buffer, filler, sizeof(filler));
5124
buffer_len = required_len;
5125
ret = GetUserNameA(buffer, &buffer_len);
5126
ok(ret == TRUE, "GetUserNameA returned %d, last error %lu\n", ret, GetLastError());
5127
ok(memcmp(buffer, filler, sizeof(filler)) != 0, "Output buffer was untouched\n");
5128
ok(buffer_len == required_len ||
5129
broken(buffer_len == required_len / sizeof(WCHAR)), /* XP+ */
5130
"Outputted buffer length was %lu\n", buffer_len);
5131
ok(GetLastError() == 0xdeadbeef, "Last error was %lu\n", GetLastError());
5132
5133
/* Use the reported buffer size from the last GetUserNameA call and pass
5134
* a length that is one less than the required value. */
5135
SetLastError(0xdeadbeef);
5136
memcpy(buffer, filler, sizeof(filler));
5137
buffer_len--;
5138
ret = GetUserNameA(buffer, &buffer_len);
5139
ok(ret == FALSE, "GetUserNameA returned %d\n", ret);
5140
ok(!memcmp(buffer, filler, sizeof(filler)), "Output buffer was untouched\n");
5141
ok(buffer_len == required_len, "Outputted buffer length was %lu\n", buffer_len);
5142
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError());
5143
}
5144
5145
static void test_GetUserNameW(void)
5146
{
5147
WCHAR buffer[UNLEN + 1], filler[UNLEN + 1];
5148
DWORD required_len, buffer_len;
5149
BOOL ret;
5150
5151
/* Test crashes on Windows. */
5152
if (0)
5153
{
5154
SetLastError(0xdeadbeef);
5155
GetUserNameW(NULL, NULL);
5156
}
5157
5158
SetLastError(0xdeadbeef);
5159
required_len = 0;
5160
ret = GetUserNameW(NULL, &required_len);
5161
ok(ret == FALSE, "GetUserNameW returned %d\n", ret);
5162
ok(required_len != 0, "Outputted buffer length was %lu\n", required_len);
5163
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError());
5164
5165
SetLastError(0xdeadbeef);
5166
required_len = 1;
5167
ret = GetUserNameW(NULL, &required_len);
5168
ok(ret == FALSE, "GetUserNameW returned %d\n", ret);
5169
ok(required_len != 0 && required_len != 1, "Outputted buffer length was %lu\n", required_len);
5170
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError());
5171
5172
/* Tests crash on Windows. */
5173
if (0)
5174
{
5175
SetLastError(0xdeadbeef);
5176
required_len = UNLEN + 1;
5177
GetUserNameW(NULL, &required_len);
5178
5179
SetLastError(0xdeadbeef);
5180
GetUserNameW(buffer, NULL);
5181
}
5182
5183
memset(filler, 'x', sizeof(filler));
5184
5185
SetLastError(0xdeadbeef);
5186
memcpy(buffer, filler, sizeof(filler));
5187
required_len = 0;
5188
ret = GetUserNameW(buffer, &required_len);
5189
ok(ret == FALSE, "GetUserNameW returned %d\n", ret);
5190
ok(!memcmp(buffer, filler, sizeof(filler)), "Output buffer was altered\n");
5191
ok(required_len != 0, "Outputted buffer length was %lu\n", required_len);
5192
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError());
5193
5194
SetLastError(0xdeadbeef);
5195
memcpy(buffer, filler, sizeof(filler));
5196
buffer_len = required_len;
5197
ret = GetUserNameW(buffer, &buffer_len);
5198
ok(ret == TRUE, "GetUserNameW returned %d, last error %lu\n", ret, GetLastError());
5199
ok(memcmp(buffer, filler, sizeof(filler)) != 0, "Output buffer was untouched\n");
5200
ok(buffer_len == required_len, "Outputted buffer length was %lu\n", buffer_len);
5201
ok(GetLastError() == 0xdeadbeef, "Last error was %lu\n", GetLastError());
5202
5203
/* GetUserNameW on XP and newer writes a truncated portion of the username string to the buffer. */
5204
SetLastError(0xdeadbeef);
5205
memcpy(buffer, filler, sizeof(filler));
5206
buffer_len--;
5207
ret = GetUserNameW(buffer, &buffer_len);
5208
ok(ret == FALSE, "GetUserNameW returned %d\n", ret);
5209
ok(!memcmp(buffer, filler, sizeof(filler)) ||
5210
broken(memcmp(buffer, filler, sizeof(filler)) != 0), /* XP+ */
5211
"Output buffer was altered\n");
5212
ok(buffer_len == required_len, "Outputted buffer length was %lu\n", buffer_len);
5213
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Last error was %lu\n", GetLastError());
5214
}
5215
5216
static void test_CreateRestrictedToken(void)
5217
{
5218
HANDLE process_token, token, r_token;
5219
PTOKEN_GROUPS token_groups, groups2;
5220
LUID_AND_ATTRIBUTES lattr;
5221
SID_AND_ATTRIBUTES sattr;
5222
SECURITY_IMPERSONATION_LEVEL level;
5223
SID *removed_sid = NULL;
5224
char privs_buffer[1000];
5225
TOKEN_PRIVILEGES *privs = (TOKEN_PRIVILEGES *)privs_buffer;
5226
PRIVILEGE_SET priv_set;
5227
TOKEN_TYPE type;
5228
BOOL is_member;
5229
DWORD size;
5230
LUID luid = { 0, 0 };
5231
BOOL ret;
5232
DWORD i;
5233
5234
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &process_token);
5235
ok(ret, "got error %ld\n", GetLastError());
5236
5237
ret = DuplicateTokenEx(process_token, TOKEN_DUPLICATE|TOKEN_ADJUST_GROUPS|TOKEN_QUERY,
5238
NULL, SecurityImpersonation, TokenImpersonation, &token);
5239
ok(ret, "got error %ld\n", GetLastError());
5240
5241
ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
5242
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
5243
"got %d with error %ld\n", ret, GetLastError());
5244
token_groups = malloc(size);
5245
ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
5246
ok(ret, "got error %ld\n", GetLastError());
5247
5248
for (i = 0; i < token_groups->GroupCount; i++)
5249
{
5250
if (token_groups->Groups[i].Attributes & SE_GROUP_ENABLED)
5251
{
5252
removed_sid = token_groups->Groups[i].Sid;
5253
break;
5254
}
5255
}
5256
ok(!!removed_sid, "user is not a member of any group\n");
5257
5258
is_member = FALSE;
5259
ret = CheckTokenMembership(token, removed_sid, &is_member);
5260
ok(ret, "got error %ld\n", GetLastError());
5261
ok(is_member, "not a member\n");
5262
5263
sattr.Sid = removed_sid;
5264
sattr.Attributes = 0;
5265
r_token = NULL;
5266
ret = CreateRestrictedToken(token, 0, 1, &sattr, 0, NULL, 0, NULL, &r_token);
5267
ok(ret, "got error %ld\n", GetLastError());
5268
5269
is_member = TRUE;
5270
ret = CheckTokenMembership(r_token, removed_sid, &is_member);
5271
ok(ret, "got error %ld\n", GetLastError());
5272
ok(!is_member, "not a member\n");
5273
5274
ret = GetTokenInformation(r_token, TokenGroups, NULL, 0, &size);
5275
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %ld\n",
5276
ret, GetLastError());
5277
groups2 = malloc(size);
5278
ret = GetTokenInformation(r_token, TokenGroups, groups2, size, &size);
5279
ok(ret, "got error %ld\n", GetLastError());
5280
5281
for (i = 0; i < groups2->GroupCount; i++)
5282
{
5283
if (EqualSid(groups2->Groups[i].Sid, removed_sid))
5284
{
5285
DWORD attr = groups2->Groups[i].Attributes;
5286
ok(attr & SE_GROUP_USE_FOR_DENY_ONLY, "got wrong attributes %#lx\n", attr);
5287
ok(!(attr & SE_GROUP_ENABLED), "got wrong attributes %#lx\n", attr);
5288
break;
5289
}
5290
}
5291
5292
free(groups2);
5293
5294
size = sizeof(type);
5295
ret = GetTokenInformation(r_token, TokenType, &type, size, &size);
5296
ok(ret, "got error %ld\n", GetLastError());
5297
ok(type == TokenImpersonation, "got type %u\n", type);
5298
5299
size = sizeof(level);
5300
ret = GetTokenInformation(r_token, TokenImpersonationLevel, &level, size, &size);
5301
ok(ret, "got error %ld\n", GetLastError());
5302
ok(level == SecurityImpersonation, "got level %u\n", type);
5303
5304
CloseHandle(r_token);
5305
5306
r_token = NULL;
5307
ret = CreateRestrictedToken(process_token, 0, 1, &sattr, 0, NULL, 0, NULL, &r_token);
5308
ok(ret, "got error %lu\n", GetLastError());
5309
5310
size = sizeof(type);
5311
ret = GetTokenInformation(r_token, TokenType, &type, size, &size);
5312
ok(ret, "got error %lu\n", GetLastError());
5313
ok(type == TokenPrimary, "got type %u\n", type);
5314
5315
CloseHandle(r_token);
5316
5317
ret = GetTokenInformation(token, TokenPrivileges, privs, sizeof(privs_buffer), &size);
5318
ok(ret, "got error %lu\n", GetLastError());
5319
5320
for (i = 0; i < privs->PrivilegeCount; i++)
5321
{
5322
if (privs->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED)
5323
{
5324
luid = privs->Privileges[i].Luid;
5325
break;
5326
}
5327
}
5328
ok(i < privs->PrivilegeCount, "user has no privileges\n");
5329
5330
lattr.Luid = luid;
5331
lattr.Attributes = 0;
5332
r_token = NULL;
5333
ret = CreateRestrictedToken(token, 0, 0, NULL, 1, &lattr, 0, NULL, &r_token);
5334
ok(ret, "got error %lu\n", GetLastError());
5335
5336
priv_set.PrivilegeCount = 1;
5337
priv_set.Control = 0;
5338
priv_set.Privilege[0].Luid = luid;
5339
priv_set.Privilege[0].Attributes = 0;
5340
ret = PrivilegeCheck(r_token, &priv_set, &is_member);
5341
ok(ret, "got error %lu\n", GetLastError());
5342
ok(!is_member, "privilege should not be enabled\n");
5343
5344
ret = GetTokenInformation(r_token, TokenPrivileges, privs, sizeof(privs_buffer), &size);
5345
ok(ret, "got error %lu\n", GetLastError());
5346
5347
is_member = FALSE;
5348
for (i = 0; i < privs->PrivilegeCount; i++)
5349
{
5350
if (!memcmp(&privs->Privileges[i].Luid, &luid, sizeof(luid)))
5351
is_member = TRUE;
5352
}
5353
ok(!is_member, "disabled privilege should not be present\n");
5354
5355
CloseHandle(r_token);
5356
5357
removed_sid->SubAuthority[0] = 0xdeadbeef;
5358
lattr.Luid.LowPart = 0xdeadbeef;
5359
r_token = NULL;
5360
ret = CreateRestrictedToken(token, 0, 1, &sattr, 1, &lattr, 0, NULL, &r_token);
5361
ok(ret, "got error %lu\n", GetLastError());
5362
CloseHandle(r_token);
5363
5364
free(token_groups);
5365
CloseHandle(token);
5366
CloseHandle(process_token);
5367
}
5368
5369
static void validate_default_security_descriptor(SECURITY_DESCRIPTOR *sd)
5370
{
5371
BOOL ret, present, defaulted;
5372
ACL *acl;
5373
void *sid;
5374
5375
ret = IsValidSecurityDescriptor(sd);
5376
ok(ret, "security descriptor is not valid\n");
5377
5378
present = -1;
5379
defaulted = -1;
5380
acl = (void *)0xdeadbeef;
5381
SetLastError(0xdeadbeef);
5382
ret = GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted);
5383
ok(ret, "GetSecurityDescriptorDacl error %ld\n", GetLastError());
5384
todo_wine
5385
ok(present == 1, "acl is not present\n");
5386
todo_wine
5387
ok(acl != (void *)0xdeadbeef && acl != NULL, "acl pointer is not set\n");
5388
ok(defaulted == 0, "defaulted is set to TRUE\n");
5389
5390
defaulted = -1;
5391
sid = (void *)0xdeadbeef;
5392
SetLastError(0xdeadbeef);
5393
ret = GetSecurityDescriptorOwner(sd, &sid, &defaulted);
5394
ok(ret, "GetSecurityDescriptorOwner error %ld\n", GetLastError());
5395
todo_wine
5396
ok(sid != (void *)0xdeadbeef && sid != NULL, "sid pointer is not set\n");
5397
ok(defaulted == 0, "defaulted is set to TRUE\n");
5398
5399
defaulted = -1;
5400
sid = (void *)0xdeadbeef;
5401
SetLastError(0xdeadbeef);
5402
ret = GetSecurityDescriptorGroup(sd, &sid, &defaulted);
5403
ok(ret, "GetSecurityDescriptorGroup error %ld\n", GetLastError());
5404
todo_wine
5405
ok(sid != (void *)0xdeadbeef && sid != NULL, "sid pointer is not set\n");
5406
ok(defaulted == 0, "defaulted is set to TRUE\n");
5407
}
5408
5409
static void test_default_handle_security(HANDLE token, HANDLE handle, GENERIC_MAPPING *mapping)
5410
{
5411
DWORD ret, granted, priv_set_len;
5412
BOOL status;
5413
PRIVILEGE_SET priv_set;
5414
SECURITY_DESCRIPTOR *sd;
5415
5416
sd = test_get_security_descriptor(handle, __LINE__);
5417
validate_default_security_descriptor(sd);
5418
5419
priv_set_len = sizeof(priv_set);
5420
granted = 0xdeadbeef;
5421
status = 0xdeadbeef;
5422
SetLastError(0xdeadbeef);
5423
ret = AccessCheck(sd, token, MAXIMUM_ALLOWED, mapping, &priv_set, &priv_set_len, &granted, &status);
5424
todo_wine {
5425
ok(ret, "AccessCheck error %ld\n", GetLastError());
5426
ok(status == 1, "expected 1, got %d\n", status);
5427
ok(granted == mapping->GenericAll, "expected all access %#lx, got %#lx\n", mapping->GenericAll, granted);
5428
}
5429
priv_set_len = sizeof(priv_set);
5430
granted = 0xdeadbeef;
5431
status = 0xdeadbeef;
5432
SetLastError(0xdeadbeef);
5433
ret = AccessCheck(sd, token, 0, mapping, &priv_set, &priv_set_len, &granted, &status);
5434
todo_wine {
5435
ok(ret, "AccessCheck error %ld\n", GetLastError());
5436
ok(status == 0, "expected 0, got %d\n", status);
5437
ok(granted == 0, "expected 0, got %#lx\n", granted);
5438
}
5439
priv_set_len = sizeof(priv_set);
5440
granted = 0xdeadbeef;
5441
status = 0xdeadbeef;
5442
SetLastError(0xdeadbeef);
5443
ret = AccessCheck(sd, token, ACCESS_SYSTEM_SECURITY, mapping, &priv_set, &priv_set_len, &granted, &status);
5444
todo_wine {
5445
ok(ret, "AccessCheck error %ld\n", GetLastError());
5446
ok(status == 0, "expected 0, got %d\n", status);
5447
ok(granted == 0, "expected 0, got %#lx\n", granted);
5448
}
5449
priv_set_len = sizeof(priv_set);
5450
granted = 0xdeadbeef;
5451
status = 0xdeadbeef;
5452
SetLastError(0xdeadbeef);
5453
ret = AccessCheck(sd, token, mapping->GenericRead, mapping, &priv_set, &priv_set_len, &granted, &status);
5454
todo_wine {
5455
ok(ret, "AccessCheck error %ld\n", GetLastError());
5456
ok(status == 1, "expected 1, got %d\n", status);
5457
ok(granted == mapping->GenericRead, "expected read access %#lx, got %#lx\n", mapping->GenericRead, granted);
5458
}
5459
priv_set_len = sizeof(priv_set);
5460
granted = 0xdeadbeef;
5461
status = 0xdeadbeef;
5462
SetLastError(0xdeadbeef);
5463
ret = AccessCheck(sd, token, mapping->GenericWrite, mapping, &priv_set, &priv_set_len, &granted, &status);
5464
todo_wine {
5465
ok(ret, "AccessCheck error %ld\n", GetLastError());
5466
ok(status == 1, "expected 1, got %d\n", status);
5467
ok(granted == mapping->GenericWrite, "expected write access %#lx, got %#lx\n", mapping->GenericWrite, granted);
5468
}
5469
priv_set_len = sizeof(priv_set);
5470
granted = 0xdeadbeef;
5471
status = 0xdeadbeef;
5472
SetLastError(0xdeadbeef);
5473
ret = AccessCheck(sd, token, mapping->GenericExecute, mapping, &priv_set, &priv_set_len, &granted, &status);
5474
todo_wine {
5475
ok(ret, "AccessCheck error %ld\n", GetLastError());
5476
ok(status == 1, "expected 1, got %d\n", status);
5477
ok(granted == mapping->GenericExecute, "expected execute access %#lx, got %#lx\n", mapping->GenericExecute, granted);
5478
}
5479
free(sd);
5480
}
5481
5482
static ACCESS_MASK get_obj_access(HANDLE obj)
5483
{
5484
OBJECT_BASIC_INFORMATION info;
5485
NTSTATUS status;
5486
5487
status = NtQueryObject(obj, ObjectBasicInformation, &info, sizeof(info), NULL);
5488
ok(!status, "NtQueryObject error %#lx\n", status);
5489
5490
return info.GrantedAccess;
5491
}
5492
5493
static void test_mutex_security(HANDLE token)
5494
{
5495
DWORD ret, i, access;
5496
HANDLE mutex, dup;
5497
GENERIC_MAPPING mapping = { STANDARD_RIGHTS_READ | MUTANT_QUERY_STATE | SYNCHRONIZE,
5498
STANDARD_RIGHTS_WRITE | MUTEX_MODIFY_STATE | SYNCHRONIZE,
5499
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
5500
STANDARD_RIGHTS_ALL | MUTEX_ALL_ACCESS };
5501
static const struct
5502
{
5503
int generic, mapped;
5504
} map[] =
5505
{
5506
{ 0, 0 },
5507
{ GENERIC_READ, STANDARD_RIGHTS_READ | MUTANT_QUERY_STATE },
5508
{ GENERIC_WRITE, STANDARD_RIGHTS_WRITE },
5509
{ GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE },
5510
{ GENERIC_ALL, STANDARD_RIGHTS_ALL | MUTANT_QUERY_STATE }
5511
};
5512
5513
SetLastError(0xdeadbeef);
5514
mutex = OpenMutexA(0, FALSE, "WineTestMutex");
5515
ok(!mutex, "mutex should not exist\n");
5516
ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %lu\n", GetLastError());
5517
5518
SetLastError(0xdeadbeef);
5519
mutex = CreateMutexA(NULL, FALSE, "WineTestMutex");
5520
ok(mutex != 0, "CreateMutex error %ld\n", GetLastError());
5521
5522
access = get_obj_access(mutex);
5523
ok(access == MUTANT_ALL_ACCESS, "expected MUTANT_ALL_ACCESS, got %#lx\n", access);
5524
5525
for (i = 0; i < ARRAY_SIZE(map); i++)
5526
{
5527
SetLastError( 0xdeadbeef );
5528
ret = DuplicateHandle(GetCurrentProcess(), mutex, GetCurrentProcess(), &dup,
5529
map[i].generic, FALSE, 0);
5530
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
5531
5532
access = get_obj_access(dup);
5533
ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
5534
5535
CloseHandle(dup);
5536
5537
SetLastError(0xdeadbeef);
5538
dup = OpenMutexA(0, FALSE, "WineTestMutex");
5539
ok(!dup, "OpenMutex should fail\n");
5540
ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %lu\n", GetLastError());
5541
}
5542
5543
test_default_handle_security(token, mutex, &mapping);
5544
5545
CloseHandle (mutex);
5546
}
5547
5548
static void test_event_security(HANDLE token)
5549
{
5550
DWORD ret, i, access;
5551
HANDLE event, dup;
5552
GENERIC_MAPPING mapping = { STANDARD_RIGHTS_READ | EVENT_QUERY_STATE | SYNCHRONIZE,
5553
STANDARD_RIGHTS_WRITE | EVENT_MODIFY_STATE | SYNCHRONIZE,
5554
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
5555
STANDARD_RIGHTS_ALL | EVENT_ALL_ACCESS };
5556
static const struct
5557
{
5558
int generic, mapped;
5559
} map[] =
5560
{
5561
{ 0, 0 },
5562
{ GENERIC_READ, STANDARD_RIGHTS_READ | EVENT_QUERY_STATE },
5563
{ GENERIC_WRITE, STANDARD_RIGHTS_WRITE | EVENT_MODIFY_STATE },
5564
{ GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE },
5565
{ GENERIC_ALL, STANDARD_RIGHTS_ALL | EVENT_QUERY_STATE | EVENT_MODIFY_STATE }
5566
};
5567
5568
SetLastError(0xdeadbeef);
5569
event = OpenEventA(0, FALSE, "WineTestEvent");
5570
ok(!event, "event should not exist\n");
5571
ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %lu\n", GetLastError());
5572
5573
SetLastError(0xdeadbeef);
5574
event = CreateEventA(NULL, FALSE, FALSE, "WineTestEvent");
5575
ok(event != 0, "CreateEvent error %ld\n", GetLastError());
5576
5577
access = get_obj_access(event);
5578
ok(access == EVENT_ALL_ACCESS, "expected EVENT_ALL_ACCESS, got %#lx\n", access);
5579
5580
for (i = 0; i < ARRAY_SIZE(map); i++)
5581
{
5582
SetLastError( 0xdeadbeef );
5583
ret = DuplicateHandle(GetCurrentProcess(), event, GetCurrentProcess(), &dup,
5584
map[i].generic, FALSE, 0);
5585
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
5586
5587
access = get_obj_access(dup);
5588
ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
5589
5590
CloseHandle(dup);
5591
5592
SetLastError(0xdeadbeef);
5593
dup = OpenEventA(0, FALSE, "WineTestEvent");
5594
ok(!dup, "OpenEvent should fail\n");
5595
ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %lu\n", GetLastError());
5596
}
5597
5598
test_default_handle_security(token, event, &mapping);
5599
5600
CloseHandle(event);
5601
}
5602
5603
static void test_semaphore_security(HANDLE token)
5604
{
5605
DWORD ret, i, access;
5606
HANDLE sem, dup;
5607
GENERIC_MAPPING mapping = { STANDARD_RIGHTS_READ | SEMAPHORE_QUERY_STATE,
5608
STANDARD_RIGHTS_WRITE | SEMAPHORE_MODIFY_STATE,
5609
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
5610
STANDARD_RIGHTS_ALL | SEMAPHORE_ALL_ACCESS };
5611
static const struct
5612
{
5613
int generic, mapped;
5614
} map[] =
5615
{
5616
{ 0, 0 },
5617
{ GENERIC_READ, STANDARD_RIGHTS_READ | SEMAPHORE_QUERY_STATE },
5618
{ GENERIC_WRITE, STANDARD_RIGHTS_WRITE | SEMAPHORE_MODIFY_STATE },
5619
{ GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE },
5620
{ GENERIC_ALL, STANDARD_RIGHTS_ALL | SEMAPHORE_QUERY_STATE | SEMAPHORE_MODIFY_STATE }
5621
};
5622
5623
SetLastError(0xdeadbeef);
5624
sem = OpenSemaphoreA(0, FALSE, "WineTestSemaphore");
5625
ok(!sem, "semaphore should not exist\n");
5626
ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %lu\n", GetLastError());
5627
5628
SetLastError(0xdeadbeef);
5629
sem = CreateSemaphoreA(NULL, 0, 10, "WineTestSemaphore");
5630
ok(sem != 0, "CreateSemaphore error %ld\n", GetLastError());
5631
5632
access = get_obj_access(sem);
5633
ok(access == SEMAPHORE_ALL_ACCESS, "expected SEMAPHORE_ALL_ACCESS, got %#lx\n", access);
5634
5635
for (i = 0; i < ARRAY_SIZE(map); i++)
5636
{
5637
SetLastError( 0xdeadbeef );
5638
ret = DuplicateHandle(GetCurrentProcess(), sem, GetCurrentProcess(), &dup,
5639
map[i].generic, FALSE, 0);
5640
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
5641
5642
access = get_obj_access(dup);
5643
ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
5644
5645
CloseHandle(dup);
5646
}
5647
5648
test_default_handle_security(token, sem, &mapping);
5649
5650
CloseHandle(sem);
5651
}
5652
5653
#define WINE_TEST_PIPE "\\\\.\\pipe\\WineTestPipe"
5654
static void test_named_pipe_security(HANDLE token)
5655
{
5656
DWORD ret, i, access;
5657
HANDLE pipe, file, dup;
5658
GENERIC_MAPPING mapping = { FILE_GENERIC_READ,
5659
FILE_GENERIC_WRITE,
5660
FILE_GENERIC_EXECUTE,
5661
STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS };
5662
static const struct
5663
{
5664
int generic, mapped;
5665
} map[] =
5666
{
5667
{ 0, 0 },
5668
{ GENERIC_READ, FILE_GENERIC_READ },
5669
{ GENERIC_WRITE, FILE_GENERIC_WRITE },
5670
{ GENERIC_EXECUTE, FILE_GENERIC_EXECUTE },
5671
{ GENERIC_ALL, STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS }
5672
};
5673
static const struct
5674
{
5675
DWORD open_mode;
5676
DWORD access;
5677
} creation_access[] =
5678
{
5679
{ PIPE_ACCESS_INBOUND, FILE_GENERIC_READ },
5680
{ PIPE_ACCESS_OUTBOUND, FILE_GENERIC_WRITE },
5681
{ PIPE_ACCESS_DUPLEX, FILE_GENERIC_READ|FILE_GENERIC_WRITE },
5682
{ PIPE_ACCESS_INBOUND|WRITE_DAC, FILE_GENERIC_READ|WRITE_DAC },
5683
{ PIPE_ACCESS_INBOUND|WRITE_OWNER, FILE_GENERIC_READ|WRITE_OWNER }
5684
/* ACCESS_SYSTEM_SECURITY is also valid, but will fail with ERROR_PRIVILEGE_NOT_HELD */
5685
};
5686
5687
/* Test the different security access options for pipes */
5688
for (i = 0; i < ARRAY_SIZE(creation_access); i++)
5689
{
5690
SetLastError(0xdeadbeef);
5691
pipe = CreateNamedPipeA(WINE_TEST_PIPE, creation_access[i].open_mode,
5692
PIPE_TYPE_BYTE | PIPE_NOWAIT, PIPE_UNLIMITED_INSTANCES, 0, 0,
5693
NMPWAIT_USE_DEFAULT_WAIT, NULL);
5694
ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe(0x%lx) error %ld\n",
5695
creation_access[i].open_mode, GetLastError());
5696
access = get_obj_access(pipe);
5697
ok(access == creation_access[i].access,
5698
"CreateNamedPipeA(0x%lx) pipe expected access 0x%lx (got 0x%lx)\n",
5699
creation_access[i].open_mode, creation_access[i].access, access);
5700
CloseHandle(pipe);
5701
}
5702
5703
SetLastError(0xdeadbeef);
5704
pipe = CreateNamedPipeA(WINE_TEST_PIPE, PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
5705
PIPE_TYPE_BYTE | PIPE_NOWAIT, PIPE_UNLIMITED_INSTANCES,
5706
0, 0, NMPWAIT_USE_DEFAULT_WAIT, NULL);
5707
ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe error %ld\n", GetLastError());
5708
5709
test_default_handle_security(token, pipe, &mapping);
5710
5711
SetLastError(0xdeadbeef);
5712
file = CreateFileA(WINE_TEST_PIPE, FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING, 0, 0);
5713
ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
5714
5715
access = get_obj_access(file);
5716
ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#lx\n", access);
5717
5718
for (i = 0; i < ARRAY_SIZE(map); i++)
5719
{
5720
SetLastError( 0xdeadbeef );
5721
ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup,
5722
map[i].generic, FALSE, 0);
5723
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
5724
5725
access = get_obj_access(dup);
5726
ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
5727
5728
CloseHandle(dup);
5729
}
5730
5731
CloseHandle(file);
5732
CloseHandle(pipe);
5733
5734
SetLastError(0xdeadbeef);
5735
file = CreateFileA("\\\\.\\pipe\\", FILE_ALL_ACCESS, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
5736
ok(file != INVALID_HANDLE_VALUE || broken(file == INVALID_HANDLE_VALUE) /* before Vista */, "CreateFile error %ld\n", GetLastError());
5737
5738
if (file != INVALID_HANDLE_VALUE)
5739
{
5740
access = get_obj_access(file);
5741
ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#lx\n", access);
5742
5743
for (i = 0; i < ARRAY_SIZE(map); i++)
5744
{
5745
SetLastError( 0xdeadbeef );
5746
ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup,
5747
map[i].generic, FALSE, 0);
5748
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
5749
5750
access = get_obj_access(dup);
5751
ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
5752
CloseHandle(dup);
5753
}
5754
}
5755
5756
CloseHandle(file);
5757
}
5758
5759
static void test_file_security(HANDLE token)
5760
{
5761
DWORD ret, i, access, bytes;
5762
HANDLE file, dup;
5763
static const struct
5764
{
5765
int generic, mapped;
5766
} map[] =
5767
{
5768
{ 0, 0 },
5769
{ GENERIC_READ, FILE_GENERIC_READ },
5770
{ GENERIC_WRITE, FILE_GENERIC_WRITE },
5771
{ GENERIC_EXECUTE, FILE_GENERIC_EXECUTE },
5772
{ GENERIC_ALL, STANDARD_RIGHTS_ALL | FILE_ALL_ACCESS }
5773
};
5774
char temp_path[MAX_PATH];
5775
char file_name[MAX_PATH];
5776
char buf[16];
5777
5778
GetTempPathA(MAX_PATH, temp_path);
5779
GetTempFileNameA(temp_path, "tmp", 0, file_name);
5780
5781
/* file */
5782
SetLastError(0xdeadbeef);
5783
file = CreateFileA(file_name, GENERIC_ALL, 0, NULL, CREATE_ALWAYS, 0, NULL);
5784
ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
5785
5786
access = get_obj_access(file);
5787
ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#lx\n", access);
5788
5789
for (i = 0; i < ARRAY_SIZE(map); i++)
5790
{
5791
SetLastError( 0xdeadbeef );
5792
ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup,
5793
map[i].generic, FALSE, 0);
5794
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
5795
5796
access = get_obj_access(dup);
5797
ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
5798
5799
CloseHandle(dup);
5800
}
5801
5802
CloseHandle(file);
5803
5804
SetLastError(0xdeadbeef);
5805
file = CreateFileA(file_name, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
5806
ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
5807
5808
access = get_obj_access(file);
5809
ok(access == (FILE_READ_ATTRIBUTES | SYNCHRONIZE), "expected FILE_READ_ATTRIBUTES | SYNCHRONIZE, got %#lx\n", access);
5810
5811
bytes = 0xdeadbeef;
5812
SetLastError(0xdeadbeef);
5813
ret = ReadFile(file, buf, sizeof(buf), &bytes, NULL);
5814
ok(!ret, "ReadFile should fail\n");
5815
ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
5816
ok(bytes == 0, "expected 0, got %lu\n", bytes);
5817
5818
CloseHandle(file);
5819
5820
SetLastError(0xdeadbeef);
5821
file = CreateFileA(file_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
5822
ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
5823
5824
access = get_obj_access(file);
5825
ok(access == (FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES), "expected FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES, got %#lx\n", access);
5826
5827
bytes = 0xdeadbeef;
5828
SetLastError(0xdeadbeef);
5829
ret = ReadFile(file, buf, sizeof(buf), &bytes, NULL);
5830
ok(!ret, "ReadFile should fail\n");
5831
ok(GetLastError() == ERROR_ACCESS_DENIED, "expected ERROR_ACCESS_DENIED, got %ld\n", GetLastError());
5832
ok(bytes == 0, "expected 0, got %lu\n", bytes);
5833
5834
CloseHandle(file);
5835
DeleteFileA(file_name);
5836
5837
/* directory */
5838
SetLastError(0xdeadbeef);
5839
file = CreateFileA(temp_path, GENERIC_ALL, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
5840
ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
5841
5842
access = get_obj_access(file);
5843
ok(access == FILE_ALL_ACCESS, "expected FILE_ALL_ACCESS, got %#lx\n", access);
5844
5845
for (i = 0; i < ARRAY_SIZE(map); i++)
5846
{
5847
SetLastError( 0xdeadbeef );
5848
ret = DuplicateHandle(GetCurrentProcess(), file, GetCurrentProcess(), &dup,
5849
map[i].generic, FALSE, 0);
5850
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
5851
5852
access = get_obj_access(dup);
5853
ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
5854
5855
CloseHandle(dup);
5856
}
5857
5858
CloseHandle(file);
5859
5860
SetLastError(0xdeadbeef);
5861
file = CreateFileA(temp_path, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
5862
ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
5863
5864
access = get_obj_access(file);
5865
ok(access == (FILE_READ_ATTRIBUTES | SYNCHRONIZE), "expected FILE_READ_ATTRIBUTES | SYNCHRONIZE, got %#lx\n", access);
5866
5867
CloseHandle(file);
5868
5869
SetLastError(0xdeadbeef);
5870
file = CreateFileA(temp_path, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
5871
ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
5872
5873
access = get_obj_access(file);
5874
ok(access == (FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES), "expected FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES, got %#lx\n", access);
5875
5876
CloseHandle(file);
5877
}
5878
5879
static void test_filemap_security(void)
5880
{
5881
char temp_path[MAX_PATH];
5882
char file_name[MAX_PATH];
5883
DWORD ret, i, access;
5884
HANDLE file, mapping, dup, created_mapping;
5885
static const struct
5886
{
5887
int generic, mapped;
5888
BOOL open_only;
5889
} map[] =
5890
{
5891
{ 0, 0 },
5892
{ GENERIC_READ, STANDARD_RIGHTS_READ | SECTION_QUERY | SECTION_MAP_READ },
5893
{ GENERIC_WRITE, STANDARD_RIGHTS_WRITE | SECTION_MAP_WRITE },
5894
{ GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SECTION_MAP_EXECUTE },
5895
{ GENERIC_ALL, STANDARD_RIGHTS_REQUIRED | SECTION_ALL_ACCESS },
5896
{ SECTION_MAP_READ | SECTION_MAP_WRITE, SECTION_MAP_READ | SECTION_MAP_WRITE },
5897
{ SECTION_MAP_WRITE, SECTION_MAP_WRITE },
5898
{ SECTION_MAP_READ | SECTION_QUERY, SECTION_MAP_READ | SECTION_QUERY },
5899
{ SECTION_QUERY, SECTION_MAP_READ, TRUE },
5900
{ SECTION_QUERY | SECTION_MAP_READ, SECTION_QUERY | SECTION_MAP_READ }
5901
};
5902
static const struct
5903
{
5904
int prot, mapped;
5905
} prot_map[] =
5906
{
5907
{ 0, 0 },
5908
{ PAGE_NOACCESS, 0 },
5909
{ PAGE_READONLY, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ },
5910
{ PAGE_READWRITE, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE },
5911
{ PAGE_WRITECOPY, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ },
5912
{ PAGE_EXECUTE, 0 },
5913
{ PAGE_EXECUTE_READ, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_EXECUTE },
5914
{ PAGE_EXECUTE_READWRITE, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE },
5915
{ PAGE_EXECUTE_WRITECOPY, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_EXECUTE }
5916
};
5917
5918
GetTempPathA(MAX_PATH, temp_path);
5919
GetTempFileNameA(temp_path, "tmp", 0, file_name);
5920
5921
SetLastError(0xdeadbeef);
5922
file = CreateFileA(file_name, GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE, 0, NULL, CREATE_ALWAYS, 0, 0);
5923
ok(file != INVALID_HANDLE_VALUE, "CreateFile error %ld\n", GetLastError());
5924
SetFilePointer(file, 4096, NULL, FILE_BEGIN);
5925
SetEndOfFile(file);
5926
5927
for (i = 0; i < ARRAY_SIZE(prot_map); i++)
5928
{
5929
if (map[i].open_only) continue;
5930
5931
SetLastError(0xdeadbeef);
5932
mapping = CreateFileMappingW(file, NULL, prot_map[i].prot, 0, 4096, NULL);
5933
if (prot_map[i].mapped)
5934
{
5935
ok(mapping != 0, "CreateFileMapping(%04x) error %ld\n", prot_map[i].prot, GetLastError());
5936
}
5937
else
5938
{
5939
ok(!mapping, "CreateFileMapping(%04x) should fail\n", prot_map[i].prot);
5940
ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
5941
continue;
5942
}
5943
5944
access = get_obj_access(mapping);
5945
ok(access == prot_map[i].mapped, "%ld: expected %#x, got %#lx\n", i, prot_map[i].mapped, access);
5946
5947
CloseHandle(mapping);
5948
}
5949
5950
SetLastError(0xdeadbeef);
5951
mapping = CreateFileMappingW(file, NULL, PAGE_EXECUTE_READWRITE, 0, 4096, NULL);
5952
ok(mapping != 0, "CreateFileMapping error %ld\n", GetLastError());
5953
5954
access = get_obj_access(mapping);
5955
ok(access == (STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE),
5956
"expected STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE, got %#lx\n", access);
5957
5958
for (i = 0; i < ARRAY_SIZE(map); i++)
5959
{
5960
if (map[i].open_only) continue;
5961
5962
SetLastError( 0xdeadbeef );
5963
ret = DuplicateHandle(GetCurrentProcess(), mapping, GetCurrentProcess(), &dup,
5964
map[i].generic, FALSE, 0);
5965
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
5966
5967
access = get_obj_access(dup);
5968
ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
5969
5970
CloseHandle(dup);
5971
}
5972
5973
CloseHandle(mapping);
5974
CloseHandle(file);
5975
DeleteFileA(file_name);
5976
5977
created_mapping = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 0x1000,
5978
"Wine Test Open Mapping");
5979
ok(created_mapping != NULL, "CreateFileMapping failed with error %lu\n", GetLastError());
5980
5981
for (i = 0; i < ARRAY_SIZE(map); i++)
5982
{
5983
if (!map[i].generic) continue;
5984
5985
mapping = OpenFileMappingA(map[i].generic, FALSE, "Wine Test Open Mapping");
5986
ok(mapping != NULL, "OpenFileMapping failed with error %ld\n", GetLastError());
5987
access = get_obj_access(mapping);
5988
ok(access == map[i].mapped, "%ld: unexpected access flags %#lx, expected %#x\n",
5989
i, access, map[i].mapped);
5990
CloseHandle(mapping);
5991
}
5992
5993
CloseHandle(created_mapping);
5994
}
5995
5996
static void test_thread_security(void)
5997
{
5998
DWORD ret, i, access;
5999
HANDLE thread, dup;
6000
static const struct
6001
{
6002
int generic, mapped;
6003
} map[] =
6004
{
6005
{ 0, 0 },
6006
{ GENERIC_READ, STANDARD_RIGHTS_READ | THREAD_QUERY_INFORMATION | THREAD_GET_CONTEXT },
6007
{ GENERIC_WRITE, STANDARD_RIGHTS_WRITE | THREAD_SET_INFORMATION | THREAD_SET_CONTEXT | THREAD_TERMINATE | THREAD_SUSPEND_RESUME | 0x4 },
6008
{ GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE },
6009
{ GENERIC_ALL, THREAD_ALL_ACCESS_NT4 }
6010
};
6011
6012
SetLastError(0xdeadbeef);
6013
thread = CreateThread(NULL, 0, (void *)0xdeadbeef, NULL, CREATE_SUSPENDED, &ret);
6014
ok(thread != 0, "CreateThread error %ld\n", GetLastError());
6015
6016
access = get_obj_access(thread);
6017
ok(access == THREAD_ALL_ACCESS_NT4 || access == THREAD_ALL_ACCESS_VISTA, "expected THREAD_ALL_ACCESS, got %#lx\n", access);
6018
6019
for (i = 0; i < ARRAY_SIZE(map); i++)
6020
{
6021
SetLastError( 0xdeadbeef );
6022
ret = DuplicateHandle(GetCurrentProcess(), thread, GetCurrentProcess(), &dup,
6023
map[i].generic, FALSE, 0);
6024
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
6025
6026
access = get_obj_access(dup);
6027
switch (map[i].generic)
6028
{
6029
case GENERIC_READ:
6030
case GENERIC_EXECUTE:
6031
ok(access == map[i].mapped ||
6032
access == (map[i].mapped | THREAD_QUERY_LIMITED_INFORMATION) /* Vista+ */ ||
6033
access == (map[i].mapped | THREAD_QUERY_LIMITED_INFORMATION | THREAD_RESUME) /* win8 */,
6034
"%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
6035
break;
6036
case GENERIC_WRITE:
6037
ok(access == map[i].mapped ||
6038
access == (map[i].mapped | THREAD_SET_LIMITED_INFORMATION) /* Vista+ */ ||
6039
access == (map[i].mapped | THREAD_SET_LIMITED_INFORMATION | THREAD_RESUME) /* win8 */,
6040
"%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
6041
break;
6042
case GENERIC_ALL:
6043
ok(access == map[i].mapped || access == THREAD_ALL_ACCESS_VISTA,
6044
"%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
6045
break;
6046
default:
6047
ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
6048
break;
6049
}
6050
6051
CloseHandle(dup);
6052
}
6053
6054
SetLastError( 0xdeadbeef );
6055
ret = DuplicateHandle(GetCurrentProcess(), thread, GetCurrentProcess(), &dup,
6056
THREAD_QUERY_INFORMATION, FALSE, 0);
6057
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
6058
access = get_obj_access(dup);
6059
ok(access == (THREAD_QUERY_INFORMATION | THREAD_QUERY_LIMITED_INFORMATION) /* Vista+ */ ||
6060
access == THREAD_QUERY_INFORMATION /* before Vista */,
6061
"expected THREAD_QUERY_INFORMATION|THREAD_QUERY_LIMITED_INFORMATION, got %#lx\n", access);
6062
CloseHandle(dup);
6063
6064
TerminateThread(thread, 0);
6065
CloseHandle(thread);
6066
}
6067
6068
static void test_process_access(void)
6069
{
6070
DWORD ret, i, access;
6071
HANDLE process, dup;
6072
STARTUPINFOA sti;
6073
PROCESS_INFORMATION pi;
6074
char cmdline[] = "winver.exe";
6075
static const struct
6076
{
6077
int generic, mapped;
6078
} map[] =
6079
{
6080
{ 0, 0 },
6081
{ GENERIC_READ, STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ },
6082
{ GENERIC_WRITE, STANDARD_RIGHTS_WRITE | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION | PROCESS_SUSPEND_RESUME |
6083
PROCESS_VM_WRITE | PROCESS_DUP_HANDLE | PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION },
6084
{ GENERIC_EXECUTE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE },
6085
{ GENERIC_ALL, PROCESS_ALL_ACCESS_NT4 }
6086
};
6087
6088
memset(&sti, 0, sizeof(sti));
6089
sti.cb = sizeof(sti);
6090
SetLastError(0xdeadbeef);
6091
ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &sti, &pi);
6092
ok(ret, "CreateProcess() error %ld\n", GetLastError());
6093
6094
CloseHandle(pi.hThread);
6095
process = pi.hProcess;
6096
6097
access = get_obj_access(process);
6098
ok(access == PROCESS_ALL_ACCESS_NT4 || access == PROCESS_ALL_ACCESS_VISTA, "expected PROCESS_ALL_ACCESS, got %#lx\n", access);
6099
6100
for (i = 0; i < ARRAY_SIZE(map); i++)
6101
{
6102
SetLastError( 0xdeadbeef );
6103
ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup,
6104
map[i].generic, FALSE, 0);
6105
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
6106
6107
access = get_obj_access(dup);
6108
switch (map[i].generic)
6109
{
6110
case GENERIC_READ:
6111
ok(access == map[i].mapped || access == (map[i].mapped | PROCESS_QUERY_LIMITED_INFORMATION) /* Vista+ */,
6112
"%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
6113
break;
6114
case GENERIC_WRITE:
6115
ok(access == map[i].mapped ||
6116
access == (map[i].mapped | PROCESS_TERMINATE) /* before Vista */ ||
6117
access == (map[i].mapped | PROCESS_SET_LIMITED_INFORMATION) /* win8 */ ||
6118
access == (map[i].mapped | PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_SET_LIMITED_INFORMATION) /* Win10 Anniversary Update */,
6119
"%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
6120
break;
6121
case GENERIC_EXECUTE:
6122
ok(access == map[i].mapped || access == (map[i].mapped | PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_TERMINATE) /* Vista+ */,
6123
"%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
6124
break;
6125
case GENERIC_ALL:
6126
ok(access == map[i].mapped || access == PROCESS_ALL_ACCESS_VISTA,
6127
"%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
6128
break;
6129
default:
6130
ok(access == map[i].mapped, "%ld: expected %#x, got %#lx\n", i, map[i].mapped, access);
6131
break;
6132
}
6133
6134
CloseHandle(dup);
6135
}
6136
6137
SetLastError( 0xdeadbeef );
6138
ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup,
6139
PROCESS_QUERY_INFORMATION, FALSE, 0);
6140
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
6141
access = get_obj_access(dup);
6142
ok(access == (PROCESS_QUERY_INFORMATION | PROCESS_QUERY_LIMITED_INFORMATION) /* Vista+ */ ||
6143
access == PROCESS_QUERY_INFORMATION /* before Vista */,
6144
"expected PROCESS_QUERY_INFORMATION|PROCESS_QUERY_LIMITED_INFORMATION, got %#lx\n", access);
6145
CloseHandle(dup);
6146
6147
SetLastError( 0xdeadbeef );
6148
ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup,
6149
PROCESS_VM_OPERATION, FALSE, 0);
6150
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
6151
access = get_obj_access(dup);
6152
ok(access == PROCESS_VM_OPERATION, "unexpected access right %lx\n", access);
6153
CloseHandle(dup);
6154
6155
SetLastError( 0xdeadbeef );
6156
ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup,
6157
PROCESS_VM_WRITE, FALSE, 0);
6158
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
6159
access = get_obj_access(dup);
6160
ok(access == PROCESS_VM_WRITE, "unexpected access right %lx\n", access);
6161
CloseHandle(dup);
6162
6163
SetLastError( 0xdeadbeef );
6164
ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup,
6165
PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, 0);
6166
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
6167
access = get_obj_access(dup);
6168
ok(access == (PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_QUERY_LIMITED_INFORMATION) ||
6169
broken(access == (PROCESS_VM_OPERATION | PROCESS_VM_WRITE)) /* Win8 and before */,
6170
"expected PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_QUERY_LIMITED_INFORMATION, got %#lx\n", access);
6171
CloseHandle(dup);
6172
6173
SetLastError( 0xdeadbeef );
6174
ret = DuplicateHandle(GetCurrentProcess(), process, GetCurrentProcess(), &dup,
6175
PROCESS_VM_OPERATION | PROCESS_VM_READ, FALSE, 0);
6176
ok(ret, "DuplicateHandle error %ld\n", GetLastError());
6177
access = get_obj_access(dup);
6178
ok(access == (PROCESS_VM_OPERATION | PROCESS_VM_READ), "unexpected access right %lx\n", access);
6179
CloseHandle(dup);
6180
6181
TerminateProcess(process, 0);
6182
CloseHandle(process);
6183
}
6184
6185
static BOOL validate_impersonation_token(HANDLE token, DWORD *token_type)
6186
{
6187
DWORD ret, needed;
6188
TOKEN_TYPE type;
6189
SECURITY_IMPERSONATION_LEVEL sil;
6190
6191
type = 0xdeadbeef;
6192
needed = 0;
6193
SetLastError(0xdeadbeef);
6194
ret = GetTokenInformation(token, TokenType, &type, sizeof(type), &needed);
6195
ok(ret, "GetTokenInformation error %ld\n", GetLastError());
6196
ok(needed == sizeof(type), "GetTokenInformation should return required buffer length\n");
6197
ok(type == TokenPrimary || type == TokenImpersonation, "expected TokenPrimary or TokenImpersonation, got %d\n", type);
6198
6199
*token_type = type;
6200
if (type != TokenImpersonation) return FALSE;
6201
6202
needed = 0;
6203
SetLastError(0xdeadbeef);
6204
ret = GetTokenInformation(token, TokenImpersonationLevel, &sil, sizeof(sil), &needed);
6205
ok(ret, "GetTokenInformation error %ld\n", GetLastError());
6206
ok(needed == sizeof(sil), "GetTokenInformation should return required buffer length\n");
6207
ok(sil == SecurityImpersonation, "expected SecurityImpersonation, got %d\n", sil);
6208
6209
needed = 0xdeadbeef;
6210
SetLastError(0xdeadbeef);
6211
ret = GetTokenInformation(token, TokenDefaultDacl, NULL, 0, &needed);
6212
ok(!ret, "GetTokenInformation should fail\n");
6213
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
6214
ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n");
6215
ok(needed > sizeof(TOKEN_DEFAULT_DACL), "GetTokenInformation returned empty default DACL\n");
6216
6217
needed = 0xdeadbeef;
6218
SetLastError(0xdeadbeef);
6219
ret = GetTokenInformation(token, TokenOwner, NULL, 0, &needed);
6220
ok(!ret, "GetTokenInformation should fail\n");
6221
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
6222
ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n");
6223
ok(needed > sizeof(TOKEN_OWNER), "GetTokenInformation returned empty token owner\n");
6224
6225
needed = 0xdeadbeef;
6226
SetLastError(0xdeadbeef);
6227
ret = GetTokenInformation(token, TokenPrimaryGroup, NULL, 0, &needed);
6228
ok(!ret, "GetTokenInformation should fail\n");
6229
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
6230
ok(needed != 0xdeadbeef, "GetTokenInformation should return required buffer length\n");
6231
ok(needed > sizeof(TOKEN_PRIMARY_GROUP), "GetTokenInformation returned empty token primary group\n");
6232
6233
return TRUE;
6234
}
6235
6236
static void test_kernel_objects_security(void)
6237
{
6238
HANDLE token, process_token;
6239
DWORD ret, token_type;
6240
6241
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &process_token);
6242
ok(ret, "OpenProcessToken error %ld\n", GetLastError());
6243
6244
ret = validate_impersonation_token(process_token, &token_type);
6245
ok(token_type == TokenPrimary, "expected TokenPrimary, got %ld\n", token_type);
6246
ok(!ret, "access token should not be an impersonation token\n");
6247
6248
ret = DuplicateToken(process_token, SecurityImpersonation, &token);
6249
ok(ret, "DuplicateToken error %ld\n", GetLastError());
6250
6251
ret = validate_impersonation_token(token, &token_type);
6252
ok(ret, "access token should be a valid impersonation token\n");
6253
ok(token_type == TokenImpersonation, "expected TokenImpersonation, got %ld\n", token_type);
6254
6255
test_mutex_security(token);
6256
test_event_security(token);
6257
test_named_pipe_security(token);
6258
test_semaphore_security(token);
6259
test_file_security(token);
6260
test_filemap_security();
6261
test_thread_security();
6262
test_process_access();
6263
/* FIXME: test other kernel object types */
6264
6265
CloseHandle(process_token);
6266
CloseHandle(token);
6267
}
6268
6269
static void test_TokenIntegrityLevel(void)
6270
{
6271
TOKEN_MANDATORY_LABEL *tml;
6272
BYTE buffer[64]; /* using max. 28 byte in win7 x64 */
6273
HANDLE token;
6274
DWORD size;
6275
DWORD res;
6276
static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
6277
{SECURITY_MANDATORY_HIGH_RID}};
6278
static SID high_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
6279
{SECURITY_MANDATORY_MEDIUM_RID}};
6280
6281
SetLastError(0xdeadbeef);
6282
res = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
6283
ok(res, "got %ld with %ld (expected TRUE)\n", res, GetLastError());
6284
6285
SetLastError(0xdeadbeef);
6286
res = GetTokenInformation(token, TokenIntegrityLevel, buffer, sizeof(buffer), &size);
6287
6288
/* not supported before Vista */
6289
if (!res && ((GetLastError() == ERROR_INVALID_PARAMETER) || GetLastError() == ERROR_INVALID_FUNCTION))
6290
{
6291
win_skip("TokenIntegrityLevel not supported\n");
6292
CloseHandle(token);
6293
return;
6294
}
6295
6296
ok(res, "got %lu with %lu (expected TRUE)\n", res, GetLastError());
6297
if (!res)
6298
{
6299
CloseHandle(token);
6300
return;
6301
}
6302
6303
tml = (TOKEN_MANDATORY_LABEL*) buffer;
6304
ok(tml->Label.Attributes == (SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED),
6305
"got 0x%lx (expected 0x%x)\n", tml->Label.Attributes, (SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED));
6306
6307
ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level),
6308
"got %s (expected %s or %s)\n", debugstr_sid(tml->Label.Sid),
6309
debugstr_sid(&medium_level), debugstr_sid(&high_level));
6310
6311
CloseHandle(token);
6312
}
6313
6314
static void test_default_dacl_owner_group_sid(void)
6315
{
6316
TOKEN_USER *token_user;
6317
TOKEN_OWNER *token_owner;
6318
TOKEN_PRIMARY_GROUP *token_primary_group;
6319
HANDLE handle, token;
6320
BOOL ret, defaulted, present, found;
6321
DWORD size, index;
6322
SECURITY_DESCRIPTOR *sd;
6323
SECURITY_ATTRIBUTES sa;
6324
PSID owner, group;
6325
ACL *dacl;
6326
ACCESS_ALLOWED_ACE *ace;
6327
6328
ret = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &token );
6329
ok(ret, "OpenProcessToken failed with error %ld\n", GetLastError());
6330
6331
token_user = get_alloc_token_user( token );
6332
token_owner = get_alloc_token_owner( token );
6333
token_primary_group = get_alloc_token_primary_group( token );
6334
6335
CloseHandle( token );
6336
6337
sd = malloc( SECURITY_DESCRIPTOR_MIN_LENGTH );
6338
ret = InitializeSecurityDescriptor( sd, SECURITY_DESCRIPTOR_REVISION );
6339
ok( ret, "error %lu\n", GetLastError() );
6340
6341
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
6342
sa.lpSecurityDescriptor = sd;
6343
sa.bInheritHandle = FALSE;
6344
handle = CreateEventA( &sa, TRUE, TRUE, "test_event" );
6345
ok( handle != NULL, "error %lu\n", GetLastError() );
6346
6347
size = 0;
6348
ret = GetKernelObjectSecurity( handle, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, NULL, 0, &size );
6349
ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "error %lu\n", GetLastError() );
6350
6351
sd = malloc( size );
6352
ret = GetKernelObjectSecurity( handle, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, sd, size, &size );
6353
ok( ret, "error %lu\n", GetLastError() );
6354
6355
owner = (void *)0xdeadbeef;
6356
defaulted = TRUE;
6357
ret = GetSecurityDescriptorOwner( sd, &owner, &defaulted );
6358
ok( ret, "error %lu\n", GetLastError() );
6359
ok( owner != (void *)0xdeadbeef, "owner not set\n" );
6360
ok( !defaulted, "owner defaulted\n" );
6361
ok( EqualSid( owner, token_owner->Owner ), "owner shall equal token owner\n" );
6362
6363
group = (void *)0xdeadbeef;
6364
defaulted = TRUE;
6365
ret = GetSecurityDescriptorGroup( sd, &group, &defaulted );
6366
ok( ret, "error %lu\n", GetLastError() );
6367
ok( group != (void *)0xdeadbeef, "group not set\n" );
6368
ok( !defaulted, "group defaulted\n" );
6369
ok( EqualSid( group, token_primary_group->PrimaryGroup ), "group shall equal token primary group\n" );
6370
6371
dacl = (void *)0xdeadbeef;
6372
present = FALSE;
6373
defaulted = TRUE;
6374
ret = GetSecurityDescriptorDacl( sd, &present, &dacl, &defaulted );
6375
ok( ret, "error %lu\n", GetLastError() );
6376
ok( present, "dacl not present\n" );
6377
ok( dacl != (void *)0xdeadbeef, "dacl not set\n" );
6378
ok( !defaulted, "dacl defaulted\n" );
6379
6380
index = 0;
6381
found = FALSE;
6382
while (GetAce( dacl, index++, (void **)&ace ))
6383
{
6384
ok( ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE,
6385
"expected ACCESS_ALLOWED_ACE_TYPE, got %d\n", ace->Header.AceType );
6386
if (EqualSid( &ace->SidStart, owner )) found = TRUE;
6387
}
6388
ok( found, "owner sid not found in dacl\n" );
6389
6390
if (!EqualSid( token_user->User.Sid, token_owner->Owner ))
6391
{
6392
index = 0;
6393
found = FALSE;
6394
while (GetAce( dacl, index++, (void **)&ace ))
6395
{
6396
ok( ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE,
6397
"expected ACCESS_ALLOWED_ACE_TYPE, got %d\n", ace->Header.AceType );
6398
if (EqualSid( &ace->SidStart, token_user->User.Sid )) found = TRUE;
6399
}
6400
ok( !found, "DACL shall not reference token user if it is different from token owner\n" );
6401
}
6402
6403
free( sa.lpSecurityDescriptor );
6404
free( sd );
6405
CloseHandle( handle );
6406
6407
free( token_primary_group );
6408
free( token_owner );
6409
free( token_user );
6410
}
6411
6412
static void test_AdjustTokenPrivileges(void)
6413
{
6414
TOKEN_PRIVILEGES tp;
6415
HANDLE token;
6416
DWORD len;
6417
LUID luid;
6418
BOOL ret;
6419
6420
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
6421
return;
6422
6423
if (!LookupPrivilegeValueA(NULL, SE_BACKUP_NAME, &luid))
6424
{
6425
CloseHandle(token);
6426
return;
6427
}
6428
6429
tp.PrivilegeCount = 1;
6430
tp.Privileges[0].Luid = luid;
6431
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
6432
6433
len = 0xdeadbeef;
6434
ret = AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, &len);
6435
ok(ret, "got %d\n", ret);
6436
ok(len == 0xdeadbeef, "got length %ld\n", len);
6437
6438
/* revert */
6439
tp.PrivilegeCount = 1;
6440
tp.Privileges[0].Luid = luid;
6441
tp.Privileges[0].Attributes = 0;
6442
ret = AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
6443
ok(ret, "got %d\n", ret);
6444
6445
CloseHandle(token);
6446
}
6447
6448
static void test_AddAce(void)
6449
{
6450
static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
6451
6452
char acl_buf[1024], ace_buf[256];
6453
ACCESS_ALLOWED_ACE *ace = (ACCESS_ALLOWED_ACE*)ace_buf;
6454
PACL acl = (PACL)acl_buf;
6455
BOOL ret;
6456
6457
memset(ace, 0, sizeof(ace_buf));
6458
ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
6459
ace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD)+sizeof(SID);
6460
memcpy(&ace->SidStart, &sidWorld, sizeof(sidWorld));
6461
6462
ret = InitializeAcl(acl, sizeof(acl_buf), ACL_REVISION2);
6463
ok(ret, "InitializeAcl failed: %ld\n", GetLastError());
6464
6465
ret = AddAce(acl, ACL_REVISION1, MAXDWORD, ace, ace->Header.AceSize);
6466
ok(ret, "AddAce failed: %ld\n", GetLastError());
6467
ret = AddAce(acl, ACL_REVISION2, MAXDWORD, ace, ace->Header.AceSize);
6468
ok(ret, "AddAce failed: %ld\n", GetLastError());
6469
ret = AddAce(acl, ACL_REVISION3, MAXDWORD, ace, ace->Header.AceSize);
6470
ok(ret, "AddAce failed: %ld\n", GetLastError());
6471
ok(acl->AclRevision == ACL_REVISION3, "acl->AclRevision = %d\n", acl->AclRevision);
6472
ret = AddAce(acl, ACL_REVISION4, MAXDWORD, ace, ace->Header.AceSize);
6473
ok(ret, "AddAce failed: %ld\n", GetLastError());
6474
ok(acl->AclRevision == ACL_REVISION4, "acl->AclRevision = %d\n", acl->AclRevision);
6475
ret = AddAce(acl, ACL_REVISION1, MAXDWORD, ace, ace->Header.AceSize);
6476
ok(ret, "AddAce failed: %ld\n", GetLastError());
6477
ok(acl->AclRevision == ACL_REVISION4, "acl->AclRevision = %d\n", acl->AclRevision);
6478
ret = AddAce(acl, ACL_REVISION2, MAXDWORD, ace, ace->Header.AceSize);
6479
ok(ret, "AddAce failed: %ld\n", GetLastError());
6480
6481
ret = AddAce(acl, MIN_ACL_REVISION-1, MAXDWORD, ace, ace->Header.AceSize);
6482
ok(ret, "AddAce failed: %ld\n", GetLastError());
6483
/* next test succeededs but corrupts ACL */
6484
ret = AddAce(acl, MAX_ACL_REVISION+1, MAXDWORD, ace, ace->Header.AceSize);
6485
ok(ret, "AddAce failed: %ld\n", GetLastError());
6486
ok(acl->AclRevision == MAX_ACL_REVISION+1, "acl->AclRevision = %d\n", acl->AclRevision);
6487
SetLastError(0xdeadbeef);
6488
ret = AddAce(acl, ACL_REVISION1, MAXDWORD, ace, ace->Header.AceSize);
6489
ok(!ret, "AddAce succeeded\n");
6490
ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError() = %ld\n", GetLastError());
6491
}
6492
6493
static void test_AddMandatoryAce(void)
6494
{
6495
static SID low_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
6496
{SECURITY_MANDATORY_LOW_RID}};
6497
static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
6498
{SECURITY_MANDATORY_MEDIUM_RID}};
6499
static SID_IDENTIFIER_AUTHORITY sia_world = {SECURITY_WORLD_SID_AUTHORITY};
6500
char buffer_sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
6501
SECURITY_DESCRIPTOR *sd2, *sd = (SECURITY_DESCRIPTOR *)&buffer_sd;
6502
BOOL defaulted, present, ret;
6503
ACL_SIZE_INFORMATION acl_size_info;
6504
SYSTEM_MANDATORY_LABEL_ACE *ace;
6505
char buffer_acl[256];
6506
ACL *acl = (ACL *)&buffer_acl;
6507
SECURITY_ATTRIBUTES sa;
6508
DWORD size;
6509
HANDLE handle;
6510
SID *everyone;
6511
ACL *sacl;
6512
6513
if (!pAddMandatoryAce)
6514
{
6515
win_skip("AddMandatoryAce not supported, skipping test\n");
6516
return;
6517
}
6518
6519
ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
6520
ok(ret, "InitializeSecurityDescriptor failed with error %lu\n", GetLastError());
6521
6522
sa.nLength = sizeof(sa);
6523
sa.lpSecurityDescriptor = sd;
6524
sa.bInheritHandle = FALSE;
6525
6526
handle = CreateEventA(&sa, TRUE, TRUE, "test_event");
6527
ok(handle != NULL, "CreateEventA failed with error %lu\n", GetLastError());
6528
6529
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
6530
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
6531
"Unexpected GetKernelObjectSecurity return value %u, error %lu\n", ret, GetLastError());
6532
6533
sd2 = malloc(size);
6534
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
6535
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
6536
6537
sacl = (void *)0xdeadbeef;
6538
present = TRUE;
6539
ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted);
6540
ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
6541
ok(!present, "SACL is present\n");
6542
ok(sacl == (void *)0xdeadbeef, "SACL is set\n");
6543
6544
free(sd2);
6545
CloseHandle(handle);
6546
6547
memset(buffer_acl, 0, sizeof(buffer_acl));
6548
ret = InitializeAcl(acl, 256, ACL_REVISION);
6549
ok(ret, "InitializeAcl failed with %lu\n", GetLastError());
6550
6551
SetLastError(0xdeadbeef);
6552
ret = pAddMandatoryAce(acl, ACL_REVISION, 0, 0x1234, &low_level);
6553
ok(!ret, "AddMandatoryAce succeeded\n");
6554
ok(GetLastError() == ERROR_INVALID_PARAMETER,
6555
"Expected ERROR_INVALID_PARAMETER got %lu\n", GetLastError());
6556
6557
ret = pAddMandatoryAce(acl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, &low_level);
6558
ok(ret, "AddMandatoryAce failed with %lu\n", GetLastError());
6559
6560
ret = GetAce(acl, 0, (void **)&ace);
6561
ok(ret, "got error %lu\n", GetLastError());
6562
ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, "got type %#x\n", ace->Header.AceType);
6563
ok(!ace->Header.AceFlags, "got flags %#x\n", ace->Header.AceFlags);
6564
ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, "got mask %#lx\n", ace->Mask);
6565
ok(EqualSid(&ace->SidStart, &low_level), "wrong sid\n");
6566
6567
SetLastError(0xdeadbeef);
6568
ret = GetAce(acl, 1, (void **)&ace);
6569
ok(!ret, "expected failure\n");
6570
ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError());
6571
6572
ret = SetSecurityDescriptorSacl(sd, TRUE, acl, FALSE);
6573
ok(ret, "SetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
6574
6575
handle = CreateEventA(&sa, TRUE, TRUE, "test_event");
6576
ok(handle != NULL, "CreateEventA failed with error %lu\n", GetLastError());
6577
6578
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
6579
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
6580
"Unexpected GetKernelObjectSecurity return value %u, error %lu\n", ret, GetLastError());
6581
6582
sd2 = malloc(size);
6583
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
6584
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
6585
6586
sacl = (void *)0xdeadbeef;
6587
present = FALSE;
6588
defaulted = TRUE;
6589
ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted);
6590
ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
6591
ok(present, "SACL not present\n");
6592
ok(sacl != (void *)0xdeadbeef, "SACL not set\n");
6593
ok(!defaulted, "SACL defaulted\n");
6594
ret = GetAclInformation(sacl, &acl_size_info, sizeof(acl_size_info), AclSizeInformation);
6595
ok(ret, "GetAclInformation failed with error %lu\n", GetLastError());
6596
ok(acl_size_info.AceCount == 1, "SACL contains an unexpected ACE count %lu\n", acl_size_info.AceCount);
6597
6598
ret = GetAce(sacl, 0, (void **)&ace);
6599
ok(ret, "GetAce failed with error %lu\n", GetLastError());
6600
ok (ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, "Unexpected ACE type %#x\n", ace->Header.AceType);
6601
ok(!ace->Header.AceFlags, "Unexpected ACE flags %#x\n", ace->Header.AceFlags);
6602
ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, "Unexpected ACE mask %#lx\n", ace->Mask);
6603
ok(EqualSid(&ace->SidStart, &low_level), "Expected low integrity level\n");
6604
6605
free(sd2);
6606
6607
ret = pAddMandatoryAce(acl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP, &medium_level);
6608
ok(ret, "AddMandatoryAce failed with error %lu\n", GetLastError());
6609
6610
ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd);
6611
ok(ret, "SetKernelObjectSecurity failed with error %lu\n", GetLastError());
6612
6613
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
6614
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
6615
"Unexpected GetKernelObjectSecurity return value %u, error %lu\n", ret, GetLastError());
6616
6617
sd2 = malloc(size);
6618
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
6619
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
6620
6621
sacl = (void *)0xdeadbeef;
6622
present = FALSE;
6623
defaulted = TRUE;
6624
ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted);
6625
ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
6626
ok(present, "SACL not present\n");
6627
ok(sacl != (void *)0xdeadbeef, "SACL not set\n");
6628
ok(sacl->AceCount == 2, "Expected 2 ACEs, got %d\n", sacl->AceCount);
6629
ok(!defaulted, "SACL defaulted\n");
6630
6631
ret = GetAce(acl, 0, (void **)&ace);
6632
ok(ret, "got error %lu\n", GetLastError());
6633
ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, "got type %#x\n", ace->Header.AceType);
6634
ok(!ace->Header.AceFlags, "got flags %#x\n", ace->Header.AceFlags);
6635
ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, "got mask %#lx\n", ace->Mask);
6636
ok(EqualSid(&ace->SidStart, &low_level), "wrong sid\n");
6637
6638
ret = GetAce(acl, 1, (void **)&ace);
6639
ok(ret, "got error %lu\n", GetLastError());
6640
ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, "got type %#x\n", ace->Header.AceType);
6641
ok(!ace->Header.AceFlags, "got flags %#x\n", ace->Header.AceFlags);
6642
ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP, "got mask %#lx\n", ace->Mask);
6643
ok(EqualSid(&ace->SidStart, &medium_level), "wrong sid\n");
6644
6645
SetLastError(0xdeadbeef);
6646
ret = GetAce(acl, 2, (void **)&ace);
6647
ok(!ret, "expected failure\n");
6648
ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError());
6649
6650
free(sd2);
6651
6652
ret = SetSecurityDescriptorSacl(sd, FALSE, NULL, FALSE);
6653
ok(ret, "SetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
6654
6655
ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd);
6656
ok(ret, "SetKernelObjectSecurity failed with error %lu\n", GetLastError());
6657
6658
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
6659
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
6660
"Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError());
6661
6662
sd2 = malloc(size);
6663
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
6664
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
6665
6666
sacl = (void *)0xdeadbeef;
6667
present = FALSE;
6668
defaulted = TRUE;
6669
ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted);
6670
ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
6671
ok(present, "SACL not present\n");
6672
ok(sacl && sacl != (void *)0xdeadbeef, "SACL not set\n");
6673
ok(!defaulted, "SACL defaulted\n");
6674
ok(!sacl->AceCount, "SACL contains an unexpected ACE count %u\n", sacl->AceCount);
6675
6676
free(sd2);
6677
6678
ret = InitializeAcl(acl, 256, ACL_REVISION);
6679
ok(ret, "InitializeAcl failed with error %lu\n", GetLastError());
6680
6681
ret = pAddMandatoryAce(acl, ACL_REVISION3, 0, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP, &medium_level);
6682
ok(ret, "AddMandatoryAce failed with error %lu\n", GetLastError());
6683
6684
ret = SetSecurityDescriptorSacl(sd, TRUE, acl, FALSE);
6685
ok(ret, "SetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
6686
6687
ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd);
6688
ok(ret, "SetKernelObjectSecurity failed with error %lu\n", GetLastError());
6689
6690
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
6691
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
6692
"Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError());
6693
6694
sd2 = malloc(size);
6695
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
6696
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
6697
6698
sacl = (void *)0xdeadbeef;
6699
present = FALSE;
6700
defaulted = TRUE;
6701
ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted);
6702
ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
6703
ok(present, "SACL not present\n");
6704
ok(sacl != (void *)0xdeadbeef, "SACL not set\n");
6705
ok(sacl->AclRevision == ACL_REVISION3, "Expected revision 3, got %d\n", sacl->AclRevision);
6706
ok(!defaulted, "SACL defaulted\n");
6707
6708
free(sd2);
6709
6710
ret = InitializeAcl(acl, 256, ACL_REVISION);
6711
ok(ret, "InitializeAcl failed with error %lu\n", GetLastError());
6712
6713
ret = AllocateAndInitializeSid(&sia_world, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, (void **)&everyone);
6714
ok(ret, "AllocateAndInitializeSid failed with error %lu\n", GetLastError());
6715
6716
ret = AddAccessAllowedAce(acl, ACL_REVISION, KEY_READ, everyone);
6717
ok(ret, "AddAccessAllowedAce failed with error %lu\n", GetLastError());
6718
6719
ret = SetSecurityDescriptorSacl(sd, TRUE, acl, FALSE);
6720
ok(ret, "SetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
6721
6722
ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd);
6723
ok(ret, "SetKernelObjectSecurity failed with error %lu\n", GetLastError());
6724
6725
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
6726
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
6727
"Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError());
6728
6729
sd2 = malloc(size);
6730
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
6731
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
6732
6733
sacl = (void *)0xdeadbeef;
6734
present = FALSE;
6735
defaulted = TRUE;
6736
ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted);
6737
ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
6738
ok(present, "SACL not present\n");
6739
ok(sacl && sacl != (void *)0xdeadbeef, "SACL not set\n");
6740
ok(!defaulted, "SACL defaulted\n");
6741
ok(!sacl->AceCount, "SACL contains an unexpected ACE count %u\n", sacl->AceCount);
6742
6743
FreeSid(everyone);
6744
free(sd2);
6745
CloseHandle(handle);
6746
}
6747
6748
static void test_system_security_access(void)
6749
{
6750
static const WCHAR testkeyW[] = L"SOFTWARE\\Wine\\SACLtest";
6751
LONG res;
6752
HKEY hkey;
6753
PSECURITY_DESCRIPTOR sd;
6754
ACL *sacl;
6755
DWORD err, len = 128;
6756
TOKEN_PRIVILEGES priv, *priv_prev;
6757
HANDLE token;
6758
LUID luid;
6759
BOOL ret;
6760
6761
if (!OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &token )) return;
6762
if (!LookupPrivilegeValueA( NULL, SE_SECURITY_NAME, &luid ))
6763
{
6764
CloseHandle( token );
6765
return;
6766
}
6767
6768
/* ACCESS_SYSTEM_SECURITY requires special privilege */
6769
res = RegCreateKeyExW( HKEY_LOCAL_MACHINE, testkeyW, 0, NULL, 0, KEY_READ|ACCESS_SYSTEM_SECURITY, NULL, &hkey, NULL );
6770
if (res == ERROR_ACCESS_DENIED)
6771
{
6772
skip( "unprivileged user\n" );
6773
CloseHandle( token );
6774
return;
6775
}
6776
todo_wine ok( res == ERROR_PRIVILEGE_NOT_HELD, "got %ld\n", res );
6777
6778
priv.PrivilegeCount = 1;
6779
priv.Privileges[0].Luid = luid;
6780
priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
6781
6782
priv_prev = malloc( len );
6783
ret = AdjustTokenPrivileges( token, FALSE, &priv, len, priv_prev, &len );
6784
ok( ret, "got %lu\n", GetLastError());
6785
6786
res = RegCreateKeyExW( HKEY_LOCAL_MACHINE, testkeyW, 0, NULL, 0, KEY_READ|ACCESS_SYSTEM_SECURITY, NULL, &hkey, NULL );
6787
if (res == ERROR_PRIVILEGE_NOT_HELD)
6788
{
6789
win_skip( "privilege not held\n" );
6790
free( priv_prev );
6791
CloseHandle( token );
6792
return;
6793
}
6794
ok( !res, "got %ld\n", res );
6795
6796
/* restore privileges */
6797
ret = AdjustTokenPrivileges( token, FALSE, priv_prev, 0, NULL, NULL );
6798
ok( ret, "got %lu\n", GetLastError() );
6799
free( priv_prev );
6800
6801
/* privilege is checked on access */
6802
err = GetSecurityInfo( hkey, SE_REGISTRY_KEY, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, &sacl, &sd );
6803
todo_wine ok( err == ERROR_PRIVILEGE_NOT_HELD || err == ERROR_ACCESS_DENIED, "got %lu\n", err );
6804
if (err == ERROR_SUCCESS)
6805
LocalFree( sd );
6806
6807
priv.PrivilegeCount = 1;
6808
priv.Privileges[0].Luid = luid;
6809
priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
6810
6811
priv_prev = malloc( len );
6812
ret = AdjustTokenPrivileges( token, FALSE, &priv, len, priv_prev, &len );
6813
ok( ret, "got %lu\n", GetLastError());
6814
6815
err = GetSecurityInfo( hkey, SE_REGISTRY_KEY, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, &sacl, &sd );
6816
ok( err == ERROR_SUCCESS, "got %lu\n", err );
6817
RegCloseKey( hkey );
6818
LocalFree( sd );
6819
6820
/* handle created without ACCESS_SYSTEM_SECURITY, privilege held */
6821
res = RegCreateKeyExW( HKEY_LOCAL_MACHINE, testkeyW, 0, NULL, 0, KEY_READ, NULL, &hkey, NULL );
6822
ok( res == ERROR_SUCCESS, "got %ld\n", res );
6823
6824
sd = NULL;
6825
err = GetSecurityInfo( hkey, SE_REGISTRY_KEY, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, &sacl, &sd );
6826
todo_wine ok( err == ERROR_SUCCESS, "got %lu\n", err );
6827
RegCloseKey( hkey );
6828
LocalFree( sd );
6829
6830
/* restore privileges */
6831
ret = AdjustTokenPrivileges( token, FALSE, priv_prev, 0, NULL, NULL );
6832
ok( ret, "got %lu\n", GetLastError() );
6833
free( priv_prev );
6834
6835
/* handle created without ACCESS_SYSTEM_SECURITY, privilege not held */
6836
res = RegCreateKeyExW( HKEY_LOCAL_MACHINE, testkeyW, 0, NULL, 0, KEY_READ, NULL, &hkey, NULL );
6837
ok( res == ERROR_SUCCESS, "got %ld\n", res );
6838
6839
err = GetSecurityInfo( hkey, SE_REGISTRY_KEY, SACL_SECURITY_INFORMATION, NULL, NULL, NULL, &sacl, &sd );
6840
ok( err == ERROR_PRIVILEGE_NOT_HELD || err == ERROR_ACCESS_DENIED, "got %lu\n", err );
6841
RegCloseKey( hkey );
6842
6843
res = RegDeleteKeyW( HKEY_LOCAL_MACHINE, testkeyW );
6844
ok( !res, "got %ld\n", res );
6845
CloseHandle( token );
6846
}
6847
6848
static void test_GetWindowsAccountDomainSid(void)
6849
{
6850
char *user, buffer1[SECURITY_MAX_SID_SIZE], buffer2[SECURITY_MAX_SID_SIZE];
6851
SID_IDENTIFIER_AUTHORITY domain_ident = { SECURITY_NT_AUTHORITY };
6852
PSID domain_sid = (PSID *)&buffer1;
6853
PSID domain_sid2 = (PSID *)&buffer2;
6854
DWORD sid_size;
6855
PSID user_sid;
6856
HANDLE token;
6857
BOOL bret = TRUE;
6858
int i;
6859
6860
if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
6861
{
6862
if (GetLastError() != ERROR_NO_TOKEN) bret = FALSE;
6863
else if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) bret = FALSE;
6864
}
6865
if (!bret)
6866
{
6867
win_skip("Failed to get current user token\n");
6868
return;
6869
}
6870
6871
bret = GetTokenInformation(token, TokenUser, NULL, 0, &sid_size);
6872
ok(!bret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
6873
"GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError());
6874
user = malloc(sid_size);
6875
bret = GetTokenInformation(token, TokenUser, user, sid_size, &sid_size);
6876
ok(bret, "GetTokenInformation(TokenUser) failed with error %ld\n", GetLastError());
6877
CloseHandle(token);
6878
user_sid = ((TOKEN_USER *)user)->User.Sid;
6879
6880
SetLastError(0xdeadbeef);
6881
bret = GetWindowsAccountDomainSid(0, 0, 0);
6882
ok(!bret, "GetWindowsAccountDomainSid succeeded\n");
6883
ok(GetLastError() == ERROR_INVALID_SID, "expected ERROR_INVALID_SID, got %ld\n", GetLastError());
6884
6885
SetLastError(0xdeadbeef);
6886
bret = GetWindowsAccountDomainSid(user_sid, 0, 0);
6887
ok(!bret, "GetWindowsAccountDomainSid succeeded\n");
6888
ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
6889
6890
sid_size = SECURITY_MAX_SID_SIZE;
6891
SetLastError(0xdeadbeef);
6892
bret = GetWindowsAccountDomainSid(user_sid, 0, &sid_size);
6893
ok(!bret, "GetWindowsAccountDomainSid succeeded\n");
6894
ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
6895
ok(sid_size == GetSidLengthRequired(4), "expected size %ld, got %ld\n", GetSidLengthRequired(4), sid_size);
6896
6897
SetLastError(0xdeadbeef);
6898
bret = GetWindowsAccountDomainSid(user_sid, domain_sid, 0);
6899
ok(!bret, "GetWindowsAccountDomainSid succeeded\n");
6900
ok(GetLastError() == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
6901
6902
sid_size = 1;
6903
SetLastError(0xdeadbeef);
6904
bret = GetWindowsAccountDomainSid(user_sid, domain_sid, &sid_size);
6905
ok(!bret, "GetWindowsAccountDomainSid succeeded\n");
6906
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError());
6907
ok(sid_size == GetSidLengthRequired(4), "expected size %ld, got %ld\n", GetSidLengthRequired(4), sid_size);
6908
6909
sid_size = SECURITY_MAX_SID_SIZE;
6910
bret = GetWindowsAccountDomainSid(user_sid, domain_sid, &sid_size);
6911
ok(bret, "GetWindowsAccountDomainSid failed with error %ld\n", GetLastError());
6912
ok(sid_size == GetSidLengthRequired(4), "expected size %ld, got %ld\n", GetSidLengthRequired(4), sid_size);
6913
InitializeSid(domain_sid2, &domain_ident, 4);
6914
for (i = 0; i < 4; i++)
6915
*GetSidSubAuthority(domain_sid2, i) = *GetSidSubAuthority(user_sid, i);
6916
ok(EqualSid(domain_sid, domain_sid2), "unexpected domain sid %s != %s\n",
6917
debugstr_sid(domain_sid), debugstr_sid(domain_sid2));
6918
6919
free(user);
6920
}
6921
6922
static void test_GetSidIdentifierAuthority(void)
6923
{
6924
char buffer[SECURITY_MAX_SID_SIZE];
6925
PSID authority_sid = (PSID *)buffer;
6926
PSID_IDENTIFIER_AUTHORITY id;
6927
BOOL ret;
6928
6929
memset(buffer, 0xcc, sizeof(buffer));
6930
ret = IsValidSid(authority_sid);
6931
ok(!ret, "expected FALSE, got %u\n", ret);
6932
6933
SetLastError(0xdeadbeef);
6934
id = GetSidIdentifierAuthority(authority_sid);
6935
ok(id != NULL, "got NULL pointer as identifier authority\n");
6936
ok(GetLastError() == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", GetLastError());
6937
6938
SetLastError(0xdeadbeef);
6939
id = GetSidIdentifierAuthority(NULL);
6940
ok(id != NULL, "got NULL pointer as identifier authority\n");
6941
ok(GetLastError() == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %lu\n", GetLastError());
6942
}
6943
6944
static void test_pseudo_tokens(void)
6945
{
6946
TOKEN_STATISTICS statistics1, statistics2;
6947
HANDLE token;
6948
DWORD retlen;
6949
BOOL ret;
6950
6951
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
6952
ok(ret, "OpenProcessToken failed with error %lu\n", GetLastError());
6953
memset(&statistics1, 0x11, sizeof(statistics1));
6954
ret = GetTokenInformation(token, TokenStatistics, &statistics1, sizeof(statistics1), &retlen);
6955
ok(ret, "GetTokenInformation failed with %lu\n", GetLastError());
6956
CloseHandle(token);
6957
6958
/* test GetCurrentProcessToken() */
6959
SetLastError(0xdeadbeef);
6960
memset(&statistics2, 0x22, sizeof(statistics2));
6961
ret = GetTokenInformation(GetCurrentProcessToken(), TokenStatistics,
6962
&statistics2, sizeof(statistics2), &retlen);
6963
ok(ret || broken(GetLastError() == ERROR_INVALID_HANDLE),
6964
"GetTokenInformation failed with %lu\n", GetLastError());
6965
if (ret)
6966
ok(!memcmp(&statistics1, &statistics2, sizeof(statistics1)), "Token statistics do not match\n");
6967
else
6968
win_skip("CurrentProcessToken not supported, skipping test\n");
6969
6970
/* test GetCurrentThreadEffectiveToken() */
6971
SetLastError(0xdeadbeef);
6972
memset(&statistics2, 0x22, sizeof(statistics2));
6973
ret = GetTokenInformation(GetCurrentThreadEffectiveToken(), TokenStatistics,
6974
&statistics2, sizeof(statistics2), &retlen);
6975
ok(ret || broken(GetLastError() == ERROR_INVALID_HANDLE),
6976
"GetTokenInformation failed with %lu\n", GetLastError());
6977
if (ret)
6978
ok(!memcmp(&statistics1, &statistics2, sizeof(statistics1)), "Token statistics do not match\n");
6979
else
6980
win_skip("CurrentThreadEffectiveToken not supported, skipping test\n");
6981
6982
SetLastError(0xdeadbeef);
6983
ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &token);
6984
ok(!ret, "OpenThreadToken should have failed\n");
6985
ok(GetLastError() == ERROR_NO_TOKEN, "Expected ERROR_NO_TOKEN, got %lu\n", GetLastError());
6986
6987
/* test GetCurrentThreadToken() */
6988
SetLastError(0xdeadbeef);
6989
ret = GetTokenInformation(GetCurrentThreadToken(), TokenStatistics,
6990
&statistics2, sizeof(statistics2), &retlen);
6991
todo_wine ok(GetLastError() == ERROR_NO_TOKEN || broken(GetLastError() == ERROR_INVALID_HANDLE),
6992
"Expected ERROR_NO_TOKEN, got %lu\n", GetLastError());
6993
}
6994
6995
static void test_maximum_allowed(void)
6996
{
6997
HANDLE (WINAPI *pCreateEventExA)(SECURITY_ATTRIBUTES *, LPCSTR, DWORD, DWORD);
6998
char buffer_sd[SECURITY_DESCRIPTOR_MIN_LENGTH], buffer_acl[256];
6999
SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *)&buffer_sd;
7000
SECURITY_ATTRIBUTES sa;
7001
ACL *acl = (ACL *)&buffer_acl;
7002
HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
7003
ACCESS_MASK mask;
7004
HANDLE handle;
7005
BOOL ret;
7006
7007
pCreateEventExA = (void *)GetProcAddress(hkernel32, "CreateEventExA");
7008
if (!pCreateEventExA)
7009
{
7010
win_skip("CreateEventExA is not available\n");
7011
return;
7012
}
7013
7014
ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
7015
ok(ret, "InitializeSecurityDescriptor failed with %lu\n", GetLastError());
7016
memset(buffer_acl, 0, sizeof(buffer_acl));
7017
ret = InitializeAcl(acl, 256, ACL_REVISION);
7018
ok(ret, "InitializeAcl failed with %lu\n", GetLastError());
7019
ret = SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE);
7020
ok(ret, "SetSecurityDescriptorDacl failed with %lu\n", GetLastError());
7021
7022
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
7023
sa.lpSecurityDescriptor = sd;
7024
sa.bInheritHandle = FALSE;
7025
7026
handle = pCreateEventExA(&sa, NULL, 0, MAXIMUM_ALLOWED | 0x4);
7027
ok(handle != NULL, "CreateEventExA failed with error %lu\n", GetLastError());
7028
mask = get_obj_access(handle);
7029
ok(mask == EVENT_ALL_ACCESS, "Expected %x, got %lx\n", EVENT_ALL_ACCESS, mask);
7030
CloseHandle(handle);
7031
}
7032
7033
static void check_token_label(HANDLE token, DWORD *level, BOOL sacl_inherited)
7034
{
7035
static SID medium_sid = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
7036
{SECURITY_MANDATORY_MEDIUM_RID}};
7037
static SID high_sid = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
7038
{SECURITY_MANDATORY_HIGH_RID}};
7039
SECURITY_DESCRIPTOR_CONTROL control;
7040
SYSTEM_MANDATORY_LABEL_ACE *ace;
7041
BOOL ret, present, defaulted;
7042
SECURITY_DESCRIPTOR *sd;
7043
ACL *sacl = NULL, *dacl;
7044
DWORD size, revision;
7045
char *str;
7046
SID *sid;
7047
7048
ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
7049
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7050
"Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError());
7051
7052
sd = malloc(size);
7053
ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd, size, &size);
7054
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
7055
7056
ret = GetSecurityDescriptorControl(sd, &control, &revision);
7057
ok(ret, "GetSecurityDescriptorControl failed with error %lu\n", GetLastError());
7058
if (sacl_inherited)
7059
todo_wine ok(control == (SE_SELF_RELATIVE | SE_SACL_AUTO_INHERITED | SE_SACL_PRESENT),
7060
"Unexpected security descriptor control %#x\n", control);
7061
else
7062
todo_wine ok(control == (SE_SELF_RELATIVE | SE_SACL_PRESENT),
7063
"Unexpected security descriptor control %#x\n", control);
7064
ok(revision == 1, "Unexpected security descriptor revision %lu\n", revision);
7065
7066
sid = (void *)0xdeadbeef;
7067
defaulted = TRUE;
7068
ret = GetSecurityDescriptorOwner(sd, (void **)&sid, &defaulted);
7069
ok(ret, "GetSecurityDescriptorOwner failed with error %lu\n", GetLastError());
7070
ok(!sid, "Owner present\n");
7071
ok(!defaulted, "Owner defaulted\n");
7072
7073
sid = (void *)0xdeadbeef;
7074
defaulted = TRUE;
7075
ret = GetSecurityDescriptorGroup(sd, (void **)&sid, &defaulted);
7076
ok(ret, "GetSecurityDescriptorGroup failed with error %lu\n", GetLastError());
7077
ok(!sid, "Group present\n");
7078
ok(!defaulted, "Group defaulted\n");
7079
7080
ret = GetSecurityDescriptorSacl(sd, &present, &sacl, &defaulted);
7081
ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
7082
ok(present, "No SACL in the security descriptor\n");
7083
ok(!!sacl, "NULL SACL in the security descriptor\n");
7084
ok(!defaulted, "SACL defaulted\n");
7085
ok(sacl->AceCount == 1, "SACL contains an unexpected ACE count %u\n", sacl->AceCount);
7086
7087
ret = GetAce(sacl, 0, (void **)&ace);
7088
ok(ret, "GetAce failed with error %lu\n", GetLastError());
7089
7090
ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE,
7091
"Unexpected ACE type %#x\n", ace->Header.AceType);
7092
ok(!ace->Header.AceFlags, "Unexpected ACE flags %#x\n", ace->Header.AceFlags);
7093
ok(ace->Header.AceSize, "Unexpected ACE size %u\n", ace->Header.AceSize);
7094
ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, "Unexpected ACE mask %#lx\n", ace->Mask);
7095
7096
sid = (SID *)&ace->SidStart;
7097
ConvertSidToStringSidA(sid, &str);
7098
ok(EqualSid(sid, &medium_sid) || EqualSid(sid, &high_sid), "Got unexpected SID %s\n", str);
7099
*level = sid->SubAuthority[0];
7100
LocalFree(str);
7101
7102
ret = GetSecurityDescriptorDacl(sd, &present, &dacl, &defaulted);
7103
ok(ret, "GetSecurityDescriptorDacl failed with error %lu\n", GetLastError());
7104
todo_wine ok(!present, "DACL present\n");
7105
7106
free(sd);
7107
}
7108
7109
static void test_token_label(void)
7110
{
7111
SID low_sid = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
7112
{SECURITY_MANDATORY_LOW_RID}};
7113
char sacl_buffer[50];
7114
SECURITY_ATTRIBUTES attr = {.nLength = sizeof(SECURITY_ATTRIBUTES)};
7115
ACL *sacl = (ACL *)sacl_buffer;
7116
TOKEN_LINKED_TOKEN linked;
7117
DWORD level, level2, size;
7118
PSECURITY_DESCRIPTOR sd;
7119
HANDLE token, token2;
7120
BOOL ret;
7121
7122
if (!pAddMandatoryAce)
7123
{
7124
win_skip("Mandatory integrity control is not supported.\n");
7125
return;
7126
}
7127
7128
ret = OpenProcessToken(GetCurrentProcess(), READ_CONTROL | TOKEN_QUERY | TOKEN_DUPLICATE, &token);
7129
ok(ret, "OpenProcessToken failed with error %lu\n", GetLastError());
7130
7131
check_token_label(token, &level, TRUE);
7132
7133
ret = DuplicateTokenEx(token, READ_CONTROL, NULL, SecurityAnonymous, TokenPrimary, &token2);
7134
ok(ret, "Failed to duplicate token, error %lu\n", GetLastError());
7135
7136
check_token_label(token2, &level2, TRUE);
7137
ok(level2 == level, "Expected level %#lx, got %#lx.\n", level, level2);
7138
7139
CloseHandle(token2);
7140
7141
ret = DuplicateTokenEx(token, READ_CONTROL, NULL, SecurityImpersonation, TokenImpersonation, &token2);
7142
ok(ret, "Failed to duplicate token, error %lu\n", GetLastError());
7143
7144
check_token_label(token2, &level2, TRUE);
7145
ok(level2 == level, "Expected level %#lx, got %#lx.\n", level, level2);
7146
7147
CloseHandle(token2);
7148
7149
/* Any label set in the SD when calling DuplicateTokenEx() is ignored. */
7150
7151
ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
7152
ok(!ret, "expected failure\n");
7153
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got error %lu\n", GetLastError());
7154
7155
sd = malloc(size);
7156
ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd, size, &size);
7157
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
7158
7159
InitializeAcl(sacl, sizeof(sacl_buffer), ACL_REVISION);
7160
AddMandatoryAce(sacl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, &low_sid);
7161
SetSecurityDescriptorSacl(sd, TRUE, sacl, FALSE);
7162
7163
attr.lpSecurityDescriptor = sd;
7164
ret = DuplicateTokenEx(token, TOKEN_ALL_ACCESS, &attr, SecurityImpersonation, TokenImpersonation, &token2);
7165
ok(ret, "Failed to duplicate token, error %lu\n", GetLastError());
7166
7167
check_token_label(token2, &level2, TRUE);
7168
ok(level2 == level, "Expected level %#lx, got %#lx.\n", level, level2);
7169
7170
/* Trying to set a SD on the token also claims success but has no effect. */
7171
7172
ret = SetKernelObjectSecurity(token2, LABEL_SECURITY_INFORMATION, sd);
7173
ok(ret, "Failed to set SD, error %lu\n", GetLastError());
7174
7175
check_token_label(token2, &level2, FALSE);
7176
ok(level2 == level, "Expected level %#lx, got %#lx.\n", level, level2);
7177
7178
free(sd);
7179
7180
/* Test the linked token. */
7181
7182
ret = GetTokenInformation(token, TokenLinkedToken, &linked, sizeof(linked), &size);
7183
ok(ret, "Failed to get linked token, error %lu\n", GetLastError());
7184
7185
check_token_label(linked.LinkedToken, &level2, TRUE);
7186
ok(level2 == level, "Expected level %#lx, got %#lx.\n", level, level2);
7187
7188
CloseHandle(linked.LinkedToken);
7189
7190
CloseHandle(token);
7191
}
7192
7193
static void test_token_security_descriptor(void)
7194
{
7195
static SID low_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
7196
{SECURITY_MANDATORY_LOW_RID}};
7197
char buffer_sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
7198
SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *)&buffer_sd, *sd2;
7199
char buffer_acl[256], buffer[MAX_PATH];
7200
ACL *acl = (ACL *)&buffer_acl, *acl2, *acl_child;
7201
BOOL defaulted, present, ret, found;
7202
HANDLE token, token2, token3;
7203
EXPLICIT_ACCESSW exp_access;
7204
PROCESS_INFORMATION info;
7205
DWORD size, index, retd;
7206
ACCESS_ALLOWED_ACE *ace;
7207
SECURITY_ATTRIBUTES sa;
7208
STARTUPINFOA startup;
7209
PSID psid;
7210
7211
/* Test whether we can create tokens with security descriptors */
7212
ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token);
7213
ok(ret, "OpenProcessToken failed with error %lu\n", GetLastError());
7214
7215
ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
7216
ok(ret, "InitializeSecurityDescriptor failed with error %lu\n", GetLastError());
7217
7218
memset(buffer_acl, 0, sizeof(buffer_acl));
7219
ret = InitializeAcl(acl, 256, ACL_REVISION);
7220
ok(ret, "InitializeAcl failed with error %lu\n", GetLastError());
7221
7222
ret = ConvertStringSidToSidA("S-1-5-6", &psid);
7223
ok(ret, "ConvertStringSidToSidA failed with error %lu\n", GetLastError());
7224
7225
ret = AddAccessAllowedAceEx(acl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, GENERIC_ALL, psid);
7226
ok(ret, "AddAccessAllowedAceEx failed with error %lu\n", GetLastError());
7227
7228
ret = SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE);
7229
ok(ret, "SetSecurityDescriptorDacl failed with error %lu\n", GetLastError());
7230
7231
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
7232
sa.lpSecurityDescriptor = sd;
7233
sa.bInheritHandle = FALSE;
7234
7235
ret = DuplicateTokenEx(token, MAXIMUM_ALLOWED, &sa, SecurityImpersonation, TokenImpersonation, &token2);
7236
ok(ret, "DuplicateTokenEx failed with error %lu\n", GetLastError());
7237
7238
ret = GetKernelObjectSecurity(token2, DACL_SECURITY_INFORMATION, NULL, 0, &size);
7239
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7240
"Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError());
7241
7242
sd2 = malloc(size);
7243
ret = GetKernelObjectSecurity(token2, DACL_SECURITY_INFORMATION, sd2, size, &size);
7244
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
7245
7246
acl2 = (void *)0xdeadbeef;
7247
present = FALSE;
7248
defaulted = TRUE;
7249
ret = GetSecurityDescriptorDacl(sd2, &present, &acl2, &defaulted);
7250
ok(ret, "GetSecurityDescriptorDacl failed with error %lu\n", GetLastError());
7251
ok(present, "acl2 not present\n");
7252
ok(acl2 != (void *)0xdeadbeef, "acl2 not set\n");
7253
ok(acl2->AceCount == 1, "Expected 1 ACE, got %d\n", acl2->AceCount);
7254
ok(!defaulted, "acl2 defaulted\n");
7255
7256
ret = GetAce(acl2, 0, (void **)&ace);
7257
ok(ret, "GetAce failed with error %lu\n", GetLastError());
7258
ok(ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE, "Unexpected ACE type %#x\n", ace->Header.AceType);
7259
ok(EqualSid(&ace->SidStart, psid), "Expected access allowed ACE\n");
7260
ok(ace->Header.AceFlags == NO_PROPAGATE_INHERIT_ACE,
7261
"Expected NO_PROPAGATE_INHERIT_ACE as flags, got %x\n", ace->Header.AceFlags);
7262
7263
free(sd2);
7264
7265
/* Duplicate token without security attributes.
7266
* Tokens do not inherit the security descriptor in DuplicateToken. */
7267
ret = DuplicateTokenEx(token2, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenImpersonation, &token3);
7268
ok(ret, "DuplicateTokenEx failed with error %lu\n", GetLastError());
7269
7270
ret = GetKernelObjectSecurity(token3, DACL_SECURITY_INFORMATION, NULL, 0, &size);
7271
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7272
"Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError());
7273
7274
sd2 = malloc(size);
7275
ret = GetKernelObjectSecurity(token3, DACL_SECURITY_INFORMATION, sd2, size, &size);
7276
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
7277
7278
acl2 = (void *)0xdeadbeef;
7279
present = FALSE;
7280
defaulted = TRUE;
7281
ret = GetSecurityDescriptorDacl(sd2, &present, &acl2, &defaulted);
7282
ok(ret, "GetSecurityDescriptorDacl failed with error %lu\n", GetLastError());
7283
ok(present, "DACL not present\n");
7284
7285
ok(acl2 != (void *)0xdeadbeef, "DACL not set\n");
7286
ok(!defaulted, "DACL defaulted\n");
7287
7288
index = 0;
7289
found = FALSE;
7290
while (GetAce(acl2, index++, (void **)&ace))
7291
{
7292
if (ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE && EqualSid(&ace->SidStart, psid))
7293
found = TRUE;
7294
}
7295
ok(!found, "Access allowed ACE was inherited\n");
7296
7297
free(sd2);
7298
7299
/* When creating a child process, the process does inherit the token of
7300
* the parent but not the DACL of the token */
7301
ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, NULL, 0, &size);
7302
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7303
"Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError());
7304
7305
sd2 = malloc(size);
7306
ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, sd2, size, &size);
7307
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
7308
7309
acl2 = (void *)0xdeadbeef;
7310
present = FALSE;
7311
defaulted = TRUE;
7312
ret = GetSecurityDescriptorDacl(sd2, &present, &acl2, &defaulted);
7313
ok(ret, "GetSecurityDescriptorDacl failed with error %lu\n", GetLastError());
7314
ok(present, "DACL not present\n");
7315
ok(acl2 != (void *)0xdeadbeef, "DACL not set\n");
7316
ok(!defaulted, "DACL defaulted\n");
7317
7318
exp_access.grfAccessPermissions = GENERIC_ALL;
7319
exp_access.grfAccessMode = GRANT_ACCESS;
7320
exp_access.grfInheritance = NO_PROPAGATE_INHERIT_ACE;
7321
exp_access.Trustee.pMultipleTrustee = NULL;
7322
exp_access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
7323
exp_access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
7324
exp_access.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
7325
exp_access.Trustee.ptstrName = (void*)psid;
7326
7327
retd = SetEntriesInAclW(1, &exp_access, acl2, &acl_child);
7328
ok(retd == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %lu\n", retd);
7329
7330
memset(sd, 0, sizeof(buffer_sd));
7331
ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
7332
ok(ret, "InitializeSecurityDescriptor failed with error %lu\n", GetLastError());
7333
7334
ret = SetSecurityDescriptorDacl(sd, TRUE, acl_child, FALSE);
7335
ok(ret, "SetSecurityDescriptorDacl failed with error %lu\n", GetLastError());
7336
7337
ret = SetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, sd);
7338
ok(ret, "SetKernelObjectSecurity failed with error %lu\n", GetLastError());
7339
7340
/* The security label is also not inherited */
7341
if (pAddMandatoryAce)
7342
{
7343
ret = InitializeAcl(acl, 256, ACL_REVISION);
7344
ok(ret, "InitializeAcl failed with error %lu\n", GetLastError());
7345
7346
ret = pAddMandatoryAce(acl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, &low_level);
7347
ok(ret, "AddMandatoryAce failed with error %lu\n", GetLastError());
7348
7349
memset(sd, 0, sizeof(buffer_sd));
7350
ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
7351
ok(ret, "InitializeSecurityDescriptor failed with error %lu\n", GetLastError());
7352
7353
ret = SetSecurityDescriptorSacl(sd, TRUE, acl, FALSE);
7354
ok(ret, "SetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
7355
7356
ret = SetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd);
7357
ok(ret, "SetKernelObjectSecurity failed with error %lu\n", GetLastError());
7358
}
7359
else
7360
win_skip("SYSTEM_MANDATORY_LABEL not supported\n");
7361
7362
/* Start child process with our modified token */
7363
memset(&startup, 0, sizeof(startup));
7364
startup.cb = sizeof(startup);
7365
startup.dwFlags = STARTF_USESHOWWINDOW;
7366
startup.wShowWindow = SW_SHOWNORMAL;
7367
7368
sprintf(buffer, "%s security test_token_sd", myARGV[0]);
7369
ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info);
7370
ok(ret, "CreateProcess failed with error %lu\n", GetLastError());
7371
wait_child_process(&info);
7372
7373
LocalFree(acl_child);
7374
free(sd2);
7375
LocalFree(psid);
7376
7377
CloseHandle(token3);
7378
CloseHandle(token2);
7379
CloseHandle(token);
7380
}
7381
7382
static void test_child_token_sd(void)
7383
{
7384
static SID low_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
7385
{SECURITY_MANDATORY_LOW_RID}};
7386
SYSTEM_MANDATORY_LABEL_ACE *ace_label;
7387
BOOL ret, present, defaulted;
7388
ACCESS_ALLOWED_ACE *acc_ace;
7389
SECURITY_DESCRIPTOR *sd;
7390
DWORD size, i;
7391
HANDLE token;
7392
PSID psid;
7393
ACL *acl;
7394
7395
ret = ConvertStringSidToSidA("S-1-5-6", &psid);
7396
ok(ret, "ConvertStringSidToSidA failed with error %lu\n", GetLastError());
7397
7398
ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token);
7399
ok(ret, "OpenProcessToken failed with error %lu\n", GetLastError());
7400
7401
ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, NULL, 0, &size);
7402
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7403
"Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError());
7404
7405
sd = malloc(size);
7406
ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, sd, size, &size);
7407
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
7408
7409
acl = NULL;
7410
present = FALSE;
7411
defaulted = TRUE;
7412
ret = GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted);
7413
ok(ret, "GetSecurityDescriptorDacl failed with error %lu\n", GetLastError());
7414
ok(present, "DACL not present\n");
7415
ok(acl && acl != (void *)0xdeadbeef, "Got invalid DACL\n");
7416
ok(!defaulted, "DACL defaulted\n");
7417
7418
ok(acl->AceCount, "Expected at least one ACE\n");
7419
for (i = 0; i < acl->AceCount; i++)
7420
{
7421
ret = GetAce(acl, i, (void **)&acc_ace);
7422
ok(ret, "GetAce failed with error %lu\n", GetLastError());
7423
ok(acc_ace->Header.AceType != ACCESS_ALLOWED_ACE_TYPE || !EqualSid(&acc_ace->SidStart, psid),
7424
"ACE inherited from the parent\n");
7425
}
7426
7427
LocalFree(psid);
7428
free(sd);
7429
7430
if (!pAddMandatoryAce)
7431
{
7432
win_skip("SYSTEM_MANDATORY_LABEL not supported\n");
7433
return;
7434
}
7435
7436
ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
7437
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
7438
"Unexpected GetKernelObjectSecurity return value %d, error %lu\n", ret, GetLastError());
7439
7440
sd = malloc(size);
7441
ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd, size, &size);
7442
ok(ret, "GetKernelObjectSecurity failed with error %lu\n", GetLastError());
7443
7444
acl = NULL;
7445
present = FALSE;
7446
defaulted = TRUE;
7447
ret = GetSecurityDescriptorSacl(sd, &present, &acl, &defaulted);
7448
ok(ret, "GetSecurityDescriptorSacl failed with error %lu\n", GetLastError());
7449
ok(present, "SACL not present\n");
7450
ok(acl && acl != (void *)0xdeadbeef, "Got invalid SACL\n");
7451
ok(!defaulted, "SACL defaulted\n");
7452
ok(acl->AceCount == 1, "Expected exactly one ACE\n");
7453
ret = GetAce(acl, 0, (void **)&ace_label);
7454
ok(ret, "GetAce failed with error %lu\n", GetLastError());
7455
ok(ace_label->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE,
7456
"Unexpected ACE type %#x\n", ace_label->Header.AceType);
7457
ok(!EqualSid(&ace_label->SidStart, &low_level),
7458
"Low integrity level should not have been inherited\n");
7459
7460
free(sd);
7461
}
7462
7463
static void test_GetExplicitEntriesFromAclW(void)
7464
{
7465
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
7466
SID_IDENTIFIER_AUTHORITY SIDAuthNT = { SECURITY_NT_AUTHORITY };
7467
PSID everyone_sid = NULL, users_sid = NULL;
7468
EXPLICIT_ACCESSW access;
7469
EXPLICIT_ACCESSW *access2;
7470
PACL new_acl, old_acl = NULL;
7471
ULONG count;
7472
DWORD res;
7473
7474
old_acl = malloc(256);
7475
res = InitializeAcl(old_acl, 256, ACL_REVISION);
7476
ok(res, "InitializeAcl failed with error %ld\n", GetLastError());
7477
7478
res = AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &everyone_sid);
7479
ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
7480
7481
res = AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
7482
DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &users_sid);
7483
ok(res, "AllocateAndInitializeSid failed with error %ld\n", GetLastError());
7484
7485
res = AddAccessAllowedAce(old_acl, ACL_REVISION, KEY_READ, users_sid);
7486
ok(res, "AddAccessAllowedAce failed with error %ld\n", GetLastError());
7487
7488
access2 = NULL;
7489
res = GetExplicitEntriesFromAclW(old_acl, &count, &access2);
7490
ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %ld\n", GetLastError());
7491
ok(count == 1, "Expected count == 1, got %ld\n", count);
7492
ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode);
7493
ok(access2[0].grfAccessPermissions == KEY_READ, "Expected KEY_READ, got %ld\n", access2[0].grfAccessPermissions);
7494
ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm);
7495
ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %lx\n", access2[0].grfInheritance);
7496
ok(EqualSid(access2[0].Trustee.ptstrName, users_sid), "Expected equal SIDs\n");
7497
LocalFree(access2);
7498
7499
access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
7500
access.Trustee.pMultipleTrustee = NULL;
7501
7502
access.grfAccessPermissions = KEY_WRITE;
7503
access.grfAccessMode = GRANT_ACCESS;
7504
access.grfInheritance = NO_INHERITANCE;
7505
access.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
7506
access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
7507
access.Trustee.ptstrName = everyone_sid;
7508
res = SetEntriesInAclW(1, &access, old_acl, &new_acl);
7509
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
7510
ok(new_acl != NULL, "returned acl was NULL\n");
7511
7512
access2 = NULL;
7513
res = GetExplicitEntriesFromAclW(new_acl, &count, &access2);
7514
ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %ld\n", GetLastError());
7515
ok(count == 2, "Expected count == 2, got %ld\n", count);
7516
ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode);
7517
ok(access2[0].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %ld\n", access2[0].grfAccessPermissions);
7518
ok(access2[0].Trustee.TrusteeType == TRUSTEE_IS_UNKNOWN,
7519
"Expected TRUSTEE_IS_UNKNOWN trustee type, got %d\n", access2[0].Trustee.TrusteeType);
7520
ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm);
7521
ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %lx\n", access2[0].grfInheritance);
7522
ok(EqualSid(access2[0].Trustee.ptstrName, everyone_sid), "Expected equal SIDs\n");
7523
LocalFree(access2);
7524
LocalFree(new_acl);
7525
7526
access.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
7527
res = SetEntriesInAclW(1, &access, old_acl, &new_acl);
7528
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
7529
ok(new_acl != NULL, "returned acl was NULL\n");
7530
7531
access2 = NULL;
7532
res = GetExplicitEntriesFromAclW(new_acl, &count, &access2);
7533
ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %ld\n", GetLastError());
7534
ok(count == 2, "Expected count == 2, got %ld\n", count);
7535
ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode);
7536
ok(access2[0].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %ld\n", access2[0].grfAccessPermissions);
7537
ok(access2[0].Trustee.TrusteeType == TRUSTEE_IS_UNKNOWN,
7538
"Expected TRUSTEE_IS_UNKNOWN trustee type, got %d\n", access2[0].Trustee.TrusteeType);
7539
ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm);
7540
ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %lx\n", access2[0].grfInheritance);
7541
ok(EqualSid(access2[0].Trustee.ptstrName, everyone_sid), "Expected equal SIDs\n");
7542
LocalFree(access2);
7543
LocalFree(new_acl);
7544
7545
access.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
7546
access.Trustee.ptstrName = (WCHAR *)L"CURRENT_USER";
7547
res = SetEntriesInAclW(1, &access, old_acl, &new_acl);
7548
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
7549
ok(new_acl != NULL, "returned acl was NULL\n");
7550
7551
access2 = NULL;
7552
res = GetExplicitEntriesFromAclW(new_acl, &count, &access2);
7553
ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %ld\n", GetLastError());
7554
ok(count == 2, "Expected count == 2, got %ld\n", count);
7555
ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode);
7556
ok(access2[0].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %ld\n", access2[0].grfAccessPermissions);
7557
ok(access2[0].Trustee.TrusteeType == TRUSTEE_IS_UNKNOWN,
7558
"Expected TRUSTEE_IS_UNKNOWN trustee type, got %d\n", access2[0].Trustee.TrusteeType);
7559
ok(access2[0].Trustee.TrusteeForm == TRUSTEE_IS_SID, "Expected SID trustee, got %d\n", access2[0].Trustee.TrusteeForm);
7560
ok(access2[0].grfInheritance == NO_INHERITANCE, "Expected NO_INHERITANCE, got %lx\n", access2[0].grfInheritance);
7561
LocalFree(access2);
7562
LocalFree(new_acl);
7563
7564
access.grfAccessMode = REVOKE_ACCESS;
7565
access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
7566
access.Trustee.ptstrName = users_sid;
7567
res = SetEntriesInAclW(1, &access, old_acl, &new_acl);
7568
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
7569
ok(new_acl != NULL, "returned acl was NULL\n");
7570
7571
access2 = (void *)0xdeadbeef;
7572
res = GetExplicitEntriesFromAclW(new_acl, &count, &access2);
7573
ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %ld\n", GetLastError());
7574
ok(count == 0, "Expected count == 0, got %ld\n", count);
7575
ok(access2 == NULL, "access2 was not NULL\n");
7576
LocalFree(new_acl);
7577
7578
/* Make the ACL both Allow and Deny Everyone. */
7579
res = AddAccessAllowedAce(old_acl, ACL_REVISION, KEY_READ, everyone_sid);
7580
ok(res, "AddAccessAllowedAce failed with error %ld\n", GetLastError());
7581
res = AddAccessDeniedAce(old_acl, ACL_REVISION, KEY_WRITE, everyone_sid);
7582
ok(res, "AddAccessDeniedAce failed with error %ld\n", GetLastError());
7583
/* Revoke Everyone. */
7584
access.Trustee.ptstrName = everyone_sid;
7585
access.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
7586
access.grfAccessPermissions = 0;
7587
new_acl = NULL;
7588
res = SetEntriesInAclW(1, &access, old_acl, &new_acl);
7589
ok(res == ERROR_SUCCESS, "SetEntriesInAclW failed: %lu\n", res);
7590
ok(new_acl != NULL, "returned acl was NULL\n");
7591
/* Deny Everyone should remain (along with Grant Users from earlier). */
7592
access2 = NULL;
7593
res = GetExplicitEntriesFromAclW(new_acl, &count, &access2);
7594
ok(res == ERROR_SUCCESS, "GetExplicitEntriesFromAclW failed with error %ld\n", GetLastError());
7595
ok(count == 2, "Expected count == 2, got %ld\n", count);
7596
ok(access2[0].grfAccessMode == GRANT_ACCESS, "Expected GRANT_ACCESS, got %d\n", access2[0].grfAccessMode);
7597
ok(access2[0].grfAccessPermissions == KEY_READ , "Expected KEY_READ, got %ld\n", access2[0].grfAccessPermissions);
7598
ok(EqualSid(access2[0].Trustee.ptstrName, users_sid), "Expected equal SIDs\n");
7599
ok(access2[1].grfAccessMode == DENY_ACCESS, "Expected DENY_ACCESS, got %d\n", access2[1].grfAccessMode);
7600
ok(access2[1].grfAccessPermissions == KEY_WRITE, "Expected KEY_WRITE, got %ld\n", access2[1].grfAccessPermissions);
7601
ok(EqualSid(access2[1].Trustee.ptstrName, everyone_sid), "Expected equal SIDs\n");
7602
LocalFree(access2);
7603
7604
FreeSid(users_sid);
7605
FreeSid(everyone_sid);
7606
free(old_acl);
7607
}
7608
7609
static void test_BuildSecurityDescriptorW(void)
7610
{
7611
SECURITY_DESCRIPTOR old_sd, *new_sd, *rel_sd;
7612
ULONG new_sd_size;
7613
DWORD buf_size;
7614
char buf[1024];
7615
BOOL success;
7616
DWORD ret;
7617
7618
InitializeSecurityDescriptor(&old_sd, SECURITY_DESCRIPTOR_REVISION);
7619
7620
buf_size = sizeof(buf);
7621
rel_sd = (SECURITY_DESCRIPTOR *)buf;
7622
success = MakeSelfRelativeSD(&old_sd, rel_sd, &buf_size);
7623
ok(success, "MakeSelfRelativeSD failed with %lu\n", GetLastError());
7624
7625
new_sd = NULL;
7626
new_sd_size = 0;
7627
ret = BuildSecurityDescriptorW(NULL, NULL, 0, NULL, 0, NULL, NULL, &new_sd_size, (void **)&new_sd);
7628
ok(ret == ERROR_SUCCESS, "BuildSecurityDescriptor failed with %lu\n", ret);
7629
ok(new_sd != NULL, "expected new_sd != NULL\n");
7630
LocalFree(new_sd);
7631
7632
new_sd = (void *)0xdeadbeef;
7633
ret = BuildSecurityDescriptorW(NULL, NULL, 0, NULL, 0, NULL, &old_sd, &new_sd_size, (void **)&new_sd);
7634
ok(ret == ERROR_INVALID_SECURITY_DESCR, "expected ERROR_INVALID_SECURITY_DESCR, got %lu\n", ret);
7635
ok(new_sd == (void *)0xdeadbeef, "expected new_sd == 0xdeadbeef, got %p\n", new_sd);
7636
7637
new_sd = NULL;
7638
new_sd_size = 0;
7639
ret = BuildSecurityDescriptorW(NULL, NULL, 0, NULL, 0, NULL, rel_sd, &new_sd_size, (void **)&new_sd);
7640
ok(ret == ERROR_SUCCESS, "BuildSecurityDescriptor failed with %lu\n", ret);
7641
ok(new_sd != NULL, "expected new_sd != NULL\n");
7642
LocalFree(new_sd);
7643
}
7644
7645
static void test_EqualDomainSid(void)
7646
{
7647
SID_IDENTIFIER_AUTHORITY ident = { SECURITY_NT_AUTHORITY };
7648
char sid_buffer[SECURITY_MAX_SID_SIZE], sid_buffer2[SECURITY_MAX_SID_SIZE];
7649
PSID domainsid, sid = sid_buffer, sid2 = sid_buffer2;
7650
DWORD size;
7651
BOOL ret, equal;
7652
unsigned int i;
7653
7654
ret = AllocateAndInitializeSid(&ident, 6, SECURITY_NT_NON_UNIQUE, 12, 23, 34, 45, 56, 0, 0, &domainsid);
7655
ok(ret, "AllocateAndInitializeSid error %lu\n", GetLastError());
7656
7657
SetLastError(0xdeadbeef);
7658
ret = EqualDomainSid(NULL, NULL, NULL);
7659
ok(!ret, "got %d\n", ret);
7660
ok(GetLastError() == ERROR_INVALID_SID, "got %lu\n", GetLastError());
7661
7662
SetLastError(0xdeadbeef);
7663
ret = EqualDomainSid(domainsid, domainsid, NULL);
7664
ok(!ret, "got %d\n", ret);
7665
ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError());
7666
7667
for (i = 0; i < ARRAY_SIZE(well_known_sid_values); i++)
7668
{
7669
SID *pisid = sid;
7670
7671
size = sizeof(sid_buffer);
7672
if (!CreateWellKnownSid(i, NULL, sid, &size))
7673
{
7674
trace("Well known SID %u not supported\n", i);
7675
continue;
7676
}
7677
7678
equal = 0xdeadbeef;
7679
SetLastError(0xdeadbeef);
7680
ret = EqualDomainSid(sid, domainsid, &equal);
7681
if (pisid->SubAuthority[0] != SECURITY_BUILTIN_DOMAIN_RID)
7682
{
7683
ok(!ret, "%u: got %d\n", i, ret);
7684
ok(GetLastError() == ERROR_NON_DOMAIN_SID, "%u: got %lu\n", i, GetLastError());
7685
ok(equal == 0xdeadbeef, "%u: got %d\n", i, equal);
7686
continue;
7687
}
7688
7689
ok(ret, "%u: got %d\n", i, ret);
7690
ok(GetLastError() == 0, "%u: got %lu\n", i, GetLastError());
7691
ok(equal == 0, "%u: got %d\n", i, equal);
7692
7693
size = sizeof(sid_buffer2);
7694
ret = CreateWellKnownSid(i, well_known_sid_values[i].without_domain ? NULL : domainsid, sid2, &size);
7695
ok(ret, "%u: CreateWellKnownSid error %lu\n", i, GetLastError());
7696
7697
equal = 0xdeadbeef;
7698
SetLastError(0xdeadbeef);
7699
ret = EqualDomainSid(sid, sid2, &equal);
7700
ok(ret, "%u: got %d\n", i, ret);
7701
ok(GetLastError() == 0, "%u: got %lu\n", i, GetLastError());
7702
ok(equal == 1, "%u: got %d\n", i, equal);
7703
}
7704
7705
FreeSid(domainsid);
7706
}
7707
7708
static DWORD WINAPI duplicate_handle_access_thread(void *arg)
7709
{
7710
HANDLE event = arg, event2;
7711
BOOL ret;
7712
7713
event2 = OpenEventA(SYNCHRONIZE, FALSE, "test_dup");
7714
ok(!!event2, "got error %lu\n", GetLastError());
7715
CloseHandle(event2);
7716
7717
event2 = OpenEventA(EVENT_MODIFY_STATE, FALSE, "test_dup");
7718
ok(!!event2, "got error %lu\n", GetLastError());
7719
CloseHandle(event2);
7720
7721
ret = DuplicateHandle(GetCurrentProcess(), event, GetCurrentProcess(),
7722
&event2, EVENT_MODIFY_STATE, FALSE, 0);
7723
ok(ret, "got error %lu\n", GetLastError());
7724
CloseHandle(event2);
7725
7726
return 0;
7727
}
7728
7729
static void test_duplicate_handle_access(void)
7730
{
7731
char acl_buffer[200], everyone_sid_buffer[100], local_sid_buffer[100], cmdline[300];
7732
HANDLE token, restricted, impersonation, all_event, sync_event, event2, thread;
7733
SECURITY_ATTRIBUTES sa = {.nLength = sizeof(sa)};
7734
SID *everyone_sid = (SID *)everyone_sid_buffer;
7735
SID *local_sid = (SID *)local_sid_buffer;
7736
ACL *acl = (ACL *)acl_buffer;
7737
SID_AND_ATTRIBUTES sid_attr;
7738
SECURITY_DESCRIPTOR sd;
7739
PROCESS_INFORMATION pi;
7740
STARTUPINFOA si = {0};
7741
DWORD size;
7742
BOOL ret;
7743
7744
/* DuplicateHandle() validates access against the calling thread's token and
7745
* the target process's token. It does *not* validate access against the
7746
* calling process's token, even if the calling thread is not impersonating.
7747
*/
7748
7749
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, &token);
7750
ok(ret, "got error %lu\n", GetLastError());
7751
7752
size = sizeof(everyone_sid_buffer);
7753
ret = CreateWellKnownSid(WinWorldSid, NULL, everyone_sid, &size);
7754
ok(ret, "got error %lu\n", GetLastError());
7755
size = sizeof(local_sid_buffer);
7756
ret = CreateWellKnownSid(WinLocalSid, NULL, local_sid, &size);
7757
ok(ret, "got error %lu\n", GetLastError());
7758
7759
InitializeAcl(acl, sizeof(acl_buffer), ACL_REVISION);
7760
ret = AddAccessAllowedAce(acl, ACL_REVISION, SYNCHRONIZE, everyone_sid);
7761
ok(ret, "got error %lu\n", GetLastError());
7762
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
7763
ret = AddAccessAllowedAce(acl, ACL_REVISION, EVENT_MODIFY_STATE, local_sid);
7764
ok(ret, "got error %lu\n", GetLastError());
7765
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
7766
ret = SetSecurityDescriptorDacl(&sd, TRUE, acl, FALSE);
7767
ok(ret, "got error %lu\n", GetLastError());
7768
sa.lpSecurityDescriptor = &sd;
7769
7770
sid_attr.Sid = local_sid;
7771
sid_attr.Attributes = 0;
7772
ret = CreateRestrictedToken(token, 0, 1, &sid_attr, 0, NULL, 0, NULL, &restricted);
7773
ok(ret, "got error %lu\n", GetLastError());
7774
ret = DuplicateTokenEx(restricted, TOKEN_IMPERSONATE, NULL,
7775
SecurityImpersonation, TokenImpersonation, &impersonation);
7776
ok(ret, "got error %lu\n", GetLastError());
7777
7778
all_event = CreateEventA(&sa, TRUE, TRUE, "test_dup");
7779
ok(!!all_event, "got error %lu\n", GetLastError());
7780
sync_event = OpenEventA(SYNCHRONIZE, FALSE, "test_dup");
7781
ok(!!sync_event, "got error %lu\n", GetLastError());
7782
7783
event2 = OpenEventA(SYNCHRONIZE, FALSE, "test_dup");
7784
ok(!!event2, "got error %lu\n", GetLastError());
7785
CloseHandle(event2);
7786
7787
event2 = OpenEventA(EVENT_MODIFY_STATE, FALSE, "test_dup");
7788
ok(!!event2, "got error %lu\n", GetLastError());
7789
CloseHandle(event2);
7790
7791
ret = DuplicateHandle(GetCurrentProcess(), all_event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0);
7792
ok(ret, "got error %lu\n", GetLastError());
7793
CloseHandle(event2);
7794
7795
ret = DuplicateHandle(GetCurrentProcess(), sync_event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0);
7796
ok(ret, "got error %lu\n", GetLastError());
7797
CloseHandle(event2);
7798
7799
ret = SetThreadToken(NULL, impersonation);
7800
ok(ret, "got error %lu\n", GetLastError());
7801
7802
thread = CreateThread(NULL, 0, duplicate_handle_access_thread, sync_event, 0, NULL);
7803
ret = WaitForSingleObject(thread, 1000);
7804
ok(!ret, "wait failed\n");
7805
7806
event2 = OpenEventA(SYNCHRONIZE, FALSE, "test_dup");
7807
ok(!!event2, "got error %lu\n", GetLastError());
7808
CloseHandle(event2);
7809
7810
SetLastError(0xdeadbeef);
7811
event2 = OpenEventA(EVENT_MODIFY_STATE, FALSE, "test_dup");
7812
ok(!event2, "expected failure\n");
7813
ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
7814
7815
ret = DuplicateHandle(GetCurrentProcess(), all_event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0);
7816
ok(ret, "got error %lu\n", GetLastError());
7817
CloseHandle(event2);
7818
7819
SetLastError(0xdeadbeef);
7820
ret = DuplicateHandle(GetCurrentProcess(), sync_event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0);
7821
ok(!ret, "expected failure\n");
7822
ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
7823
7824
ret = RevertToSelf();
7825
ok(ret, "got error %lu\n", GetLastError());
7826
7827
sprintf(cmdline, "%s security duplicate %Iu %lu %Iu", myARGV[0],
7828
(ULONG_PTR)sync_event, GetCurrentProcessId(), (ULONG_PTR)impersonation );
7829
ret = CreateProcessAsUserA(restricted, NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
7830
ok(ret, "got error %lu\n", GetLastError());
7831
7832
ret = DuplicateHandle(GetCurrentProcess(), all_event, pi.hProcess, &event2, EVENT_MODIFY_STATE, FALSE, 0);
7833
ok(ret, "got error %lu\n", GetLastError());
7834
7835
SetLastError(0xdeadbeef);
7836
ret = DuplicateHandle(GetCurrentProcess(), sync_event, pi.hProcess, &event2, EVENT_MODIFY_STATE, FALSE, 0);
7837
ok(!ret, "expected failure\n");
7838
ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
7839
7840
ret = WaitForSingleObject(pi.hProcess, 1000);
7841
ok(!ret, "wait failed\n");
7842
7843
CloseHandle(impersonation);
7844
CloseHandle(restricted);
7845
CloseHandle(token);
7846
CloseHandle(sync_event);
7847
CloseHandle(all_event);
7848
}
7849
7850
static void test_duplicate_handle_access_child(void)
7851
{
7852
HANDLE event, event2, process, token;
7853
BOOL ret;
7854
7855
event = (HANDLE)(ULONG_PTR)_atoi64(myARGV[3]);
7856
process = OpenProcess(PROCESS_DUP_HANDLE, FALSE, atoi(myARGV[4]));
7857
ok(!!process, "failed to open process, error %lu\n", GetLastError());
7858
7859
event2 = OpenEventA(SYNCHRONIZE, FALSE, "test_dup");
7860
ok(!!event2, "got error %lu\n", GetLastError());
7861
CloseHandle(event2);
7862
7863
SetLastError(0xdeadbeef);
7864
event2 = OpenEventA(EVENT_MODIFY_STATE, FALSE, "test_dup");
7865
ok(!event2, "expected failure\n");
7866
ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
7867
7868
ret = DuplicateHandle(process, event, process, &event2, EVENT_MODIFY_STATE, FALSE, 0);
7869
ok(ret, "got error %lu\n", GetLastError());
7870
7871
SetLastError(0xdeadbeef);
7872
ret = DuplicateHandle(process, event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0);
7873
ok(!ret, "expected failure\n");
7874
ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
7875
7876
ret = DuplicateHandle(process, (HANDLE)(ULONG_PTR)_atoi64(myARGV[5]),
7877
GetCurrentProcess(), &token, 0, FALSE, DUPLICATE_SAME_ACCESS);
7878
ok(ret, "failed to retrieve token, error %lu\n", GetLastError());
7879
ret = SetThreadToken(NULL, token);
7880
ok(ret, "failed to set thread token, error %lu\n", GetLastError());
7881
7882
SetLastError(0xdeadbeef);
7883
ret = DuplicateHandle(process, event, process, &event2, EVENT_MODIFY_STATE, FALSE, 0);
7884
ok(!ret, "expected failure\n");
7885
ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
7886
7887
SetLastError(0xdeadbeef);
7888
ret = DuplicateHandle(process, event, GetCurrentProcess(), &event2, EVENT_MODIFY_STATE, FALSE, 0);
7889
ok(!ret, "expected failure\n");
7890
ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
7891
7892
ret = RevertToSelf();
7893
ok(ret, "failed to revert, error %lu\n", GetLastError());
7894
CloseHandle(token);
7895
CloseHandle(process);
7896
}
7897
7898
#define join_process(a) join_process_(__LINE__, a)
7899
static void join_process_(int line, const PROCESS_INFORMATION *pi)
7900
{
7901
DWORD ret = WaitForSingleObject(pi->hProcess, 1000);
7902
ok_(__FILE__, line)(!ret, "wait failed\n");
7903
CloseHandle(pi->hProcess);
7904
CloseHandle(pi->hThread);
7905
}
7906
7907
static void test_create_process_token(void)
7908
{
7909
char cmdline[300], acl_buffer[200], sid_buffer[100];
7910
SECURITY_ATTRIBUTES sa = {.nLength = sizeof(sa)};
7911
ACL *acl = (ACL *)acl_buffer;
7912
SID *sid = (SID *)sid_buffer;
7913
SID_AND_ATTRIBUTES sid_attr;
7914
HANDLE event, token, token2;
7915
PROCESS_INFORMATION pi;
7916
SECURITY_DESCRIPTOR sd;
7917
STARTUPINFOA si = {0};
7918
DWORD size;
7919
BOOL ret;
7920
7921
size = sizeof(sid_buffer);
7922
ret = CreateWellKnownSid(WinLocalSid, NULL, sid, &size);
7923
ok(ret, "got error %lu\n", GetLastError());
7924
ret = InitializeAcl(acl, sizeof(acl_buffer), ACL_REVISION);
7925
ok(ret, "got error %lu\n", GetLastError());
7926
ret = AddAccessAllowedAce(acl, ACL_REVISION, EVENT_MODIFY_STATE, sid);
7927
ok(ret, "got error %lu\n", GetLastError());
7928
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
7929
ret = SetSecurityDescriptorDacl(&sd, TRUE, acl, FALSE);
7930
ok(ret, "got error %lu\n", GetLastError());
7931
sa.lpSecurityDescriptor = &sd;
7932
event = CreateEventA(&sa, TRUE, TRUE, "test_event");
7933
ok(!!event, "got error %lu\n", GetLastError());
7934
7935
sprintf(cmdline, "%s security restricted 0", myARGV[0]);
7936
7937
ret = CreateProcessAsUserA(NULL, NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
7938
ok(ret, "got error %lu\n", GetLastError());
7939
join_process(&pi);
7940
7941
ret = CreateProcessAsUserA(GetCurrentProcessToken(), NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
7942
todo_wine ok(!ret, "expected failure\n");
7943
todo_wine ok(GetLastError() == ERROR_INVALID_HANDLE, "got error %lu\n", GetLastError());
7944
if (ret) join_process(&pi);
7945
7946
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, &token);
7947
ok(ret, "got error %lu\n", GetLastError());
7948
ret = CreateProcessAsUserA(token, NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
7949
ok(ret || broken(GetLastError() == ERROR_ACCESS_DENIED) /* < 7 */, "got error %lu\n", GetLastError());
7950
if (ret) join_process(&pi);
7951
CloseHandle(token);
7952
7953
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
7954
ok(ret, "got error %lu\n", GetLastError());
7955
ret = CreateProcessAsUserA(token, NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
7956
ok(!ret, "expected failure\n");
7957
ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
7958
CloseHandle(token);
7959
7960
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_ASSIGN_PRIMARY, &token);
7961
ok(ret, "got error %lu\n", GetLastError());
7962
ret = CreateProcessAsUserA(token, NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
7963
ok(!ret, "expected failure\n");
7964
ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
7965
CloseHandle(token);
7966
7967
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE, &token);
7968
ok(ret, "got error %lu\n", GetLastError());
7969
7970
ret = DuplicateTokenEx(token, TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, NULL,
7971
SecurityImpersonation, TokenImpersonation, &token2);
7972
ok(ret, "got error %lu\n", GetLastError());
7973
ret = CreateProcessAsUserA(token2, NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
7974
ok(ret || broken(GetLastError() == ERROR_BAD_TOKEN_TYPE) /* < 7 */, "got error %lu\n", GetLastError());
7975
if (ret) join_process(&pi);
7976
CloseHandle(token2);
7977
7978
sprintf(cmdline, "%s security restricted 1", myARGV[0]);
7979
sid_attr.Sid = sid;
7980
sid_attr.Attributes = 0;
7981
ret = CreateRestrictedToken(token, 0, 1, &sid_attr, 0, NULL, 0, NULL, &token2);
7982
ok(ret, "got error %lu\n", GetLastError());
7983
ret = CreateProcessAsUserA(token2, NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
7984
ok(ret, "got error %lu\n", GetLastError());
7985
join_process(&pi);
7986
CloseHandle(token2);
7987
7988
CloseHandle(token);
7989
7990
CloseHandle(event);
7991
}
7992
7993
static void test_create_process_token_child(void)
7994
{
7995
HANDLE event;
7996
7997
SetLastError(0xdeadbeef);
7998
event = OpenEventA(EVENT_MODIFY_STATE, FALSE, "test_event");
7999
if (!atoi(myARGV[3]))
8000
{
8001
ok(!!event, "got error %lu\n", GetLastError());
8002
CloseHandle(event);
8003
}
8004
else
8005
{
8006
ok(!event, "expected failure\n");
8007
ok(GetLastError() == ERROR_ACCESS_DENIED, "got error %lu\n", GetLastError());
8008
}
8009
}
8010
8011
static void test_pseudo_handle_security(void)
8012
{
8013
char buffer[200];
8014
PSECURITY_DESCRIPTOR sd = buffer, sd_ptr;
8015
unsigned int i;
8016
DWORD size;
8017
BOOL ret;
8018
8019
static const HKEY keys[] =
8020
{
8021
HKEY_CLASSES_ROOT,
8022
HKEY_CURRENT_USER,
8023
HKEY_LOCAL_MACHINE,
8024
HKEY_USERS,
8025
HKEY_PERFORMANCE_DATA,
8026
HKEY_CURRENT_CONFIG,
8027
HKEY_DYN_DATA,
8028
};
8029
8030
ret = GetKernelObjectSecurity(GetCurrentProcess(), OWNER_SECURITY_INFORMATION, &sd, sizeof(buffer), &size);
8031
ok(ret, "got error %lu\n", GetLastError());
8032
8033
ret = GetKernelObjectSecurity(GetCurrentThread(), OWNER_SECURITY_INFORMATION, &sd, sizeof(buffer), &size);
8034
ok(ret, "got error %lu\n", GetLastError());
8035
8036
for (i = 0; i < ARRAY_SIZE(keys); ++i)
8037
{
8038
SetLastError(0xdeadbeef);
8039
ret = GetKernelObjectSecurity(keys[i], OWNER_SECURITY_INFORMATION, &sd, sizeof(buffer), &size);
8040
ok(!ret, "key %p: expected failure\n", keys[i]);
8041
ok(GetLastError() == ERROR_INVALID_HANDLE, "key %p: got error %lu\n", keys[i], GetLastError());
8042
8043
ret = GetSecurityInfo(keys[i], SE_REGISTRY_KEY,
8044
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &sd_ptr);
8045
if (keys[i] == HKEY_PERFORMANCE_DATA)
8046
ok(ret == ERROR_INVALID_HANDLE, "key %p: got error %u\n", keys[i], ret);
8047
else if (keys[i] == HKEY_DYN_DATA)
8048
todo_wine ok(ret == ERROR_CALL_NOT_IMPLEMENTED || broken(ret == ERROR_INVALID_HANDLE) /* <7 */,
8049
"key %p: got error %u\n", keys[i], ret);
8050
else
8051
ok(!ret, "key %p: got error %u\n", keys[i], ret);
8052
if (!ret) LocalFree(sd_ptr);
8053
8054
ret = GetSecurityInfo(keys[i], SE_KERNEL_OBJECT,
8055
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &sd_ptr);
8056
ok(ret == ERROR_INVALID_HANDLE, "key %p: got error %u\n", keys[i], ret);
8057
}
8058
}
8059
8060
static const LUID_AND_ATTRIBUTES *find_privilege(const TOKEN_PRIVILEGES *privs, const LUID *luid)
8061
{
8062
DWORD i;
8063
8064
for (i = 0; i < privs->PrivilegeCount; ++i)
8065
{
8066
if (!memcmp(luid, &privs->Privileges[i].Luid, sizeof(LUID)))
8067
return &privs->Privileges[i];
8068
}
8069
8070
return NULL;
8071
}
8072
8073
static void test_duplicate_token(void)
8074
{
8075
const DWORD orig_access = TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT | TOKEN_ADJUST_PRIVILEGES;
8076
char prev_privs_buffer[128], ret_privs_buffer[1024];
8077
TOKEN_PRIVILEGES *prev_privs = (void *)prev_privs_buffer;
8078
TOKEN_PRIVILEGES *ret_privs = (void *)ret_privs_buffer;
8079
const LUID_AND_ATTRIBUTES *priv;
8080
TOKEN_PRIVILEGES privs;
8081
SECURITY_QUALITY_OF_SERVICE qos = {.Length = sizeof(qos)};
8082
OBJECT_ATTRIBUTES attr = {.Length = sizeof(attr)};
8083
SECURITY_IMPERSONATION_LEVEL level;
8084
HANDLE token, token2;
8085
DWORD size;
8086
BOOL ret;
8087
8088
ret = OpenProcessToken(GetCurrentProcess(), orig_access, &token);
8089
ok(ret, "got error %lu\n", GetLastError());
8090
8091
/* Disable a privilege, to see if that privilege modification is preserved
8092
* in the duplicated tokens. */
8093
privs.PrivilegeCount = 1;
8094
ret = LookupPrivilegeValueA(NULL, "SeChangeNotifyPrivilege", &privs.Privileges[0].Luid);
8095
ok(ret, "got error %lu\n", GetLastError());
8096
privs.Privileges[0].Attributes = 0;
8097
ret = AdjustTokenPrivileges(token, FALSE, &privs, sizeof(prev_privs_buffer), prev_privs, &size);
8098
ok(ret, "got error %lu\n", GetLastError());
8099
8100
ret = DuplicateToken(token, SecurityAnonymous, &token2);
8101
ok(ret, "got error %lu\n", GetLastError());
8102
TEST_GRANTED_ACCESS(token2, TOKEN_QUERY | TOKEN_IMPERSONATE);
8103
ret = GetTokenInformation(token2, TokenImpersonationLevel, &level, sizeof(level), &size);
8104
ok(ret, "got error %lu\n", GetLastError());
8105
ok(level == SecurityAnonymous, "got impersonation level %#x\n", level);
8106
ret = GetTokenInformation(token2, TokenPrivileges, ret_privs, sizeof(ret_privs_buffer), &size);
8107
ok(ret, "got error %lu\n", GetLastError());
8108
priv = find_privilege(ret_privs, &privs.Privileges[0].Luid);
8109
ok(!!priv, "Privilege should exist\n");
8110
todo_wine ok(priv->Attributes == SE_GROUP_MANDATORY, "Got attributes %#lx\n", priv->Attributes);
8111
CloseHandle(token2);
8112
8113
ret = DuplicateTokenEx(token, 0, NULL, SecurityAnonymous, TokenPrimary, &token2);
8114
ok(ret, "got error %lu\n", GetLastError());
8115
TEST_GRANTED_ACCESS(token2, orig_access);
8116
ret = GetTokenInformation(token2, TokenImpersonationLevel, &level, sizeof(level), &size);
8117
ok(!ret, "expected failure\n");
8118
ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got error %lu.\n", GetLastError());
8119
ret = GetTokenInformation(token2, TokenPrivileges, ret_privs, sizeof(ret_privs_buffer), &size);
8120
ok(ret, "got error %lu\n", GetLastError());
8121
priv = find_privilege(ret_privs, &privs.Privileges[0].Luid);
8122
ok(!!priv, "Privilege should exist\n");
8123
todo_wine ok(priv->Attributes == SE_GROUP_MANDATORY, "Got attributes %#lx\n", priv->Attributes);
8124
CloseHandle(token2);
8125
8126
ret = DuplicateTokenEx(token, MAXIMUM_ALLOWED, NULL, SecurityAnonymous, TokenPrimary, &token2);
8127
ok(ret, "got error %lu\n", GetLastError());
8128
TEST_GRANTED_ACCESS(token2, TOKEN_ALL_ACCESS);
8129
CloseHandle(token2);
8130
8131
ret = DuplicateTokenEx(token, TOKEN_QUERY_SOURCE, NULL, SecurityAnonymous, TokenPrimary, &token2);
8132
ok(ret, "got error %lu\n", GetLastError());
8133
TEST_GRANTED_ACCESS(token2, TOKEN_QUERY_SOURCE);
8134
CloseHandle(token2);
8135
8136
ret = DuplicateTokenEx(token, 0, NULL, SecurityIdentification, TokenImpersonation, &token2);
8137
ok(ret, "got error %lu\n", GetLastError());
8138
TEST_GRANTED_ACCESS(token2, orig_access);
8139
ret = GetTokenInformation(token2, TokenImpersonationLevel, &level, sizeof(level), &size);
8140
ok(ret, "got error %lu\n", GetLastError());
8141
ok(level == SecurityIdentification, "got impersonation level %#x\n", level);
8142
ret = GetTokenInformation(token2, TokenPrivileges, ret_privs, sizeof(ret_privs_buffer), &size);
8143
ok(ret, "got error %lu\n", GetLastError());
8144
priv = find_privilege(ret_privs, &privs.Privileges[0].Luid);
8145
ok(!!priv, "Privilege should exist\n");
8146
todo_wine ok(priv->Attributes == SE_GROUP_MANDATORY, "Got attributes %#lx\n", priv->Attributes);
8147
CloseHandle(token2);
8148
8149
ret = NtDuplicateToken(token, 0, &attr, FALSE, TokenImpersonation, &token2);
8150
ok(ret == STATUS_SUCCESS, "Got status %#x.\n", ret);
8151
TEST_GRANTED_ACCESS(token2, orig_access);
8152
ret = GetTokenInformation(token2, TokenImpersonationLevel, &level, sizeof(level), &size);
8153
ok(ret, "got error %lu\n", GetLastError());
8154
ok(level == SecurityAnonymous, "got impersonation level %#x\n", level);
8155
ret = GetTokenInformation(token2, TokenPrivileges, ret_privs, sizeof(ret_privs_buffer), &size);
8156
ok(ret, "got error %lu\n", GetLastError());
8157
priv = find_privilege(ret_privs, &privs.Privileges[0].Luid);
8158
ok(!!priv, "Privilege should exist\n");
8159
todo_wine ok(priv->Attributes == SE_GROUP_MANDATORY, "Got attributes %#lx\n", priv->Attributes);
8160
CloseHandle(token2);
8161
8162
ret = NtDuplicateToken(token, 0, &attr, TRUE, TokenImpersonation, &token2);
8163
ok(ret == STATUS_SUCCESS, "Got status %#x.\n", ret);
8164
TEST_GRANTED_ACCESS(token2, orig_access);
8165
ret = GetTokenInformation(token2, TokenPrivileges, ret_privs, sizeof(ret_privs_buffer), &size);
8166
ok(ret, "got error %lu\n", GetLastError());
8167
priv = find_privilege(ret_privs, &privs.Privileges[0].Luid);
8168
todo_wine ok(!priv, "Privilege shouldn't exist\n");
8169
CloseHandle(token2);
8170
8171
qos.ImpersonationLevel = SecurityIdentification;
8172
qos.ContextTrackingMode = SECURITY_STATIC_TRACKING;
8173
qos.EffectiveOnly = FALSE;
8174
attr.SecurityQualityOfService = &qos;
8175
ret = NtDuplicateToken(token, 0, &attr, FALSE, TokenImpersonation, &token2);
8176
ok(ret == STATUS_SUCCESS, "Got status %#x.\n", ret);
8177
TEST_GRANTED_ACCESS(token2, orig_access);
8178
ret = GetTokenInformation(token2, TokenImpersonationLevel, &level, sizeof(level), &size);
8179
ok(ret, "got error %lu\n", GetLastError());
8180
ok(level == SecurityIdentification, "got impersonation level %#x\n", level);
8181
CloseHandle(token2);
8182
8183
privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
8184
ret = AdjustTokenPrivileges(token, FALSE, &privs, sizeof(prev_privs_buffer), prev_privs, &size);
8185
ok(ret, "got error %lu\n", GetLastError());
8186
8187
CloseHandle(token);
8188
}
8189
8190
static void test_GetKernelObjectSecurity(void)
8191
{
8192
/* Basic tests for parameter validation. */
8193
8194
SECURITY_DESCRIPTOR_CONTROL control;
8195
DWORD size, ret_size, revision;
8196
BOOL ret, present, defaulted;
8197
PSECURITY_DESCRIPTOR sd;
8198
PSID sid;
8199
ACL *acl;
8200
8201
SetLastError(0xdeadbeef);
8202
size = 0xdeadbeef;
8203
ret = GetKernelObjectSecurity(NULL, OWNER_SECURITY_INFORMATION, NULL, 0, &size);
8204
ok(!ret, "expected failure\n");
8205
ok(GetLastError() == ERROR_INVALID_HANDLE, "got error %lu\n", GetLastError());
8206
ok(size == 0xdeadbeef, "got size %lu\n", size);
8207
8208
SetLastError(0xdeadbeef);
8209
ret = GetKernelObjectSecurity(GetCurrentProcess(), OWNER_SECURITY_INFORMATION, NULL, 0, NULL);
8210
ok(!ret, "expected failure\n");
8211
ok(GetLastError() == ERROR_NOACCESS, "got error %lu\n", GetLastError());
8212
8213
SetLastError(0xdeadbeef);
8214
size = 0xdeadbeef;
8215
ret = GetKernelObjectSecurity(GetCurrentProcess(), OWNER_SECURITY_INFORMATION, NULL, 0, &size);
8216
ok(!ret, "expected failure\n");
8217
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got error %lu\n", GetLastError());
8218
ok(size > 0 && size != 0xdeadbeef, "got size 0\n");
8219
8220
sd = malloc(size + 1);
8221
8222
SetLastError(0xdeadbeef);
8223
ret = GetKernelObjectSecurity(GetCurrentProcess(), OWNER_SECURITY_INFORMATION, sd, size - 1, &ret_size);
8224
ok(!ret, "expected failure\n");
8225
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got error %lu\n", GetLastError());
8226
ok(ret_size == size, "expected size %lu, got %lu\n", size, ret_size);
8227
8228
SetLastError(0xdeadbeef);
8229
ret = GetKernelObjectSecurity(GetCurrentProcess(), OWNER_SECURITY_INFORMATION, sd, size + 1, &ret_size);
8230
ok(ret, "expected success\n");
8231
ok(GetLastError() == 0xdeadbeef, "got error %lu\n", GetLastError());
8232
ok(ret_size == size, "expected size %lu, got %lu\n", size, ret_size);
8233
8234
free(sd);
8235
8236
/* Calling the function with flags not defined succeeds and yields an empty
8237
* descriptor. */
8238
8239
SetLastError(0xdeadbeef);
8240
ret = GetKernelObjectSecurity(GetCurrentProcess(), 0x100000, NULL, 0, &size);
8241
ok(!ret, "expected failure\n");
8242
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got error %lu\n", GetLastError());
8243
8244
sd = malloc(size);
8245
SetLastError(0xdeadbeef);
8246
ret = GetKernelObjectSecurity(GetCurrentProcess(), 0x100000, sd, size, &ret_size);
8247
ok(ret, "expected success\n");
8248
ok(GetLastError() == 0xdeadbeef, "got error %lu\n", GetLastError());
8249
ok(ret_size == size, "expected size %lu, got %lu\n", size, ret_size);
8250
8251
ret = GetSecurityDescriptorControl(sd, &control, &revision);
8252
ok(ret, "got error %lu\n", GetLastError());
8253
todo_wine ok(control == SE_SELF_RELATIVE, "got control %#x\n", control);
8254
ok(revision == SECURITY_DESCRIPTOR_REVISION1, "got revision %lu\n", revision);
8255
8256
ret = GetSecurityDescriptorOwner(sd, &sid, &defaulted);
8257
ok(ret, "got error %lu\n", GetLastError());
8258
ok(!sid, "expected no owner SID\n");
8259
ok(!defaulted, "expected owner not defaulted\n");
8260
8261
ret = GetSecurityDescriptorGroup(sd, &sid, &defaulted);
8262
ok(ret, "got error %lu\n", GetLastError());
8263
ok(!sid, "expected no group SID\n");
8264
ok(!defaulted, "expected group not defaulted\n");
8265
8266
ret = GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted);
8267
ok(ret, "got error %lu\n", GetLastError());
8268
todo_wine ok(!present, "expected no DACL present\n");
8269
/* the descriptor is defaulted only on Windows >= 7 */
8270
8271
ret = GetSecurityDescriptorSacl(sd, &present, &acl, &defaulted);
8272
ok(ret, "got error %lu\n", GetLastError());
8273
ok(!present, "expected no SACL present\n");
8274
/* the descriptor is defaulted only on Windows >= 7 */
8275
8276
free(sd);
8277
}
8278
8279
static void check_different_token(HANDLE token1, HANDLE token2)
8280
{
8281
TOKEN_STATISTICS stats1, stats2;
8282
DWORD size;
8283
BOOL ret;
8284
8285
ret = GetTokenInformation(token1, TokenStatistics, &stats1, sizeof(stats1), &size);
8286
ok(ret, "got error %lu\n", GetLastError());
8287
ret = GetTokenInformation(token2, TokenStatistics, &stats2, sizeof(stats2), &size);
8288
ok(ret, "got error %lu\n", GetLastError());
8289
8290
ok(memcmp(&stats1.TokenId, &stats2.TokenId, sizeof(LUID)), "expected different IDs\n");
8291
}
8292
8293
static void test_elevation(void)
8294
{
8295
TOKEN_LINKED_TOKEN linked, linked2;
8296
DWORD orig_type, type, size;
8297
TOKEN_ELEVATION elevation;
8298
HANDLE token, token2;
8299
BOOL ret;
8300
8301
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | READ_CONTROL | TOKEN_DUPLICATE
8302
| TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_DEFAULT, &token);
8303
ok(ret, "got error %lu\n", GetLastError());
8304
8305
ret = GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &size);
8306
ok(ret, "got error %lu\n", GetLastError());
8307
orig_type = type;
8308
ret = GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &size);
8309
ok(ret, "got error %lu\n", GetLastError());
8310
ret = GetTokenInformation(token, TokenLinkedToken, &linked, sizeof(linked), &size);
8311
if (!ret && GetLastError() == ERROR_NO_SUCH_LOGON_SESSION) /* fails on w2008s64 */
8312
{
8313
win_skip("Failed to get linked token.\n");
8314
CloseHandle(token);
8315
return;
8316
}
8317
ok(ret, "got error %lu\n", GetLastError());
8318
8319
if (type == TokenElevationTypeDefault)
8320
{
8321
ok(elevation.TokenIsElevated == FALSE, "got elevation %#lx\n", elevation.TokenIsElevated);
8322
ok(!linked.LinkedToken, "expected no linked token\n");
8323
}
8324
else if (type == TokenElevationTypeLimited)
8325
{
8326
ok(elevation.TokenIsElevated == FALSE, "got elevation %#lx\n", elevation.TokenIsElevated);
8327
ok(!!linked.LinkedToken, "expected a linked token\n");
8328
8329
TEST_GRANTED_ACCESS(linked.LinkedToken, TOKEN_ALL_ACCESS);
8330
ret = GetTokenInformation(linked.LinkedToken, TokenElevationType, &type, sizeof(type), &size);
8331
ok(ret, "got error %lu\n", GetLastError());
8332
ok(type == TokenElevationTypeFull, "got type %#lx\n", type);
8333
ret = GetTokenInformation(linked.LinkedToken, TokenElevation, &elevation, sizeof(elevation), &size);
8334
ok(ret, "got error %lu\n", GetLastError());
8335
ok(elevation.TokenIsElevated == TRUE, "got elevation %#lx\n", elevation.TokenIsElevated);
8336
ret = GetTokenInformation(linked.LinkedToken, TokenType, &type, sizeof(type), &size);
8337
ok(ret, "got error %lu\n", GetLastError());
8338
ok(type == TokenImpersonation, "got type %#lx\n", type);
8339
ret = GetTokenInformation(linked.LinkedToken, TokenImpersonationLevel, &type, sizeof(type), &size);
8340
ok(ret, "got error %lu\n", GetLastError());
8341
ok(type == SecurityIdentification, "got impersonation level %#lx\n", type);
8342
8343
/* Asking for the linked token again gives us a different token. */
8344
ret = GetTokenInformation(token, TokenLinkedToken, &linked2, sizeof(linked2), &size);
8345
ok(ret, "got error %lu\n", GetLastError());
8346
8347
ret = GetTokenInformation(linked2.LinkedToken, TokenElevationType, &type, sizeof(type), &size);
8348
ok(ret, "got error %lu\n", GetLastError());
8349
ok(type == TokenElevationTypeFull, "got type %#lx\n", type);
8350
ret = GetTokenInformation(linked2.LinkedToken, TokenElevation, &elevation, sizeof(elevation), &size);
8351
ok(ret, "got error %lu\n", GetLastError());
8352
ok(elevation.TokenIsElevated == TRUE, "got elevation %#lx\n", elevation.TokenIsElevated);
8353
8354
check_different_token(linked.LinkedToken, linked2.LinkedToken);
8355
8356
CloseHandle(linked2.LinkedToken);
8357
8358
/* Asking for the linked token's linked token gives us a new limited token. */
8359
ret = GetTokenInformation(linked.LinkedToken, TokenLinkedToken, &linked2, sizeof(linked2), &size);
8360
ok(ret, "got error %lu\n", GetLastError());
8361
8362
ret = GetTokenInformation(linked2.LinkedToken, TokenElevationType, &type, sizeof(type), &size);
8363
ok(ret, "got error %lu\n", GetLastError());
8364
ok(type == TokenElevationTypeLimited, "got type %#lx\n", type);
8365
ret = GetTokenInformation(linked2.LinkedToken, TokenElevation, &elevation, sizeof(elevation), &size);
8366
ok(ret, "got error %lu\n", GetLastError());
8367
ok(elevation.TokenIsElevated == FALSE, "got elevation %#lx\n", elevation.TokenIsElevated);
8368
8369
check_different_token(token, linked2.LinkedToken);
8370
8371
CloseHandle(linked2.LinkedToken);
8372
8373
CloseHandle(linked.LinkedToken);
8374
8375
type = TokenElevationTypeLimited;
8376
ret = SetTokenInformation(token, TokenElevationType, &type, sizeof(type));
8377
ok(!ret, "expected failure\n");
8378
todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError());
8379
8380
elevation.TokenIsElevated = FALSE;
8381
ret = SetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation));
8382
ok(!ret, "expected failure\n");
8383
todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError());
8384
}
8385
else
8386
{
8387
ok(elevation.TokenIsElevated == TRUE, "got elevation %#lx\n", elevation.TokenIsElevated);
8388
ok(!!linked.LinkedToken, "expected a linked token\n");
8389
8390
TEST_GRANTED_ACCESS(linked.LinkedToken, TOKEN_ALL_ACCESS);
8391
ret = GetTokenInformation(linked.LinkedToken, TokenElevationType, &type, sizeof(type), &size);
8392
ok(ret, "got error %lu\n", GetLastError());
8393
ok(type == TokenElevationTypeLimited, "got type %#lx\n", type);
8394
ret = GetTokenInformation(linked.LinkedToken, TokenElevation, &elevation, sizeof(elevation), &size);
8395
ok(ret, "got error %lu\n", GetLastError());
8396
ok(elevation.TokenIsElevated == FALSE, "got elevation %#lx\n", elevation.TokenIsElevated);
8397
ret = GetTokenInformation(linked.LinkedToken, TokenType, &type, sizeof(type), &size);
8398
ok(ret, "got error %lu\n", GetLastError());
8399
ok(type == TokenImpersonation, "got type %#lx\n", type);
8400
ret = GetTokenInformation(linked.LinkedToken, TokenImpersonationLevel, &type, sizeof(type), &size);
8401
ok(ret, "got error %lu\n", GetLastError());
8402
ok(type == SecurityIdentification, "got impersonation level %#lx\n", type);
8403
8404
/* Asking for the linked token again gives us a different token. */
8405
ret = GetTokenInformation(token, TokenLinkedToken, &linked2, sizeof(linked2), &size);
8406
ok(ret, "got error %lu\n", GetLastError());
8407
8408
ret = GetTokenInformation(linked2.LinkedToken, TokenElevationType, &type, sizeof(type), &size);
8409
ok(ret, "got error %lu\n", GetLastError());
8410
ok(type == TokenElevationTypeLimited, "got type %#lx\n", type);
8411
ret = GetTokenInformation(linked2.LinkedToken, TokenElevation, &elevation, sizeof(elevation), &size);
8412
ok(ret, "got error %lu\n", GetLastError());
8413
ok(elevation.TokenIsElevated == FALSE, "got elevation %#lx\n", elevation.TokenIsElevated);
8414
8415
check_different_token(linked.LinkedToken, linked2.LinkedToken);
8416
8417
CloseHandle(linked2.LinkedToken);
8418
8419
/* Asking for the linked token's linked token gives us a new elevated token. */
8420
ret = GetTokenInformation(linked.LinkedToken, TokenLinkedToken, &linked2, sizeof(linked2), &size);
8421
ok(ret, "got error %lu\n", GetLastError());
8422
8423
ret = GetTokenInformation(linked2.LinkedToken, TokenElevationType, &type, sizeof(type), &size);
8424
ok(ret, "got error %lu\n", GetLastError());
8425
ok(type == TokenElevationTypeFull, "got type %#lx\n", type);
8426
ret = GetTokenInformation(linked2.LinkedToken, TokenElevation, &elevation, sizeof(elevation), &size);
8427
ok(ret, "got error %lu\n", GetLastError());
8428
ok(elevation.TokenIsElevated == TRUE, "got elevation %#lx\n", elevation.TokenIsElevated);
8429
8430
check_different_token(token, linked2.LinkedToken);
8431
8432
CloseHandle(linked2.LinkedToken);
8433
8434
CloseHandle(linked.LinkedToken);
8435
8436
type = TokenElevationTypeLimited;
8437
ret = SetTokenInformation(token, TokenElevationType, &type, sizeof(type));
8438
ok(!ret, "expected failure\n");
8439
todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError());
8440
8441
elevation.TokenIsElevated = FALSE;
8442
ret = SetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation));
8443
ok(!ret, "expected failure\n");
8444
todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError());
8445
}
8446
8447
ret = DuplicateTokenEx(token, TOKEN_ALL_ACCESS, NULL, SecurityAnonymous, TokenPrimary, &token2);
8448
ok(ret, "got error %lu\n", GetLastError());
8449
ret = GetTokenInformation(token2, TokenElevationType, &type, sizeof(type), &size);
8450
ok(ret, "got error %lu\n", GetLastError());
8451
ok(type == orig_type, "expected same type\n");
8452
ret = GetTokenInformation(token2, TokenElevation, &elevation, sizeof(elevation), &size);
8453
ok(ret, "got error %lu\n", GetLastError());
8454
ok(elevation.TokenIsElevated == (type == TokenElevationTypeFull), "got elevation %#lx\n", elevation.TokenIsElevated);
8455
ret = GetTokenInformation(token2, TokenLinkedToken, &linked, sizeof(linked), &size);
8456
ok(ret, "got error %lu\n", GetLastError());
8457
if (type == TokenElevationTypeDefault)
8458
{
8459
ok(!linked.LinkedToken, "expected no linked token\n");
8460
ret = GetTokenInformation(linked.LinkedToken, TokenType, &type, sizeof(type), &size);
8461
ok(ret, "got error %lu\n", GetLastError());
8462
ok(type == TokenImpersonation, "got type %#lx\n", type);
8463
ret = GetTokenInformation(linked.LinkedToken, TokenImpersonationLevel, &type, sizeof(type), &size);
8464
ok(ret, "got error %lu\n", GetLastError());
8465
ok(type == SecurityIdentification, "got impersonation level %#lx\n", type);
8466
CloseHandle(linked.LinkedToken);
8467
}
8468
else
8469
ok(!!linked.LinkedToken, "expected a linked token\n");
8470
CloseHandle(token2);
8471
8472
ret = CreateRestrictedToken(token, 0, 0, NULL, 0, NULL, 0, NULL, &token2);
8473
ok(ret, "got error %lu\n", GetLastError());
8474
ret = GetTokenInformation(token2, TokenElevationType, &type, sizeof(type), &size);
8475
ok(ret, "got error %lu\n", GetLastError());
8476
ok(type == orig_type, "expected same type\n");
8477
ret = GetTokenInformation(token2, TokenElevation, &elevation, sizeof(elevation), &size);
8478
ok(ret, "got error %lu\n", GetLastError());
8479
ok(elevation.TokenIsElevated == (type == TokenElevationTypeFull), "got elevation %#lx\n", elevation.TokenIsElevated);
8480
ret = GetTokenInformation(token2, TokenLinkedToken, &linked, sizeof(linked), &size);
8481
ok(ret, "got error %lu\n", GetLastError());
8482
if (type == TokenElevationTypeDefault)
8483
ok(!linked.LinkedToken, "expected no linked token\n");
8484
else
8485
ok(!!linked.LinkedToken, "expected a linked token\n");
8486
CloseHandle(linked.LinkedToken);
8487
CloseHandle(token2);
8488
8489
if (type != TokenElevationTypeDefault)
8490
{
8491
char prev_privs_buffer[128], acl_buffer[256], prev_acl_buffer[256];
8492
TOKEN_PRIVILEGES privs, *prev_privs = (TOKEN_PRIVILEGES *)prev_privs_buffer;
8493
TOKEN_DEFAULT_DACL *prev_acl = (TOKEN_DEFAULT_DACL *)prev_acl_buffer;
8494
TOKEN_DEFAULT_DACL *ret_acl = (TOKEN_DEFAULT_DACL *)acl_buffer;
8495
TOKEN_DEFAULT_DACL default_acl;
8496
PRIVILEGE_SET priv_set;
8497
BOOL ret, is_member;
8498
DWORD size;
8499
ACL acl;
8500
8501
/* Linked tokens do not preserve privilege modifications. */
8502
8503
privs.PrivilegeCount = 1;
8504
ret = LookupPrivilegeValueA(NULL, "SeChangeNotifyPrivilege", &privs.Privileges[0].Luid);
8505
ok(ret, "got error %lu\n", GetLastError());
8506
privs.Privileges[0].Attributes = SE_PRIVILEGE_REMOVED;
8507
ret = AdjustTokenPrivileges(token, FALSE, &privs, sizeof(prev_privs_buffer), prev_privs, &size);
8508
ok(ret, "got error %lu\n", GetLastError());
8509
8510
priv_set.PrivilegeCount = 1;
8511
priv_set.Control = 0;
8512
priv_set.Privilege[0] = privs.Privileges[0];
8513
ret = PrivilegeCheck(token, &priv_set, &is_member);
8514
ok(ret, "got error %lu\n", GetLastError());
8515
ok(!is_member, "not a member\n");
8516
8517
ret = GetTokenInformation(token, TokenLinkedToken, &linked, sizeof(linked), &size);
8518
ok(ret, "got error %lu\n", GetLastError());
8519
8520
ret = PrivilegeCheck(linked.LinkedToken, &priv_set, &is_member);
8521
ok(ret, "got error %lu\n", GetLastError());
8522
ok(is_member, "not a member\n");
8523
8524
CloseHandle(linked.LinkedToken);
8525
8526
ret = AdjustTokenPrivileges(token, FALSE, prev_privs, 0, NULL, NULL);
8527
ok(ret, "got error %lu\n", GetLastError());
8528
8529
/* Linked tokens do not preserve default DACL modifications. */
8530
8531
ret = GetTokenInformation(token, TokenDefaultDacl, prev_acl, sizeof(prev_acl_buffer), &size);
8532
ok(ret, "got error %lu\n", GetLastError());
8533
ok(prev_acl->DefaultDacl->AceCount, "expected non-empty default DACL\n");
8534
8535
InitializeAcl(&acl, sizeof(acl), ACL_REVISION);
8536
default_acl.DefaultDacl = &acl;
8537
ret = SetTokenInformation(token, TokenDefaultDacl, &default_acl, sizeof(default_acl));
8538
ok(ret, "got error %lu\n", GetLastError());
8539
8540
ret = GetTokenInformation(token, TokenDefaultDacl, ret_acl, sizeof(acl_buffer), &size);
8541
ok(ret, "got error %lu\n", GetLastError());
8542
ok(!ret_acl->DefaultDacl->AceCount, "expected empty default DACL\n");
8543
8544
ret = GetTokenInformation(token, TokenLinkedToken, &linked, sizeof(linked), &size);
8545
ok(ret, "got error %lu\n", GetLastError());
8546
8547
ret = GetTokenInformation(linked.LinkedToken, TokenDefaultDacl, ret_acl, sizeof(acl_buffer), &size);
8548
ok(ret, "got error %lu\n", GetLastError());
8549
ok(ret_acl->DefaultDacl->AceCount, "expected non-empty default DACL\n");
8550
8551
CloseHandle(linked.LinkedToken);
8552
8553
ret = SetTokenInformation(token, TokenDefaultDacl, prev_acl, sizeof(*prev_acl));
8554
ok(ret, "got error %lu\n", GetLastError());
8555
}
8556
8557
CloseHandle(token);
8558
}
8559
8560
static void test_admin_elevation(void)
8561
{
8562
/* Tokens with elevation type TokenElevationTypeDefault should still come
8563
back as elevated from a TokenElevation query if they belong to the admin
8564
group. The owner of the desktop window should have such a token. */
8565
DWORD tid, pid;
8566
HANDLE hproc, htok;
8567
TOKEN_ELEVATION_TYPE elevation_type;
8568
TOKEN_ELEVATION elevation;
8569
DWORD size;
8570
BOOL ret;
8571
8572
tid = GetWindowThreadProcessId(GetDesktopWindow(), &pid);
8573
ok(tid, "got error %lu\n", GetLastError());
8574
8575
hproc = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
8576
if (!hproc)
8577
{
8578
skip("could not open process, error %lu\n", GetLastError());
8579
return;
8580
}
8581
8582
ret = OpenProcessToken(hproc, TOKEN_READ, &htok);
8583
ok(ret, "got error %lu\n", GetLastError());
8584
8585
CloseHandle(hproc);
8586
8587
size = sizeof(elevation_type);
8588
ret = GetTokenInformation(htok, TokenElevationType, &elevation_type, size, &size);
8589
ok(ret, "got error %lu\n", GetLastError());
8590
ok(elevation_type == TokenElevationTypeDefault, "unexpected elevation type %d\n", elevation_type);
8591
8592
size = sizeof(elevation);
8593
ret = GetTokenInformation(htok, TokenElevation, &elevation, size, &size);
8594
ok(ret, "got error %lu\n", GetLastError());
8595
ok(elevation.TokenIsElevated, "expected token to be elevated\n");
8596
8597
CloseHandle(htok);
8598
}
8599
8600
static void test_group_as_file_owner(void)
8601
{
8602
char sd_buffer[200], sid_buffer[100];
8603
SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *)sd_buffer;
8604
char temp_path[MAX_PATH], path[MAX_PATH];
8605
SID *admin_sid = (SID *)sid_buffer;
8606
BOOL ret, present, defaulted;
8607
SECURITY_DESCRIPTOR new_sd;
8608
HANDLE file;
8609
DWORD size;
8610
ACL *dacl;
8611
8612
/* The EA Origin client sets the SD owner of a directory to Administrators,
8613
* while using the default DACL, and subsequently tries to create
8614
* subdirectories. */
8615
8616
size = sizeof(sid_buffer);
8617
CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &size);
8618
8619
ret = CheckTokenMembership(NULL, admin_sid, &present);
8620
ok(ret, "got error %lu\n", GetLastError());
8621
if (!present)
8622
{
8623
skip("user is not an administrator\n");
8624
return;
8625
}
8626
8627
GetTempPathA(ARRAY_SIZE(temp_path), temp_path);
8628
sprintf(path, "%s\\testdir", temp_path);
8629
8630
ret = CreateDirectoryA(path, NULL);
8631
ok(ret, "got error %lu\n", GetLastError());
8632
8633
file = CreateFileA(path, FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
8634
ok(file != INVALID_HANDLE_VALUE, "got error %lu\n", GetLastError());
8635
8636
ret = GetKernelObjectSecurity(file, DACL_SECURITY_INFORMATION, sd_buffer, sizeof(sd_buffer), &size);
8637
ok(ret, "got error %lu\n", GetLastError());
8638
ret = GetSecurityDescriptorDacl(sd, &present, &dacl, &defaulted);
8639
ok(ret, "got error %lu\n", GetLastError());
8640
8641
InitializeSecurityDescriptor(&new_sd, SECURITY_DESCRIPTOR_REVISION);
8642
8643
ret = SetSecurityDescriptorOwner(&new_sd, admin_sid, FALSE);
8644
ok(ret, "got error %lu\n", GetLastError());
8645
8646
ret = GetSecurityDescriptorDacl(sd, &present, &dacl, &defaulted);
8647
ok(ret, "got error %lu\n", GetLastError());
8648
8649
ret = SetSecurityDescriptorDacl(&new_sd, present, dacl, defaulted);
8650
ok(ret, "got error %lu\n", GetLastError());
8651
8652
ret = SetKernelObjectSecurity(file, OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, &new_sd);
8653
ok(ret, "got error %lu\n", GetLastError());
8654
8655
CloseHandle(file);
8656
8657
sprintf(path, "%s\\testdir\\subdir", temp_path);
8658
ret = CreateDirectoryA(path, NULL);
8659
ok(ret, "got error %lu\n", GetLastError());
8660
8661
ret = RemoveDirectoryA(path);
8662
ok(ret, "got error %lu\n", GetLastError());
8663
sprintf(path, "%s\\testdir", temp_path);
8664
ret = RemoveDirectoryA(path);
8665
ok(ret, "got error %lu\n", GetLastError());
8666
}
8667
8668
static void test_IsValidSecurityDescriptor(void)
8669
{
8670
SECURITY_DESCRIPTOR *sd;
8671
BOOL ret;
8672
8673
SetLastError(0xdeadbeef);
8674
ret = IsValidSecurityDescriptor(NULL);
8675
ok(!ret, "Unexpected return value %d.\n", ret);
8676
ok(GetLastError() == ERROR_INVALID_SECURITY_DESCR, "Unexpected error %ld.\n", GetLastError());
8677
8678
sd = calloc(1, SECURITY_DESCRIPTOR_MIN_LENGTH);
8679
8680
SetLastError(0xdeadbeef);
8681
ret = IsValidSecurityDescriptor(sd);
8682
ok(!ret, "Unexpected return value %d.\n", ret);
8683
ok(GetLastError() == ERROR_INVALID_SECURITY_DESCR, "Unexpected error %ld.\n", GetLastError());
8684
8685
ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
8686
ok(ret, "Unexpected return value %d, error %ld.\n", ret, GetLastError());
8687
8688
SetLastError(0xdeadbeef);
8689
ret = IsValidSecurityDescriptor(sd);
8690
ok(ret, "Unexpected return value %d.\n", ret);
8691
ok(GetLastError() == 0xdeadbeef, "Unexpected error %ld.\n", GetLastError());
8692
8693
free(sd);
8694
}
8695
8696
static void test_window_security(void)
8697
{
8698
PSECURITY_DESCRIPTOR sd;
8699
BOOL present, defaulted;
8700
HDESK desktop;
8701
DWORD ret;
8702
ACL *dacl;
8703
8704
desktop = GetThreadDesktop(GetCurrentThreadId());
8705
8706
ret = GetSecurityInfo(desktop, SE_WINDOW_OBJECT,
8707
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &sd);
8708
ok(!ret, "got error %lu\n", ret);
8709
8710
ret = GetSecurityDescriptorDacl(sd, &present, &dacl, &defaulted);
8711
ok(ret == TRUE, "got error %lu\n", GetLastError());
8712
todo_wine ok(present == TRUE, "got present %d\n", present);
8713
ok(defaulted == FALSE, "got defaulted %d\n", defaulted);
8714
8715
LocalFree(sd);
8716
}
8717
8718
START_TEST(security)
8719
{
8720
init();
8721
if (!hmod) return;
8722
8723
if (myARGC >= 3)
8724
{
8725
if (!strcmp(myARGV[2], "test_token_sd"))
8726
test_child_token_sd();
8727
else if (!strcmp(myARGV[2], "test"))
8728
test_process_security_child();
8729
else if (!strcmp(myARGV[2], "duplicate"))
8730
test_duplicate_handle_access_child();
8731
else if (!strcmp(myARGV[2], "restricted"))
8732
test_create_process_token_child();
8733
return;
8734
}
8735
test_kernel_objects_security();
8736
test_ConvertStringSidToSid();
8737
test_trustee();
8738
test_allocateLuid();
8739
test_lookupPrivilegeName();
8740
test_lookupPrivilegeValue();
8741
test_CreateWellKnownSid();
8742
test_FileSecurity();
8743
test_AccessCheck();
8744
test_token_attr();
8745
test_GetTokenInformation();
8746
test_LookupAccountSid();
8747
test_LookupAccountName();
8748
test_security_descriptor();
8749
test_process_security();
8750
test_impersonation_level();
8751
test_SetEntriesInAclW();
8752
test_SetEntriesInAclA();
8753
test_CreateDirectoryA();
8754
test_GetNamedSecurityInfoA();
8755
test_ConvertStringSecurityDescriptor();
8756
test_ConvertSecurityDescriptorToString();
8757
test_PrivateObjectSecurity();
8758
test_InitializeAcl();
8759
test_GetWindowsAccountDomainSid();
8760
test_EqualDomainSid();
8761
test_GetSecurityInfo();
8762
test_GetSidSubAuthority();
8763
test_CheckTokenMembership();
8764
test_EqualSid();
8765
test_GetUserNameA();
8766
test_GetUserNameW();
8767
test_CreateRestrictedToken();
8768
test_TokenIntegrityLevel();
8769
test_default_dacl_owner_group_sid();
8770
test_AdjustTokenPrivileges();
8771
test_AddAce();
8772
test_AddMandatoryAce();
8773
test_system_security_access();
8774
test_GetSidIdentifierAuthority();
8775
test_pseudo_tokens();
8776
test_maximum_allowed();
8777
test_token_label();
8778
test_GetExplicitEntriesFromAclW();
8779
test_BuildSecurityDescriptorW();
8780
test_duplicate_handle_access();
8781
test_create_process_token();
8782
test_pseudo_handle_security();
8783
test_duplicate_token();
8784
test_GetKernelObjectSecurity();
8785
test_elevation();
8786
test_admin_elevation();
8787
test_group_as_file_owner();
8788
test_IsValidSecurityDescriptor();
8789
test_window_security();
8790
8791
/* Must be the last test, modifies process token */
8792
test_token_security_descriptor();
8793
}
8794
8795