2 * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
3 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
4 * Copyright 2006 Robert Reif
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.
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.
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
26 #define WIN32_NO_STATUS
40 #include "advapi32_misc.h"
43 #include "wine/debug.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(advapi
);
47 static DWORD
trustee_to_sid(DWORD nDestinationSidLength
, PSID pDestinationSid
, PTRUSTEEW pTrustee
);
49 typedef struct _MAX_SID
51 /* same fields as struct _SID */
53 BYTE SubAuthorityCount
;
54 SID_IDENTIFIER_AUTHORITY IdentifierAuthority
;
55 DWORD SubAuthority
[SID_MAX_SUB_AUTHORITIES
];
58 typedef struct _AccountSid
{
59 WELL_KNOWN_SID_TYPE type
;
62 SID_NAME_USE name_use
;
66 static const AccountSid ACCOUNT_SIDS
[] = {
67 { WinNullSid
, L
"NULL SID", L
"", SidTypeWellKnownGroup
},
68 { WinWorldSid
, L
"Everyone", L
"", SidTypeWellKnownGroup
},
69 { WinLocalSid
, L
"LOCAL", L
"", SidTypeWellKnownGroup
},
70 { WinCreatorOwnerSid
, L
"CREATOR OWNER", L
"", SidTypeWellKnownGroup
},
71 { WinCreatorGroupSid
, L
"CREATOR GROUP", L
"", SidTypeWellKnownGroup
},
72 { WinCreatorOwnerServerSid
, L
"CREATOR OWNER SERVER", L
"", SidTypeWellKnownGroup
},
73 { WinCreatorGroupServerSid
, L
"CREATOR GROUP SERVER", L
"", SidTypeWellKnownGroup
},
74 { WinNtAuthoritySid
, L
"NT Pseudo Domain", L
"NT Pseudo Domain", SidTypeDomain
},
75 { WinDialupSid
, L
"DIALUP", L
"NT AUTHORITY", SidTypeWellKnownGroup
},
76 { WinNetworkSid
, L
"NETWORK", L
"NT AUTHORITY", SidTypeWellKnownGroup
},
77 { WinBatchSid
, L
"BATCH", L
"NT AUTHORITY", SidTypeWellKnownGroup
},
78 { WinInteractiveSid
, L
"INTERACTIVE", L
"NT AUTHORITY", SidTypeWellKnownGroup
},
79 { WinServiceSid
, L
"SERVICE", L
"NT AUTHORITY", SidTypeWellKnownGroup
},
80 { WinAnonymousSid
, L
"ANONYMOUS LOGON", L
"NT AUTHORITY", SidTypeWellKnownGroup
},
81 { WinProxySid
, L
"PROXY", L
"NT AUTHORITY", SidTypeWellKnownGroup
},
82 { WinEnterpriseControllersSid
, L
"ENTERPRISE DOMAIN CONTROLLERS", L
"NT AUTHORITY", SidTypeWellKnownGroup
},
83 { WinSelfSid
, L
"SELF", L
"NT AUTHORITY", SidTypeWellKnownGroup
},
84 { WinAuthenticatedUserSid
, L
"Authenticated Users", L
"NT AUTHORITY", SidTypeWellKnownGroup
},
85 { WinRestrictedCodeSid
, L
"RESTRICTED", L
"NT AUTHORITY", SidTypeWellKnownGroup
},
86 { WinTerminalServerSid
, L
"TERMINAL SERVER USER", L
"NT AUTHORITY", SidTypeWellKnownGroup
},
87 { WinRemoteLogonIdSid
, L
"REMOTE INTERACTIVE LOGON", L
"NT AUTHORITY", SidTypeWellKnownGroup
},
88 { WinLocalSystemSid
, L
"SYSTEM", L
"NT AUTHORITY", SidTypeWellKnownGroup
},
89 { WinLocalServiceSid
, L
"LOCAL SERVICE", L
"NT AUTHORITY", SidTypeWellKnownGroup
, L
"LOCALSERVICE" },
90 { WinNetworkServiceSid
, L
"NETWORK SERVICE", L
"NT AUTHORITY", SidTypeWellKnownGroup
, L
"NETWORKSERVICE"},
91 { WinBuiltinDomainSid
, L
"BUILTIN", L
"BUILTIN", SidTypeDomain
},
92 { WinBuiltinAdministratorsSid
, L
"Administrators", L
"BUILTIN", SidTypeAlias
},
93 { WinBuiltinUsersSid
, L
"Users", L
"BUILTIN", SidTypeAlias
},
94 { WinBuiltinGuestsSid
, L
"Guests", L
"BUILTIN", SidTypeAlias
},
95 { WinBuiltinPowerUsersSid
, L
"Power Users", L
"BUILTIN", SidTypeAlias
},
96 { WinBuiltinAccountOperatorsSid
, L
"Account Operators", L
"BUILTIN", SidTypeAlias
},
97 { WinBuiltinSystemOperatorsSid
, L
"Server Operators", L
"BUILTIN", SidTypeAlias
},
98 { WinBuiltinPrintOperatorsSid
, L
"Print Operators", L
"BUILTIN", SidTypeAlias
},
99 { WinBuiltinBackupOperatorsSid
, L
"Backup Operators", L
"BUILTIN", SidTypeAlias
},
100 { WinBuiltinReplicatorSid
, L
"Replicators", L
"BUILTIN", SidTypeAlias
},
101 { WinBuiltinPreWindows2000CompatibleAccessSid
, L
"Pre-Windows 2000 Compatible Access", L
"BUILTIN", SidTypeAlias
},
102 { WinBuiltinRemoteDesktopUsersSid
, L
"Remote Desktop Users", L
"BUILTIN", SidTypeAlias
},
103 { WinBuiltinNetworkConfigurationOperatorsSid
, L
"Network Configuration Operators", L
"BUILTIN", SidTypeAlias
},
104 { WinNTLMAuthenticationSid
, L
"NTLM Authentication", L
"NT AUTHORITY", SidTypeWellKnownGroup
},
105 { WinDigestAuthenticationSid
, L
"Digest Authentication", L
"NT AUTHORITY", SidTypeWellKnownGroup
},
106 { WinSChannelAuthenticationSid
, L
"SChannel Authentication", L
"NT AUTHORITY", SidTypeWellKnownGroup
},
107 { WinThisOrganizationSid
, L
"This Organization", L
"NT AUTHORITY", SidTypeWellKnownGroup
},
108 { WinOtherOrganizationSid
, L
"Other Organization", L
"NT AUTHORITY", SidTypeWellKnownGroup
},
109 { WinBuiltinPerfMonitoringUsersSid
, L
"Performance Monitor Users", L
"BUILTIN", SidTypeAlias
},
110 { WinBuiltinPerfLoggingUsersSid
, L
"Performance Log Users", L
"BUILTIN", SidTypeAlias
},
111 { WinBuiltinAnyPackageSid
, L
"ALL APPLICATION PACKAGES", L
"APPLICATION PACKAGE AUTHORITY", SidTypeWellKnownGroup
},
114 const char * debugstr_sid(PSID sid
)
122 auth
= psid
->IdentifierAuthority
.Value
[5] +
123 (psid
->IdentifierAuthority
.Value
[4] << 8) +
124 (psid
->IdentifierAuthority
.Value
[3] << 16) +
125 (psid
->IdentifierAuthority
.Value
[2] << 24);
127 switch (psid
->SubAuthorityCount
) {
129 return wine_dbg_sprintf("S-%d-%d", psid
->Revision
, auth
);
131 return wine_dbg_sprintf("S-%d-%d-%u", psid
->Revision
, auth
,
132 psid
->SubAuthority
[0]);
134 return wine_dbg_sprintf("S-%d-%d-%u-%u", psid
->Revision
, auth
,
135 psid
->SubAuthority
[0], psid
->SubAuthority
[1]);
137 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid
->Revision
, auth
,
138 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2]);
140 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid
->Revision
, auth
,
141 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
142 psid
->SubAuthority
[3]);
144 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid
->Revision
, auth
,
145 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
146 psid
->SubAuthority
[3], psid
->SubAuthority
[4]);
148 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid
->Revision
, auth
,
149 psid
->SubAuthority
[3], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
150 psid
->SubAuthority
[0], psid
->SubAuthority
[4], psid
->SubAuthority
[5]);
152 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid
->Revision
, auth
,
153 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
154 psid
->SubAuthority
[3], psid
->SubAuthority
[4], psid
->SubAuthority
[5],
155 psid
->SubAuthority
[6]);
157 return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid
->Revision
, auth
,
158 psid
->SubAuthority
[0], psid
->SubAuthority
[1], psid
->SubAuthority
[2],
159 psid
->SubAuthority
[3], psid
->SubAuthority
[4], psid
->SubAuthority
[5],
160 psid
->SubAuthority
[6], psid
->SubAuthority
[7]);
165 /* helper function for SE_FILE_OBJECT objects in [Get|Set]NamedSecurityInfo */
166 static inline DWORD
get_security_file( LPCWSTR full_file_name
, DWORD access
, HANDLE
*file
)
168 UNICODE_STRING file_nameW
;
169 OBJECT_ATTRIBUTES attr
;
173 if (!RtlDosPathNameToNtPathName_U( full_file_name
, &file_nameW
, NULL
, NULL
))
174 return ERROR_PATH_NOT_FOUND
;
175 attr
.Length
= sizeof(attr
);
176 attr
.RootDirectory
= 0;
177 attr
.Attributes
= OBJ_CASE_INSENSITIVE
;
178 attr
.ObjectName
= &file_nameW
;
179 attr
.SecurityDescriptor
= NULL
;
180 status
= NtCreateFile( file
, access
|SYNCHRONIZE
, &attr
, &io
, NULL
, FILE_FLAG_BACKUP_SEMANTICS
,
181 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
,
182 FILE_OPEN_FOR_BACKUP_INTENT
, NULL
, 0 );
183 RtlFreeUnicodeString( &file_nameW
);
184 return RtlNtStatusToDosError( status
);
187 /* helper function for SE_SERVICE objects in [Get|Set]NamedSecurityInfo */
188 static inline DWORD
get_security_service( LPWSTR full_service_name
, DWORD access
, HANDLE
*service
)
190 SC_HANDLE manager
= OpenSCManagerW( NULL
, NULL
, access
);
193 *service
= OpenServiceW( manager
, full_service_name
, access
);
194 CloseServiceHandle( manager
);
196 return ERROR_SUCCESS
;
198 return GetLastError();
201 /* helper function for SE_REGISTRY_KEY objects in [Get|Set]NamedSecurityInfo */
202 static inline DWORD
get_security_regkey( LPWSTR full_key_name
, DWORD access
, HANDLE
*key
)
204 LPWSTR p
= wcschr(full_key_name
, '\\');
205 int len
= p
-full_key_name
;
208 if (!p
) return ERROR_INVALID_PARAMETER
;
209 if (!wcsncmp( full_key_name
, L
"CLASSES_ROOT", len
))
210 hParent
= HKEY_CLASSES_ROOT
;
211 else if (!wcsncmp( full_key_name
, L
"CURRENT_USER", len
))
212 hParent
= HKEY_CURRENT_USER
;
213 else if (!wcsncmp( full_key_name
, L
"MACHINE", len
))
214 hParent
= HKEY_LOCAL_MACHINE
;
215 else if (!wcsncmp( full_key_name
, L
"USERS", len
))
216 hParent
= HKEY_USERS
;
218 return ERROR_INVALID_PARAMETER
;
219 return RegOpenKeyExW( hParent
, p
+1, 0, access
, (HKEY
*)key
);
223 /************************************************************
224 * ADVAPI_IsLocalComputer
226 * Checks whether the server name indicates local machine.
228 BOOL
ADVAPI_IsLocalComputer(LPCWSTR ServerName
)
230 DWORD dwSize
= MAX_COMPUTERNAME_LENGTH
+ 1;
234 if (!ServerName
|| !ServerName
[0])
237 buf
= heap_alloc(dwSize
* sizeof(WCHAR
));
238 Result
= GetComputerNameW(buf
, &dwSize
);
239 if (Result
&& (ServerName
[0] == '\\') && (ServerName
[1] == '\\'))
241 Result
= Result
&& !wcscmp(ServerName
, buf
);
247 /************************************************************
248 * ADVAPI_GetComputerSid
250 BOOL
ADVAPI_GetComputerSid(PSID sid
)
252 static const struct /* same fields as struct SID */
255 BYTE SubAuthorityCount
;
256 SID_IDENTIFIER_AUTHORITY IdentifierAuthority
;
257 DWORD SubAuthority
[4];
259 { SID_REVISION
, 4, { SECURITY_NT_AUTHORITY
}, { SECURITY_NT_NON_UNIQUE
, 0, 0, 0 } };
261 memcpy( sid
, &computer_sid
, sizeof(computer_sid
) );
266 GetEffectiveRightsFromAclA( PACL pacl
, PTRUSTEEA pTrustee
, PACCESS_MASK pAccessRights
)
268 FIXME("%p %p %p - stub\n", pacl
, pTrustee
, pAccessRights
);
270 *pAccessRights
= STANDARD_RIGHTS_ALL
| SPECIFIC_RIGHTS_ALL
;
275 GetEffectiveRightsFromAclW( PACL pacl
, PTRUSTEEW pTrustee
, PACCESS_MASK pAccessRights
)
277 FIXME("%p %p %p - stub\n", pacl
, pTrustee
, pAccessRights
);
282 /* ##############################################
283 ###### SECURITY DESCRIPTOR FUNCTIONS ######
284 ##############################################
287 /******************************************************************************
288 * BuildSecurityDescriptorA [ADVAPI32.@]
295 * cCountOfAccessEntries [I]
296 * pListOfAccessEntries [I]
297 * cCountOfAuditEntries [I]
298 * pListofAuditEntries [I]
300 * lpdwBufferLength [I/O]
304 * Success: ERROR_SUCCESS
305 * Failure: nonzero error code from Winerror.h
307 DWORD WINAPI
BuildSecurityDescriptorA(
310 IN ULONG cCountOfAccessEntries
,
311 IN PEXPLICIT_ACCESSA pListOfAccessEntries
,
312 IN ULONG cCountOfAuditEntries
,
313 IN PEXPLICIT_ACCESSA pListofAuditEntries
,
314 IN PSECURITY_DESCRIPTOR pOldSD
,
315 IN OUT PULONG lpdwBufferLength
,
316 OUT PSECURITY_DESCRIPTOR
* pNewSD
)
318 FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner
,pGroup
,
319 cCountOfAccessEntries
,pListOfAccessEntries
,cCountOfAuditEntries
,
320 pListofAuditEntries
,pOldSD
,lpdwBufferLength
,pNewSD
);
322 return ERROR_CALL_NOT_IMPLEMENTED
;
325 /******************************************************************************
326 * BuildSecurityDescriptorW [ADVAPI32.@]
328 * See BuildSecurityDescriptorA.
330 DWORD WINAPI
BuildSecurityDescriptorW(
333 IN ULONG cCountOfAccessEntries
,
334 IN PEXPLICIT_ACCESSW pListOfAccessEntries
,
335 IN ULONG cCountOfAuditEntries
,
336 IN PEXPLICIT_ACCESSW pListOfAuditEntries
,
337 IN PSECURITY_DESCRIPTOR pOldSD
,
338 IN OUT PULONG lpdwBufferLength
,
339 OUT PSECURITY_DESCRIPTOR
* pNewSD
)
341 SECURITY_DESCRIPTOR desc
;
343 DWORD ret
= ERROR_SUCCESS
;
345 TRACE("(%p,%p,%d,%p,%d,%p,%p,%p,%p)\n", pOwner
, pGroup
,
346 cCountOfAccessEntries
, pListOfAccessEntries
, cCountOfAuditEntries
,
347 pListOfAuditEntries
, pOldSD
, lpdwBufferLength
, pNewSD
);
351 SECURITY_DESCRIPTOR_CONTROL control
;
352 DWORD desc_size
, dacl_size
= 0, sacl_size
= 0, owner_size
= 0, group_size
= 0;
353 PACL dacl
= NULL
, sacl
= NULL
;
354 PSID owner
= NULL
, group
= NULL
;
357 if ((status
= RtlGetControlSecurityDescriptor( pOldSD
, &control
, &revision
)) != STATUS_SUCCESS
)
358 return RtlNtStatusToDosError( status
);
359 if (!(control
& SE_SELF_RELATIVE
))
360 return ERROR_INVALID_SECURITY_DESCR
;
362 desc_size
= sizeof(desc
);
363 status
= RtlSelfRelativeToAbsoluteSD( pOldSD
, &desc
, &desc_size
, dacl
, &dacl_size
, sacl
, &sacl_size
,
364 owner
, &owner_size
, group
, &group_size
);
365 if (status
== STATUS_BUFFER_TOO_SMALL
)
368 dacl
= LocalAlloc( LMEM_FIXED
, dacl_size
);
370 sacl
= LocalAlloc( LMEM_FIXED
, sacl_size
);
372 owner
= LocalAlloc( LMEM_FIXED
, owner_size
);
374 group
= LocalAlloc( LMEM_FIXED
, group_size
);
376 desc_size
= sizeof(desc
);
377 status
= RtlSelfRelativeToAbsoluteSD( pOldSD
, &desc
, &desc_size
, dacl
, &dacl_size
, sacl
, &sacl_size
,
378 owner
, &owner_size
, group
, &group_size
);
380 if (status
!= STATUS_SUCCESS
)
386 return RtlNtStatusToDosError( status
);
391 if ((status
= RtlCreateSecurityDescriptor( &desc
, SECURITY_DESCRIPTOR_REVISION
)) != STATUS_SUCCESS
)
392 return RtlNtStatusToDosError( status
);
397 LocalFree( desc
.Owner
);
398 desc
.Owner
= LocalAlloc( LMEM_FIXED
, sizeof(MAX_SID
) );
399 if ((ret
= trustee_to_sid( sizeof(MAX_SID
), desc
.Owner
, pOwner
)))
405 LocalFree( desc
.Group
);
406 desc
.Group
= LocalAlloc( LMEM_FIXED
, sizeof(MAX_SID
) );
407 if ((ret
= trustee_to_sid( sizeof(MAX_SID
), desc
.Group
, pGroup
)))
411 if (pListOfAccessEntries
)
415 if ((ret
= SetEntriesInAclW( cCountOfAccessEntries
, pListOfAccessEntries
, desc
.Dacl
, &new_dacl
)))
418 LocalFree( desc
.Dacl
);
419 desc
.Dacl
= new_dacl
;
420 desc
.Control
|= SE_DACL_PRESENT
;
423 if (pListOfAuditEntries
)
427 if ((ret
= SetEntriesInAclW( cCountOfAuditEntries
, pListOfAuditEntries
, desc
.Sacl
, &new_sacl
)))
430 LocalFree( desc
.Sacl
);
431 desc
.Sacl
= new_sacl
;
432 desc
.Control
|= SE_SACL_PRESENT
;
435 *lpdwBufferLength
= RtlLengthSecurityDescriptor( &desc
);
436 *pNewSD
= LocalAlloc( LMEM_FIXED
, *lpdwBufferLength
);
438 if ((status
= RtlMakeSelfRelativeSD( &desc
, *pNewSD
, lpdwBufferLength
)) != STATUS_SUCCESS
)
440 ret
= RtlNtStatusToDosError( status
);
441 LocalFree( *pNewSD
);
446 /* free absolute descriptor */
447 LocalFree( desc
.Owner
);
448 LocalFree( desc
.Group
);
449 LocalFree( desc
.Sacl
);
450 LocalFree( desc
.Dacl
);
454 static const WCHAR
* const WellKnownPrivNames
[SE_MAX_WELL_KNOWN_PRIVILEGE
+ 1] =
458 L
"SeCreateTokenPrivilege",
459 L
"SeAssignPrimaryTokenPrivilege",
460 L
"SeLockMemoryPrivilege",
461 L
"SeIncreaseQuotaPrivilege",
462 L
"SeMachineAccountPrivilege",
464 L
"SeSecurityPrivilege",
465 L
"SeTakeOwnershipPrivilege",
466 L
"SeLoadDriverPrivilege",
467 L
"SeSystemProfilePrivilege",
468 L
"SeSystemtimePrivilege",
469 L
"SeProfileSingleProcessPrivilege",
470 L
"SeIncreaseBasePriorityPrivilege",
471 L
"SeCreatePagefilePrivilege",
472 L
"SeCreatePermanentPrivilege",
473 L
"SeBackupPrivilege",
474 L
"SeRestorePrivilege",
475 L
"SeShutdownPrivilege",
478 L
"SeSystemEnvironmentPrivilege",
479 L
"SeChangeNotifyPrivilege",
480 L
"SeRemoteShutdownPrivilege",
481 L
"SeUndockPrivilege",
482 L
"SeSyncAgentPrivilege",
483 L
"SeEnableDelegationPrivilege",
484 L
"SeManageVolumePrivilege",
485 L
"SeImpersonatePrivilege",
486 L
"SeCreateGlobalPrivilege",
489 const WCHAR
*get_wellknown_privilege_name(const LUID
*luid
)
491 if (luid
->HighPart
|| luid
->LowPart
< SE_MIN_WELL_KNOWN_PRIVILEGE
||
492 luid
->LowPart
> SE_MAX_WELL_KNOWN_PRIVILEGE
|| !WellKnownPrivNames
[luid
->LowPart
])
495 return WellKnownPrivNames
[luid
->LowPart
];
498 /******************************************************************************
499 * LookupPrivilegeValueW [ADVAPI32.@]
501 * See LookupPrivilegeValueA.
504 LookupPrivilegeValueW( LPCWSTR lpSystemName
, LPCWSTR lpName
, PLUID lpLuid
)
508 TRACE("%s,%s,%p\n",debugstr_w(lpSystemName
), debugstr_w(lpName
), lpLuid
);
510 if (!ADVAPI_IsLocalComputer(lpSystemName
))
512 SetLastError(RPC_S_SERVER_UNAVAILABLE
);
517 SetLastError(ERROR_NO_SUCH_PRIVILEGE
);
520 for( i
=SE_MIN_WELL_KNOWN_PRIVILEGE
; i
<=SE_MAX_WELL_KNOWN_PRIVILEGE
; i
++ )
522 if( !WellKnownPrivNames
[i
] )
524 if( wcsicmp( WellKnownPrivNames
[i
], lpName
) )
527 lpLuid
->HighPart
= 0;
528 TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName
),
529 lpLuid
->HighPart
, lpLuid
->LowPart
);
532 SetLastError(ERROR_NO_SUCH_PRIVILEGE
);
536 /******************************************************************************
537 * LookupPrivilegeValueA [ADVAPI32.@]
539 * Retrieves LUID used on a system to represent the privilege name.
542 * lpSystemName [I] Name of the system
543 * lpName [I] Name of the privilege
544 * lpLuid [O] Destination for the resulting LUID
547 * Success: TRUE. lpLuid contains the requested LUID.
551 LookupPrivilegeValueA( LPCSTR lpSystemName
, LPCSTR lpName
, PLUID lpLuid
)
553 UNICODE_STRING lpSystemNameW
;
554 UNICODE_STRING lpNameW
;
557 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW
, lpSystemName
);
558 RtlCreateUnicodeStringFromAsciiz(&lpNameW
,lpName
);
559 ret
= LookupPrivilegeValueW(lpSystemNameW
.Buffer
, lpNameW
.Buffer
, lpLuid
);
560 RtlFreeUnicodeString(&lpNameW
);
561 RtlFreeUnicodeString(&lpSystemNameW
);
565 BOOL WINAPI
LookupPrivilegeDisplayNameA( LPCSTR lpSystemName
, LPCSTR lpName
, LPSTR lpDisplayName
,
566 LPDWORD cchDisplayName
, LPDWORD lpLanguageId
)
568 FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName
), debugstr_a(lpName
),
569 debugstr_a(lpDisplayName
), cchDisplayName
, lpLanguageId
);
574 BOOL WINAPI
LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName
, LPCWSTR lpName
, LPWSTR lpDisplayName
,
575 LPDWORD cchDisplayName
, LPDWORD lpLanguageId
)
577 FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName
), debugstr_w(lpName
),
578 debugstr_w(lpDisplayName
), cchDisplayName
, lpLanguageId
);
583 /******************************************************************************
584 * LookupPrivilegeNameA [ADVAPI32.@]
586 * See LookupPrivilegeNameW.
589 LookupPrivilegeNameA( LPCSTR lpSystemName
, PLUID lpLuid
, LPSTR lpName
,
592 UNICODE_STRING lpSystemNameW
;
596 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName
), lpLuid
, lpName
, cchName
);
598 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW
, lpSystemName
);
599 ret
= LookupPrivilegeNameW(lpSystemNameW
.Buffer
, lpLuid
, NULL
, &wLen
);
600 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
602 LPWSTR lpNameW
= heap_alloc(wLen
* sizeof(WCHAR
));
604 ret
= LookupPrivilegeNameW(lpSystemNameW
.Buffer
, lpLuid
, lpNameW
,
608 /* Windows crashes if cchName is NULL, so will I */
609 unsigned int len
= WideCharToMultiByte(CP_ACP
, 0, lpNameW
, -1, lpName
,
610 *cchName
, NULL
, NULL
);
614 /* WideCharToMultiByte failed */
617 else if (len
> *cchName
)
620 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
625 /* WideCharToMultiByte succeeded, output length needs to be
626 * length not including NULL terminator
633 RtlFreeUnicodeString(&lpSystemNameW
);
637 /******************************************************************************
638 * LookupPrivilegeNameW [ADVAPI32.@]
640 * Retrieves the privilege name referred to by the LUID lpLuid.
643 * lpSystemName [I] Name of the system
644 * lpLuid [I] Privilege value
645 * lpName [O] Name of the privilege
646 * cchName [I/O] Number of characters in lpName.
649 * Success: TRUE. lpName contains the name of the privilege whose value is
654 * Only well-known privilege names (those defined in winnt.h) can be retrieved
655 * using this function.
656 * If the length of lpName is too small, on return *cchName will contain the
657 * number of WCHARs needed to contain the privilege, including the NULL
658 * terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
659 * On success, *cchName will contain the number of characters stored in
660 * lpName, NOT including the NULL terminator.
663 LookupPrivilegeNameW( LPCWSTR lpSystemName
, PLUID lpLuid
, LPWSTR lpName
,
668 TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName
), lpLuid
, lpName
, cchName
);
670 if (!ADVAPI_IsLocalComputer(lpSystemName
))
672 SetLastError(RPC_S_SERVER_UNAVAILABLE
);
675 if (lpLuid
->HighPart
|| (lpLuid
->LowPart
< SE_MIN_WELL_KNOWN_PRIVILEGE
||
676 lpLuid
->LowPart
> SE_MAX_WELL_KNOWN_PRIVILEGE
))
678 SetLastError(ERROR_NO_SUCH_PRIVILEGE
);
681 privNameLen
= lstrlenW(WellKnownPrivNames
[lpLuid
->LowPart
]);
682 /* Windows crashes if cchName is NULL, so will I */
683 if (*cchName
<= privNameLen
)
685 *cchName
= privNameLen
+ 1;
686 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
691 lstrcpyW(lpName
, WellKnownPrivNames
[lpLuid
->LowPart
]);
692 *cchName
= privNameLen
;
697 /******************************************************************************
698 * GetFileSecurityA [ADVAPI32.@]
700 * Obtains Specified information about the security of a file or directory.
703 * lpFileName [I] Name of the file to get info for
704 * RequestedInformation [I] SE_ flags from "winnt.h"
705 * pSecurityDescriptor [O] Destination for security information
706 * nLength [I] Length of pSecurityDescriptor
707 * lpnLengthNeeded [O] Destination for length of returned security information
710 * Success: TRUE. pSecurityDescriptor contains the requested information.
711 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
714 * The information returned is constrained by the callers access rights and
718 GetFileSecurityA( LPCSTR lpFileName
,
719 SECURITY_INFORMATION RequestedInformation
,
720 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
721 DWORD nLength
, LPDWORD lpnLengthNeeded
)
726 name
= strdupAW(lpFileName
);
727 r
= GetFileSecurityW( name
, RequestedInformation
, pSecurityDescriptor
,
728 nLength
, lpnLengthNeeded
);
734 /******************************************************************************
735 * LookupAccountSidA [ADVAPI32.@]
742 IN OUT LPDWORD accountSize
,
744 IN OUT LPDWORD domainSize
,
745 OUT PSID_NAME_USE name_use
)
750 LPWSTR accountW
= NULL
;
751 LPWSTR domainW
= NULL
;
752 DWORD accountSizeW
= *accountSize
;
753 DWORD domainSizeW
= *domainSize
;
755 systemW
= strdupAW(system
);
757 accountW
= heap_alloc( accountSizeW
* sizeof(WCHAR
) );
759 domainW
= heap_alloc( domainSizeW
* sizeof(WCHAR
) );
761 r
= LookupAccountSidW( systemW
, sid
, accountW
, &accountSizeW
, domainW
, &domainSizeW
, name_use
);
764 if (accountW
&& *accountSize
) {
765 len
= WideCharToMultiByte( CP_ACP
, 0, accountW
, -1, NULL
, 0, NULL
, NULL
);
766 WideCharToMultiByte( CP_ACP
, 0, accountW
, -1, account
, len
, NULL
, NULL
);
769 *accountSize
= accountSizeW
+ 1;
771 if (domainW
&& *domainSize
) {
772 len
= WideCharToMultiByte( CP_ACP
, 0, domainW
, -1, NULL
, 0, NULL
, NULL
);
773 WideCharToMultiByte( CP_ACP
, 0, domainW
, -1, domain
, len
, NULL
, NULL
);
776 *domainSize
= domainSizeW
+ 1;
780 *accountSize
= accountSizeW
+ 1;
781 *domainSize
= domainSizeW
+ 1;
784 heap_free( systemW
);
785 heap_free( accountW
);
786 heap_free( domainW
);
791 /******************************************************************************
792 * LookupAccountSidLocalA [ADVAPI32.@]
795 LookupAccountSidLocalA(
801 PSID_NAME_USE name_use
)
803 return LookupAccountSidA(NULL
, sid
, account
, accountSize
, domain
, domainSize
, name_use
);
806 /******************************************************************************
807 * LookupAccountSidW [ADVAPI32.@]
824 IN OUT LPDWORD accountSize
,
826 IN OUT LPDWORD domainSize
,
827 OUT PSID_NAME_USE name_use
)
830 const WCHAR
* ac
= NULL
;
831 const WCHAR
* dm
= NULL
;
832 SID_NAME_USE use
= 0;
833 LPWSTR computer_name
= NULL
;
834 LPWSTR account_name
= NULL
;
836 TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
837 debugstr_w(system
),debugstr_sid(sid
),
838 account
,accountSize
,accountSize
?*accountSize
:0,
839 domain
,domainSize
,domainSize
?*domainSize
:0,
842 if (!ADVAPI_IsLocalComputer(system
)) {
843 FIXME("Only local computer supported!\n");
844 SetLastError(RPC_S_SERVER_UNAVAILABLE
);
848 /* check the well known SIDs first */
849 for (i
= 0; i
<= WinAccountProtectedUsersSid
; i
++) {
850 if (IsWellKnownSid(sid
, i
)) {
851 for (j
= 0; j
< ARRAY_SIZE(ACCOUNT_SIDS
); j
++) {
852 if (ACCOUNT_SIDS
[j
].type
== i
) {
853 ac
= ACCOUNT_SIDS
[j
].account
;
854 dm
= ACCOUNT_SIDS
[j
].domain
;
855 use
= ACCOUNT_SIDS
[j
].name_use
;
865 /* check for the local computer next */
866 if (ADVAPI_GetComputerSid(&local
)) {
867 DWORD size
= MAX_COMPUTERNAME_LENGTH
+ 1;
870 computer_name
= heap_alloc(size
* sizeof(WCHAR
));
871 result
= GetComputerNameW(computer_name
, &size
);
874 if (EqualSid(sid
, &local
)) {
879 local
.SubAuthorityCount
++;
881 if (EqualPrefixSid(sid
, &local
)) {
884 switch (((MAX_SID
*)sid
)->SubAuthority
[4]) {
885 case DOMAIN_USER_RID_ADMIN
:
886 ac
= L
"Administrator";
888 case DOMAIN_USER_RID_GUEST
:
891 case DOMAIN_GROUP_RID_ADMINS
:
892 ac
= L
"Domain Admins";
894 case DOMAIN_GROUP_RID_USERS
:
898 case DOMAIN_GROUP_RID_GUESTS
:
899 ac
= L
"Domain Guests";
901 case DOMAIN_GROUP_RID_COMPUTERS
:
902 ac
= L
"Domain Computers";
904 case DOMAIN_GROUP_RID_CONTROLLERS
:
905 ac
= L
"Domain Controllers";
907 case DOMAIN_GROUP_RID_CERT_ADMINS
:
908 ac
= L
"Cert Publishers";
910 case DOMAIN_GROUP_RID_SCHEMA_ADMINS
:
911 ac
= L
"Schema Admins";
913 case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS
:
914 ac
= L
"Enterprise Admins";
916 case DOMAIN_GROUP_RID_POLICY_ADMINS
:
917 ac
= L
"Group Policy Creator Owners";
919 case DOMAIN_ALIAS_RID_RAS_SERVERS
:
920 ac
= L
"RAS and IAS Servers";
922 case 1000: /* first user account */
924 account_name
= heap_alloc(size
* sizeof(WCHAR
));
925 if (GetUserNameW(account_name
, &size
))
942 DWORD ac_len
= lstrlenW(ac
);
943 DWORD dm_len
= lstrlenW(dm
);
946 if (*accountSize
> ac_len
) {
948 lstrcpyW(account
, ac
);
950 if (*domainSize
> dm_len
) {
952 lstrcpyW(domain
, dm
);
954 if ((*accountSize
&& *accountSize
< ac_len
) ||
955 (!account
&& !*accountSize
&& ac_len
) ||
956 (*domainSize
&& *domainSize
< dm_len
) ||
957 (!domain
&& !*domainSize
&& dm_len
))
959 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
963 *domainSize
= dm_len
;
965 *domainSize
= dm_len
+ 1;
967 *accountSize
= ac_len
;
969 *accountSize
= ac_len
+ 1;
971 heap_free(account_name
);
972 heap_free(computer_name
);
973 if (status
) *name_use
= use
;
977 heap_free(account_name
);
978 heap_free(computer_name
);
979 SetLastError(ERROR_NONE_MAPPED
);
983 /******************************************************************************
984 * LookupAccountSidLocalW [ADVAPI32.@]
987 LookupAccountSidLocalW(
993 PSID_NAME_USE name_use
)
995 return LookupAccountSidW(NULL
, sid
, account
, accountSize
, domain
, domainSize
, name_use
);
998 /******************************************************************************
999 * SetFileSecurityA [ADVAPI32.@]
1001 * See SetFileSecurityW.
1003 BOOL WINAPI
SetFileSecurityA( LPCSTR lpFileName
,
1004 SECURITY_INFORMATION RequestedInformation
,
1005 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
1010 name
= strdupAW(lpFileName
);
1011 r
= SetFileSecurityW( name
, RequestedInformation
, pSecurityDescriptor
);
1017 /******************************************************************************
1018 * QueryWindows31FilesMigration [ADVAPI32.@]
1024 QueryWindows31FilesMigration( DWORD x1
)
1026 FIXME("(%d):stub\n",x1
);
1030 /******************************************************************************
1031 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
1040 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1
, DWORD x2
, DWORD x3
,
1043 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1
,x2
,x3
,x4
);
1047 /******************************************************************************
1048 * NotifyBootConfigStatus [ADVAPI32.@]
1054 NotifyBootConfigStatus( BOOL x1
)
1056 FIXME("(0x%08d):stub\n",x1
);
1060 /******************************************************************************
1061 * LookupAccountNameA [ADVAPI32.@]
1069 LPSTR ReferencedDomainName
,
1070 IN OUT LPDWORD cbReferencedDomainName
,
1071 OUT PSID_NAME_USE name_use
)
1074 UNICODE_STRING lpSystemW
;
1075 UNICODE_STRING lpAccountW
;
1076 LPWSTR lpReferencedDomainNameW
= NULL
;
1078 RtlCreateUnicodeStringFromAsciiz(&lpSystemW
, system
);
1079 RtlCreateUnicodeStringFromAsciiz(&lpAccountW
, account
);
1081 if (ReferencedDomainName
)
1082 lpReferencedDomainNameW
= heap_alloc(*cbReferencedDomainName
* sizeof(WCHAR
));
1084 ret
= LookupAccountNameW(lpSystemW
.Buffer
, lpAccountW
.Buffer
, sid
, cbSid
, lpReferencedDomainNameW
,
1085 cbReferencedDomainName
, name_use
);
1087 if (ret
&& lpReferencedDomainNameW
)
1089 WideCharToMultiByte(CP_ACP
, 0, lpReferencedDomainNameW
, -1,
1090 ReferencedDomainName
, *cbReferencedDomainName
+1, NULL
, NULL
);
1093 RtlFreeUnicodeString(&lpSystemW
);
1094 RtlFreeUnicodeString(&lpAccountW
);
1095 heap_free(lpReferencedDomainNameW
);
1100 /******************************************************************************
1101 * lookup_user_account_name
1103 static BOOL
lookup_user_account_name(PSID Sid
, PDWORD cbSid
, LPWSTR ReferencedDomainName
,
1104 LPDWORD cchReferencedDomainName
, PSID_NAME_USE peUse
)
1106 char buffer
[sizeof(TOKEN_USER
) + sizeof(SID
) + sizeof(DWORD
)*SID_MAX_SUB_AUTHORITIES
];
1107 DWORD len
= sizeof(buffer
);
1111 WCHAR domainName
[MAX_COMPUTERNAME_LENGTH
+ 1];
1114 if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ
, TRUE
, &token
))
1116 if (GetLastError() != ERROR_NO_TOKEN
) return FALSE
;
1117 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ
, &token
)) return FALSE
;
1120 ret
= GetTokenInformation(token
, TokenUser
, buffer
, len
, &len
);
1121 CloseHandle( token
);
1123 if (!ret
) return FALSE
;
1125 pSid
= ((TOKEN_USER
*)buffer
)->User
.Sid
;
1127 if (Sid
!= NULL
&& (*cbSid
>= GetLengthSid(pSid
)))
1128 CopySid(*cbSid
, Sid
, pSid
);
1129 if (*cbSid
< GetLengthSid(pSid
))
1131 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1134 *cbSid
= GetLengthSid(pSid
);
1136 nameLen
= MAX_COMPUTERNAME_LENGTH
+ 1;
1137 if (!GetComputerNameW(domainName
, &nameLen
))
1142 if (*cchReferencedDomainName
<= nameLen
|| !ret
)
1144 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1148 else if (ReferencedDomainName
)
1149 lstrcpyW(ReferencedDomainName
, domainName
);
1151 *cchReferencedDomainName
= nameLen
;
1154 *peUse
= SidTypeUser
;
1159 /******************************************************************************
1160 * lookup_computer_account_name
1162 static BOOL
lookup_computer_account_name(PSID Sid
, PDWORD cbSid
, LPWSTR ReferencedDomainName
,
1163 LPDWORD cchReferencedDomainName
, PSID_NAME_USE peUse
)
1167 WCHAR domainName
[MAX_COMPUTERNAME_LENGTH
+ 1];
1170 if ((ret
= ADVAPI_GetComputerSid(&local
)))
1172 if (Sid
!= NULL
&& (*cbSid
>= GetLengthSid(&local
)))
1173 CopySid(*cbSid
, Sid
, &local
);
1174 if (*cbSid
< GetLengthSid(&local
))
1176 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1179 *cbSid
= GetLengthSid(&local
);
1182 nameLen
= MAX_COMPUTERNAME_LENGTH
+ 1;
1183 if (!GetComputerNameW(domainName
, &nameLen
))
1188 if (*cchReferencedDomainName
<= nameLen
|| !ret
)
1190 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1194 else if (ReferencedDomainName
)
1195 lstrcpyW(ReferencedDomainName
, domainName
);
1197 *cchReferencedDomainName
= nameLen
;
1200 *peUse
= SidTypeDomain
;
1205 static void split_domain_account( const LSA_UNICODE_STRING
*str
, LSA_UNICODE_STRING
*account
,
1206 LSA_UNICODE_STRING
*domain
)
1208 WCHAR
*p
= str
->Buffer
+ str
->Length
/ sizeof(WCHAR
) - 1;
1210 while (p
> str
->Buffer
&& *p
!= '\\') p
--;
1214 domain
->Buffer
= str
->Buffer
;
1215 domain
->Length
= (p
- str
->Buffer
) * sizeof(WCHAR
);
1217 account
->Buffer
= p
+ 1;
1218 account
->Length
= str
->Length
- ((p
- str
->Buffer
+ 1) * sizeof(WCHAR
));
1222 domain
->Buffer
= NULL
;
1225 account
->Buffer
= str
->Buffer
;
1226 account
->Length
= str
->Length
;
1230 static BOOL
match_domain( ULONG idx
, const LSA_UNICODE_STRING
*domain
)
1232 ULONG len
= lstrlenW( ACCOUNT_SIDS
[idx
].domain
);
1234 if (len
== domain
->Length
/ sizeof(WCHAR
) && !wcsnicmp( domain
->Buffer
, ACCOUNT_SIDS
[idx
].domain
, len
))
1240 static BOOL
match_account( ULONG idx
, const LSA_UNICODE_STRING
*account
)
1242 ULONG len
= lstrlenW( ACCOUNT_SIDS
[idx
].account
);
1244 if (len
== account
->Length
/ sizeof(WCHAR
) && !wcsnicmp( account
->Buffer
, ACCOUNT_SIDS
[idx
].account
, len
))
1247 if (ACCOUNT_SIDS
[idx
].alias
)
1249 len
= lstrlenW( ACCOUNT_SIDS
[idx
].alias
);
1250 if (len
== account
->Length
/ sizeof(WCHAR
) && !wcsnicmp( account
->Buffer
, ACCOUNT_SIDS
[idx
].alias
, len
))
1257 * Helper function for LookupAccountNameW
1259 BOOL
lookup_local_wellknown_name( const LSA_UNICODE_STRING
*account_and_domain
,
1260 PSID Sid
, LPDWORD cbSid
,
1261 LPWSTR ReferencedDomainName
,
1262 LPDWORD cchReferencedDomainName
,
1263 PSID_NAME_USE peUse
, BOOL
*handled
)
1266 LSA_UNICODE_STRING account
, domain
;
1271 split_domain_account( account_and_domain
, &account
, &domain
);
1273 for (i
= 0; i
< ARRAY_SIZE(ACCOUNT_SIDS
); i
++)
1275 /* check domain first */
1276 if (domain
.Buffer
&& !match_domain( i
, &domain
)) continue;
1278 if (match_account( i
, &account
))
1280 DWORD len
, sidLen
= SECURITY_MAX_SID_SIZE
;
1282 if (!(pSid
= heap_alloc( sidLen
))) return FALSE
;
1284 if ((ret
= CreateWellKnownSid( ACCOUNT_SIDS
[i
].type
, NULL
, pSid
, &sidLen
)))
1286 if (*cbSid
< sidLen
)
1288 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1293 CopySid(*cbSid
, Sid
, pSid
);
1298 len
= lstrlenW( ACCOUNT_SIDS
[i
].domain
);
1299 if (*cchReferencedDomainName
<= len
|| !ret
)
1301 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1305 else if (ReferencedDomainName
)
1307 lstrcpyW( ReferencedDomainName
, ACCOUNT_SIDS
[i
].domain
);
1310 *cchReferencedDomainName
= len
;
1312 *peUse
= ACCOUNT_SIDS
[i
].name_use
;
1322 BOOL
lookup_local_user_name( const LSA_UNICODE_STRING
*account_and_domain
,
1323 PSID Sid
, LPDWORD cbSid
,
1324 LPWSTR ReferencedDomainName
,
1325 LPDWORD cchReferencedDomainName
,
1326 PSID_NAME_USE peUse
, BOOL
*handled
)
1329 LPWSTR userName
= NULL
;
1330 LSA_UNICODE_STRING account
, domain
;
1334 split_domain_account( account_and_domain
, &account
, &domain
);
1336 /* Let the current Unix user id masquerade as first Windows user account */
1338 nameLen
= UNLEN
+ 1;
1339 if (!(userName
= heap_alloc( nameLen
* sizeof(WCHAR
) ))) return FALSE
;
1343 /* check to make sure this account is on this computer */
1344 if (GetComputerNameW( userName
, &nameLen
) &&
1345 (domain
.Length
/ sizeof(WCHAR
) != nameLen
|| wcsncmp( domain
.Buffer
, userName
, nameLen
)))
1347 SetLastError(ERROR_NONE_MAPPED
);
1350 nameLen
= UNLEN
+ 1;
1353 if (GetUserNameW( userName
, &nameLen
) &&
1354 account
.Length
/ sizeof(WCHAR
) == nameLen
- 1 && !wcsncmp( account
.Buffer
, userName
, nameLen
- 1 ))
1356 ret
= lookup_user_account_name( Sid
, cbSid
, ReferencedDomainName
, cchReferencedDomainName
, peUse
);
1361 nameLen
= UNLEN
+ 1;
1362 if (GetComputerNameW( userName
, &nameLen
) &&
1363 account
.Length
/ sizeof(WCHAR
) == nameLen
&& !wcsncmp( account
.Buffer
, userName
, nameLen
))
1365 ret
= lookup_computer_account_name( Sid
, cbSid
, ReferencedDomainName
, cchReferencedDomainName
, peUse
);
1370 heap_free(userName
);
1374 /******************************************************************************
1375 * LookupAccountNameW [ADVAPI32.@]
1377 BOOL WINAPI
LookupAccountNameW( LPCWSTR lpSystemName
, LPCWSTR lpAccountName
, PSID Sid
,
1378 LPDWORD cbSid
, LPWSTR ReferencedDomainName
,
1379 LPDWORD cchReferencedDomainName
, PSID_NAME_USE peUse
)
1382 LSA_UNICODE_STRING account
;
1384 TRACE("%s %s %p %p %p %p %p\n", debugstr_w(lpSystemName
), debugstr_w(lpAccountName
),
1385 Sid
, cbSid
, ReferencedDomainName
, cchReferencedDomainName
, peUse
);
1387 if (!ADVAPI_IsLocalComputer( lpSystemName
))
1389 FIXME("remote computer not supported\n");
1390 SetLastError( RPC_S_SERVER_UNAVAILABLE
);
1394 if (!lpAccountName
|| !wcscmp( lpAccountName
, L
"" ))
1396 lpAccountName
= L
"BUILTIN";
1399 RtlInitUnicodeString( &account
, lpAccountName
);
1401 /* Check well known SIDs first */
1402 ret
= lookup_local_wellknown_name( &account
, Sid
, cbSid
, ReferencedDomainName
,
1403 cchReferencedDomainName
, peUse
, &handled
);
1407 /* Check user names */
1408 ret
= lookup_local_user_name( &account
, Sid
, cbSid
, ReferencedDomainName
,
1409 cchReferencedDomainName
, peUse
, &handled
);
1413 SetLastError( ERROR_NONE_MAPPED
);
1417 /******************************************************************************
1418 * AccessCheckAndAuditAlarmA [ADVAPI32.@]
1420 BOOL WINAPI
AccessCheckAndAuditAlarmA(LPCSTR Subsystem
, LPVOID HandleId
, LPSTR ObjectTypeName
,
1421 LPSTR ObjectName
, PSECURITY_DESCRIPTOR SecurityDescriptor
, DWORD DesiredAccess
,
1422 PGENERIC_MAPPING GenericMapping
, BOOL ObjectCreation
, LPDWORD GrantedAccess
,
1423 LPBOOL AccessStatus
, LPBOOL pfGenerateOnClose
)
1425 FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem
),
1426 HandleId
, debugstr_a(ObjectTypeName
), debugstr_a(ObjectName
),
1427 SecurityDescriptor
, DesiredAccess
, GenericMapping
,
1428 ObjectCreation
, GrantedAccess
, AccessStatus
, pfGenerateOnClose
);
1432 BOOL WINAPI
ObjectCloseAuditAlarmA(LPCSTR SubsystemName
, LPVOID HandleId
, BOOL GenerateOnClose
)
1434 FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName
), HandleId
, GenerateOnClose
);
1439 BOOL WINAPI
ObjectOpenAuditAlarmA(LPCSTR SubsystemName
, LPVOID HandleId
, LPSTR ObjectTypeName
,
1440 LPSTR ObjectName
, PSECURITY_DESCRIPTOR pSecurityDescriptor
, HANDLE ClientToken
, DWORD DesiredAccess
,
1441 DWORD GrantedAccess
, PPRIVILEGE_SET Privileges
, BOOL ObjectCreation
, BOOL AccessGranted
,
1442 LPBOOL GenerateOnClose
)
1444 FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName
),
1445 HandleId
, debugstr_a(ObjectTypeName
), debugstr_a(ObjectName
), pSecurityDescriptor
,
1446 ClientToken
, DesiredAccess
, GrantedAccess
, Privileges
, ObjectCreation
, AccessGranted
,
1452 BOOL WINAPI
ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName
, LPVOID HandleId
, HANDLE ClientToken
,
1453 DWORD DesiredAccess
, PPRIVILEGE_SET Privileges
, BOOL AccessGranted
)
1455 FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName
), HandleId
, ClientToken
,
1456 DesiredAccess
, Privileges
, AccessGranted
);
1461 BOOL WINAPI
PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName
, LPCSTR ServiceName
, HANDLE ClientToken
,
1462 PPRIVILEGE_SET Privileges
, BOOL AccessGranted
)
1464 FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName
), debugstr_a(ServiceName
),
1465 ClientToken
, Privileges
, AccessGranted
);
1470 #define HKEY_SPECIAL_ROOT_FIRST HKEY_CLASSES_ROOT
1471 #define HKEY_SPECIAL_ROOT_LAST HKEY_DYN_DATA
1473 /******************************************************************************
1474 * GetSecurityInfo [ADVAPI32.@]
1476 * Retrieves a copy of the security descriptor associated with an object.
1479 * hObject [I] A handle for the object.
1480 * ObjectType [I] The type of object.
1481 * SecurityInfo [I] A bitmask indicating what info to retrieve.
1482 * ppsidOwner [O] If non-null, receives a pointer to the owner SID.
1483 * ppsidGroup [O] If non-null, receives a pointer to the group SID.
1484 * ppDacl [O] If non-null, receives a pointer to the DACL.
1485 * ppSacl [O] If non-null, receives a pointer to the SACL.
1486 * ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
1487 * which must be freed with LocalFree.
1490 * ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
1492 DWORD WINAPI
GetSecurityInfo( HANDLE handle
, SE_OBJECT_TYPE type
, SECURITY_INFORMATION SecurityInfo
,
1493 PSID
*ppsidOwner
, PSID
*ppsidGroup
, PACL
*ppDacl
, PACL
*ppSacl
,
1494 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1496 PSECURITY_DESCRIPTOR sd
;
1499 BOOL present
, defaulted
;
1501 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
1502 if (!(ppsidOwner
||ppsidGroup
||ppDacl
||ppSacl
||ppSecurityDescriptor
)) return ERROR_INVALID_PARAMETER
;
1504 /* If no descriptor, we have to check that there's a pointer for the requested information */
1505 if( !ppSecurityDescriptor
&& (
1506 ((SecurityInfo
& OWNER_SECURITY_INFORMATION
) && !ppsidOwner
)
1507 || ((SecurityInfo
& GROUP_SECURITY_INFORMATION
) && !ppsidGroup
)
1508 || ((SecurityInfo
& DACL_SECURITY_INFORMATION
) && !ppDacl
)
1509 || ((SecurityInfo
& SACL_SECURITY_INFORMATION
) && !ppSacl
) ))
1510 return ERROR_INVALID_PARAMETER
;
1512 if (type
== SE_SERVICE
)
1514 if (!QueryServiceObjectSecurity( handle
, SecurityInfo
, NULL
, 0, &size
)
1515 && GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
1516 return GetLastError();
1518 if (!(sd
= LocalAlloc( 0, size
))) return ERROR_NOT_ENOUGH_MEMORY
;
1520 if (!QueryServiceObjectSecurity( handle
, SecurityInfo
, sd
, size
, &size
))
1523 return GetLastError();
1530 if (type
== SE_REGISTRY_KEY
&& (HandleToUlong(handle
) >= HandleToUlong(HKEY_SPECIAL_ROOT_FIRST
))
1531 && (HandleToUlong(handle
) <= HandleToUlong(HKEY_SPECIAL_ROOT_LAST
)))
1533 REGSAM access
= READ_CONTROL
;
1536 if (SecurityInfo
& SACL_SECURITY_INFORMATION
)
1537 access
|= ACCESS_SYSTEM_SECURITY
;
1539 if ((ret
= RegCreateKeyExW( handle
, NULL
, 0, NULL
, 0, access
, NULL
, &key
, NULL
)))
1545 status
= NtQuerySecurityObject( handle
, SecurityInfo
, NULL
, 0, &size
);
1546 if (status
!= STATUS_SUCCESS
&& status
!= STATUS_BUFFER_TOO_SMALL
)
1549 return RtlNtStatusToDosError( status
);
1552 if (!(sd
= LocalAlloc( 0, size
)))
1555 return ERROR_NOT_ENOUGH_MEMORY
;
1558 if ((status
= NtQuerySecurityObject( handle
, SecurityInfo
, sd
, size
, &size
)))
1562 return RtlNtStatusToDosError( status
);
1570 GetSecurityDescriptorOwner(sd
, ppsidOwner
, &defaulted
);
1575 GetSecurityDescriptorGroup(sd
, ppsidGroup
, &defaulted
);
1580 GetSecurityDescriptorDacl(sd
, &present
, ppDacl
, &defaulted
);
1585 GetSecurityDescriptorSacl(sd
, &present
, ppSacl
, &defaulted
);
1587 if (ppSecurityDescriptor
)
1588 *ppSecurityDescriptor
= sd
;
1590 /* The security descriptor (sd) cannot be freed if ppSecurityDescriptor is
1591 * NULL, because native happily returns the SIDs and ACLs that are requested
1595 return ERROR_SUCCESS
;
1598 /******************************************************************************
1599 * GetSecurityInfoExA [ADVAPI32.@]
1601 DWORD WINAPI
GetSecurityInfoExA(
1602 HANDLE hObject
, SE_OBJECT_TYPE ObjectType
,
1603 SECURITY_INFORMATION SecurityInfo
, LPCSTR lpProvider
,
1604 LPCSTR lpProperty
, PACTRL_ACCESSA
*ppAccessList
,
1605 PACTRL_AUDITA
*ppAuditList
, LPSTR
*lppOwner
, LPSTR
*lppGroup
1609 return ERROR_BAD_PROVIDER
;
1612 /******************************************************************************
1613 * GetSecurityInfoExW [ADVAPI32.@]
1615 DWORD WINAPI
GetSecurityInfoExW(
1616 HANDLE hObject
, SE_OBJECT_TYPE ObjectType
,
1617 SECURITY_INFORMATION SecurityInfo
, LPCWSTR lpProvider
,
1618 LPCWSTR lpProperty
, PACTRL_ACCESSW
*ppAccessList
,
1619 PACTRL_AUDITW
*ppAuditList
, LPWSTR
*lppOwner
, LPWSTR
*lppGroup
1623 return ERROR_BAD_PROVIDER
;
1626 /******************************************************************************
1627 * BuildExplicitAccessWithNameA [ADVAPI32.@]
1629 VOID WINAPI
BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess
,
1630 LPSTR pTrusteeName
, DWORD AccessPermissions
,
1631 ACCESS_MODE AccessMode
, DWORD Inheritance
)
1633 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess
, debugstr_a(pTrusteeName
),
1634 AccessPermissions
, AccessMode
, Inheritance
);
1636 pExplicitAccess
->grfAccessPermissions
= AccessPermissions
;
1637 pExplicitAccess
->grfAccessMode
= AccessMode
;
1638 pExplicitAccess
->grfInheritance
= Inheritance
;
1640 pExplicitAccess
->Trustee
.pMultipleTrustee
= NULL
;
1641 pExplicitAccess
->Trustee
.MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1642 pExplicitAccess
->Trustee
.TrusteeForm
= TRUSTEE_IS_NAME
;
1643 pExplicitAccess
->Trustee
.TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1644 pExplicitAccess
->Trustee
.ptstrName
= pTrusteeName
;
1647 /******************************************************************************
1648 * BuildExplicitAccessWithNameW [ADVAPI32.@]
1650 VOID WINAPI
BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess
,
1651 LPWSTR pTrusteeName
, DWORD AccessPermissions
,
1652 ACCESS_MODE AccessMode
, DWORD Inheritance
)
1654 TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess
, debugstr_w(pTrusteeName
),
1655 AccessPermissions
, AccessMode
, Inheritance
);
1657 pExplicitAccess
->grfAccessPermissions
= AccessPermissions
;
1658 pExplicitAccess
->grfAccessMode
= AccessMode
;
1659 pExplicitAccess
->grfInheritance
= Inheritance
;
1661 pExplicitAccess
->Trustee
.pMultipleTrustee
= NULL
;
1662 pExplicitAccess
->Trustee
.MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1663 pExplicitAccess
->Trustee
.TrusteeForm
= TRUSTEE_IS_NAME
;
1664 pExplicitAccess
->Trustee
.TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1665 pExplicitAccess
->Trustee
.ptstrName
= pTrusteeName
;
1668 /******************************************************************************
1669 * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
1671 VOID WINAPI
BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee
, POBJECTS_AND_NAME_A pObjName
,
1672 SE_OBJECT_TYPE ObjectType
, LPSTR ObjectTypeName
,
1673 LPSTR InheritedObjectTypeName
, LPSTR Name
)
1675 DWORD ObjectsPresent
= 0;
1677 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee
, pObjName
,
1678 ObjectType
, ObjectTypeName
, InheritedObjectTypeName
, debugstr_a(Name
));
1680 /* Fill the OBJECTS_AND_NAME structure */
1681 pObjName
->ObjectType
= ObjectType
;
1682 if (ObjectTypeName
!= NULL
)
1684 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1687 pObjName
->InheritedObjectTypeName
= InheritedObjectTypeName
;
1688 if (InheritedObjectTypeName
!= NULL
)
1690 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1693 pObjName
->ObjectsPresent
= ObjectsPresent
;
1694 pObjName
->ptstrName
= Name
;
1696 /* Fill the TRUSTEE structure */
1697 pTrustee
->pMultipleTrustee
= NULL
;
1698 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1699 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_NAME
;
1700 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1701 pTrustee
->ptstrName
= (LPSTR
)pObjName
;
1704 /******************************************************************************
1705 * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
1707 VOID WINAPI
BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee
, POBJECTS_AND_NAME_W pObjName
,
1708 SE_OBJECT_TYPE ObjectType
, LPWSTR ObjectTypeName
,
1709 LPWSTR InheritedObjectTypeName
, LPWSTR Name
)
1711 DWORD ObjectsPresent
= 0;
1713 TRACE("%p %p 0x%08x %p %p %s\n", pTrustee
, pObjName
,
1714 ObjectType
, ObjectTypeName
, InheritedObjectTypeName
, debugstr_w(Name
));
1716 /* Fill the OBJECTS_AND_NAME structure */
1717 pObjName
->ObjectType
= ObjectType
;
1718 if (ObjectTypeName
!= NULL
)
1720 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1723 pObjName
->InheritedObjectTypeName
= InheritedObjectTypeName
;
1724 if (InheritedObjectTypeName
!= NULL
)
1726 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1729 pObjName
->ObjectsPresent
= ObjectsPresent
;
1730 pObjName
->ptstrName
= Name
;
1732 /* Fill the TRUSTEE structure */
1733 pTrustee
->pMultipleTrustee
= NULL
;
1734 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1735 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_NAME
;
1736 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1737 pTrustee
->ptstrName
= (LPWSTR
)pObjName
;
1740 /******************************************************************************
1741 * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
1743 VOID WINAPI
BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee
, POBJECTS_AND_SID pObjSid
,
1744 GUID
* pObjectGuid
, GUID
* pInheritedObjectGuid
, PSID pSid
)
1746 DWORD ObjectsPresent
= 0;
1748 TRACE("%p %p %p %p %p\n", pTrustee
, pObjSid
, pObjectGuid
, pInheritedObjectGuid
, pSid
);
1750 /* Fill the OBJECTS_AND_SID structure */
1751 if (pObjectGuid
!= NULL
)
1753 pObjSid
->ObjectTypeGuid
= *pObjectGuid
;
1754 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1758 ZeroMemory(&pObjSid
->ObjectTypeGuid
,
1762 if (pInheritedObjectGuid
!= NULL
)
1764 pObjSid
->InheritedObjectTypeGuid
= *pInheritedObjectGuid
;
1765 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1769 ZeroMemory(&pObjSid
->InheritedObjectTypeGuid
,
1773 pObjSid
->ObjectsPresent
= ObjectsPresent
;
1774 pObjSid
->pSid
= pSid
;
1776 /* Fill the TRUSTEE structure */
1777 pTrustee
->pMultipleTrustee
= NULL
;
1778 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1779 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_SID
;
1780 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1781 pTrustee
->ptstrName
= (LPSTR
) pObjSid
;
1784 /******************************************************************************
1785 * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
1787 VOID WINAPI
BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee
, POBJECTS_AND_SID pObjSid
,
1788 GUID
* pObjectGuid
, GUID
* pInheritedObjectGuid
, PSID pSid
)
1790 DWORD ObjectsPresent
= 0;
1792 TRACE("%p %p %p %p %p\n", pTrustee
, pObjSid
, pObjectGuid
, pInheritedObjectGuid
, pSid
);
1794 /* Fill the OBJECTS_AND_SID structure */
1795 if (pObjectGuid
!= NULL
)
1797 pObjSid
->ObjectTypeGuid
= *pObjectGuid
;
1798 ObjectsPresent
|= ACE_OBJECT_TYPE_PRESENT
;
1802 ZeroMemory(&pObjSid
->ObjectTypeGuid
,
1806 if (pInheritedObjectGuid
!= NULL
)
1808 pObjSid
->InheritedObjectTypeGuid
= *pInheritedObjectGuid
;
1809 ObjectsPresent
|= ACE_INHERITED_OBJECT_TYPE_PRESENT
;
1813 ZeroMemory(&pObjSid
->InheritedObjectTypeGuid
,
1817 pObjSid
->ObjectsPresent
= ObjectsPresent
;
1818 pObjSid
->pSid
= pSid
;
1820 /* Fill the TRUSTEE structure */
1821 pTrustee
->pMultipleTrustee
= NULL
;
1822 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1823 pTrustee
->TrusteeForm
= TRUSTEE_IS_OBJECTS_AND_SID
;
1824 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1825 pTrustee
->ptstrName
= (LPWSTR
) pObjSid
;
1828 /******************************************************************************
1829 * BuildTrusteeWithSidA [ADVAPI32.@]
1831 VOID WINAPI
BuildTrusteeWithSidA(PTRUSTEEA pTrustee
, PSID pSid
)
1833 TRACE("%p %p\n", pTrustee
, pSid
);
1835 pTrustee
->pMultipleTrustee
= NULL
;
1836 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1837 pTrustee
->TrusteeForm
= TRUSTEE_IS_SID
;
1838 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1839 pTrustee
->ptstrName
= pSid
;
1842 /******************************************************************************
1843 * BuildTrusteeWithSidW [ADVAPI32.@]
1845 VOID WINAPI
BuildTrusteeWithSidW(PTRUSTEEW pTrustee
, PSID pSid
)
1847 TRACE("%p %p\n", pTrustee
, pSid
);
1849 pTrustee
->pMultipleTrustee
= NULL
;
1850 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1851 pTrustee
->TrusteeForm
= TRUSTEE_IS_SID
;
1852 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1853 pTrustee
->ptstrName
= pSid
;
1856 /******************************************************************************
1857 * BuildTrusteeWithNameA [ADVAPI32.@]
1859 VOID WINAPI
BuildTrusteeWithNameA(PTRUSTEEA pTrustee
, LPSTR name
)
1861 TRACE("%p %s\n", pTrustee
, debugstr_a(name
) );
1863 pTrustee
->pMultipleTrustee
= NULL
;
1864 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1865 pTrustee
->TrusteeForm
= TRUSTEE_IS_NAME
;
1866 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1867 pTrustee
->ptstrName
= name
;
1870 /******************************************************************************
1871 * BuildTrusteeWithNameW [ADVAPI32.@]
1873 VOID WINAPI
BuildTrusteeWithNameW(PTRUSTEEW pTrustee
, LPWSTR name
)
1875 TRACE("%p %s\n", pTrustee
, debugstr_w(name
) );
1877 pTrustee
->pMultipleTrustee
= NULL
;
1878 pTrustee
->MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
1879 pTrustee
->TrusteeForm
= TRUSTEE_IS_NAME
;
1880 pTrustee
->TrusteeType
= TRUSTEE_IS_UNKNOWN
;
1881 pTrustee
->ptstrName
= name
;
1884 /******************************************************************************
1885 * GetTrusteeFormA [ADVAPI32.@]
1887 TRUSTEE_FORM WINAPI
GetTrusteeFormA(PTRUSTEEA pTrustee
)
1889 TRACE("(%p)\n", pTrustee
);
1892 return TRUSTEE_BAD_FORM
;
1894 return pTrustee
->TrusteeForm
;
1897 /******************************************************************************
1898 * GetTrusteeFormW [ADVAPI32.@]
1900 TRUSTEE_FORM WINAPI
GetTrusteeFormW(PTRUSTEEW pTrustee
)
1902 TRACE("(%p)\n", pTrustee
);
1905 return TRUSTEE_BAD_FORM
;
1907 return pTrustee
->TrusteeForm
;
1910 /******************************************************************************
1911 * GetTrusteeNameA [ADVAPI32.@]
1913 LPSTR WINAPI
GetTrusteeNameA(PTRUSTEEA pTrustee
)
1915 TRACE("(%p)\n", pTrustee
);
1920 return pTrustee
->ptstrName
;
1923 /******************************************************************************
1924 * GetTrusteeNameW [ADVAPI32.@]
1926 LPWSTR WINAPI
GetTrusteeNameW(PTRUSTEEW pTrustee
)
1928 TRACE("(%p)\n", pTrustee
);
1933 return pTrustee
->ptstrName
;
1936 /******************************************************************************
1937 * GetTrusteeTypeA [ADVAPI32.@]
1939 TRUSTEE_TYPE WINAPI
GetTrusteeTypeA(PTRUSTEEA pTrustee
)
1941 TRACE("(%p)\n", pTrustee
);
1944 return TRUSTEE_IS_UNKNOWN
;
1946 return pTrustee
->TrusteeType
;
1949 /******************************************************************************
1950 * GetTrusteeTypeW [ADVAPI32.@]
1952 TRUSTEE_TYPE WINAPI
GetTrusteeTypeW(PTRUSTEEW pTrustee
)
1954 TRACE("(%p)\n", pTrustee
);
1957 return TRUSTEE_IS_UNKNOWN
;
1959 return pTrustee
->TrusteeType
;
1962 static DWORD
trustee_name_A_to_W(TRUSTEE_FORM form
, char *trustee_nameA
, WCHAR
**ptrustee_nameW
)
1966 case TRUSTEE_IS_NAME
:
1968 *ptrustee_nameW
= strdupAW(trustee_nameA
);
1969 return ERROR_SUCCESS
;
1971 case TRUSTEE_IS_OBJECTS_AND_NAME
:
1973 OBJECTS_AND_NAME_A
*objA
= (OBJECTS_AND_NAME_A
*)trustee_nameA
;
1974 OBJECTS_AND_NAME_W
*objW
= NULL
;
1978 if (!(objW
= heap_alloc( sizeof(OBJECTS_AND_NAME_W
) )))
1979 return ERROR_NOT_ENOUGH_MEMORY
;
1981 objW
->ObjectsPresent
= objA
->ObjectsPresent
;
1982 objW
->ObjectType
= objA
->ObjectType
;
1983 objW
->ObjectTypeName
= strdupAW(objA
->ObjectTypeName
);
1984 objW
->InheritedObjectTypeName
= strdupAW(objA
->InheritedObjectTypeName
);
1985 objW
->ptstrName
= strdupAW(objA
->ptstrName
);
1988 *ptrustee_nameW
= (WCHAR
*)objW
;
1989 return ERROR_SUCCESS
;
1991 /* These forms do not require conversion. */
1992 case TRUSTEE_IS_SID
:
1993 case TRUSTEE_IS_OBJECTS_AND_SID
:
1994 *ptrustee_nameW
= (WCHAR
*)trustee_nameA
;
1995 return ERROR_SUCCESS
;
1997 return ERROR_INVALID_PARAMETER
;
2001 static void free_trustee_name(TRUSTEE_FORM form
, WCHAR
*trustee_nameW
)
2005 case TRUSTEE_IS_NAME
:
2006 heap_free( trustee_nameW
);
2008 case TRUSTEE_IS_OBJECTS_AND_NAME
:
2010 OBJECTS_AND_NAME_W
*objW
= (OBJECTS_AND_NAME_W
*)trustee_nameW
;
2014 heap_free( objW
->ptstrName
);
2015 heap_free( objW
->InheritedObjectTypeName
);
2016 heap_free( objW
->ObjectTypeName
);
2022 /* Other forms did not require allocation, so no freeing is necessary. */
2028 static DWORD
trustee_to_sid( DWORD nDestinationSidLength
, PSID pDestinationSid
, PTRUSTEEW pTrustee
)
2030 if (pTrustee
->MultipleTrusteeOperation
== TRUSTEE_IS_IMPERSONATE
)
2032 WARN("bad multiple trustee operation %d\n", pTrustee
->MultipleTrusteeOperation
);
2033 return ERROR_INVALID_PARAMETER
;
2036 switch (pTrustee
->TrusteeForm
)
2038 case TRUSTEE_IS_SID
:
2039 if (!CopySid(nDestinationSidLength
, pDestinationSid
, pTrustee
->ptstrName
))
2041 WARN("bad sid %p\n", pTrustee
->ptstrName
);
2042 return ERROR_INVALID_PARAMETER
;
2045 case TRUSTEE_IS_NAME
:
2047 DWORD sid_size
= nDestinationSidLength
;
2048 DWORD domain_size
= MAX_COMPUTERNAME_LENGTH
+ 1;
2050 if (!wcscmp( pTrustee
->ptstrName
, L
"CURRENT_USER" ))
2052 if (!lookup_user_account_name( pDestinationSid
, &sid_size
, NULL
, &domain_size
, &use
))
2054 return GetLastError();
2057 else if (!LookupAccountNameW(NULL
, pTrustee
->ptstrName
, pDestinationSid
, &sid_size
, NULL
, &domain_size
, &use
))
2059 WARN("bad user name %s\n", debugstr_w(pTrustee
->ptstrName
));
2060 return ERROR_INVALID_PARAMETER
;
2064 case TRUSTEE_IS_OBJECTS_AND_SID
:
2065 FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
2067 case TRUSTEE_IS_OBJECTS_AND_NAME
:
2068 FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
2071 WARN("bad trustee form %d\n", pTrustee
->TrusteeForm
);
2072 return ERROR_INVALID_PARAMETER
;
2075 return ERROR_SUCCESS
;
2078 /******************************************************************************
2079 * SetEntriesInAclA [ADVAPI32.@]
2081 DWORD WINAPI
SetEntriesInAclA( ULONG count
, PEXPLICIT_ACCESSA pEntries
,
2082 PACL OldAcl
, PACL
* NewAcl
)
2084 DWORD err
= ERROR_SUCCESS
;
2085 EXPLICIT_ACCESSW
*pEntriesW
;
2086 UINT alloc_index
, free_index
;
2088 TRACE("%d %p %p %p\n", count
, pEntries
, OldAcl
, NewAcl
);
2093 if (!count
&& !OldAcl
)
2094 return ERROR_SUCCESS
;
2096 pEntriesW
= heap_alloc( count
* sizeof(EXPLICIT_ACCESSW
) );
2098 return ERROR_NOT_ENOUGH_MEMORY
;
2100 for (alloc_index
= 0; alloc_index
< count
; ++alloc_index
)
2102 pEntriesW
[alloc_index
].grfAccessPermissions
= pEntries
[alloc_index
].grfAccessPermissions
;
2103 pEntriesW
[alloc_index
].grfAccessMode
= pEntries
[alloc_index
].grfAccessMode
;
2104 pEntriesW
[alloc_index
].grfInheritance
= pEntries
[alloc_index
].grfInheritance
;
2105 pEntriesW
[alloc_index
].Trustee
.pMultipleTrustee
= NULL
; /* currently not supported */
2106 pEntriesW
[alloc_index
].Trustee
.MultipleTrusteeOperation
= pEntries
[alloc_index
].Trustee
.MultipleTrusteeOperation
;
2107 pEntriesW
[alloc_index
].Trustee
.TrusteeForm
= pEntries
[alloc_index
].Trustee
.TrusteeForm
;
2108 pEntriesW
[alloc_index
].Trustee
.TrusteeType
= pEntries
[alloc_index
].Trustee
.TrusteeType
;
2110 err
= trustee_name_A_to_W( pEntries
[alloc_index
].Trustee
.TrusteeForm
,
2111 pEntries
[alloc_index
].Trustee
.ptstrName
,
2112 &pEntriesW
[alloc_index
].Trustee
.ptstrName
);
2113 if (err
!= ERROR_SUCCESS
)
2115 if (err
== ERROR_INVALID_PARAMETER
)
2116 WARN("bad trustee form %d for trustee %d\n",
2117 pEntries
[alloc_index
].Trustee
.TrusteeForm
, alloc_index
);
2123 err
= SetEntriesInAclW( count
, pEntriesW
, OldAcl
, NewAcl
);
2126 /* Free any previously allocated trustee name buffers, taking into account
2127 * a possible out-of-memory condition while building the EXPLICIT_ACCESSW
2129 for (free_index
= 0; free_index
< alloc_index
; ++free_index
)
2130 free_trustee_name( pEntriesW
[free_index
].Trustee
.TrusteeForm
, pEntriesW
[free_index
].Trustee
.ptstrName
);
2132 heap_free( pEntriesW
);
2136 /******************************************************************************
2137 * SetEntriesInAclW [ADVAPI32.@]
2139 DWORD WINAPI
SetEntriesInAclW( ULONG count
, PEXPLICIT_ACCESSW pEntries
,
2140 PACL OldAcl
, PACL
* NewAcl
)
2144 DWORD ret
= ERROR_SUCCESS
;
2145 DWORD acl_size
= sizeof(ACL
);
2148 TRACE("%d %p %p %p\n", count
, pEntries
, OldAcl
, NewAcl
);
2153 if (!count
&& !OldAcl
)
2154 return ERROR_SUCCESS
;
2156 /* allocate array of maximum sized sids allowed */
2157 ppsid
= heap_alloc(count
* (sizeof(SID
*) + FIELD_OFFSET(SID
, SubAuthority
[SID_MAX_SUB_AUTHORITIES
])));
2159 return ERROR_OUTOFMEMORY
;
2161 for (i
= 0; i
< count
; i
++)
2163 ppsid
[i
] = (char *)&ppsid
[count
] + i
* FIELD_OFFSET(SID
, SubAuthority
[SID_MAX_SUB_AUTHORITIES
]);
2165 TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
2166 "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
2167 "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i
,
2168 pEntries
[i
].grfAccessPermissions
, pEntries
[i
].grfAccessMode
, pEntries
[i
].grfInheritance
,
2169 pEntries
[i
].Trustee
.pMultipleTrustee
, pEntries
[i
].Trustee
.MultipleTrusteeOperation
,
2170 pEntries
[i
].Trustee
.TrusteeForm
, pEntries
[i
].Trustee
.TrusteeType
,
2171 pEntries
[i
].Trustee
.ptstrName
);
2173 ret
= trustee_to_sid( FIELD_OFFSET(SID
, SubAuthority
[SID_MAX_SUB_AUTHORITIES
]), ppsid
[i
], &pEntries
[i
].Trustee
);
2177 /* Note: we overestimate the ACL size here as a tradeoff between
2178 * instructions (simplicity) and memory */
2179 switch (pEntries
[i
].grfAccessMode
)
2183 acl_size
+= FIELD_OFFSET(ACCESS_ALLOWED_ACE
, SidStart
) + GetLengthSid(ppsid
[i
]);
2186 acl_size
+= FIELD_OFFSET(ACCESS_DENIED_ACE
, SidStart
) + GetLengthSid(ppsid
[i
]);
2188 case SET_AUDIT_SUCCESS
:
2189 case SET_AUDIT_FAILURE
:
2190 acl_size
+= FIELD_OFFSET(SYSTEM_AUDIT_ACE
, SidStart
) + GetLengthSid(ppsid
[i
]);
2195 WARN("bad access mode %d for trustee %d\n", pEntries
[i
].grfAccessMode
, i
);
2196 ret
= ERROR_INVALID_PARAMETER
;
2203 ACL_SIZE_INFORMATION size_info
;
2205 status
= RtlQueryInformationAcl(OldAcl
, &size_info
, sizeof(size_info
), AclSizeInformation
);
2206 if (status
!= STATUS_SUCCESS
)
2208 ret
= RtlNtStatusToDosError(status
);
2211 acl_size
+= size_info
.AclBytesInUse
- sizeof(ACL
);
2214 *NewAcl
= LocalAlloc(0, acl_size
);
2217 ret
= ERROR_OUTOFMEMORY
;
2221 status
= RtlCreateAcl( *NewAcl
, acl_size
, ACL_REVISION
);
2222 if (status
!= STATUS_SUCCESS
)
2224 ret
= RtlNtStatusToDosError(status
);
2228 for (i
= 0; i
< count
; i
++)
2230 switch (pEntries
[i
].grfAccessMode
)
2233 status
= RtlAddAccessAllowedAceEx(*NewAcl
, ACL_REVISION
,
2234 pEntries
[i
].grfInheritance
,
2235 pEntries
[i
].grfAccessPermissions
,
2246 const ACE_HEADER
*existing_ace_header
;
2247 status
= RtlGetAce(OldAcl
, j
, (LPVOID
*)&existing_ace_header
);
2248 if (status
!= STATUS_SUCCESS
)
2250 if (pEntries
[i
].grfAccessMode
== SET_ACCESS
&&
2251 existing_ace_header
->AceType
== ACCESS_ALLOWED_ACE_TYPE
&&
2252 EqualSid(ppsid
[i
], &((ACCESS_ALLOWED_ACE
*)existing_ace_header
)->SidStart
))
2260 status
= RtlAddAccessAllowedAceEx(*NewAcl
, ACL_REVISION
,
2261 pEntries
[i
].grfInheritance
,
2262 pEntries
[i
].grfAccessPermissions
,
2267 status
= RtlAddAccessDeniedAceEx(*NewAcl
, ACL_REVISION
,
2268 pEntries
[i
].grfInheritance
,
2269 pEntries
[i
].grfAccessPermissions
,
2272 case SET_AUDIT_SUCCESS
:
2273 status
= RtlAddAuditAccessAceEx(*NewAcl
, ACL_REVISION
,
2274 pEntries
[i
].grfInheritance
,
2275 pEntries
[i
].grfAccessPermissions
,
2276 ppsid
[i
], TRUE
, FALSE
);
2278 case SET_AUDIT_FAILURE
:
2279 status
= RtlAddAuditAccessAceEx(*NewAcl
, ACL_REVISION
,
2280 pEntries
[i
].grfInheritance
,
2281 pEntries
[i
].grfAccessPermissions
,
2282 ppsid
[i
], FALSE
, TRUE
);
2285 FIXME("unhandled access mode %d\n", pEntries
[i
].grfAccessMode
);
2295 const ACE_HEADER
*old_ace_header
;
2296 status
= RtlGetAce(OldAcl
, i
, (LPVOID
*)&old_ace_header
);
2297 if (status
!= STATUS_SUCCESS
) break;
2298 for (j
= 0; j
< count
; j
++)
2300 if (pEntries
[j
].grfAccessMode
== SET_ACCESS
&&
2301 old_ace_header
->AceType
== ACCESS_ALLOWED_ACE_TYPE
&&
2302 EqualSid(ppsid
[j
], &((ACCESS_ALLOWED_ACE
*)old_ace_header
)->SidStart
))
2304 status
= RtlAddAccessAllowedAceEx(*NewAcl
, ACL_REVISION
, pEntries
[j
].grfInheritance
, pEntries
[j
].grfAccessPermissions
, ppsid
[j
]);
2308 else if (pEntries
[j
].grfAccessMode
== REVOKE_ACCESS
)
2310 switch (old_ace_header
->AceType
)
2312 case ACCESS_ALLOWED_ACE_TYPE
:
2313 if (EqualSid(ppsid
[j
], &((ACCESS_ALLOWED_ACE
*)old_ace_header
)->SidStart
))
2316 case ACCESS_DENIED_ACE_TYPE
:
2317 /* REVOKE_ACCESS does not affect ACCESS_DENIED_ACE. */
2319 case SYSTEM_AUDIT_ACE_TYPE
:
2320 if (EqualSid(ppsid
[j
], &((SYSTEM_AUDIT_ACE
*)old_ace_header
)->SidStart
))
2323 case SYSTEM_ALARM_ACE_TYPE
:
2324 if (EqualSid(ppsid
[j
], &((SYSTEM_ALARM_ACE
*)old_ace_header
)->SidStart
))
2328 FIXME("unhandled ace type %d\n", old_ace_header
->AceType
);
2336 status
= RtlAddAce(*NewAcl
, ACL_REVISION
, 1, (PACE_HEADER
)old_ace_header
, old_ace_header
->AceSize
);
2337 if (status
!= STATUS_SUCCESS
)
2339 WARN("RtlAddAce failed with error 0x%08x\n", status
);
2340 ret
= RtlNtStatusToDosError(status
);
2351 /******************************************************************************
2352 * SetNamedSecurityInfoA [ADVAPI32.@]
2354 DWORD WINAPI
SetNamedSecurityInfoA(LPSTR pObjectName
,
2355 SE_OBJECT_TYPE ObjectType
, SECURITY_INFORMATION SecurityInfo
,
2356 PSID psidOwner
, PSID psidGroup
, PACL pDacl
, PACL pSacl
)
2361 TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName
), ObjectType
,
2362 SecurityInfo
, psidOwner
, psidGroup
, pDacl
, pSacl
);
2364 wstr
= strdupAW(pObjectName
);
2365 r
= SetNamedSecurityInfoW( wstr
, ObjectType
, SecurityInfo
, psidOwner
,
2366 psidGroup
, pDacl
, pSacl
);
2373 /******************************************************************************
2374 * SetNamedSecurityInfoW [ADVAPI32.@]
2376 DWORD WINAPI
SetNamedSecurityInfoW(LPWSTR pObjectName
,
2377 SE_OBJECT_TYPE ObjectType
, SECURITY_INFORMATION SecurityInfo
,
2378 PSID psidOwner
, PSID psidGroup
, PACL pDacl
, PACL pSacl
)
2384 TRACE( "%s %d %d %p %p %p %p\n", debugstr_w(pObjectName
), ObjectType
,
2385 SecurityInfo
, psidOwner
, psidGroup
, pDacl
, pSacl
);
2387 if (!pObjectName
) return ERROR_INVALID_PARAMETER
;
2389 if (SecurityInfo
& (OWNER_SECURITY_INFORMATION
|GROUP_SECURITY_INFORMATION
))
2390 access
|= WRITE_OWNER
;
2391 if (SecurityInfo
& DACL_SECURITY_INFORMATION
)
2392 access
|= WRITE_DAC
;
2393 if (SecurityInfo
& SACL_SECURITY_INFORMATION
)
2394 access
|= ACCESS_SYSTEM_SECURITY
;
2399 if (!(err
= get_security_service( pObjectName
, access
, &handle
)))
2401 err
= SetSecurityInfo( handle
, ObjectType
, SecurityInfo
, psidOwner
, psidGroup
, pDacl
, pSacl
);
2402 CloseServiceHandle( handle
);
2405 case SE_REGISTRY_KEY
:
2406 if (!(err
= get_security_regkey( pObjectName
, access
, &handle
)))
2408 err
= SetSecurityInfo( handle
, ObjectType
, SecurityInfo
, psidOwner
, psidGroup
, pDacl
, pSacl
);
2409 RegCloseKey( handle
);
2412 case SE_FILE_OBJECT
:
2413 if (SecurityInfo
& DACL_SECURITY_INFORMATION
)
2414 access
|= READ_CONTROL
;
2415 if (!(err
= get_security_file( pObjectName
, access
, &handle
)))
2417 err
= SetSecurityInfo( handle
, ObjectType
, SecurityInfo
, psidOwner
, psidGroup
, pDacl
, pSacl
);
2418 CloseHandle( handle
);
2422 FIXME( "Object type %d is not currently supported.\n", ObjectType
);
2423 return ERROR_SUCCESS
;
2428 /******************************************************************************
2429 * GetExplicitEntriesFromAclA [ADVAPI32.@]
2431 DWORD WINAPI
GetExplicitEntriesFromAclA( PACL pacl
, PULONG pcCountOfExplicitEntries
,
2432 PEXPLICIT_ACCESSA
* pListOfExplicitEntries
)
2434 FIXME("%p %p %p\n",pacl
, pcCountOfExplicitEntries
, pListOfExplicitEntries
);
2435 return ERROR_CALL_NOT_IMPLEMENTED
;
2438 /******************************************************************************
2439 * GetExplicitEntriesFromAclW [ADVAPI32.@]
2441 DWORD WINAPI
GetExplicitEntriesFromAclW( PACL pacl
, PULONG count
, PEXPLICIT_ACCESSW
*list
)
2443 ACL_SIZE_INFORMATION sizeinfo
;
2444 EXPLICIT_ACCESSW
*entries
;
2445 MAX_SID
*sid_entries
;
2450 TRACE("%p %p %p\n",pacl
, count
, list
);
2452 if (!count
|| !list
)
2453 return ERROR_INVALID_PARAMETER
;
2455 status
= RtlQueryInformationAcl(pacl
, &sizeinfo
, sizeof(sizeinfo
), AclSizeInformation
);
2456 if (status
) return RtlNtStatusToDosError(status
);
2458 if (!sizeinfo
.AceCount
)
2462 return ERROR_SUCCESS
;
2465 entries
= LocalAlloc(LMEM_FIXED
| LMEM_ZEROINIT
, (sizeof(EXPLICIT_ACCESSW
) + sizeof(MAX_SID
)) * sizeinfo
.AceCount
);
2466 if (!entries
) return ERROR_OUTOFMEMORY
;
2467 sid_entries
= (MAX_SID
*)(entries
+ sizeinfo
.AceCount
);
2469 for (i
= 0; i
< sizeinfo
.AceCount
; i
++)
2471 status
= RtlGetAce(pacl
, i
, (void**)&ace
);
2472 if (status
) goto error
;
2474 switch (ace
->AceType
)
2476 case ACCESS_ALLOWED_ACE_TYPE
:
2478 ACCESS_ALLOWED_ACE
*allow
= (ACCESS_ALLOWED_ACE
*)ace
;
2479 entries
[i
].grfAccessMode
= GRANT_ACCESS
;
2480 entries
[i
].grfInheritance
= ace
->AceFlags
;
2481 entries
[i
].grfAccessPermissions
= allow
->Mask
;
2483 CopySid(sizeof(MAX_SID
), (PSID
)&sid_entries
[i
], (PSID
)&allow
->SidStart
);
2484 entries
[i
].Trustee
.pMultipleTrustee
= NULL
;
2485 entries
[i
].Trustee
.MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2486 entries
[i
].Trustee
.TrusteeForm
= TRUSTEE_IS_SID
;
2487 entries
[i
].Trustee
.TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2488 entries
[i
].Trustee
.ptstrName
= (WCHAR
*)&sid_entries
[i
];
2492 case ACCESS_DENIED_ACE_TYPE
:
2494 ACCESS_DENIED_ACE
*deny
= (ACCESS_DENIED_ACE
*)ace
;
2495 entries
[i
].grfAccessMode
= DENY_ACCESS
;
2496 entries
[i
].grfInheritance
= ace
->AceFlags
;
2497 entries
[i
].grfAccessPermissions
= deny
->Mask
;
2499 CopySid(sizeof(MAX_SID
), (PSID
)&sid_entries
[i
], (PSID
)&deny
->SidStart
);
2500 entries
[i
].Trustee
.pMultipleTrustee
= NULL
;
2501 entries
[i
].Trustee
.MultipleTrusteeOperation
= NO_MULTIPLE_TRUSTEE
;
2502 entries
[i
].Trustee
.TrusteeForm
= TRUSTEE_IS_SID
;
2503 entries
[i
].Trustee
.TrusteeType
= TRUSTEE_IS_UNKNOWN
;
2504 entries
[i
].Trustee
.ptstrName
= (WCHAR
*)&sid_entries
[i
];
2509 FIXME("Unhandled ace type %d\n", ace
->AceType
);
2510 entries
[i
].grfAccessMode
= NOT_USED_ACCESS
;
2515 *count
= sizeinfo
.AceCount
;
2517 return ERROR_SUCCESS
;
2521 return RtlNtStatusToDosError(status
);
2524 /******************************************************************************
2525 * GetAuditedPermissionsFromAclA [ADVAPI32.@]
2527 DWORD WINAPI
GetAuditedPermissionsFromAclA( PACL pacl
, PTRUSTEEA pTrustee
, PACCESS_MASK pSuccessfulAuditedRights
,
2528 PACCESS_MASK pFailedAuditRights
)
2530 FIXME("%p %p %p %p\n",pacl
, pTrustee
, pSuccessfulAuditedRights
, pFailedAuditRights
);
2531 return ERROR_CALL_NOT_IMPLEMENTED
;
2535 /******************************************************************************
2536 * GetAuditedPermissionsFromAclW [ADVAPI32.@]
2538 DWORD WINAPI
GetAuditedPermissionsFromAclW( PACL pacl
, PTRUSTEEW pTrustee
, PACCESS_MASK pSuccessfulAuditedRights
,
2539 PACCESS_MASK pFailedAuditRights
)
2541 FIXME("%p %p %p %p\n",pacl
, pTrustee
, pSuccessfulAuditedRights
, pFailedAuditRights
);
2542 return ERROR_CALL_NOT_IMPLEMENTED
;
2546 /******************************************************************************
2547 * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
2549 BOOL WINAPI
ConvertStringSecurityDescriptorToSecurityDescriptorA(
2550 LPCSTR StringSecurityDescriptor
,
2551 DWORD StringSDRevision
,
2552 PSECURITY_DESCRIPTOR
* SecurityDescriptor
,
2553 PULONG SecurityDescriptorSize
)
2556 LPWSTR StringSecurityDescriptorW
;
2558 TRACE("%s, %u, %p, %p\n", debugstr_a(StringSecurityDescriptor
), StringSDRevision
,
2559 SecurityDescriptor
, SecurityDescriptorSize
);
2561 if(!StringSecurityDescriptor
)
2564 StringSecurityDescriptorW
= strdupAW(StringSecurityDescriptor
);
2565 ret
= ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW
,
2566 StringSDRevision
, SecurityDescriptor
,
2567 SecurityDescriptorSize
);
2568 heap_free(StringSecurityDescriptorW
);
2573 /******************************************************************************
2574 * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
2576 BOOL WINAPI
ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor
, DWORD SDRevision
, SECURITY_INFORMATION Information
, LPSTR
*OutputString
, PULONG OutputLen
)
2580 if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor
, SDRevision
, Information
, &wstr
, &len
))
2584 lenA
= WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, NULL
, 0, NULL
, NULL
);
2585 *OutputString
= heap_alloc(lenA
);
2586 WideCharToMultiByte(CP_ACP
, 0, wstr
, len
, *OutputString
, lenA
, NULL
, NULL
);
2589 if (OutputLen
!= NULL
)
2595 *OutputString
= NULL
;
2602 /******************************************************************************
2603 * ConvertStringSidToSidA [ADVAPI32.@]
2605 BOOL WINAPI
ConvertStringSidToSidA(LPCSTR StringSid
, PSID
* Sid
)
2609 TRACE("%s, %p\n", debugstr_a(StringSid
), Sid
);
2610 if (GetVersion() & 0x80000000)
2611 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
2612 else if (!StringSid
|| !Sid
)
2613 SetLastError(ERROR_INVALID_PARAMETER
);
2616 WCHAR
*wStringSid
= strdupAW(StringSid
);
2617 bret
= ConvertStringSidToSidW(wStringSid
, Sid
);
2618 heap_free(wStringSid
);
2623 /******************************************************************************
2624 * ConvertSidToStringSidA [ADVAPI32.@]
2626 BOOL WINAPI
ConvertSidToStringSidA(PSID pSid
, LPSTR
*pstr
)
2632 TRACE("%p %p\n", pSid
, pstr
);
2634 if( !ConvertSidToStringSidW( pSid
, &wstr
) )
2637 len
= WideCharToMultiByte( CP_ACP
, 0, wstr
, -1, NULL
, 0, NULL
, NULL
);
2638 str
= LocalAlloc( 0, len
);
2639 WideCharToMultiByte( CP_ACP
, 0, wstr
, -1, str
, len
, NULL
, NULL
);
2647 /******************************************************************************
2648 * CreateProcessWithLogonW
2650 BOOL WINAPI
CreateProcessWithLogonW( LPCWSTR lpUsername
, LPCWSTR lpDomain
, LPCWSTR lpPassword
, DWORD dwLogonFlags
,
2651 LPCWSTR lpApplicationName
, LPWSTR lpCommandLine
, DWORD dwCreationFlags
, LPVOID lpEnvironment
,
2652 LPCWSTR lpCurrentDirectory
, LPSTARTUPINFOW lpStartupInfo
, LPPROCESS_INFORMATION lpProcessInformation
)
2654 FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername
), debugstr_w(lpDomain
),
2655 debugstr_w(lpPassword
), dwLogonFlags
, debugstr_w(lpApplicationName
),
2656 debugstr_w(lpCommandLine
), dwCreationFlags
, lpEnvironment
, debugstr_w(lpCurrentDirectory
),
2657 lpStartupInfo
, lpProcessInformation
);
2662 BOOL WINAPI
CreateProcessWithTokenW(HANDLE token
, DWORD logon_flags
, LPCWSTR application_name
, LPWSTR command_line
,
2663 DWORD creation_flags
, void *environment
, LPCWSTR current_directory
, STARTUPINFOW
*startup_info
,
2664 PROCESS_INFORMATION
*process_information
)
2666 FIXME("%p 0x%08x %s %s 0x%08x %p %s %p %p - semi-stub\n", token
,
2667 logon_flags
, debugstr_w(application_name
), debugstr_w(command_line
),
2668 creation_flags
, environment
, debugstr_w(current_directory
),
2669 startup_info
, process_information
);
2671 /* FIXME: check if handles should be inherited */
2672 return CreateProcessW( application_name
, command_line
, NULL
, NULL
, FALSE
, creation_flags
, environment
,
2673 current_directory
, startup_info
, process_information
);
2676 /******************************************************************************
2677 * GetNamedSecurityInfoA [ADVAPI32.@]
2679 DWORD WINAPI
GetNamedSecurityInfoA(LPSTR pObjectName
,
2680 SE_OBJECT_TYPE ObjectType
, SECURITY_INFORMATION SecurityInfo
,
2681 PSID
* ppsidOwner
, PSID
* ppsidGroup
, PACL
* ppDacl
, PACL
* ppSacl
,
2682 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
2687 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName
, ObjectType
, SecurityInfo
,
2688 ppsidOwner
, ppsidGroup
, ppDacl
, ppSacl
, ppSecurityDescriptor
);
2690 wstr
= strdupAW(pObjectName
);
2691 r
= GetNamedSecurityInfoW( wstr
, ObjectType
, SecurityInfo
, ppsidOwner
,
2692 ppsidGroup
, ppDacl
, ppSacl
, ppSecurityDescriptor
);
2699 /******************************************************************************
2700 * GetNamedSecurityInfoW [ADVAPI32.@]
2702 DWORD WINAPI
GetNamedSecurityInfoW( LPWSTR name
, SE_OBJECT_TYPE type
,
2703 SECURITY_INFORMATION info
, PSID
* owner
, PSID
* group
, PACL
* dacl
,
2704 PACL
* sacl
, PSECURITY_DESCRIPTOR
* descriptor
)
2710 TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name
), type
, info
, owner
,
2711 group
, dacl
, sacl
, descriptor
);
2713 /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
2714 if (!name
|| !(owner
||group
||dacl
||sacl
||descriptor
) ) return ERROR_INVALID_PARAMETER
;
2716 /* If no descriptor, we have to check that there's a pointer for the requested information */
2717 if( !descriptor
&& (
2718 ((info
& OWNER_SECURITY_INFORMATION
) && !owner
)
2719 || ((info
& GROUP_SECURITY_INFORMATION
) && !group
)
2720 || ((info
& DACL_SECURITY_INFORMATION
) && !dacl
)
2721 || ((info
& SACL_SECURITY_INFORMATION
) && !sacl
) ))
2722 return ERROR_INVALID_PARAMETER
;
2724 if (info
& (OWNER_SECURITY_INFORMATION
|GROUP_SECURITY_INFORMATION
|DACL_SECURITY_INFORMATION
))
2725 access
|= READ_CONTROL
;
2726 if (info
& SACL_SECURITY_INFORMATION
)
2727 access
|= ACCESS_SYSTEM_SECURITY
;
2732 if (!(err
= get_security_service( name
, access
, &handle
)))
2734 err
= GetSecurityInfo( handle
, type
, info
, owner
, group
, dacl
, sacl
, descriptor
);
2735 CloseServiceHandle( handle
);
2738 case SE_REGISTRY_KEY
:
2739 if (!(err
= get_security_regkey( name
, access
, &handle
)))
2741 err
= GetSecurityInfo( handle
, type
, info
, owner
, group
, dacl
, sacl
, descriptor
);
2742 RegCloseKey( handle
);
2745 case SE_FILE_OBJECT
:
2746 if (!(err
= get_security_file( name
, access
, &handle
)))
2748 err
= GetSecurityInfo( handle
, type
, info
, owner
, group
, dacl
, sacl
, descriptor
);
2749 CloseHandle( handle
);
2753 FIXME( "Object type %d is not currently supported.\n", type
);
2754 if (owner
) *owner
= NULL
;
2755 if (group
) *group
= NULL
;
2756 if (dacl
) *dacl
= NULL
;
2757 if (sacl
) *sacl
= NULL
;
2758 if (descriptor
) *descriptor
= NULL
;
2759 return ERROR_SUCCESS
;
2764 /******************************************************************************
2765 * GetNamedSecurityInfoExW [ADVAPI32.@]
2767 DWORD WINAPI
GetNamedSecurityInfoExW( LPCWSTR object
, SE_OBJECT_TYPE type
,
2768 SECURITY_INFORMATION info
, LPCWSTR provider
, LPCWSTR property
,
2769 PACTRL_ACCESSW
* access_list
, PACTRL_AUDITW
* audit_list
, LPWSTR
* owner
, LPWSTR
* group
)
2771 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_w(object
), type
, info
,
2772 debugstr_w(provider
), debugstr_w(property
), access_list
, audit_list
, owner
, group
);
2773 return ERROR_CALL_NOT_IMPLEMENTED
;
2776 /******************************************************************************
2777 * GetNamedSecurityInfoExA [ADVAPI32.@]
2779 DWORD WINAPI
GetNamedSecurityInfoExA( LPCSTR object
, SE_OBJECT_TYPE type
,
2780 SECURITY_INFORMATION info
, LPCSTR provider
, LPCSTR property
,
2781 PACTRL_ACCESSA
* access_list
, PACTRL_AUDITA
* audit_list
, LPSTR
* owner
, LPSTR
* group
)
2783 FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_a(object
), type
, info
,
2784 debugstr_a(provider
), debugstr_a(property
), access_list
, audit_list
, owner
, group
);
2785 return ERROR_CALL_NOT_IMPLEMENTED
;
2788 /******************************************************************************
2789 * DecryptFileW [ADVAPI32.@]
2791 BOOL WINAPI
DecryptFileW(LPCWSTR lpFileName
, DWORD dwReserved
)
2793 FIXME("(%s, %08x): stub\n", debugstr_w(lpFileName
), dwReserved
);
2797 /******************************************************************************
2798 * DecryptFileA [ADVAPI32.@]
2800 BOOL WINAPI
DecryptFileA(LPCSTR lpFileName
, DWORD dwReserved
)
2802 FIXME("(%s, %08x): stub\n", debugstr_a(lpFileName
), dwReserved
);
2806 /******************************************************************************
2807 * EncryptFileW [ADVAPI32.@]
2809 BOOL WINAPI
EncryptFileW(LPCWSTR lpFileName
)
2811 FIXME("(%s): stub\n", debugstr_w(lpFileName
));
2815 /******************************************************************************
2816 * EncryptFileA [ADVAPI32.@]
2818 BOOL WINAPI
EncryptFileA(LPCSTR lpFileName
)
2820 FIXME("(%s): stub\n", debugstr_a(lpFileName
));
2824 /******************************************************************************
2825 * FileEncryptionStatusW [ADVAPI32.@]
2827 BOOL WINAPI
FileEncryptionStatusW(LPCWSTR lpFileName
, LPDWORD lpStatus
)
2829 FIXME("(%s %p): stub\n", debugstr_w(lpFileName
), lpStatus
);
2832 *lpStatus
= FILE_SYSTEM_NOT_SUPPORT
;
2836 /******************************************************************************
2837 * FileEncryptionStatusA [ADVAPI32.@]
2839 BOOL WINAPI
FileEncryptionStatusA(LPCSTR lpFileName
, LPDWORD lpStatus
)
2841 FIXME("(%s %p): stub\n", debugstr_a(lpFileName
), lpStatus
);
2844 *lpStatus
= FILE_SYSTEM_NOT_SUPPORT
;
2848 static NTSTATUS
combine_dacls(ACL
*parent
, ACL
*child
, ACL
**result
)
2854 /* initialize a combined DACL containing both inherited and new ACEs */
2855 combined
= heap_alloc_zero(child
->AclSize
+parent
->AclSize
);
2857 return STATUS_NO_MEMORY
;
2859 status
= RtlCreateAcl(combined
, parent
->AclSize
+child
->AclSize
, ACL_REVISION
);
2860 if (status
!= STATUS_SUCCESS
)
2862 heap_free(combined
);
2866 /* copy the new ACEs */
2867 for (i
=0; i
<child
->AceCount
; i
++)
2871 if (!GetAce(child
, i
, (void*)&ace
))
2873 if (!AddAce(combined
, ACL_REVISION
, MAXDWORD
, ace
, ace
->AceSize
))
2874 WARN("error adding new ACE\n");
2877 /* copy the inherited ACEs */
2878 for (i
=0; i
<parent
->AceCount
; i
++)
2882 if (!GetAce(parent
, i
, (void*)&ace
))
2884 if (!(ace
->AceFlags
& (OBJECT_INHERIT_ACE
|CONTAINER_INHERIT_ACE
)))
2886 if ((ace
->AceFlags
& (OBJECT_INHERIT_ACE
|CONTAINER_INHERIT_ACE
)) !=
2887 (OBJECT_INHERIT_ACE
|CONTAINER_INHERIT_ACE
))
2889 FIXME("unsupported flags: %x\n", ace
->AceFlags
);
2893 if (ace
->AceFlags
& NO_PROPAGATE_INHERIT_ACE
)
2894 ace
->AceFlags
&= ~(OBJECT_INHERIT_ACE
|CONTAINER_INHERIT_ACE
|NO_PROPAGATE_INHERIT_ACE
);
2895 ace
->AceFlags
&= ~INHERIT_ONLY_ACE
;
2896 ace
->AceFlags
|= INHERITED_ACE
;
2898 if (!AddAce(combined
, ACL_REVISION
, MAXDWORD
, ace
, ace
->AceSize
))
2899 WARN("error adding inherited ACE\n");
2903 return STATUS_SUCCESS
;
2906 /******************************************************************************
2907 * SetSecurityInfo [ADVAPI32.@]
2909 DWORD WINAPI
SetSecurityInfo(HANDLE handle
, SE_OBJECT_TYPE ObjectType
,
2910 SECURITY_INFORMATION SecurityInfo
, PSID psidOwner
,
2911 PSID psidGroup
, PACL pDacl
, PACL pSacl
)
2913 SECURITY_DESCRIPTOR sd
;
2917 if (!InitializeSecurityDescriptor(&sd
, SECURITY_DESCRIPTOR_REVISION
))
2918 return ERROR_INVALID_SECURITY_DESCR
;
2920 if (SecurityInfo
& OWNER_SECURITY_INFORMATION
)
2921 SetSecurityDescriptorOwner(&sd
, psidOwner
, FALSE
);
2922 if (SecurityInfo
& GROUP_SECURITY_INFORMATION
)
2923 SetSecurityDescriptorGroup(&sd
, psidGroup
, FALSE
);
2924 if (SecurityInfo
& DACL_SECURITY_INFORMATION
)
2926 if (ObjectType
== SE_FILE_OBJECT
&& pDacl
)
2928 SECURITY_DESCRIPTOR_CONTROL control
;
2929 PSECURITY_DESCRIPTOR psd
;
2930 OBJECT_NAME_INFORMATION
*name_info
;
2933 status
= NtQuerySecurityObject(handle
, SecurityInfo
, NULL
, 0, &size
);
2934 if (status
!= STATUS_BUFFER_TOO_SMALL
)
2935 return RtlNtStatusToDosError(status
);
2937 psd
= heap_alloc(size
);
2939 return ERROR_NOT_ENOUGH_MEMORY
;
2941 status
= NtQuerySecurityObject(handle
, SecurityInfo
, psd
, size
, &size
);
2945 return RtlNtStatusToDosError(status
);
2948 status
= RtlGetControlSecurityDescriptor(psd
, &control
, &rev
);
2951 return RtlNtStatusToDosError(status
);
2952 /* TODO: copy some control flags to new sd */
2954 /* inherit parent directory DACL */
2955 if (!(control
& SE_DACL_PROTECTED
))
2957 status
= NtQueryObject(handle
, ObjectNameInformation
, NULL
, 0, &size
);
2958 if (status
!= STATUS_INFO_LENGTH_MISMATCH
)
2959 return RtlNtStatusToDosError(status
);
2961 name_info
= heap_alloc(size
);
2963 return ERROR_NOT_ENOUGH_MEMORY
;
2965 status
= NtQueryObject(handle
, ObjectNameInformation
, name_info
, size
, NULL
);
2968 heap_free(name_info
);
2969 return RtlNtStatusToDosError(status
);
2972 for (name_info
->Name
.Length
-=2; name_info
->Name
.Length
>0; name_info
->Name
.Length
-=2)
2973 if (name_info
->Name
.Buffer
[name_info
->Name
.Length
/2-1]=='\\' ||
2974 name_info
->Name
.Buffer
[name_info
->Name
.Length
/2-1]=='/')
2976 if (name_info
->Name
.Length
)
2978 OBJECT_ATTRIBUTES attr
;
2981 PSECURITY_DESCRIPTOR parent_sd
;
2983 DWORD err
= ERROR_ACCESS_DENIED
;
2985 name_info
->Name
.Buffer
[name_info
->Name
.Length
/2] = 0;
2987 attr
.Length
= sizeof(attr
);
2988 attr
.RootDirectory
= 0;
2989 attr
.Attributes
= 0;
2990 attr
.ObjectName
= &name_info
->Name
;
2991 attr
.SecurityDescriptor
= NULL
;
2992 status
= NtOpenFile(&parent
, READ_CONTROL
|SYNCHRONIZE
, &attr
, &io
,
2993 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
2994 FILE_OPEN_FOR_BACKUP_INTENT
);
2995 heap_free(name_info
);
2998 err
= GetSecurityInfo(parent
, SE_FILE_OBJECT
, DACL_SECURITY_INFORMATION
,
2999 NULL
, NULL
, &parent_dacl
, NULL
, &parent_sd
);
3000 CloseHandle(parent
);
3005 status
= combine_dacls(parent_dacl
, pDacl
, &dacl
);
3006 LocalFree(parent_sd
);
3007 if (status
!= STATUS_SUCCESS
)
3008 return RtlNtStatusToDosError(status
);
3012 heap_free(name_info
);
3016 SetSecurityDescriptorDacl(&sd
, TRUE
, dacl
, FALSE
);
3018 if (SecurityInfo
& SACL_SECURITY_INFORMATION
)
3019 SetSecurityDescriptorSacl(&sd
, TRUE
, pSacl
, FALSE
);
3024 FIXME("stub: Service objects are not supported at this time.\n");
3025 status
= STATUS_SUCCESS
; /* Implement SetServiceObjectSecurity */
3028 status
= NtSetSecurityObject(handle
, SecurityInfo
, &sd
);
3033 return RtlNtStatusToDosError(status
);
3036 /******************************************************************************
3037 * SaferCreateLevel [ADVAPI32.@]
3039 BOOL WINAPI
SaferCreateLevel(DWORD ScopeId
, DWORD LevelId
, DWORD OpenFlags
,
3040 SAFER_LEVEL_HANDLE
* LevelHandle
, LPVOID lpReserved
)
3042 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId
, LevelId
, OpenFlags
, LevelHandle
, lpReserved
);
3044 *LevelHandle
= (SAFER_LEVEL_HANDLE
)0xdeadbeef;
3048 /******************************************************************************
3049 * SaferComputeTokenFromLevel [ADVAPI32.@]
3051 BOOL WINAPI
SaferComputeTokenFromLevel(SAFER_LEVEL_HANDLE handle
, HANDLE token
, PHANDLE access_token
,
3052 DWORD flags
, LPVOID reserved
)
3054 FIXME("(%p, %p, %p, %x, %p) stub\n", handle
, token
, access_token
, flags
, reserved
);
3056 *access_token
= (flags
& SAFER_TOKEN_NULL_IF_EQUAL
) ? NULL
: (HANDLE
)0xdeadbeef;
3060 /******************************************************************************
3061 * SaferCloseLevel [ADVAPI32.@]
3063 BOOL WINAPI
SaferCloseLevel(SAFER_LEVEL_HANDLE handle
)
3065 FIXME("(%p) stub\n", handle
);
3069 /******************************************************************************
3070 * TreeResetNamedSecurityInfoW [ADVAPI32.@]
3072 DWORD WINAPI
TreeResetNamedSecurityInfoW( LPWSTR pObjectName
,
3073 SE_OBJECT_TYPE ObjectType
, SECURITY_INFORMATION SecurityInfo
,
3074 PSID pOwner
, PSID pGroup
, PACL pDacl
, PACL pSacl
,
3075 BOOL KeepExplicit
, FN_PROGRESS fnProgress
,
3076 PROG_INVOKE_SETTING ProgressInvokeSetting
, PVOID Args
)
3078 FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p) stub\n",
3079 debugstr_w(pObjectName
), ObjectType
, SecurityInfo
, pOwner
, pGroup
,
3080 pDacl
, pSacl
, KeepExplicit
, fnProgress
, ProgressInvokeSetting
, Args
);
3082 return ERROR_SUCCESS
;
3085 /******************************************************************************
3086 * SaferGetPolicyInformation [ADVAPI32.@]
3088 BOOL WINAPI
SaferGetPolicyInformation(DWORD scope
, SAFER_POLICY_INFO_CLASS
class, DWORD size
,
3089 PVOID buffer
, PDWORD required
, LPVOID lpReserved
)
3091 FIXME("(%u %u %u %p %p %p) stub\n", scope
, class, size
, buffer
, required
, lpReserved
);
3095 /******************************************************************************
3096 * SaferIdentifyLevel [ADVAPI32.@]
3098 BOOL WINAPI
SaferIdentifyLevel(DWORD count
, SAFER_CODE_PROPERTIES
*properties
, SAFER_LEVEL_HANDLE
*handle
,
3101 FIXME("(%u %p %p %p) stub\n", count
, properties
, handle
, reserved
);
3102 *handle
= (SAFER_LEVEL_HANDLE
)0xdeadbeef;
3106 /******************************************************************************
3107 * SaferSetLevelInformation [ADVAPI32.@]
3109 BOOL WINAPI
SaferSetLevelInformation(SAFER_LEVEL_HANDLE handle
, SAFER_OBJECT_INFO_CLASS infotype
,
3110 LPVOID buffer
, DWORD size
)
3112 FIXME("(%p %u %p %u) stub\n", handle
, infotype
, buffer
, size
);
3116 /******************************************************************************
3117 * LookupSecurityDescriptorPartsA [ADVAPI32.@]
3119 DWORD WINAPI
LookupSecurityDescriptorPartsA(TRUSTEEA
*owner
, TRUSTEEA
*group
, ULONG
*access_count
,
3120 EXPLICIT_ACCESSA
*access_list
, ULONG
*audit_count
,
3121 EXPLICIT_ACCESSA
*audit_list
, SECURITY_DESCRIPTOR
*descriptor
)
3123 FIXME("(%p %p %p %p %p %p %p) stub\n", owner
, group
, access_count
,
3124 access_list
, audit_count
, audit_list
, descriptor
);
3125 return ERROR_CALL_NOT_IMPLEMENTED
;
3128 /******************************************************************************
3129 * LookupSecurityDescriptorPartsW [ADVAPI32.@]
3131 DWORD WINAPI
LookupSecurityDescriptorPartsW(TRUSTEEW
*owner
, TRUSTEEW
*group
, ULONG
*access_count
,
3132 EXPLICIT_ACCESSW
*access_list
, ULONG
*audit_count
,
3133 EXPLICIT_ACCESSW
*audit_list
, SECURITY_DESCRIPTOR
*descriptor
)
3135 FIXME("(%p %p %p %p %p %p %p) stub\n", owner
, group
, access_count
,
3136 access_list
, audit_count
, audit_list
, descriptor
);
3137 return ERROR_CALL_NOT_IMPLEMENTED
;