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