Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/advapi32/security.c
8602 views
1
/*
2
* Copyright 1999, 2000 Juergen Schmied <[email protected]>
3
* Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
4
* Copyright 2006 Robert Reif
5
*
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License as published by the Free Software Foundation; either
9
* version 2.1 of the License, or (at your option) any later version.
10
*
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Lesser General Public License for more details.
15
*
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with this library; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19
*
20
*/
21
22
#include <stdarg.h>
23
#include <string.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 "winreg.h"
31
#include "winsafer.h"
32
#include "winternl.h"
33
#include "winioctl.h"
34
#include "accctrl.h"
35
#include "sddl.h"
36
#include "winsvc.h"
37
#include "aclapi.h"
38
#include "objbase.h"
39
#include "iads.h"
40
#include "advapi32_misc.h"
41
#include "lmcons.h"
42
#include "userenv.h"
43
44
#include "wine/debug.h"
45
46
WINE_DEFAULT_DEBUG_CHANNEL(advapi);
47
48
static DWORD trustee_to_sid(DWORD nDestinationSidLength, PSID pDestinationSid, PTRUSTEEW pTrustee);
49
50
typedef struct _MAX_SID
51
{
52
/* same fields as struct _SID */
53
BYTE Revision;
54
BYTE SubAuthorityCount;
55
SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
56
DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
57
} MAX_SID;
58
59
typedef struct _AccountSid {
60
WELL_KNOWN_SID_TYPE type;
61
LPCWSTR account;
62
LPCWSTR domain;
63
SID_NAME_USE name_use;
64
LPCWSTR alias;
65
} AccountSid;
66
67
static const AccountSid ACCOUNT_SIDS[] = {
68
{ WinNullSid, L"NULL SID", L"", SidTypeWellKnownGroup },
69
{ WinWorldSid, L"Everyone", L"", SidTypeWellKnownGroup },
70
{ WinLocalSid, L"LOCAL", L"", SidTypeWellKnownGroup },
71
{ WinCreatorOwnerSid, L"CREATOR OWNER", L"", SidTypeWellKnownGroup },
72
{ WinCreatorGroupSid, L"CREATOR GROUP", L"", SidTypeWellKnownGroup },
73
{ WinCreatorOwnerServerSid, L"CREATOR OWNER SERVER", L"", SidTypeWellKnownGroup },
74
{ WinCreatorGroupServerSid, L"CREATOR GROUP SERVER", L"", SidTypeWellKnownGroup },
75
{ WinNtAuthoritySid, L"NT Pseudo Domain", L"NT Pseudo Domain", SidTypeDomain },
76
{ WinDialupSid, L"DIALUP", L"NT AUTHORITY", SidTypeWellKnownGroup },
77
{ WinNetworkSid, L"NETWORK", L"NT AUTHORITY", SidTypeWellKnownGroup },
78
{ WinBatchSid, L"BATCH", L"NT AUTHORITY", SidTypeWellKnownGroup },
79
{ WinInteractiveSid, L"INTERACTIVE", L"NT AUTHORITY", SidTypeWellKnownGroup },
80
{ WinServiceSid, L"SERVICE", L"NT AUTHORITY", SidTypeWellKnownGroup },
81
{ WinAnonymousSid, L"ANONYMOUS LOGON", L"NT AUTHORITY", SidTypeWellKnownGroup },
82
{ WinProxySid, L"PROXY", L"NT AUTHORITY", SidTypeWellKnownGroup },
83
{ WinEnterpriseControllersSid, L"ENTERPRISE DOMAIN CONTROLLERS", L"NT AUTHORITY", SidTypeWellKnownGroup },
84
{ WinSelfSid, L"SELF", L"NT AUTHORITY", SidTypeWellKnownGroup },
85
{ WinAuthenticatedUserSid, L"Authenticated Users", L"NT AUTHORITY", SidTypeWellKnownGroup },
86
{ WinRestrictedCodeSid, L"RESTRICTED", L"NT AUTHORITY", SidTypeWellKnownGroup },
87
{ WinTerminalServerSid, L"TERMINAL SERVER USER", L"NT AUTHORITY", SidTypeWellKnownGroup },
88
{ WinRemoteLogonIdSid, L"REMOTE INTERACTIVE LOGON", L"NT AUTHORITY", SidTypeWellKnownGroup },
89
{ WinLocalSystemSid, L"SYSTEM", L"NT AUTHORITY", SidTypeWellKnownGroup },
90
{ WinLocalServiceSid, L"LOCAL SERVICE", L"NT AUTHORITY", SidTypeWellKnownGroup, L"LOCALSERVICE" },
91
{ WinNetworkServiceSid, L"NETWORK SERVICE", L"NT AUTHORITY", SidTypeWellKnownGroup , L"NETWORKSERVICE"},
92
{ WinBuiltinDomainSid, L"BUILTIN", L"BUILTIN", SidTypeDomain },
93
{ WinBuiltinAdministratorsSid, L"Administrators", L"BUILTIN", SidTypeAlias },
94
{ WinBuiltinUsersSid, L"Users", L"BUILTIN", SidTypeAlias },
95
{ WinBuiltinGuestsSid, L"Guests", L"BUILTIN", SidTypeAlias },
96
{ WinBuiltinPowerUsersSid, L"Power Users", L"BUILTIN", SidTypeAlias },
97
{ WinBuiltinAccountOperatorsSid, L"Account Operators", L"BUILTIN", SidTypeAlias },
98
{ WinBuiltinSystemOperatorsSid, L"Server Operators", L"BUILTIN", SidTypeAlias },
99
{ WinBuiltinPrintOperatorsSid, L"Print Operators", L"BUILTIN", SidTypeAlias },
100
{ WinBuiltinBackupOperatorsSid, L"Backup Operators", L"BUILTIN", SidTypeAlias },
101
{ WinBuiltinReplicatorSid, L"Replicators", L"BUILTIN", SidTypeAlias },
102
{ WinBuiltinPreWindows2000CompatibleAccessSid, L"Pre-Windows 2000 Compatible Access", L"BUILTIN", SidTypeAlias },
103
{ WinBuiltinRemoteDesktopUsersSid, L"Remote Desktop Users", L"BUILTIN", SidTypeAlias },
104
{ WinBuiltinNetworkConfigurationOperatorsSid, L"Network Configuration Operators", L"BUILTIN", SidTypeAlias },
105
{ WinNTLMAuthenticationSid, L"NTLM Authentication", L"NT AUTHORITY", SidTypeWellKnownGroup },
106
{ WinDigestAuthenticationSid, L"Digest Authentication", L"NT AUTHORITY", SidTypeWellKnownGroup },
107
{ WinSChannelAuthenticationSid, L"SChannel Authentication", L"NT AUTHORITY", SidTypeWellKnownGroup },
108
{ WinThisOrganizationSid, L"This Organization", L"NT AUTHORITY", SidTypeWellKnownGroup },
109
{ WinOtherOrganizationSid, L"Other Organization", L"NT AUTHORITY", SidTypeWellKnownGroup },
110
{ WinBuiltinPerfMonitoringUsersSid, L"Performance Monitor Users", L"BUILTIN", SidTypeAlias },
111
{ WinBuiltinPerfLoggingUsersSid, L"Performance Log Users", L"BUILTIN", SidTypeAlias },
112
{ WinBuiltinAnyPackageSid, L"ALL APPLICATION PACKAGES", L"APPLICATION PACKAGE AUTHORITY", SidTypeWellKnownGroup },
113
};
114
115
const char * debugstr_sid(PSID sid)
116
{
117
int auth = 0;
118
SID * psid = sid;
119
120
if (psid == NULL)
121
return "(null)";
122
123
auth = psid->IdentifierAuthority.Value[5] +
124
(psid->IdentifierAuthority.Value[4] << 8) +
125
(psid->IdentifierAuthority.Value[3] << 16) +
126
(psid->IdentifierAuthority.Value[2] << 24);
127
128
switch (psid->SubAuthorityCount) {
129
case 0:
130
return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
131
case 1:
132
return wine_dbg_sprintf("S-%d-%d-%lu", psid->Revision, auth,
133
psid->SubAuthority[0]);
134
case 2:
135
return wine_dbg_sprintf("S-%d-%d-%lu-%lu", psid->Revision, auth,
136
psid->SubAuthority[0], psid->SubAuthority[1]);
137
case 3:
138
return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu", psid->Revision, auth,
139
psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
140
case 4:
141
return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu", psid->Revision, auth,
142
psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
143
psid->SubAuthority[3]);
144
case 5:
145
return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth,
146
psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
147
psid->SubAuthority[3], psid->SubAuthority[4]);
148
case 6:
149
return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth,
150
psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
151
psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
152
case 7:
153
return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth,
154
psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
155
psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
156
psid->SubAuthority[6]);
157
case 8:
158
return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth,
159
psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
160
psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
161
psid->SubAuthority[6], psid->SubAuthority[7]);
162
}
163
return "(too-big)";
164
}
165
166
/* helper function for SE_FILE_OBJECT objects in [Get|Set]NamedSecurityInfo */
167
static inline DWORD get_security_file( LPCWSTR full_file_name, DWORD access, HANDLE *file )
168
{
169
UNICODE_STRING file_nameW;
170
OBJECT_ATTRIBUTES attr;
171
IO_STATUS_BLOCK io;
172
NTSTATUS status;
173
174
if (!RtlDosPathNameToNtPathName_U( full_file_name, &file_nameW, NULL, NULL ))
175
return ERROR_PATH_NOT_FOUND;
176
attr.Length = sizeof(attr);
177
attr.RootDirectory = 0;
178
attr.Attributes = OBJ_CASE_INSENSITIVE;
179
attr.ObjectName = &file_nameW;
180
attr.SecurityDescriptor = NULL;
181
status = NtCreateFile( file, access|SYNCHRONIZE, &attr, &io, NULL, FILE_FLAG_BACKUP_SEMANTICS,
182
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
183
FILE_OPEN_FOR_BACKUP_INTENT, NULL, 0 );
184
RtlFreeUnicodeString( &file_nameW );
185
return RtlNtStatusToDosError( status );
186
}
187
188
/* helper function for SE_SERVICE objects in [Get|Set]NamedSecurityInfo */
189
static DWORD get_security_service( const WCHAR *full_service_name, DWORD access, HANDLE *service )
190
{
191
SC_HANDLE manager = OpenSCManagerW( NULL, NULL, access );
192
if (manager)
193
{
194
*service = OpenServiceW( manager, full_service_name, access);
195
CloseServiceHandle( manager );
196
if (*service)
197
return ERROR_SUCCESS;
198
}
199
return GetLastError();
200
}
201
202
/* helper function for SE_REGISTRY_KEY objects in [Get|Set]NamedSecurityInfo */
203
static DWORD get_security_regkey( const WCHAR *full_key_name, DWORD access, HANDLE *key )
204
{
205
const WCHAR *p = wcschr(full_key_name, '\\');
206
int len = p-full_key_name;
207
HKEY hParent;
208
209
if (!p) return ERROR_INVALID_PARAMETER;
210
if (!wcsncmp( full_key_name, L"CLASSES_ROOT", len ))
211
hParent = HKEY_CLASSES_ROOT;
212
else if (!wcsncmp( full_key_name, L"CURRENT_USER", len ))
213
hParent = HKEY_CURRENT_USER;
214
else if (!wcsncmp( full_key_name, L"MACHINE", len ))
215
hParent = HKEY_LOCAL_MACHINE;
216
else if (!wcsncmp( full_key_name, L"USERS", len ))
217
hParent = HKEY_USERS;
218
else
219
return ERROR_INVALID_PARAMETER;
220
return RegOpenKeyExW( hParent, p+1, 0, access, (HKEY *)key );
221
}
222
223
224
/************************************************************
225
* ADVAPI_IsLocalComputer
226
*
227
* Checks whether the server name indicates local machine.
228
*/
229
BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
230
{
231
DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
232
BOOL Result;
233
LPWSTR buf;
234
235
if (!ServerName || !ServerName[0])
236
return TRUE;
237
238
buf = malloc(dwSize * sizeof(WCHAR));
239
Result = GetComputerNameW(buf, &dwSize);
240
if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
241
ServerName += 2;
242
Result = Result && !wcscmp(ServerName, buf);
243
free(buf);
244
245
return Result;
246
}
247
248
/************************************************************
249
* ADVAPI_GetComputerSid
250
*/
251
BOOL ADVAPI_GetComputerSid(PSID sid)
252
{
253
static const struct /* same fields as struct SID */
254
{
255
BYTE Revision;
256
BYTE SubAuthorityCount;
257
SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
258
DWORD SubAuthority[4];
259
} computer_sid =
260
{ SID_REVISION, 4, { SECURITY_NT_AUTHORITY }, { SECURITY_NT_NON_UNIQUE, 0, 0, 0 } };
261
262
memcpy( sid, &computer_sid, sizeof(computer_sid) );
263
return TRUE;
264
}
265
266
DWORD WINAPI
267
GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
268
{
269
FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
270
271
*pAccessRights = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
272
return 0;
273
}
274
275
DWORD WINAPI
276
GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
277
{
278
FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
279
280
*pAccessRights = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
281
return 0;
282
}
283
284
/* ##############################################
285
###### SECURITY DESCRIPTOR FUNCTIONS ######
286
##############################################
287
*/
288
289
/******************************************************************************
290
* BuildSecurityDescriptorA [ADVAPI32.@]
291
*
292
* Builds a SD from
293
*
294
* PARAMS
295
* pOwner [I]
296
* pGroup [I]
297
* cCountOfAccessEntries [I]
298
* pListOfAccessEntries [I]
299
* cCountOfAuditEntries [I]
300
* pListofAuditEntries [I]
301
* pOldSD [I]
302
* lpdwBufferLength [I/O]
303
* pNewSD [O]
304
*
305
* RETURNS
306
* Success: ERROR_SUCCESS
307
* Failure: nonzero error code from Winerror.h
308
*/
309
DWORD WINAPI BuildSecurityDescriptorA(
310
IN PTRUSTEEA pOwner,
311
IN PTRUSTEEA pGroup,
312
IN ULONG cCountOfAccessEntries,
313
IN PEXPLICIT_ACCESSA pListOfAccessEntries,
314
IN ULONG cCountOfAuditEntries,
315
IN PEXPLICIT_ACCESSA pListofAuditEntries,
316
IN PSECURITY_DESCRIPTOR pOldSD,
317
IN OUT PULONG lpdwBufferLength,
318
OUT PSECURITY_DESCRIPTOR* pNewSD)
319
{
320
FIXME("(%p,%p,%ld,%p,%ld,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
321
cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
322
pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
323
324
return ERROR_CALL_NOT_IMPLEMENTED;
325
}
326
327
/******************************************************************************
328
* BuildSecurityDescriptorW [ADVAPI32.@]
329
*
330
* See BuildSecurityDescriptorA.
331
*/
332
DWORD WINAPI BuildSecurityDescriptorW(
333
IN PTRUSTEEW pOwner,
334
IN PTRUSTEEW pGroup,
335
IN ULONG cCountOfAccessEntries,
336
IN PEXPLICIT_ACCESSW pListOfAccessEntries,
337
IN ULONG cCountOfAuditEntries,
338
IN PEXPLICIT_ACCESSW pListOfAuditEntries,
339
IN PSECURITY_DESCRIPTOR pOldSD,
340
IN OUT PULONG lpdwBufferLength,
341
OUT PSECURITY_DESCRIPTOR* pNewSD)
342
{
343
SECURITY_DESCRIPTOR desc;
344
NTSTATUS status;
345
DWORD ret = ERROR_SUCCESS;
346
347
TRACE("(%p,%p,%ld,%p,%ld,%p,%p,%p,%p)\n", pOwner, pGroup,
348
cCountOfAccessEntries, pListOfAccessEntries, cCountOfAuditEntries,
349
pListOfAuditEntries, pOldSD, lpdwBufferLength, pNewSD);
350
351
if (pOldSD)
352
{
353
SECURITY_DESCRIPTOR_CONTROL control;
354
DWORD desc_size, dacl_size = 0, sacl_size = 0, owner_size = 0, group_size = 0;
355
PACL dacl = NULL, sacl = NULL;
356
PSID owner = NULL, group = NULL;
357
DWORD revision;
358
359
if ((status = RtlGetControlSecurityDescriptor( pOldSD, &control, &revision )) != STATUS_SUCCESS)
360
return RtlNtStatusToDosError( status );
361
if (!(control & SE_SELF_RELATIVE))
362
return ERROR_INVALID_SECURITY_DESCR;
363
364
desc_size = sizeof(desc);
365
status = RtlSelfRelativeToAbsoluteSD( pOldSD, &desc, &desc_size, dacl, &dacl_size, sacl, &sacl_size,
366
owner, &owner_size, group, &group_size );
367
if (status == STATUS_BUFFER_TOO_SMALL)
368
{
369
if (dacl_size)
370
dacl = LocalAlloc( LMEM_FIXED, dacl_size );
371
if (sacl_size)
372
sacl = LocalAlloc( LMEM_FIXED, sacl_size );
373
if (owner_size)
374
owner = LocalAlloc( LMEM_FIXED, owner_size );
375
if (group_size)
376
group = LocalAlloc( LMEM_FIXED, group_size );
377
378
desc_size = sizeof(desc);
379
status = RtlSelfRelativeToAbsoluteSD( pOldSD, &desc, &desc_size, dacl, &dacl_size, sacl, &sacl_size,
380
owner, &owner_size, group, &group_size );
381
}
382
if (status != STATUS_SUCCESS)
383
{
384
LocalFree( dacl );
385
LocalFree( sacl );
386
LocalFree( owner );
387
LocalFree( group );
388
return RtlNtStatusToDosError( status );
389
}
390
}
391
else
392
{
393
if ((status = RtlCreateSecurityDescriptor( &desc, SECURITY_DESCRIPTOR_REVISION )) != STATUS_SUCCESS)
394
return RtlNtStatusToDosError( status );
395
}
396
397
if (pOwner)
398
{
399
LocalFree( desc.Owner );
400
desc.Owner = LocalAlloc( LMEM_FIXED, sizeof(MAX_SID) );
401
if ((ret = trustee_to_sid( sizeof(MAX_SID), desc.Owner, pOwner )))
402
goto done;
403
}
404
405
if (pGroup)
406
{
407
LocalFree( desc.Group );
408
desc.Group = LocalAlloc( LMEM_FIXED, sizeof(MAX_SID) );
409
if ((ret = trustee_to_sid( sizeof(MAX_SID), desc.Group, pGroup )))
410
goto done;
411
}
412
413
if (pListOfAccessEntries)
414
{
415
PACL new_dacl;
416
417
if ((ret = SetEntriesInAclW( cCountOfAccessEntries, pListOfAccessEntries, desc.Dacl, &new_dacl )))
418
goto done;
419
420
LocalFree( desc.Dacl );
421
desc.Dacl = new_dacl;
422
desc.Control |= SE_DACL_PRESENT;
423
}
424
425
if (pListOfAuditEntries)
426
{
427
PACL new_sacl;
428
429
if ((ret = SetEntriesInAclW( cCountOfAuditEntries, pListOfAuditEntries, desc.Sacl, &new_sacl )))
430
goto done;
431
432
LocalFree( desc.Sacl );
433
desc.Sacl = new_sacl;
434
desc.Control |= SE_SACL_PRESENT;
435
}
436
437
*lpdwBufferLength = RtlLengthSecurityDescriptor( &desc );
438
*pNewSD = LocalAlloc( LMEM_FIXED, *lpdwBufferLength );
439
440
if ((status = RtlMakeSelfRelativeSD( &desc, *pNewSD, lpdwBufferLength )) != STATUS_SUCCESS)
441
{
442
ret = RtlNtStatusToDosError( status );
443
LocalFree( *pNewSD );
444
*pNewSD = NULL;
445
}
446
447
done:
448
/* free absolute descriptor */
449
LocalFree( desc.Owner );
450
LocalFree( desc.Group );
451
LocalFree( desc.Sacl );
452
LocalFree( desc.Dacl );
453
return ret;
454
}
455
456
static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
457
{
458
NULL,
459
NULL,
460
L"SeCreateTokenPrivilege",
461
L"SeAssignPrimaryTokenPrivilege",
462
L"SeLockMemoryPrivilege",
463
L"SeIncreaseQuotaPrivilege",
464
L"SeMachineAccountPrivilege",
465
L"SeTcbPrivilege",
466
L"SeSecurityPrivilege",
467
L"SeTakeOwnershipPrivilege",
468
L"SeLoadDriverPrivilege",
469
L"SeSystemProfilePrivilege",
470
L"SeSystemtimePrivilege",
471
L"SeProfileSingleProcessPrivilege",
472
L"SeIncreaseBasePriorityPrivilege",
473
L"SeCreatePagefilePrivilege",
474
L"SeCreatePermanentPrivilege",
475
L"SeBackupPrivilege",
476
L"SeRestorePrivilege",
477
L"SeShutdownPrivilege",
478
L"SeDebugPrivilege",
479
L"SeAuditPrivilege",
480
L"SeSystemEnvironmentPrivilege",
481
L"SeChangeNotifyPrivilege",
482
L"SeRemoteShutdownPrivilege",
483
L"SeUndockPrivilege",
484
L"SeSyncAgentPrivilege",
485
L"SeEnableDelegationPrivilege",
486
L"SeManageVolumePrivilege",
487
L"SeImpersonatePrivilege",
488
L"SeCreateGlobalPrivilege",
489
};
490
491
const WCHAR *get_wellknown_privilege_name(const LUID *luid)
492
{
493
if (luid->HighPart || luid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
494
luid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE || !WellKnownPrivNames[luid->LowPart])
495
return NULL;
496
497
return WellKnownPrivNames[luid->LowPart];
498
}
499
500
/******************************************************************************
501
* LookupPrivilegeValueW [ADVAPI32.@]
502
*
503
* See LookupPrivilegeValueA.
504
*/
505
BOOL WINAPI
506
LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
507
{
508
UINT i;
509
510
TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
511
512
if (!ADVAPI_IsLocalComputer(lpSystemName))
513
{
514
SetLastError(RPC_S_SERVER_UNAVAILABLE);
515
return FALSE;
516
}
517
if (!lpName)
518
{
519
SetLastError(ERROR_NO_SUCH_PRIVILEGE);
520
return FALSE;
521
}
522
for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
523
{
524
if( !WellKnownPrivNames[i] )
525
continue;
526
if( wcsicmp( WellKnownPrivNames[i], lpName) )
527
continue;
528
lpLuid->LowPart = i;
529
lpLuid->HighPart = 0;
530
TRACE( "%s -> %08lx-%08lx\n",debugstr_w( lpSystemName ),
531
lpLuid->HighPart, lpLuid->LowPart );
532
return TRUE;
533
}
534
SetLastError(ERROR_NO_SUCH_PRIVILEGE);
535
return FALSE;
536
}
537
538
/******************************************************************************
539
* LookupPrivilegeValueA [ADVAPI32.@]
540
*
541
* Retrieves LUID used on a system to represent the privilege name.
542
*
543
* PARAMS
544
* lpSystemName [I] Name of the system
545
* lpName [I] Name of the privilege
546
* lpLuid [O] Destination for the resulting LUID
547
*
548
* RETURNS
549
* Success: TRUE. lpLuid contains the requested LUID.
550
* Failure: FALSE.
551
*/
552
BOOL WINAPI
553
LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
554
{
555
UNICODE_STRING lpSystemNameW;
556
UNICODE_STRING lpNameW;
557
BOOL ret;
558
559
RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
560
RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
561
ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
562
RtlFreeUnicodeString(&lpNameW);
563
RtlFreeUnicodeString(&lpSystemNameW);
564
return ret;
565
}
566
567
BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
568
LPDWORD cchDisplayName, LPDWORD lpLanguageId )
569
{
570
FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
571
lpDisplayName, cchDisplayName, lpLanguageId);
572
573
return FALSE;
574
}
575
576
BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
577
LPDWORD cchDisplayName, LPDWORD lpLanguageId )
578
{
579
FIXME("%s %s %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
580
lpDisplayName, cchDisplayName, lpLanguageId);
581
582
return FALSE;
583
}
584
585
/******************************************************************************
586
* LookupPrivilegeNameA [ADVAPI32.@]
587
*
588
* See LookupPrivilegeNameW.
589
*/
590
BOOL WINAPI
591
LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
592
LPDWORD cchName)
593
{
594
UNICODE_STRING lpSystemNameW;
595
BOOL ret;
596
DWORD wLen = 0;
597
598
TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
599
600
RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
601
ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
602
if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
603
{
604
LPWSTR lpNameW = malloc(wLen * sizeof(WCHAR));
605
606
ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
607
&wLen);
608
if (ret)
609
{
610
/* Windows crashes if cchName is NULL, so will I */
611
unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
612
*cchName, NULL, NULL);
613
614
if (len == 0)
615
{
616
/* WideCharToMultiByte failed */
617
ret = FALSE;
618
}
619
else if (len > *cchName)
620
{
621
*cchName = len;
622
SetLastError(ERROR_INSUFFICIENT_BUFFER);
623
ret = FALSE;
624
}
625
else
626
{
627
/* WideCharToMultiByte succeeded, output length needs to be
628
* length not including NULL terminator
629
*/
630
*cchName = len - 1;
631
}
632
}
633
free(lpNameW);
634
}
635
RtlFreeUnicodeString(&lpSystemNameW);
636
return ret;
637
}
638
639
/******************************************************************************
640
* LookupPrivilegeNameW [ADVAPI32.@]
641
*
642
* Retrieves the privilege name referred to by the LUID lpLuid.
643
*
644
* PARAMS
645
* lpSystemName [I] Name of the system
646
* lpLuid [I] Privilege value
647
* lpName [O] Name of the privilege
648
* cchName [I/O] Number of characters in lpName.
649
*
650
* RETURNS
651
* Success: TRUE. lpName contains the name of the privilege whose value is
652
* *lpLuid.
653
* Failure: FALSE.
654
*
655
* REMARKS
656
* Only well-known privilege names (those defined in winnt.h) can be retrieved
657
* using this function.
658
* If the length of lpName is too small, on return *cchName will contain the
659
* number of WCHARs needed to contain the privilege, including the NULL
660
* terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
661
* On success, *cchName will contain the number of characters stored in
662
* lpName, NOT including the NULL terminator.
663
*/
664
BOOL WINAPI
665
LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
666
LPDWORD cchName)
667
{
668
size_t privNameLen;
669
670
TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
671
672
if (!ADVAPI_IsLocalComputer(lpSystemName))
673
{
674
SetLastError(RPC_S_SERVER_UNAVAILABLE);
675
return FALSE;
676
}
677
if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
678
lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
679
{
680
SetLastError(ERROR_NO_SUCH_PRIVILEGE);
681
return FALSE;
682
}
683
privNameLen = lstrlenW(WellKnownPrivNames[lpLuid->LowPart]);
684
/* Windows crashes if cchName is NULL, so will I */
685
if (*cchName <= privNameLen)
686
{
687
*cchName = privNameLen + 1;
688
SetLastError(ERROR_INSUFFICIENT_BUFFER);
689
return FALSE;
690
}
691
else
692
{
693
lstrcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
694
*cchName = privNameLen;
695
return TRUE;
696
}
697
}
698
699
/******************************************************************************
700
* GetFileSecurityA [ADVAPI32.@]
701
*
702
* Obtains Specified information about the security of a file or directory.
703
*
704
* PARAMS
705
* lpFileName [I] Name of the file to get info for
706
* RequestedInformation [I] SE_ flags from "winnt.h"
707
* pSecurityDescriptor [O] Destination for security information
708
* nLength [I] Length of pSecurityDescriptor
709
* lpnLengthNeeded [O] Destination for length of returned security information
710
*
711
* RETURNS
712
* Success: TRUE. pSecurityDescriptor contains the requested information.
713
* Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
714
*
715
* NOTES
716
* The information returned is constrained by the callers access rights and
717
* privileges.
718
*/
719
BOOL WINAPI
720
GetFileSecurityA( LPCSTR lpFileName,
721
SECURITY_INFORMATION RequestedInformation,
722
PSECURITY_DESCRIPTOR pSecurityDescriptor,
723
DWORD nLength, LPDWORD lpnLengthNeeded )
724
{
725
BOOL r;
726
LPWSTR name;
727
728
name = strdupAW(lpFileName);
729
r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
730
nLength, lpnLengthNeeded );
731
free( name );
732
733
return r;
734
}
735
736
/******************************************************************************
737
* LookupAccountSidA [ADVAPI32.@]
738
*/
739
BOOL WINAPI
740
LookupAccountSidA(
741
IN LPCSTR system,
742
IN PSID sid,
743
OUT LPSTR account,
744
IN OUT LPDWORD accountSize,
745
OUT LPSTR domain,
746
IN OUT LPDWORD domainSize,
747
OUT PSID_NAME_USE name_use )
748
{
749
DWORD len;
750
BOOL r;
751
LPWSTR systemW;
752
LPWSTR accountW = NULL;
753
LPWSTR domainW = NULL;
754
DWORD accountSizeW = *accountSize;
755
DWORD domainSizeW = *domainSize;
756
757
systemW = strdupAW(system);
758
if (account)
759
accountW = malloc( accountSizeW * sizeof(WCHAR) );
760
if (domain)
761
domainW = malloc( domainSizeW * sizeof(WCHAR) );
762
763
r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
764
765
if (r) {
766
if (accountW && *accountSize) {
767
len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
768
WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
769
*accountSize = len;
770
} else
771
*accountSize = accountSizeW + 1;
772
773
if (domainW && *domainSize) {
774
len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
775
WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
776
*domainSize = len;
777
} else
778
*domainSize = domainSizeW + 1;
779
}
780
else
781
{
782
*accountSize = accountSizeW + 1;
783
*domainSize = domainSizeW + 1;
784
}
785
786
free( systemW );
787
free( accountW );
788
free( domainW );
789
790
return r;
791
}
792
793
/******************************************************************************
794
* LookupAccountSidLocalA [ADVAPI32.@]
795
*/
796
BOOL WINAPI
797
LookupAccountSidLocalA(
798
PSID sid,
799
LPSTR account,
800
LPDWORD accountSize,
801
LPSTR domain,
802
LPDWORD domainSize,
803
PSID_NAME_USE name_use )
804
{
805
return LookupAccountSidA(NULL, sid, account, accountSize, domain, domainSize, name_use);
806
}
807
808
/******************************************************************************
809
* LookupAccountSidW [ADVAPI32.@]
810
*
811
* PARAMS
812
* system []
813
* sid []
814
* account []
815
* accountSize []
816
* domain []
817
* domainSize []
818
* name_use []
819
*/
820
821
BOOL WINAPI
822
LookupAccountSidW(
823
IN LPCWSTR system,
824
IN PSID sid,
825
OUT LPWSTR account,
826
IN OUT LPDWORD accountSize,
827
OUT LPWSTR domain,
828
IN OUT LPDWORD domainSize,
829
OUT PSID_NAME_USE name_use )
830
{
831
unsigned int i, j;
832
const WCHAR * ac = NULL;
833
const WCHAR * dm = NULL;
834
SID_NAME_USE use = 0;
835
LPWSTR computer_name = NULL;
836
LPWSTR account_name = NULL;
837
838
TRACE("(%s,sid=%s,%p,%p(%lu),%p,%p(%lu),%p)\n",
839
debugstr_w(system),debugstr_sid(sid),
840
account,accountSize,accountSize?*accountSize:0,
841
domain,domainSize,domainSize?*domainSize:0,
842
name_use);
843
844
if (!ADVAPI_IsLocalComputer(system)) {
845
FIXME("Only local computer supported!\n");
846
SetLastError(RPC_S_SERVER_UNAVAILABLE);
847
return FALSE;
848
}
849
850
/* check the well known SIDs first */
851
for (i = 0; i <= WinAccountProtectedUsersSid; i++) {
852
if (IsWellKnownSid(sid, i)) {
853
for (j = 0; j < ARRAY_SIZE(ACCOUNT_SIDS); j++) {
854
if (ACCOUNT_SIDS[j].type == i) {
855
ac = ACCOUNT_SIDS[j].account;
856
dm = ACCOUNT_SIDS[j].domain;
857
use = ACCOUNT_SIDS[j].name_use;
858
}
859
}
860
break;
861
}
862
}
863
864
if (dm == NULL) {
865
MAX_SID local;
866
867
/* check for the local computer next */
868
if (ADVAPI_GetComputerSid(&local)) {
869
DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
870
BOOL result;
871
872
computer_name = malloc(size * sizeof(WCHAR));
873
result = GetComputerNameW(computer_name, &size);
874
875
if (result) {
876
if (EqualSid(sid, &local)) {
877
dm = computer_name;
878
ac = L"";
879
use = 3;
880
} else {
881
local.SubAuthorityCount++;
882
883
if (EqualPrefixSid(sid, &local)) {
884
dm = computer_name;
885
use = 1;
886
switch (((MAX_SID *)sid)->SubAuthority[4]) {
887
case DOMAIN_USER_RID_ADMIN:
888
ac = L"Administrator";
889
break;
890
case DOMAIN_USER_RID_GUEST:
891
ac = L"Guest";
892
break;
893
case DOMAIN_GROUP_RID_ADMINS:
894
ac = L"Domain Admins";
895
break;
896
case DOMAIN_GROUP_RID_USERS:
897
ac = L"None";
898
use = SidTypeGroup;
899
break;
900
case DOMAIN_GROUP_RID_GUESTS:
901
ac = L"Domain Guests";
902
break;
903
case DOMAIN_GROUP_RID_COMPUTERS:
904
ac = L"Domain Computers";
905
break;
906
case DOMAIN_GROUP_RID_CONTROLLERS:
907
ac = L"Domain Controllers";
908
break;
909
case DOMAIN_GROUP_RID_CERT_ADMINS:
910
ac = L"Cert Publishers";
911
break;
912
case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
913
ac = L"Schema Admins";
914
break;
915
case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
916
ac = L"Enterprise Admins";
917
break;
918
case DOMAIN_GROUP_RID_POLICY_ADMINS:
919
ac = L"Group Policy Creator Owners";
920
break;
921
case DOMAIN_ALIAS_RID_RAS_SERVERS:
922
ac = L"RAS and IAS Servers";
923
break;
924
case 1000: /* first user account */
925
size = UNLEN + 1;
926
account_name = malloc(size * sizeof(WCHAR));
927
if (GetUserNameW(account_name, &size))
928
ac = account_name;
929
else
930
dm = NULL;
931
932
break;
933
default:
934
dm = NULL;
935
break;
936
}
937
}
938
}
939
}
940
}
941
}
942
943
if (dm) {
944
DWORD ac_len = lstrlenW(ac);
945
DWORD dm_len = lstrlenW(dm);
946
BOOL status = TRUE;
947
948
if (*accountSize > ac_len) {
949
if (account)
950
lstrcpyW(account, ac);
951
}
952
if (*domainSize > dm_len) {
953
if (domain)
954
lstrcpyW(domain, dm);
955
}
956
if ((*accountSize && *accountSize < ac_len) ||
957
(!account && !*accountSize && ac_len) ||
958
(*domainSize && *domainSize < dm_len) ||
959
(!domain && !*domainSize && dm_len))
960
{
961
SetLastError(ERROR_INSUFFICIENT_BUFFER);
962
status = FALSE;
963
}
964
if (*domainSize)
965
*domainSize = dm_len;
966
else
967
*domainSize = dm_len + 1;
968
if (*accountSize)
969
*accountSize = ac_len;
970
else
971
*accountSize = ac_len + 1;
972
973
free(account_name);
974
free(computer_name);
975
if (status) *name_use = use;
976
return status;
977
}
978
979
free(account_name);
980
free(computer_name);
981
SetLastError(ERROR_NONE_MAPPED);
982
return FALSE;
983
}
984
985
/******************************************************************************
986
* LookupAccountSidLocalW [ADVAPI32.@]
987
*/
988
BOOL WINAPI
989
LookupAccountSidLocalW(
990
PSID sid,
991
LPWSTR account,
992
LPDWORD accountSize,
993
LPWSTR domain,
994
LPDWORD domainSize,
995
PSID_NAME_USE name_use )
996
{
997
return LookupAccountSidW(NULL, sid, account, accountSize, domain, domainSize, name_use);
998
}
999
1000
/******************************************************************************
1001
* SetFileSecurityA [ADVAPI32.@]
1002
*
1003
* See SetFileSecurityW.
1004
*/
1005
BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
1006
SECURITY_INFORMATION RequestedInformation,
1007
PSECURITY_DESCRIPTOR pSecurityDescriptor)
1008
{
1009
BOOL r;
1010
LPWSTR name;
1011
1012
name = strdupAW(lpFileName);
1013
r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
1014
free( name );
1015
1016
return r;
1017
}
1018
1019
/******************************************************************************
1020
* QueryWindows31FilesMigration [ADVAPI32.@]
1021
*
1022
* PARAMS
1023
* x1 []
1024
*/
1025
BOOL WINAPI
1026
QueryWindows31FilesMigration( DWORD x1 )
1027
{
1028
FIXME("(%ld):stub\n",x1);
1029
return TRUE;
1030
}
1031
1032
/******************************************************************************
1033
* SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
1034
*
1035
* PARAMS
1036
* x1 []
1037
* x2 []
1038
* x3 []
1039
* x4 []
1040
*/
1041
BOOL WINAPI
1042
SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
1043
DWORD x4 )
1044
{
1045
FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx):stub\n",x1,x2,x3,x4);
1046
return TRUE;
1047
}
1048
1049
/******************************************************************************
1050
* NotifyBootConfigStatus [ADVAPI32.@]
1051
*
1052
* PARAMS
1053
* x1 []
1054
*/
1055
BOOL WINAPI
1056
NotifyBootConfigStatus( BOOL x1 )
1057
{
1058
FIXME("(0x%08d):stub\n",x1);
1059
return TRUE;
1060
}
1061
1062
/******************************************************************************
1063
* LookupAccountNameA [ADVAPI32.@]
1064
*/
1065
BOOL WINAPI
1066
LookupAccountNameA(
1067
IN LPCSTR system,
1068
IN LPCSTR account,
1069
OUT PSID sid,
1070
OUT LPDWORD cbSid,
1071
LPSTR ReferencedDomainName,
1072
IN OUT LPDWORD cbReferencedDomainName,
1073
OUT PSID_NAME_USE name_use )
1074
{
1075
BOOL ret;
1076
UNICODE_STRING lpSystemW;
1077
UNICODE_STRING lpAccountW;
1078
LPWSTR lpReferencedDomainNameW = NULL;
1079
1080
RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
1081
RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
1082
1083
if (ReferencedDomainName)
1084
lpReferencedDomainNameW = malloc(*cbReferencedDomainName * sizeof(WCHAR));
1085
1086
ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
1087
cbReferencedDomainName, name_use);
1088
1089
if (ret && lpReferencedDomainNameW)
1090
{
1091
WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
1092
ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
1093
}
1094
1095
RtlFreeUnicodeString(&lpSystemW);
1096
RtlFreeUnicodeString(&lpAccountW);
1097
free(lpReferencedDomainNameW);
1098
1099
return ret;
1100
}
1101
1102
/******************************************************************************
1103
* lookup_user_account_name
1104
*/
1105
static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
1106
LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
1107
{
1108
char buffer[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
1109
DWORD len = sizeof(buffer);
1110
HANDLE token;
1111
BOOL ret;
1112
PSID pSid;
1113
WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
1114
DWORD nameLen;
1115
1116
if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
1117
{
1118
if (GetLastError() != ERROR_NO_TOKEN) return FALSE;
1119
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) return FALSE;
1120
}
1121
1122
ret = GetTokenInformation(token, TokenUser, buffer, len, &len);
1123
CloseHandle( token );
1124
1125
if (!ret) return FALSE;
1126
1127
pSid = ((TOKEN_USER *)buffer)->User.Sid;
1128
1129
if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
1130
CopySid(*cbSid, Sid, pSid);
1131
if (*cbSid < GetLengthSid(pSid))
1132
{
1133
SetLastError(ERROR_INSUFFICIENT_BUFFER);
1134
ret = FALSE;
1135
}
1136
*cbSid = GetLengthSid(pSid);
1137
1138
nameLen = MAX_COMPUTERNAME_LENGTH + 1;
1139
if (!GetComputerNameW(domainName, &nameLen))
1140
{
1141
domainName[0] = 0;
1142
nameLen = 0;
1143
}
1144
if (*cchReferencedDomainName <= nameLen || !ret)
1145
{
1146
SetLastError(ERROR_INSUFFICIENT_BUFFER);
1147
nameLen += 1;
1148
ret = FALSE;
1149
}
1150
else if (ReferencedDomainName)
1151
lstrcpyW(ReferencedDomainName, domainName);
1152
1153
*cchReferencedDomainName = nameLen;
1154
1155
if (ret)
1156
*peUse = SidTypeUser;
1157
1158
return ret;
1159
}
1160
1161
/******************************************************************************
1162
* lookup_computer_account_name
1163
*/
1164
static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
1165
LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
1166
{
1167
MAX_SID local;
1168
BOOL ret;
1169
WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
1170
DWORD nameLen;
1171
1172
if ((ret = ADVAPI_GetComputerSid(&local)))
1173
{
1174
if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
1175
CopySid(*cbSid, Sid, &local);
1176
if (*cbSid < GetLengthSid(&local))
1177
{
1178
SetLastError(ERROR_INSUFFICIENT_BUFFER);
1179
ret = FALSE;
1180
}
1181
*cbSid = GetLengthSid(&local);
1182
}
1183
1184
nameLen = MAX_COMPUTERNAME_LENGTH + 1;
1185
if (!GetComputerNameW(domainName, &nameLen))
1186
{
1187
domainName[0] = 0;
1188
nameLen = 0;
1189
}
1190
if (*cchReferencedDomainName <= nameLen || !ret)
1191
{
1192
SetLastError(ERROR_INSUFFICIENT_BUFFER);
1193
nameLen += 1;
1194
ret = FALSE;
1195
}
1196
else if (ReferencedDomainName)
1197
lstrcpyW(ReferencedDomainName, domainName);
1198
1199
*cchReferencedDomainName = nameLen;
1200
1201
if (ret)
1202
*peUse = SidTypeDomain;
1203
1204
return ret;
1205
}
1206
1207
static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
1208
LSA_UNICODE_STRING *domain )
1209
{
1210
WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
1211
1212
while (p > str->Buffer && *p != '\\') p--;
1213
1214
if (p >= str->Buffer && *p == '\\')
1215
{
1216
domain->Buffer = str->Buffer;
1217
domain->Length = (p - str->Buffer) * sizeof(WCHAR);
1218
1219
account->Buffer = p + 1;
1220
account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
1221
}
1222
else
1223
{
1224
domain->Buffer = NULL;
1225
domain->Length = 0;
1226
1227
account->Buffer = str->Buffer;
1228
account->Length = str->Length;
1229
}
1230
}
1231
1232
static BOOL match_domain( ULONG idx, const LSA_UNICODE_STRING *domain )
1233
{
1234
ULONG len = lstrlenW( ACCOUNT_SIDS[idx].domain );
1235
1236
if (len == domain->Length / sizeof(WCHAR) && !wcsnicmp( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
1237
return TRUE;
1238
1239
return FALSE;
1240
}
1241
1242
static BOOL match_account( ULONG idx, const LSA_UNICODE_STRING *account )
1243
{
1244
ULONG len = lstrlenW( ACCOUNT_SIDS[idx].account );
1245
1246
if (len == account->Length / sizeof(WCHAR) && !wcsnicmp( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
1247
return TRUE;
1248
1249
if (ACCOUNT_SIDS[idx].alias)
1250
{
1251
len = lstrlenW( ACCOUNT_SIDS[idx].alias );
1252
if (len == account->Length / sizeof(WCHAR) && !wcsnicmp( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
1253
return TRUE;
1254
}
1255
return FALSE;
1256
}
1257
1258
/*
1259
* Helper function for LookupAccountNameW
1260
*/
1261
BOOL lookup_local_wellknown_name( const LSA_UNICODE_STRING *account_and_domain,
1262
PSID Sid, LPDWORD cbSid,
1263
LPWSTR ReferencedDomainName,
1264
LPDWORD cchReferencedDomainName,
1265
PSID_NAME_USE peUse, BOOL *handled )
1266
{
1267
PSID pSid;
1268
LSA_UNICODE_STRING account, domain;
1269
BOOL ret = TRUE;
1270
ULONG i;
1271
1272
*handled = FALSE;
1273
split_domain_account( account_and_domain, &account, &domain );
1274
1275
for (i = 0; i < ARRAY_SIZE(ACCOUNT_SIDS); i++)
1276
{
1277
/* check domain first */
1278
if (domain.Buffer && !match_domain( i, &domain )) continue;
1279
1280
if (match_account( i, &account ))
1281
{
1282
DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
1283
1284
if (!(pSid = malloc( sidLen ))) return FALSE;
1285
1286
if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
1287
{
1288
if (*cbSid < sidLen)
1289
{
1290
SetLastError(ERROR_INSUFFICIENT_BUFFER);
1291
ret = FALSE;
1292
}
1293
else if (Sid)
1294
{
1295
CopySid(*cbSid, Sid, pSid);
1296
}
1297
*cbSid = sidLen;
1298
}
1299
1300
len = lstrlenW( ACCOUNT_SIDS[i].domain );
1301
if (*cchReferencedDomainName <= len || !ret)
1302
{
1303
SetLastError(ERROR_INSUFFICIENT_BUFFER);
1304
len++;
1305
ret = FALSE;
1306
}
1307
else if (ReferencedDomainName)
1308
{
1309
lstrcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
1310
}
1311
1312
*cchReferencedDomainName = len;
1313
if (ret)
1314
*peUse = ACCOUNT_SIDS[i].name_use;
1315
1316
free(pSid);
1317
*handled = TRUE;
1318
return ret;
1319
}
1320
}
1321
return ret;
1322
}
1323
1324
BOOL lookup_local_user_name( const LSA_UNICODE_STRING *account_and_domain,
1325
PSID Sid, LPDWORD cbSid,
1326
LPWSTR ReferencedDomainName,
1327
LPDWORD cchReferencedDomainName,
1328
PSID_NAME_USE peUse, BOOL *handled )
1329
{
1330
DWORD nameLen;
1331
LPWSTR userName = NULL;
1332
LSA_UNICODE_STRING account, domain;
1333
BOOL ret = TRUE;
1334
1335
*handled = FALSE;
1336
split_domain_account( account_and_domain, &account, &domain );
1337
1338
/* Let the current Unix user id masquerade as first Windows user account */
1339
1340
nameLen = UNLEN + 1;
1341
if (!(userName = malloc( nameLen * sizeof(WCHAR) ))) return FALSE;
1342
1343
if (domain.Buffer)
1344
{
1345
/* check to make sure this account is on this computer */
1346
if (GetComputerNameW( userName, &nameLen ) &&
1347
(domain.Length / sizeof(WCHAR) != nameLen || wcsnicmp( domain.Buffer, userName, nameLen )))
1348
{
1349
SetLastError(ERROR_NONE_MAPPED);
1350
ret = FALSE;
1351
}
1352
nameLen = UNLEN + 1;
1353
}
1354
1355
if (GetUserNameW( userName, &nameLen ) &&
1356
account.Length / sizeof(WCHAR) == nameLen - 1 && !wcsnicmp( account.Buffer, userName, nameLen - 1 ))
1357
{
1358
ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
1359
*handled = TRUE;
1360
}
1361
else
1362
{
1363
nameLen = UNLEN + 1;
1364
if (GetComputerNameW( userName, &nameLen ) &&
1365
account.Length / sizeof(WCHAR) == nameLen && !wcsnicmp( account.Buffer, userName , nameLen ))
1366
{
1367
ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
1368
*handled = TRUE;
1369
}
1370
}
1371
1372
free(userName);
1373
return ret;
1374
}
1375
1376
/******************************************************************************
1377
* LookupAccountNameW [ADVAPI32.@]
1378
*/
1379
BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
1380
LPDWORD cbSid, LPWSTR ReferencedDomainName,
1381
LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
1382
{
1383
BOOL ret, handled;
1384
LSA_UNICODE_STRING account;
1385
1386
TRACE("%s %s %p %p %p %p %p\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
1387
Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
1388
1389
if (!ADVAPI_IsLocalComputer( lpSystemName ))
1390
{
1391
FIXME("remote computer not supported\n");
1392
SetLastError( RPC_S_SERVER_UNAVAILABLE );
1393
return FALSE;
1394
}
1395
1396
if (!lpAccountName || !wcscmp( lpAccountName, L"" ))
1397
{
1398
lpAccountName = L"BUILTIN";
1399
}
1400
1401
RtlInitUnicodeString( &account, lpAccountName );
1402
1403
/* Check well known SIDs first */
1404
ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
1405
cchReferencedDomainName, peUse, &handled );
1406
if (handled)
1407
return ret;
1408
1409
/* Check user names */
1410
ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
1411
cchReferencedDomainName, peUse, &handled);
1412
if (handled)
1413
return ret;
1414
1415
SetLastError( ERROR_NONE_MAPPED );
1416
return FALSE;
1417
}
1418
1419
/******************************************************************************
1420
* AccessCheckAndAuditAlarmA [ADVAPI32.@]
1421
*/
1422
BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
1423
LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
1424
PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
1425
LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
1426
{
1427
FIXME("stub (%s,%p,%s,%s,%p,%08lx,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
1428
HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
1429
SecurityDescriptor, DesiredAccess, GenericMapping,
1430
ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
1431
return TRUE;
1432
}
1433
1434
BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
1435
{
1436
FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
1437
1438
return TRUE;
1439
}
1440
1441
BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
1442
LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
1443
DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
1444
LPBOOL GenerateOnClose)
1445
{
1446
FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08lx,0x%08lx,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
1447
HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
1448
ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
1449
GenerateOnClose);
1450
1451
return TRUE;
1452
}
1453
1454
BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
1455
DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
1456
{
1457
FIXME("stub (%s,%p,%p,0x%08lx,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
1458
DesiredAccess, Privileges, AccessGranted);
1459
1460
return TRUE;
1461
}
1462
1463
BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
1464
PPRIVILEGE_SET Privileges, BOOL AccessGranted)
1465
{
1466
FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
1467
ClientToken, Privileges, AccessGranted);
1468
1469
return TRUE;
1470
}
1471
1472
#define HKEY_SPECIAL_ROOT_FIRST HKEY_CLASSES_ROOT
1473
#define HKEY_SPECIAL_ROOT_LAST HKEY_DYN_DATA
1474
1475
/******************************************************************************
1476
* GetSecurityInfo [ADVAPI32.@]
1477
*
1478
* Retrieves a copy of the security descriptor associated with an object.
1479
*
1480
* PARAMS
1481
* hObject [I] A handle for the object.
1482
* ObjectType [I] The type of object.
1483
* SecurityInfo [I] A bitmask indicating what info to retrieve.
1484
* ppsidOwner [O] If non-null, receives a pointer to the owner SID.
1485
* ppsidGroup [O] If non-null, receives a pointer to the group SID.
1486
* ppDacl [O] If non-null, receives a pointer to the DACL.
1487
* ppSacl [O] If non-null, receives a pointer to the SACL.
1488
* ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
1489
* which must be freed with LocalFree.
1490
*
1491
* RETURNS
1492
* ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
1493
*/
1494
DWORD WINAPI GetSecurityInfo( HANDLE handle, SE_OBJECT_TYPE type, SECURITY_INFORMATION SecurityInfo,
1495
PSID *ppsidOwner, PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
1496
PSECURITY_DESCRIPTOR *ppSecurityDescriptor )
1497
{
1498
PSECURITY_DESCRIPTOR sd;
1499
NTSTATUS status;
1500
ULONG size;
1501
BOOL present, defaulted;
1502
HKEY key = NULL;
1503
1504
if (!handle)
1505
return ERROR_INVALID_HANDLE;
1506
1507
/* A NULL descriptor is allowed if any one of the other pointers is not NULL */
1508
if (!(ppsidOwner||ppsidGroup||ppDacl||ppSacl||ppSecurityDescriptor)) return ERROR_INVALID_PARAMETER;
1509
1510
/* If no descriptor, we have to check that there's a pointer for the requested information */
1511
if( !ppSecurityDescriptor && (
1512
((SecurityInfo & OWNER_SECURITY_INFORMATION) && !ppsidOwner)
1513
|| ((SecurityInfo & GROUP_SECURITY_INFORMATION) && !ppsidGroup)
1514
|| ((SecurityInfo & DACL_SECURITY_INFORMATION) && !ppDacl)
1515
|| ((SecurityInfo & SACL_SECURITY_INFORMATION) && !ppSacl) ))
1516
return ERROR_INVALID_PARAMETER;
1517
1518
switch (type)
1519
{
1520
case SE_SERVICE:
1521
if (!QueryServiceObjectSecurity( handle, SecurityInfo, NULL, 0, &size )
1522
&& GetLastError() != ERROR_INSUFFICIENT_BUFFER)
1523
return GetLastError();
1524
1525
if (!(sd = LocalAlloc( 0, size ))) return ERROR_NOT_ENOUGH_MEMORY;
1526
1527
if (!QueryServiceObjectSecurity( handle, SecurityInfo, sd, size, &size ))
1528
{
1529
LocalFree(sd);
1530
return GetLastError();
1531
}
1532
break;
1533
1534
case SE_WINDOW_OBJECT:
1535
if (!GetUserObjectSecurity( handle, &SecurityInfo, NULL, 0, &size )
1536
&& GetLastError() != ERROR_INSUFFICIENT_BUFFER)
1537
return GetLastError();
1538
1539
if (!(sd = LocalAlloc( 0, size )))
1540
return ERROR_NOT_ENOUGH_MEMORY;
1541
1542
if (!GetUserObjectSecurity( handle, &SecurityInfo, sd, size, &size ))
1543
{
1544
LocalFree( sd );
1545
return GetLastError();
1546
}
1547
break;
1548
1549
case SE_KERNEL_OBJECT:
1550
case SE_FILE_OBJECT:
1551
case SE_WMIGUID_OBJECT:
1552
case SE_REGISTRY_KEY:
1553
if (type == SE_REGISTRY_KEY && (HandleToUlong(handle) >= HandleToUlong(HKEY_SPECIAL_ROOT_FIRST))
1554
&& (HandleToUlong(handle) <= HandleToUlong(HKEY_SPECIAL_ROOT_LAST)))
1555
{
1556
REGSAM access = READ_CONTROL;
1557
DWORD ret;
1558
1559
if (SecurityInfo & SACL_SECURITY_INFORMATION)
1560
access |= ACCESS_SYSTEM_SECURITY;
1561
1562
if ((ret = RegCreateKeyExW( handle, NULL, 0, NULL, 0, access, NULL, &key, NULL )))
1563
return ret;
1564
1565
handle = key;
1566
}
1567
1568
status = NtQuerySecurityObject( handle, SecurityInfo, NULL, 0, &size );
1569
if (status != STATUS_SUCCESS && status != STATUS_BUFFER_TOO_SMALL)
1570
{
1571
RegCloseKey( key );
1572
return RtlNtStatusToDosError( status );
1573
}
1574
1575
if (!(sd = LocalAlloc( 0, size )))
1576
{
1577
RegCloseKey( key );
1578
return ERROR_NOT_ENOUGH_MEMORY;
1579
}
1580
1581
if ((status = NtQuerySecurityObject( handle, SecurityInfo, sd, size, &size )))
1582
{
1583
RegCloseKey( key );
1584
LocalFree(sd);
1585
return RtlNtStatusToDosError( status );
1586
}
1587
RegCloseKey( key );
1588
break;
1589
1590
default:
1591
FIXME("unimplemented type %u\n", type);
1592
return ERROR_CALL_NOT_IMPLEMENTED;
1593
}
1594
1595
if (ppsidOwner)
1596
{
1597
*ppsidOwner = NULL;
1598
GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
1599
}
1600
if (ppsidGroup)
1601
{
1602
*ppsidGroup = NULL;
1603
GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
1604
}
1605
if (ppDacl)
1606
{
1607
*ppDacl = NULL;
1608
GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
1609
}
1610
if (ppSacl)
1611
{
1612
*ppSacl = NULL;
1613
GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
1614
}
1615
if (ppSecurityDescriptor)
1616
*ppSecurityDescriptor = sd;
1617
1618
/* The security descriptor (sd) cannot be freed if ppSecurityDescriptor is
1619
* NULL, because native happily returns the SIDs and ACLs that are requested
1620
* in this case.
1621
*/
1622
1623
return ERROR_SUCCESS;
1624
}
1625
1626
/******************************************************************************
1627
* GetSecurityInfoExA [ADVAPI32.@]
1628
*/
1629
DWORD WINAPI GetSecurityInfoExA(
1630
HANDLE hObject, SE_OBJECT_TYPE ObjectType,
1631
SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
1632
LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
1633
PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
1634
)
1635
{
1636
FIXME("stub!\n");
1637
return ERROR_BAD_PROVIDER;
1638
}
1639
1640
/******************************************************************************
1641
* GetSecurityInfoExW [ADVAPI32.@]
1642
*/
1643
DWORD WINAPI GetSecurityInfoExW(
1644
HANDLE hObject, SE_OBJECT_TYPE ObjectType,
1645
SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
1646
LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList,
1647
PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
1648
)
1649
{
1650
FIXME("stub!\n");
1651
return ERROR_BAD_PROVIDER;
1652
}
1653
1654
/******************************************************************************
1655
* BuildExplicitAccessWithNameA [ADVAPI32.@]
1656
*/
1657
VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
1658
LPSTR pTrusteeName, DWORD AccessPermissions,
1659
ACCESS_MODE AccessMode, DWORD Inheritance )
1660
{
1661
TRACE("%p %s 0x%08lx 0x%08x 0x%08lx\n", pExplicitAccess, debugstr_a(pTrusteeName),
1662
AccessPermissions, AccessMode, Inheritance);
1663
1664
pExplicitAccess->grfAccessPermissions = AccessPermissions;
1665
pExplicitAccess->grfAccessMode = AccessMode;
1666
pExplicitAccess->grfInheritance = Inheritance;
1667
1668
pExplicitAccess->Trustee.pMultipleTrustee = NULL;
1669
pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1670
pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
1671
pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
1672
pExplicitAccess->Trustee.ptstrName = pTrusteeName;
1673
}
1674
1675
/******************************************************************************
1676
* BuildExplicitAccessWithNameW [ADVAPI32.@]
1677
*/
1678
VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
1679
LPWSTR pTrusteeName, DWORD AccessPermissions,
1680
ACCESS_MODE AccessMode, DWORD Inheritance )
1681
{
1682
TRACE("%p %s 0x%08lx 0x%08x 0x%08lx\n", pExplicitAccess, debugstr_w(pTrusteeName),
1683
AccessPermissions, AccessMode, Inheritance);
1684
1685
pExplicitAccess->grfAccessPermissions = AccessPermissions;
1686
pExplicitAccess->grfAccessMode = AccessMode;
1687
pExplicitAccess->grfInheritance = Inheritance;
1688
1689
pExplicitAccess->Trustee.pMultipleTrustee = NULL;
1690
pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1691
pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
1692
pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
1693
pExplicitAccess->Trustee.ptstrName = pTrusteeName;
1694
}
1695
1696
/******************************************************************************
1697
* BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
1698
*/
1699
VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
1700
SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
1701
LPSTR InheritedObjectTypeName, LPSTR Name )
1702
{
1703
DWORD ObjectsPresent = 0;
1704
1705
TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
1706
ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
1707
1708
/* Fill the OBJECTS_AND_NAME structure */
1709
pObjName->ObjectType = ObjectType;
1710
if (ObjectTypeName != NULL)
1711
{
1712
ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
1713
}
1714
1715
pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
1716
if (InheritedObjectTypeName != NULL)
1717
{
1718
ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
1719
}
1720
1721
pObjName->ObjectsPresent = ObjectsPresent;
1722
pObjName->ptstrName = Name;
1723
1724
/* Fill the TRUSTEE structure */
1725
pTrustee->pMultipleTrustee = NULL;
1726
pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1727
pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
1728
pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1729
pTrustee->ptstrName = (LPSTR)pObjName;
1730
}
1731
1732
/******************************************************************************
1733
* BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
1734
*/
1735
VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
1736
SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
1737
LPWSTR InheritedObjectTypeName, LPWSTR Name )
1738
{
1739
DWORD ObjectsPresent = 0;
1740
1741
TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
1742
ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
1743
1744
/* Fill the OBJECTS_AND_NAME structure */
1745
pObjName->ObjectType = ObjectType;
1746
if (ObjectTypeName != NULL)
1747
{
1748
ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
1749
}
1750
1751
pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
1752
if (InheritedObjectTypeName != NULL)
1753
{
1754
ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
1755
}
1756
1757
pObjName->ObjectsPresent = ObjectsPresent;
1758
pObjName->ptstrName = Name;
1759
1760
/* Fill the TRUSTEE structure */
1761
pTrustee->pMultipleTrustee = NULL;
1762
pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1763
pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
1764
pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1765
pTrustee->ptstrName = (LPWSTR)pObjName;
1766
}
1767
1768
/******************************************************************************
1769
* BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
1770
*/
1771
VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
1772
GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
1773
{
1774
DWORD ObjectsPresent = 0;
1775
1776
TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
1777
1778
/* Fill the OBJECTS_AND_SID structure */
1779
if (pObjectGuid != NULL)
1780
{
1781
pObjSid->ObjectTypeGuid = *pObjectGuid;
1782
ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
1783
}
1784
else
1785
{
1786
ZeroMemory(&pObjSid->ObjectTypeGuid,
1787
sizeof(GUID));
1788
}
1789
1790
if (pInheritedObjectGuid != NULL)
1791
{
1792
pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
1793
ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
1794
}
1795
else
1796
{
1797
ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
1798
sizeof(GUID));
1799
}
1800
1801
pObjSid->ObjectsPresent = ObjectsPresent;
1802
pObjSid->pSid = pSid;
1803
1804
/* Fill the TRUSTEE structure */
1805
pTrustee->pMultipleTrustee = NULL;
1806
pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1807
pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
1808
pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1809
pTrustee->ptstrName = (LPSTR) pObjSid;
1810
}
1811
1812
/******************************************************************************
1813
* BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
1814
*/
1815
VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
1816
GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
1817
{
1818
DWORD ObjectsPresent = 0;
1819
1820
TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
1821
1822
/* Fill the OBJECTS_AND_SID structure */
1823
if (pObjectGuid != NULL)
1824
{
1825
pObjSid->ObjectTypeGuid = *pObjectGuid;
1826
ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
1827
}
1828
else
1829
{
1830
ZeroMemory(&pObjSid->ObjectTypeGuid,
1831
sizeof(GUID));
1832
}
1833
1834
if (pInheritedObjectGuid != NULL)
1835
{
1836
pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
1837
ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
1838
}
1839
else
1840
{
1841
ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
1842
sizeof(GUID));
1843
}
1844
1845
pObjSid->ObjectsPresent = ObjectsPresent;
1846
pObjSid->pSid = pSid;
1847
1848
/* Fill the TRUSTEE structure */
1849
pTrustee->pMultipleTrustee = NULL;
1850
pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1851
pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
1852
pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1853
pTrustee->ptstrName = (LPWSTR) pObjSid;
1854
}
1855
1856
/******************************************************************************
1857
* BuildTrusteeWithSidA [ADVAPI32.@]
1858
*/
1859
VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
1860
{
1861
TRACE("%p %p\n", pTrustee, pSid);
1862
1863
pTrustee->pMultipleTrustee = NULL;
1864
pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1865
pTrustee->TrusteeForm = TRUSTEE_IS_SID;
1866
pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1867
pTrustee->ptstrName = pSid;
1868
}
1869
1870
/******************************************************************************
1871
* BuildTrusteeWithSidW [ADVAPI32.@]
1872
*/
1873
VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
1874
{
1875
TRACE("%p %p\n", pTrustee, pSid);
1876
1877
pTrustee->pMultipleTrustee = NULL;
1878
pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1879
pTrustee->TrusteeForm = TRUSTEE_IS_SID;
1880
pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1881
pTrustee->ptstrName = pSid;
1882
}
1883
1884
/******************************************************************************
1885
* BuildTrusteeWithNameA [ADVAPI32.@]
1886
*/
1887
VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
1888
{
1889
TRACE("%p %s\n", pTrustee, debugstr_a(name) );
1890
1891
pTrustee->pMultipleTrustee = NULL;
1892
pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1893
pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
1894
pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1895
pTrustee->ptstrName = name;
1896
}
1897
1898
/******************************************************************************
1899
* BuildTrusteeWithNameW [ADVAPI32.@]
1900
*/
1901
VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
1902
{
1903
TRACE("%p %s\n", pTrustee, debugstr_w(name) );
1904
1905
pTrustee->pMultipleTrustee = NULL;
1906
pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1907
pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
1908
pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1909
pTrustee->ptstrName = name;
1910
}
1911
1912
/******************************************************************************
1913
* GetTrusteeFormA [ADVAPI32.@]
1914
*/
1915
TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee)
1916
{
1917
TRACE("(%p)\n", pTrustee);
1918
1919
if (!pTrustee)
1920
return TRUSTEE_BAD_FORM;
1921
1922
return pTrustee->TrusteeForm;
1923
}
1924
1925
/******************************************************************************
1926
* GetTrusteeFormW [ADVAPI32.@]
1927
*/
1928
TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee)
1929
{
1930
TRACE("(%p)\n", pTrustee);
1931
1932
if (!pTrustee)
1933
return TRUSTEE_BAD_FORM;
1934
1935
return pTrustee->TrusteeForm;
1936
}
1937
1938
/******************************************************************************
1939
* GetTrusteeNameA [ADVAPI32.@]
1940
*/
1941
LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee)
1942
{
1943
TRACE("(%p)\n", pTrustee);
1944
1945
if (!pTrustee)
1946
return NULL;
1947
1948
return pTrustee->ptstrName;
1949
}
1950
1951
/******************************************************************************
1952
* GetTrusteeNameW [ADVAPI32.@]
1953
*/
1954
LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee)
1955
{
1956
TRACE("(%p)\n", pTrustee);
1957
1958
if (!pTrustee)
1959
return NULL;
1960
1961
return pTrustee->ptstrName;
1962
}
1963
1964
/******************************************************************************
1965
* GetTrusteeTypeA [ADVAPI32.@]
1966
*/
1967
TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee)
1968
{
1969
TRACE("(%p)\n", pTrustee);
1970
1971
if (!pTrustee)
1972
return TRUSTEE_IS_UNKNOWN;
1973
1974
return pTrustee->TrusteeType;
1975
}
1976
1977
/******************************************************************************
1978
* GetTrusteeTypeW [ADVAPI32.@]
1979
*/
1980
TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee)
1981
{
1982
TRACE("(%p)\n", pTrustee);
1983
1984
if (!pTrustee)
1985
return TRUSTEE_IS_UNKNOWN;
1986
1987
return pTrustee->TrusteeType;
1988
}
1989
1990
static DWORD trustee_name_A_to_W(TRUSTEE_FORM form, char *trustee_nameA, WCHAR **ptrustee_nameW)
1991
{
1992
switch (form)
1993
{
1994
case TRUSTEE_IS_NAME:
1995
{
1996
*ptrustee_nameW = strdupAW(trustee_nameA);
1997
return ERROR_SUCCESS;
1998
}
1999
case TRUSTEE_IS_OBJECTS_AND_NAME:
2000
{
2001
OBJECTS_AND_NAME_A *objA = (OBJECTS_AND_NAME_A *)trustee_nameA;
2002
OBJECTS_AND_NAME_W *objW = NULL;
2003
2004
if (objA)
2005
{
2006
if (!(objW = malloc( sizeof(OBJECTS_AND_NAME_W) )))
2007
return ERROR_NOT_ENOUGH_MEMORY;
2008
2009
objW->ObjectsPresent = objA->ObjectsPresent;
2010
objW->ObjectType = objA->ObjectType;
2011
objW->ObjectTypeName = strdupAW(objA->ObjectTypeName);
2012
objW->InheritedObjectTypeName = strdupAW(objA->InheritedObjectTypeName);
2013
objW->ptstrName = strdupAW(objA->ptstrName);
2014
}
2015
2016
*ptrustee_nameW = (WCHAR *)objW;
2017
return ERROR_SUCCESS;
2018
}
2019
/* These forms do not require conversion. */
2020
case TRUSTEE_IS_SID:
2021
case TRUSTEE_IS_OBJECTS_AND_SID:
2022
*ptrustee_nameW = (WCHAR *)trustee_nameA;
2023
return ERROR_SUCCESS;
2024
default:
2025
return ERROR_INVALID_PARAMETER;
2026
}
2027
}
2028
2029
static void free_trustee_name(TRUSTEE_FORM form, WCHAR *trustee_nameW)
2030
{
2031
switch (form)
2032
{
2033
case TRUSTEE_IS_NAME:
2034
free( trustee_nameW );
2035
break;
2036
case TRUSTEE_IS_OBJECTS_AND_NAME:
2037
{
2038
OBJECTS_AND_NAME_W *objW = (OBJECTS_AND_NAME_W *)trustee_nameW;
2039
2040
if (objW)
2041
{
2042
free( objW->ptstrName );
2043
free( objW->InheritedObjectTypeName );
2044
free( objW->ObjectTypeName );
2045
free( objW );
2046
}
2047
2048
break;
2049
}
2050
/* Other forms did not require allocation, so no freeing is necessary. */
2051
default:
2052
break;
2053
}
2054
}
2055
2056
static DWORD trustee_to_sid( DWORD nDestinationSidLength, PSID pDestinationSid, PTRUSTEEW pTrustee )
2057
{
2058
if (pTrustee->MultipleTrusteeOperation == TRUSTEE_IS_IMPERSONATE)
2059
{
2060
WARN("bad multiple trustee operation %d\n", pTrustee->MultipleTrusteeOperation);
2061
return ERROR_INVALID_PARAMETER;
2062
}
2063
2064
switch (pTrustee->TrusteeForm)
2065
{
2066
case TRUSTEE_IS_SID:
2067
if (!CopySid(nDestinationSidLength, pDestinationSid, pTrustee->ptstrName))
2068
{
2069
WARN("bad sid %p\n", pTrustee->ptstrName);
2070
return ERROR_INVALID_PARAMETER;
2071
}
2072
break;
2073
case TRUSTEE_IS_NAME:
2074
{
2075
DWORD sid_size = nDestinationSidLength;
2076
DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
2077
SID_NAME_USE use;
2078
if (!wcscmp( pTrustee->ptstrName, L"CURRENT_USER" ))
2079
{
2080
if (!lookup_user_account_name( pDestinationSid, &sid_size, NULL, &domain_size, &use ))
2081
{
2082
return GetLastError();
2083
}
2084
}
2085
else if (!LookupAccountNameW(NULL, pTrustee->ptstrName, pDestinationSid, &sid_size, NULL, &domain_size, &use))
2086
{
2087
WARN("bad user name %s\n", debugstr_w(pTrustee->ptstrName));
2088
return ERROR_INVALID_PARAMETER;
2089
}
2090
break;
2091
}
2092
case TRUSTEE_IS_OBJECTS_AND_SID:
2093
FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
2094
break;
2095
case TRUSTEE_IS_OBJECTS_AND_NAME:
2096
FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
2097
break;
2098
default:
2099
WARN("bad trustee form %d\n", pTrustee->TrusteeForm);
2100
return ERROR_INVALID_PARAMETER;
2101
}
2102
2103
return ERROR_SUCCESS;
2104
}
2105
2106
/******************************************************************************
2107
* SetEntriesInAclA [ADVAPI32.@]
2108
*/
2109
DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
2110
PACL OldAcl, PACL* NewAcl )
2111
{
2112
DWORD err = ERROR_SUCCESS;
2113
EXPLICIT_ACCESSW *pEntriesW;
2114
UINT alloc_index, free_index;
2115
2116
TRACE("%ld %p %p %p\n", count, pEntries, OldAcl, NewAcl);
2117
2118
if (NewAcl)
2119
*NewAcl = NULL;
2120
2121
if (!count && !OldAcl)
2122
return ERROR_SUCCESS;
2123
2124
pEntriesW = malloc( count * sizeof(EXPLICIT_ACCESSW) );
2125
if (!pEntriesW)
2126
return ERROR_NOT_ENOUGH_MEMORY;
2127
2128
for (alloc_index = 0; alloc_index < count; ++alloc_index)
2129
{
2130
pEntriesW[alloc_index].grfAccessPermissions = pEntries[alloc_index].grfAccessPermissions;
2131
pEntriesW[alloc_index].grfAccessMode = pEntries[alloc_index].grfAccessMode;
2132
pEntriesW[alloc_index].grfInheritance = pEntries[alloc_index].grfInheritance;
2133
pEntriesW[alloc_index].Trustee.pMultipleTrustee = NULL; /* currently not supported */
2134
pEntriesW[alloc_index].Trustee.MultipleTrusteeOperation = pEntries[alloc_index].Trustee.MultipleTrusteeOperation;
2135
pEntriesW[alloc_index].Trustee.TrusteeForm = pEntries[alloc_index].Trustee.TrusteeForm;
2136
pEntriesW[alloc_index].Trustee.TrusteeType = pEntries[alloc_index].Trustee.TrusteeType;
2137
2138
err = trustee_name_A_to_W( pEntries[alloc_index].Trustee.TrusteeForm,
2139
pEntries[alloc_index].Trustee.ptstrName,
2140
&pEntriesW[alloc_index].Trustee.ptstrName );
2141
if (err != ERROR_SUCCESS)
2142
{
2143
if (err == ERROR_INVALID_PARAMETER)
2144
WARN("bad trustee form %d for trustee %d\n",
2145
pEntries[alloc_index].Trustee.TrusteeForm, alloc_index);
2146
2147
goto cleanup;
2148
}
2149
}
2150
2151
err = SetEntriesInAclW( count, pEntriesW, OldAcl, NewAcl );
2152
2153
cleanup:
2154
/* Free any previously allocated trustee name buffers, taking into account
2155
* a possible out-of-memory condition while building the EXPLICIT_ACCESSW
2156
* list. */
2157
for (free_index = 0; free_index < alloc_index; ++free_index)
2158
free_trustee_name( pEntriesW[free_index].Trustee.TrusteeForm, pEntriesW[free_index].Trustee.ptstrName );
2159
2160
free( pEntriesW );
2161
return err;
2162
}
2163
2164
/******************************************************************************
2165
* SetEntriesInAclW [ADVAPI32.@]
2166
*/
2167
DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
2168
PACL OldAcl, PACL* NewAcl )
2169
{
2170
ULONG i;
2171
PSID *ppsid;
2172
DWORD ret = ERROR_SUCCESS;
2173
DWORD acl_size = sizeof(ACL);
2174
NTSTATUS status;
2175
2176
TRACE("%ld %p %p %p\n", count, pEntries, OldAcl, NewAcl);
2177
2178
if (NewAcl)
2179
*NewAcl = NULL;
2180
2181
if (!count && !OldAcl)
2182
return ERROR_SUCCESS;
2183
2184
/* allocate array of maximum sized sids allowed */
2185
ppsid = malloc(count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
2186
if (!ppsid)
2187
return ERROR_OUTOFMEMORY;
2188
2189
for (i = 0; i < count; i++)
2190
{
2191
ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
2192
2193
TRACE("[%ld]:\n\tgrfAccessPermissions = 0x%lx\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%lx\n\t"
2194
"Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
2195
"Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
2196
pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
2197
pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
2198
pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
2199
pEntries[i].Trustee.ptstrName);
2200
2201
ret = trustee_to_sid( FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]), ppsid[i], &pEntries[i].Trustee);
2202
if (ret)
2203
goto exit;
2204
2205
/* Note: we overestimate the ACL size here as a tradeoff between
2206
* instructions (simplicity) and memory */
2207
switch (pEntries[i].grfAccessMode)
2208
{
2209
case GRANT_ACCESS:
2210
case SET_ACCESS:
2211
acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
2212
break;
2213
case DENY_ACCESS:
2214
acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
2215
break;
2216
case SET_AUDIT_SUCCESS:
2217
case SET_AUDIT_FAILURE:
2218
acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
2219
break;
2220
case REVOKE_ACCESS:
2221
break;
2222
default:
2223
WARN("bad access mode %d for trustee %ld\n", pEntries[i].grfAccessMode, i);
2224
ret = ERROR_INVALID_PARAMETER;
2225
goto exit;
2226
}
2227
}
2228
2229
if (OldAcl)
2230
{
2231
ACL_SIZE_INFORMATION size_info;
2232
2233
status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
2234
if (status != STATUS_SUCCESS)
2235
{
2236
ret = RtlNtStatusToDosError(status);
2237
goto exit;
2238
}
2239
acl_size += size_info.AclBytesInUse - sizeof(ACL);
2240
}
2241
2242
*NewAcl = LocalAlloc(0, acl_size);
2243
if (!*NewAcl)
2244
{
2245
ret = ERROR_OUTOFMEMORY;
2246
goto exit;
2247
}
2248
2249
status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
2250
if (status != STATUS_SUCCESS)
2251
{
2252
ret = RtlNtStatusToDosError(status);
2253
goto exit;
2254
}
2255
2256
for (i = 0; i < count; i++)
2257
{
2258
switch (pEntries[i].grfAccessMode)
2259
{
2260
case GRANT_ACCESS:
2261
status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
2262
pEntries[i].grfInheritance,
2263
pEntries[i].grfAccessPermissions,
2264
ppsid[i]);
2265
break;
2266
case SET_ACCESS:
2267
{
2268
ULONG j;
2269
BOOL add = TRUE;
2270
if (OldAcl)
2271
{
2272
for (j = 0; ; j++)
2273
{
2274
const ACE_HEADER *existing_ace_header;
2275
status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
2276
if (status != STATUS_SUCCESS)
2277
break;
2278
if (pEntries[i].grfAccessMode == SET_ACCESS &&
2279
existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
2280
EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
2281
{
2282
add = FALSE;
2283
break;
2284
}
2285
}
2286
}
2287
if (add)
2288
status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
2289
pEntries[i].grfInheritance,
2290
pEntries[i].grfAccessPermissions,
2291
ppsid[i]);
2292
break;
2293
}
2294
case DENY_ACCESS:
2295
status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
2296
pEntries[i].grfInheritance,
2297
pEntries[i].grfAccessPermissions,
2298
ppsid[i]);
2299
break;
2300
case SET_AUDIT_SUCCESS:
2301
status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
2302
pEntries[i].grfInheritance,
2303
pEntries[i].grfAccessPermissions,
2304
ppsid[i], TRUE, FALSE);
2305
break;
2306
case SET_AUDIT_FAILURE:
2307
status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
2308
pEntries[i].grfInheritance,
2309
pEntries[i].grfAccessPermissions,
2310
ppsid[i], FALSE, TRUE);
2311
break;
2312
default:
2313
FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
2314
}
2315
}
2316
2317
if (OldAcl)
2318
{
2319
for (i = 0; ; i++)
2320
{
2321
BOOL add = TRUE;
2322
ULONG j;
2323
const ACE_HEADER *old_ace_header;
2324
status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
2325
if (status != STATUS_SUCCESS) break;
2326
for (j = 0; j < count; j++)
2327
{
2328
if (pEntries[j].grfAccessMode == SET_ACCESS &&
2329
old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
2330
EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
2331
{
2332
status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
2333
add = FALSE;
2334
break;
2335
}
2336
else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
2337
{
2338
switch (old_ace_header->AceType)
2339
{
2340
case ACCESS_ALLOWED_ACE_TYPE:
2341
if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
2342
add = FALSE;
2343
break;
2344
case ACCESS_DENIED_ACE_TYPE:
2345
/* REVOKE_ACCESS does not affect ACCESS_DENIED_ACE. */
2346
break;
2347
case SYSTEM_AUDIT_ACE_TYPE:
2348
if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
2349
add = FALSE;
2350
break;
2351
case SYSTEM_ALARM_ACE_TYPE:
2352
if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
2353
add = FALSE;
2354
break;
2355
default:
2356
FIXME("unhandled ace type %d\n", old_ace_header->AceType);
2357
}
2358
2359
if (!add)
2360
break;
2361
}
2362
}
2363
if (add)
2364
status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
2365
if (status != STATUS_SUCCESS)
2366
{
2367
WARN("RtlAddAce failed with error 0x%08lx\n", status);
2368
ret = RtlNtStatusToDosError(status);
2369
break;
2370
}
2371
}
2372
}
2373
2374
exit:
2375
free(ppsid);
2376
return ret;
2377
}
2378
2379
/******************************************************************************
2380
* SetNamedSecurityInfoA [ADVAPI32.@]
2381
*/
2382
DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
2383
SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2384
PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
2385
{
2386
LPWSTR wstr;
2387
DWORD r;
2388
2389
TRACE("%s %d %ld %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
2390
SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
2391
2392
wstr = strdupAW(pObjectName);
2393
r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
2394
psidGroup, pDacl, pSacl );
2395
2396
free( wstr );
2397
2398
return r;
2399
}
2400
2401
/******************************************************************************
2402
* SetNamedSecurityInfoW [ADVAPI32.@]
2403
*/
2404
DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
2405
SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2406
PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
2407
{
2408
DWORD access = 0;
2409
HANDLE handle;
2410
DWORD err;
2411
2412
TRACE( "%s %d %ld %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
2413
SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
2414
2415
if (!pObjectName) return ERROR_INVALID_PARAMETER;
2416
2417
if (SecurityInfo & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION))
2418
access |= WRITE_OWNER;
2419
if (SecurityInfo & DACL_SECURITY_INFORMATION)
2420
access |= WRITE_DAC;
2421
if (SecurityInfo & SACL_SECURITY_INFORMATION)
2422
access |= ACCESS_SYSTEM_SECURITY;
2423
2424
switch (ObjectType)
2425
{
2426
case SE_SERVICE:
2427
if (!(err = get_security_service( pObjectName, access, &handle )))
2428
{
2429
err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
2430
CloseServiceHandle( handle );
2431
}
2432
break;
2433
case SE_REGISTRY_KEY:
2434
if (!(err = get_security_regkey( pObjectName, access, &handle )))
2435
{
2436
err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
2437
RegCloseKey( handle );
2438
}
2439
break;
2440
case SE_FILE_OBJECT:
2441
if (SecurityInfo & DACL_SECURITY_INFORMATION)
2442
access |= READ_CONTROL;
2443
if (!(err = get_security_file( pObjectName, access, &handle )))
2444
{
2445
err = SetSecurityInfo( handle, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl );
2446
CloseHandle( handle );
2447
}
2448
break;
2449
default:
2450
FIXME( "Object type %d is not currently supported.\n", ObjectType );
2451
return ERROR_SUCCESS;
2452
}
2453
return err;
2454
}
2455
2456
/******************************************************************************
2457
* GetExplicitEntriesFromAclA [ADVAPI32.@]
2458
*/
2459
DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
2460
PEXPLICIT_ACCESSA* pListOfExplicitEntries)
2461
{
2462
FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
2463
return ERROR_CALL_NOT_IMPLEMENTED;
2464
}
2465
2466
/******************************************************************************
2467
* GetExplicitEntriesFromAclW [ADVAPI32.@]
2468
*/
2469
DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG count, PEXPLICIT_ACCESSW *list )
2470
{
2471
ACL_SIZE_INFORMATION sizeinfo;
2472
EXPLICIT_ACCESSW *entries;
2473
MAX_SID *sid_entries;
2474
ACE_HEADER *ace;
2475
NTSTATUS status;
2476
int i;
2477
2478
TRACE("%p %p %p\n",pacl, count, list);
2479
2480
if (!count || !list)
2481
return ERROR_INVALID_PARAMETER;
2482
2483
status = RtlQueryInformationAcl(pacl, &sizeinfo, sizeof(sizeinfo), AclSizeInformation);
2484
if (status) return RtlNtStatusToDosError(status);
2485
2486
if (!sizeinfo.AceCount)
2487
{
2488
*count = 0;
2489
*list = NULL;
2490
return ERROR_SUCCESS;
2491
}
2492
2493
entries = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, (sizeof(EXPLICIT_ACCESSW) + sizeof(MAX_SID)) * sizeinfo.AceCount);
2494
if (!entries) return ERROR_OUTOFMEMORY;
2495
sid_entries = (MAX_SID *)(entries + sizeinfo.AceCount);
2496
2497
for (i = 0; i < sizeinfo.AceCount; i++)
2498
{
2499
status = RtlGetAce(pacl, i, (void**)&ace);
2500
if (status) goto error;
2501
2502
switch (ace->AceType)
2503
{
2504
case ACCESS_ALLOWED_ACE_TYPE:
2505
{
2506
ACCESS_ALLOWED_ACE *allow = (ACCESS_ALLOWED_ACE *)ace;
2507
entries[i].grfAccessMode = GRANT_ACCESS;
2508
entries[i].grfInheritance = ace->AceFlags;
2509
entries[i].grfAccessPermissions = allow->Mask;
2510
2511
CopySid(sizeof(MAX_SID), (PSID)&sid_entries[i], (PSID)&allow->SidStart);
2512
entries[i].Trustee.pMultipleTrustee = NULL;
2513
entries[i].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2514
entries[i].Trustee.TrusteeForm = TRUSTEE_IS_SID;
2515
entries[i].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2516
entries[i].Trustee.ptstrName = (WCHAR *)&sid_entries[i];
2517
break;
2518
}
2519
2520
case ACCESS_DENIED_ACE_TYPE:
2521
{
2522
ACCESS_DENIED_ACE *deny = (ACCESS_DENIED_ACE *)ace;
2523
entries[i].grfAccessMode = DENY_ACCESS;
2524
entries[i].grfInheritance = ace->AceFlags;
2525
entries[i].grfAccessPermissions = deny->Mask;
2526
2527
CopySid(sizeof(MAX_SID), (PSID)&sid_entries[i], (PSID)&deny->SidStart);
2528
entries[i].Trustee.pMultipleTrustee = NULL;
2529
entries[i].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2530
entries[i].Trustee.TrusteeForm = TRUSTEE_IS_SID;
2531
entries[i].Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2532
entries[i].Trustee.ptstrName = (WCHAR *)&sid_entries[i];
2533
break;
2534
}
2535
2536
default:
2537
FIXME("Unhandled ace type %d\n", ace->AceType);
2538
entries[i].grfAccessMode = NOT_USED_ACCESS;
2539
continue;
2540
}
2541
}
2542
2543
*count = sizeinfo.AceCount;
2544
*list = entries;
2545
return ERROR_SUCCESS;
2546
2547
error:
2548
LocalFree(entries);
2549
return RtlNtStatusToDosError(status);
2550
}
2551
2552
/******************************************************************************
2553
* GetAuditedPermissionsFromAclA [ADVAPI32.@]
2554
*/
2555
DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
2556
PACCESS_MASK pFailedAuditRights)
2557
{
2558
FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
2559
return ERROR_CALL_NOT_IMPLEMENTED;
2560
2561
}
2562
2563
/******************************************************************************
2564
* GetAuditedPermissionsFromAclW [ADVAPI32.@]
2565
*/
2566
DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
2567
PACCESS_MASK pFailedAuditRights)
2568
{
2569
FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
2570
return ERROR_CALL_NOT_IMPLEMENTED;
2571
2572
}
2573
2574
/******************************************************************************
2575
* ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
2576
*/
2577
BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
2578
LPCSTR StringSecurityDescriptor,
2579
DWORD StringSDRevision,
2580
PSECURITY_DESCRIPTOR* SecurityDescriptor,
2581
PULONG SecurityDescriptorSize)
2582
{
2583
BOOL ret;
2584
LPWSTR StringSecurityDescriptorW;
2585
2586
TRACE("%s, %lu, %p, %p\n", debugstr_a(StringSecurityDescriptor), StringSDRevision,
2587
SecurityDescriptor, SecurityDescriptorSize);
2588
2589
if(!StringSecurityDescriptor)
2590
return FALSE;
2591
2592
StringSecurityDescriptorW = strdupAW(StringSecurityDescriptor);
2593
ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
2594
StringSDRevision, SecurityDescriptor,
2595
SecurityDescriptorSize);
2596
free(StringSecurityDescriptorW);
2597
2598
return ret;
2599
}
2600
2601
/******************************************************************************
2602
* ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
2603
*/
2604
BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
2605
{
2606
LPWSTR wstr;
2607
ULONG len;
2608
if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
2609
{
2610
int lenA;
2611
2612
lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
2613
*OutputString = malloc(lenA);
2614
WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
2615
LocalFree(wstr);
2616
2617
if (OutputLen != NULL)
2618
*OutputLen = lenA;
2619
return TRUE;
2620
}
2621
else
2622
{
2623
*OutputString = NULL;
2624
if (OutputLen)
2625
*OutputLen = 0;
2626
return FALSE;
2627
}
2628
}
2629
2630
/******************************************************************************
2631
* ConvertStringSidToSidA [ADVAPI32.@]
2632
*/
2633
BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
2634
{
2635
BOOL bret = FALSE;
2636
2637
TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
2638
if (GetVersion() & 0x80000000)
2639
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2640
else if (!StringSid || !Sid)
2641
SetLastError(ERROR_INVALID_PARAMETER);
2642
else
2643
{
2644
WCHAR *wStringSid = strdupAW(StringSid);
2645
bret = ConvertStringSidToSidW(wStringSid, Sid);
2646
free(wStringSid);
2647
}
2648
return bret;
2649
}
2650
2651
/******************************************************************************
2652
* ConvertSidToStringSidA [ADVAPI32.@]
2653
*/
2654
BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
2655
{
2656
LPWSTR wstr = NULL;
2657
LPSTR str;
2658
UINT len;
2659
2660
TRACE("%p %p\n", pSid, pstr );
2661
2662
if( !ConvertSidToStringSidW( pSid, &wstr ) )
2663
return FALSE;
2664
2665
len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
2666
str = LocalAlloc( 0, len );
2667
WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
2668
LocalFree( wstr );
2669
2670
*pstr = str;
2671
2672
return TRUE;
2673
}
2674
2675
/******************************************************************************
2676
* CreateProcessWithLogonW [ADVAPI32.@]
2677
*/
2678
BOOL WINAPI CreateProcessWithLogonW( LPCWSTR user_name, LPCWSTR domain, LPCWSTR password,
2679
DWORD logon_flags, LPCWSTR application_name, LPWSTR command_line,
2680
DWORD creation_flags, void *environment, LPCWSTR current_directory,
2681
STARTUPINFOW *startup_info, PROCESS_INFORMATION *process_information )
2682
{
2683
HANDLE token;
2684
2685
FIXME("%s %s %p 0x%08lx %s %s 0x%08lx %p %s %p %p: semi-stub\n", debugstr_w(user_name), debugstr_w(domain),
2686
password, logon_flags, debugstr_w(application_name), debugstr_w(command_line), creation_flags,
2687
environment, debugstr_w(current_directory), startup_info, process_information);
2688
2689
if (LogonUserW(user_name, domain, password, 0, 0, &token))
2690
{
2691
void *env = environment;
2692
BOOL ret = TRUE;
2693
2694
if (!environment)
2695
{
2696
ret = CreateEnvironmentBlock(&env, token, FALSE);
2697
creation_flags |= CREATE_UNICODE_ENVIRONMENT;
2698
}
2699
2700
if (ret)
2701
{
2702
ret = CreateProcessAsUserW( token, application_name, command_line, NULL, NULL, FALSE,
2703
creation_flags, env, current_directory, startup_info, process_information );
2704
}
2705
if (env != environment)
2706
DestroyEnvironmentBlock(env);
2707
CloseHandle(token);
2708
return ret;
2709
}
2710
2711
return FALSE;
2712
}
2713
2714
/******************************************************************************
2715
* CreateProcessWithTokenW [ADVAPI32.@]
2716
*/
2717
BOOL WINAPI CreateProcessWithTokenW(HANDLE token, DWORD logon_flags, LPCWSTR application_name, LPWSTR command_line,
2718
DWORD creation_flags, void *environment, LPCWSTR current_directory, STARTUPINFOW *startup_info,
2719
PROCESS_INFORMATION *process_information )
2720
{
2721
FIXME("%p 0x%08lx %s %s 0x%08lx %p %s %p %p - semi-stub\n", token,
2722
logon_flags, debugstr_w(application_name), debugstr_w(command_line),
2723
creation_flags, environment, debugstr_w(current_directory),
2724
startup_info, process_information);
2725
2726
/* FIXME: check if handles should be inherited */
2727
return CreateProcessAsUserW( token, application_name, command_line, NULL, NULL, FALSE, creation_flags,
2728
environment, current_directory, startup_info, process_information );
2729
}
2730
2731
/******************************************************************************
2732
* GetNamedSecurityInfoA [ADVAPI32.@]
2733
*/
2734
DWORD WINAPI GetNamedSecurityInfoA(const char *pObjectName,
2735
SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2736
PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
2737
PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
2738
{
2739
LPWSTR wstr;
2740
DWORD r;
2741
2742
TRACE("%s %d %ld %p %p %p %p %p\n", debugstr_a(pObjectName), ObjectType, SecurityInfo,
2743
ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
2744
2745
wstr = strdupAW(pObjectName);
2746
r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
2747
ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
2748
2749
free( wstr );
2750
2751
return r;
2752
}
2753
2754
/******************************************************************************
2755
* GetNamedSecurityInfoW [ADVAPI32.@]
2756
*/
2757
DWORD WINAPI GetNamedSecurityInfoW( const WCHAR *name, SE_OBJECT_TYPE type,
2758
SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
2759
PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
2760
{
2761
DWORD access = 0;
2762
HANDLE handle;
2763
DWORD err;
2764
2765
TRACE( "%s %d %ld %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
2766
group, dacl, sacl, descriptor );
2767
2768
/* A NULL descriptor is allowed if any one of the other pointers is not NULL */
2769
if (!name || !(owner||group||dacl||sacl||descriptor) ) return ERROR_INVALID_PARAMETER;
2770
2771
/* If no descriptor, we have to check that there's a pointer for the requested information */
2772
if( !descriptor && (
2773
((info & OWNER_SECURITY_INFORMATION) && !owner)
2774
|| ((info & GROUP_SECURITY_INFORMATION) && !group)
2775
|| ((info & DACL_SECURITY_INFORMATION) && !dacl)
2776
|| ((info & SACL_SECURITY_INFORMATION) && !sacl) ))
2777
return ERROR_INVALID_PARAMETER;
2778
2779
if (info & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION))
2780
access |= READ_CONTROL;
2781
if (info & SACL_SECURITY_INFORMATION)
2782
access |= ACCESS_SYSTEM_SECURITY;
2783
2784
switch (type)
2785
{
2786
case SE_SERVICE:
2787
if (!(err = get_security_service( name, access, &handle )))
2788
{
2789
err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
2790
CloseServiceHandle( handle );
2791
}
2792
break;
2793
case SE_REGISTRY_KEY:
2794
if (!(err = get_security_regkey( name, access, &handle )))
2795
{
2796
err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
2797
RegCloseKey( handle );
2798
}
2799
break;
2800
case SE_FILE_OBJECT:
2801
if (!(err = get_security_file( name, access, &handle )))
2802
{
2803
err = GetSecurityInfo( handle, type, info, owner, group, dacl, sacl, descriptor );
2804
CloseHandle( handle );
2805
}
2806
break;
2807
default:
2808
FIXME( "Object type %d is not currently supported.\n", type );
2809
if (owner) *owner = NULL;
2810
if (group) *group = NULL;
2811
if (dacl) *dacl = NULL;
2812
if (sacl) *sacl = NULL;
2813
if (descriptor) *descriptor = NULL;
2814
return ERROR_SUCCESS;
2815
}
2816
return err;
2817
}
2818
2819
/******************************************************************************
2820
* GetNamedSecurityInfoExW [ADVAPI32.@]
2821
*/
2822
DWORD WINAPI GetNamedSecurityInfoExW( LPCWSTR object, SE_OBJECT_TYPE type,
2823
SECURITY_INFORMATION info, LPCWSTR provider, LPCWSTR property,
2824
PACTRL_ACCESSW* access_list, PACTRL_AUDITW* audit_list, LPWSTR* owner, LPWSTR* group )
2825
{
2826
FIXME("(%s, %d, %ld, %s, %s, %p, %p, %p, %p) stub\n", debugstr_w(object), type, info,
2827
debugstr_w(provider), debugstr_w(property), access_list, audit_list, owner, group);
2828
return ERROR_CALL_NOT_IMPLEMENTED;
2829
}
2830
2831
/******************************************************************************
2832
* GetNamedSecurityInfoExA [ADVAPI32.@]
2833
*/
2834
DWORD WINAPI GetNamedSecurityInfoExA( LPCSTR object, SE_OBJECT_TYPE type,
2835
SECURITY_INFORMATION info, LPCSTR provider, LPCSTR property,
2836
PACTRL_ACCESSA* access_list, PACTRL_AUDITA* audit_list, LPSTR* owner, LPSTR* group )
2837
{
2838
FIXME("(%s, %d, %ld, %s, %s, %p, %p, %p, %p) stub\n", debugstr_a(object), type, info,
2839
debugstr_a(provider), debugstr_a(property), access_list, audit_list, owner, group);
2840
return ERROR_CALL_NOT_IMPLEMENTED;
2841
}
2842
2843
/******************************************************************************
2844
* DecryptFileW [ADVAPI32.@]
2845
*/
2846
BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
2847
{
2848
FIXME("(%s, %08lx): stub\n", debugstr_w(lpFileName), dwReserved);
2849
return TRUE;
2850
}
2851
2852
/******************************************************************************
2853
* DecryptFileA [ADVAPI32.@]
2854
*/
2855
BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
2856
{
2857
FIXME("(%s, %08lx): stub\n", debugstr_a(lpFileName), dwReserved);
2858
return TRUE;
2859
}
2860
2861
/******************************************************************************
2862
* EncryptFileW [ADVAPI32.@]
2863
*/
2864
BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
2865
{
2866
FIXME("(%s): stub\n", debugstr_w(lpFileName));
2867
return TRUE;
2868
}
2869
2870
/******************************************************************************
2871
* EncryptFileA [ADVAPI32.@]
2872
*/
2873
BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
2874
{
2875
FIXME("(%s): stub\n", debugstr_a(lpFileName));
2876
return TRUE;
2877
}
2878
2879
/******************************************************************************
2880
* FileEncryptionStatusW [ADVAPI32.@]
2881
*/
2882
BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
2883
{
2884
FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
2885
if (!lpStatus)
2886
return FALSE;
2887
*lpStatus = FILE_SYSTEM_NOT_SUPPORT;
2888
return TRUE;
2889
}
2890
2891
/******************************************************************************
2892
* FileEncryptionStatusA [ADVAPI32.@]
2893
*/
2894
BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
2895
{
2896
FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
2897
if (!lpStatus)
2898
return FALSE;
2899
*lpStatus = FILE_SYSTEM_NOT_SUPPORT;
2900
return TRUE;
2901
}
2902
2903
static NTSTATUS combine_dacls(ACL *parent, ACL *child, ACL **result)
2904
{
2905
NTSTATUS status;
2906
ACL *combined;
2907
int i;
2908
2909
/* initialize a combined DACL containing both inherited and new ACEs */
2910
combined = calloc(1, child->AclSize + parent->AclSize);
2911
if (!combined)
2912
return STATUS_NO_MEMORY;
2913
2914
status = RtlCreateAcl(combined, parent->AclSize+child->AclSize, ACL_REVISION);
2915
if (status != STATUS_SUCCESS)
2916
{
2917
free(combined);
2918
return status;
2919
}
2920
2921
/* copy the new ACEs */
2922
for (i=0; i<child->AceCount; i++)
2923
{
2924
ACE_HEADER *ace;
2925
2926
if (!GetAce(child, i, (void*)&ace))
2927
continue;
2928
if (!AddAce(combined, ACL_REVISION, MAXDWORD, ace, ace->AceSize))
2929
WARN("error adding new ACE\n");
2930
}
2931
2932
/* copy the inherited ACEs */
2933
for (i=0; i<parent->AceCount; i++)
2934
{
2935
ACE_HEADER *ace;
2936
2937
if (!GetAce(parent, i, (void*)&ace))
2938
continue;
2939
if (!(ace->AceFlags & (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE)))
2940
continue;
2941
if ((ace->AceFlags & (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE)) !=
2942
(OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE))
2943
{
2944
FIXME("unsupported flags: %x\n", ace->AceFlags);
2945
continue;
2946
}
2947
2948
if (ace->AceFlags & NO_PROPAGATE_INHERIT_ACE)
2949
ace->AceFlags &= ~(OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE|NO_PROPAGATE_INHERIT_ACE);
2950
ace->AceFlags &= ~INHERIT_ONLY_ACE;
2951
ace->AceFlags |= INHERITED_ACE;
2952
2953
if (!AddAce(combined, ACL_REVISION, MAXDWORD, ace, ace->AceSize))
2954
WARN("error adding inherited ACE\n");
2955
}
2956
2957
*result = combined;
2958
return STATUS_SUCCESS;
2959
}
2960
2961
/******************************************************************************
2962
* SetSecurityInfo [ADVAPI32.@]
2963
*/
2964
DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType,
2965
SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
2966
PSID psidGroup, PACL pDacl, PACL pSacl)
2967
{
2968
SECURITY_DESCRIPTOR sd;
2969
PACL dacl = pDacl;
2970
NTSTATUS status;
2971
2972
if (!handle)
2973
return ERROR_INVALID_HANDLE;
2974
2975
if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
2976
return ERROR_INVALID_SECURITY_DESCR;
2977
2978
if (SecurityInfo & OWNER_SECURITY_INFORMATION)
2979
SetSecurityDescriptorOwner(&sd, psidOwner, FALSE);
2980
if (SecurityInfo & GROUP_SECURITY_INFORMATION)
2981
SetSecurityDescriptorGroup(&sd, psidGroup, FALSE);
2982
if (SecurityInfo & DACL_SECURITY_INFORMATION)
2983
{
2984
if (ObjectType == SE_FILE_OBJECT && pDacl)
2985
{
2986
SECURITY_DESCRIPTOR_CONTROL control;
2987
PSECURITY_DESCRIPTOR psd;
2988
OBJECT_NAME_INFORMATION *name_info;
2989
DWORD size, rev;
2990
2991
status = NtQuerySecurityObject(handle, SecurityInfo, NULL, 0, &size);
2992
if (status != STATUS_BUFFER_TOO_SMALL)
2993
return RtlNtStatusToDosError(status);
2994
2995
psd = malloc(size);
2996
if (!psd)
2997
return ERROR_NOT_ENOUGH_MEMORY;
2998
2999
status = NtQuerySecurityObject(handle, SecurityInfo, psd, size, &size);
3000
if (status)
3001
{
3002
free(psd);
3003
return RtlNtStatusToDosError(status);
3004
}
3005
3006
status = RtlGetControlSecurityDescriptor(psd, &control, &rev);
3007
free(psd);
3008
if (status)
3009
return RtlNtStatusToDosError(status);
3010
/* TODO: copy some control flags to new sd */
3011
3012
/* inherit parent directory DACL */
3013
if (!(control & SE_DACL_PROTECTED))
3014
{
3015
status = NtQueryObject(handle, ObjectNameInformation, NULL, 0, &size);
3016
if (status != STATUS_INFO_LENGTH_MISMATCH)
3017
return RtlNtStatusToDosError(status);
3018
3019
name_info = malloc(size);
3020
if (!name_info)
3021
return ERROR_NOT_ENOUGH_MEMORY;
3022
3023
status = NtQueryObject(handle, ObjectNameInformation, name_info, size, NULL);
3024
if (status)
3025
{
3026
free(name_info);
3027
return RtlNtStatusToDosError(status);
3028
}
3029
3030
if (name_info->Name.Length && name_info->Name.Buffer[(name_info->Name.Length / 2) - 1] == '\\')
3031
name_info->Name.Length -= 2;
3032
while (name_info->Name.Length && name_info->Name.Buffer[(name_info->Name.Length / 2) - 1] != '\\')
3033
name_info->Name.Length -= 2;
3034
3035
if (name_info->Name.Length)
3036
{
3037
OBJECT_ATTRIBUTES attr;
3038
IO_STATUS_BLOCK io;
3039
HANDLE parent;
3040
PSECURITY_DESCRIPTOR parent_sd;
3041
ACL *parent_dacl;
3042
DWORD err = ERROR_ACCESS_DENIED;
3043
3044
name_info->Name.Buffer[name_info->Name.Length/2] = 0;
3045
3046
attr.Length = sizeof(attr);
3047
attr.RootDirectory = 0;
3048
attr.Attributes = 0;
3049
attr.ObjectName = &name_info->Name;
3050
attr.SecurityDescriptor = NULL;
3051
status = NtOpenFile(&parent, READ_CONTROL|SYNCHRONIZE, &attr, &io,
3052
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3053
FILE_OPEN_FOR_BACKUP_INTENT);
3054
free(name_info);
3055
if (!status)
3056
{
3057
err = GetSecurityInfo(parent, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
3058
NULL, NULL, &parent_dacl, NULL, &parent_sd);
3059
CloseHandle(parent);
3060
}
3061
3062
if (!err)
3063
{
3064
status = combine_dacls(parent_dacl, pDacl, &dacl);
3065
LocalFree(parent_sd);
3066
if (status != STATUS_SUCCESS)
3067
return RtlNtStatusToDosError(status);
3068
}
3069
}
3070
else
3071
free(name_info);
3072
}
3073
}
3074
3075
SetSecurityDescriptorDacl(&sd, TRUE, dacl, FALSE);
3076
}
3077
if (SecurityInfo & SACL_SECURITY_INFORMATION)
3078
SetSecurityDescriptorSacl(&sd, TRUE, pSacl, FALSE);
3079
3080
switch (ObjectType)
3081
{
3082
case SE_FILE_OBJECT:
3083
case SE_KERNEL_OBJECT:
3084
case SE_WMIGUID_OBJECT:
3085
case SE_REGISTRY_KEY:
3086
status = NtSetSecurityObject(handle, SecurityInfo, &sd);
3087
break;
3088
3089
default:
3090
FIXME("unimplemented type %u, returning success\n", ObjectType);
3091
status = STATUS_SUCCESS;
3092
break;
3093
3094
}
3095
if (dacl != pDacl)
3096
free(dacl);
3097
return RtlNtStatusToDosError(status);
3098
}
3099
3100
/******************************************************************************
3101
* SaferCreateLevel [ADVAPI32.@]
3102
*/
3103
BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
3104
SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
3105
{
3106
FIXME("(%lu, %lx, %lu, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
3107
3108
*LevelHandle = (SAFER_LEVEL_HANDLE)0xdeadbeef;
3109
return TRUE;
3110
}
3111
3112
/******************************************************************************
3113
* SaferComputeTokenFromLevel [ADVAPI32.@]
3114
*/
3115
BOOL WINAPI SaferComputeTokenFromLevel(SAFER_LEVEL_HANDLE handle, HANDLE token, PHANDLE access_token,
3116
DWORD flags, LPVOID reserved)
3117
{
3118
FIXME("(%p, %p, %p, %lx, %p) stub\n", handle, token, access_token, flags, reserved);
3119
3120
*access_token = (flags & SAFER_TOKEN_NULL_IF_EQUAL) ? NULL : (HANDLE)0xdeadbeef;
3121
return TRUE;
3122
}
3123
3124
/******************************************************************************
3125
* SaferCloseLevel [ADVAPI32.@]
3126
*/
3127
BOOL WINAPI SaferCloseLevel(SAFER_LEVEL_HANDLE handle)
3128
{
3129
FIXME("(%p) stub\n", handle);
3130
return TRUE;
3131
}
3132
3133
/******************************************************************************
3134
* TreeSetNamedSecurityInfoW [ADVAPI32.@]
3135
*/
3136
DWORD WINAPI TreeSetNamedSecurityInfoW(WCHAR *name, SE_OBJECT_TYPE type, SECURITY_INFORMATION info,
3137
SID *owner, SID *group, ACL *dacl, ACL *sacl, DWORD action,
3138
FN_PROGRESS progress, PROG_INVOKE_SETTING pis, void *args)
3139
{
3140
FIXME("(%s, %d, %lu, %p, %p, %p, %p, %lu, %p, %d, %p) stub\n",
3141
debugstr_w(name), type, info, owner, group, dacl, sacl, action, progress, pis, args);
3142
3143
return ERROR_SUCCESS;
3144
}
3145
3146
/******************************************************************************
3147
* TreeResetNamedSecurityInfoW [ADVAPI32.@]
3148
*/
3149
DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
3150
SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3151
PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
3152
BOOL KeepExplicit, FN_PROGRESS fnProgress,
3153
PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
3154
{
3155
FIXME("(%s, %i, %li, %p, %p, %p, %p, %i, %p, %i, %p) stub\n",
3156
debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
3157
pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
3158
3159
return ERROR_SUCCESS;
3160
}
3161
3162
/******************************************************************************
3163
* SaferGetPolicyInformation [ADVAPI32.@]
3164
*/
3165
BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
3166
PVOID buffer, PDWORD required, LPVOID lpReserved)
3167
{
3168
FIXME("(%lu %u %lu %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
3169
return FALSE;
3170
}
3171
3172
/******************************************************************************
3173
* SaferIdentifyLevel [ADVAPI32.@]
3174
*/
3175
BOOL WINAPI SaferIdentifyLevel(DWORD count, SAFER_CODE_PROPERTIES *properties, SAFER_LEVEL_HANDLE *handle,
3176
void *reserved)
3177
{
3178
FIXME("(%lu %p %p %p) stub\n", count, properties, handle, reserved);
3179
*handle = (SAFER_LEVEL_HANDLE)0xdeadbeef;
3180
return TRUE;
3181
}
3182
3183
/******************************************************************************
3184
* SaferSetLevelInformation [ADVAPI32.@]
3185
*/
3186
BOOL WINAPI SaferSetLevelInformation(SAFER_LEVEL_HANDLE handle, SAFER_OBJECT_INFO_CLASS infotype,
3187
LPVOID buffer, DWORD size)
3188
{
3189
FIXME("(%p %u %p %lu) stub\n", handle, infotype, buffer, size);
3190
return FALSE;
3191
}
3192
3193
/******************************************************************************
3194
* LookupSecurityDescriptorPartsA [ADVAPI32.@]
3195
*/
3196
DWORD WINAPI LookupSecurityDescriptorPartsA(TRUSTEEA *owner, TRUSTEEA *group, ULONG *access_count,
3197
EXPLICIT_ACCESSA *access_list, ULONG *audit_count,
3198
EXPLICIT_ACCESSA *audit_list, SECURITY_DESCRIPTOR *descriptor)
3199
{
3200
FIXME("(%p %p %p %p %p %p %p) stub\n", owner, group, access_count,
3201
access_list, audit_count, audit_list, descriptor);
3202
return ERROR_CALL_NOT_IMPLEMENTED;
3203
}
3204
3205
/******************************************************************************
3206
* LookupSecurityDescriptorPartsW [ADVAPI32.@]
3207
*/
3208
DWORD WINAPI LookupSecurityDescriptorPartsW(TRUSTEEW *owner, TRUSTEEW *group, ULONG *access_count,
3209
EXPLICIT_ACCESSW *access_list, ULONG *audit_count,
3210
EXPLICIT_ACCESSW *audit_list, SECURITY_DESCRIPTOR *descriptor)
3211
{
3212
FIXME("(%p %p %p %p %p %p %p) stub\n", owner, group, access_count,
3213
access_list, audit_count, audit_list, descriptor);
3214
return ERROR_CALL_NOT_IMPLEMENTED;
3215
}
3216
3217