2 * COPYRIGHT: See COPYING in the top level directory
4 * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
5 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
6 * Copyright 2006 Robert Reif
8 * PROJECT: ReactOS system libraries
9 * FILE: dll/win32/advapi32/sec/misc.c
10 * PURPOSE: Miscellaneous security functions (some ported from Wine)
14 #include "wine/unicode.h"
15 #include "wine/debug.h"
17 WINE_DEFAULT_DEBUG_CHANNEL(advapi
);
19 /* Needed for LookupAccountNameW implementation from Wine */
21 typedef struct _AccountSid
23 WELL_KNOWN_SID_TYPE type
;
26 SID_NAME_USE name_use
;
29 static const WCHAR Account_Operators
[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
30 static const WCHAR Administrator
[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
31 static const WCHAR Administrators
[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
32 static const WCHAR ANONYMOUS_LOGON
[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
33 static const WCHAR Authenticated_Users
[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
34 static const WCHAR Backup_Operators
[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
35 static const WCHAR BATCH
[] = { 'B','A','T','C','H',0 };
36 static const WCHAR Blank
[] = { 0 };
37 static const WCHAR BUILTIN
[] = { 'B','U','I','L','T','I','N',0 };
38 static const WCHAR Cert_Publishers
[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
39 static const WCHAR CREATOR_GROUP
[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
40 static const WCHAR CREATOR_GROUP_SERVER
[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',' ','S','E','R','V','E','R',0 };
41 static const WCHAR CREATOR_OWNER
[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
42 static const WCHAR CREATOR_OWNER_SERVER
[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',' ','S','E','R','V','E','R',0 };
43 static const WCHAR DIALUP
[] = { 'D','I','A','L','U','P',0 };
44 static const WCHAR Digest_Authentication
[] = { 'D','i','g','e','s','t',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
45 static const WCHAR DOMAIN
[] = {'D','O','M','A','I','N',0};
46 static const WCHAR Domain_Admins
[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
47 static const WCHAR Domain_Computers
[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
48 static const WCHAR Domain_Controllers
[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
49 static const WCHAR Domain_Guests
[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
50 static const WCHAR Domain_Users
[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
51 static const WCHAR Enterprise_Admins
[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
52 static const WCHAR ENTERPRISE_DOMAIN_CONTROLLERS
[] = { 'E','N','T','E','R','P','R','I','S','E',' ','D','O','M','A','I','N',' ','C','O','N','T','R','O','L','L','E','R','S',0 };
53 static const WCHAR Everyone
[] = { 'E','v','e','r','y','o','n','e',0 };
54 static const WCHAR Group_Policy_Creator_Owners
[] = { 'G','r','o','u','p',' ','P','o','l','i','c','y',' ','C','r','e','a','t','o','r',' ','O','w','n','e','r','s',0 };
55 static const WCHAR Guest
[] = { 'G','u','e','s','t',0 };
56 static const WCHAR Guests
[] = { 'G','u','e','s','t','s',0 };
57 static const WCHAR INTERACTIVE
[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
58 static const WCHAR LOCAL
[] = { 'L','O','C','A','L',0 };
59 static const WCHAR LOCAL_SERVICE
[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
60 static const WCHAR NETWORK
[] = { 'N','E','T','W','O','R','K',0 };
61 static const WCHAR Network_Configuration_Operators
[] = { 'N','e','t','w','o','r','k',' ','C','o','n','f','i','g','u','r','a','t','i','o','n',' ','O','p','e','r','a','t','o','r','s',0 };
62 static const WCHAR NETWORK_SERVICE
[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
63 static const WCHAR NT_AUTHORITY
[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
64 static const WCHAR NT_Pseudo_Domain
[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
65 static const WCHAR NTML_Authentication
[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
66 static const WCHAR NULL_SID
[] = { 'N','U','L','L',' ','S','I','D',0 };
67 static const WCHAR Other_Organization
[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
68 static const WCHAR Performance_Log_Users
[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','L','o','g',' ','U','s','e','r','s',0 };
69 static const WCHAR Performance_Monitor_Users
[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','M','o','n','i','t','o','r',' ','U','s','e','r','s',0 };
70 static const WCHAR Power_Users
[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
71 static const WCHAR Pre_Windows_2000_Compatible_Access
[] = { 'P','r','e','-','W','i','n','d','o','w','s',' ','2','0','0','0',' ','C','o','m','p','a','t','i','b','l','e',' ','A','c','c','e','s','s',0 };
72 static const WCHAR Print_Operators
[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
73 static const WCHAR PROXY
[] = { 'P','R','O','X','Y',0 };
74 static const WCHAR RAS_and_IAS_Servers
[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
75 static const WCHAR Remote_Desktop_Users
[] = { 'R','e','m','o','t','e',' ','D','e','s','k','t','o','p',' ','U','s','e','r','s',0 };
76 static const WCHAR REMOTE_INTERACTIVE_LOGON
[] = { 'R','E','M','O','T','E',' ','I','N','T','E','R','A','C','T','I','V','E',' ','L','O','G','O','N',0 };
77 static const WCHAR Replicators
[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
78 static const WCHAR RESTRICTED
[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
79 static const WCHAR SChannel_Authentication
[] = { 'S','C','h','a','n','n','e','l',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
80 static const WCHAR Schema_Admins
[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
81 static const WCHAR SELF
[] = { 'S','E','L','F',0 };
82 static const WCHAR Server_Operators
[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
83 static const WCHAR SERVICE
[] = { 'S','E','R','V','I','C','E',0 };
84 static const WCHAR SYSTEM
[] = { 'S','Y','S','T','E','M',0 };
85 static const WCHAR TERMINAL_SERVER_USER
[] = { 'T','E','R','M','I','N','A','L',' ','S','E','R','V','E','R',' ','U','S','E','R',0 };
86 static const WCHAR This_Organization
[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
87 static const WCHAR Users
[] = { 'U','s','e','r','s',0 };
89 static const AccountSid ACCOUNT_SIDS
[] = {
90 { WinNullSid
, NULL_SID
, Blank
, SidTypeWellKnownGroup
},
91 { WinWorldSid
, Everyone
, Blank
, SidTypeWellKnownGroup
},
92 { WinLocalSid
, LOCAL
, Blank
, SidTypeWellKnownGroup
},
93 { WinCreatorOwnerSid
, CREATOR_OWNER
, Blank
, SidTypeWellKnownGroup
},
94 { WinCreatorGroupSid
, CREATOR_GROUP
, Blank
, SidTypeWellKnownGroup
},
95 { WinCreatorOwnerServerSid
, CREATOR_OWNER_SERVER
, Blank
, SidTypeWellKnownGroup
},
96 { WinCreatorGroupServerSid
, CREATOR_GROUP_SERVER
, Blank
, SidTypeWellKnownGroup
},
97 { WinNtAuthoritySid
, NT_Pseudo_Domain
, NT_Pseudo_Domain
, SidTypeDomain
},
98 { WinDialupSid
, DIALUP
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
99 { WinNetworkSid
, NETWORK
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
100 { WinBatchSid
, BATCH
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
101 { WinInteractiveSid
, INTERACTIVE
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
102 { WinServiceSid
, SERVICE
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
103 { WinAnonymousSid
, ANONYMOUS_LOGON
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
104 { WinProxySid
, PROXY
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
105 { WinEnterpriseControllersSid
, ENTERPRISE_DOMAIN_CONTROLLERS
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
106 { WinSelfSid
, SELF
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
107 { WinAuthenticatedUserSid
, Authenticated_Users
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
108 { WinRestrictedCodeSid
, RESTRICTED
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
109 { WinTerminalServerSid
, TERMINAL_SERVER_USER
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
110 { WinRemoteLogonIdSid
, REMOTE_INTERACTIVE_LOGON
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
111 { WinLocalSystemSid
, SYSTEM
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
112 { WinLocalServiceSid
, LOCAL_SERVICE
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
113 { WinNetworkServiceSid
, NETWORK_SERVICE
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
114 { WinBuiltinDomainSid
, BUILTIN
, BUILTIN
, SidTypeDomain
},
115 { WinBuiltinAdministratorsSid
, Administrators
, BUILTIN
, SidTypeAlias
},
116 { WinBuiltinUsersSid
, Users
, BUILTIN
, SidTypeAlias
},
117 { WinBuiltinGuestsSid
, Guests
, BUILTIN
, SidTypeAlias
},
118 { WinBuiltinPowerUsersSid
, Power_Users
, BUILTIN
, SidTypeAlias
},
119 { WinBuiltinAccountOperatorsSid
, Account_Operators
, BUILTIN
, SidTypeAlias
},
120 { WinBuiltinSystemOperatorsSid
, Server_Operators
, BUILTIN
, SidTypeAlias
},
121 { WinBuiltinPrintOperatorsSid
, Print_Operators
, BUILTIN
, SidTypeAlias
},
122 { WinBuiltinBackupOperatorsSid
, Backup_Operators
, BUILTIN
, SidTypeAlias
},
123 { WinBuiltinReplicatorSid
, Replicators
, BUILTIN
, SidTypeAlias
},
124 { WinBuiltinPreWindows2000CompatibleAccessSid
, Pre_Windows_2000_Compatible_Access
, BUILTIN
, SidTypeAlias
},
125 { WinBuiltinRemoteDesktopUsersSid
, Remote_Desktop_Users
, BUILTIN
, SidTypeAlias
},
126 { WinBuiltinNetworkConfigurationOperatorsSid
, Network_Configuration_Operators
, BUILTIN
, SidTypeAlias
},
127 { WinNTLMAuthenticationSid
, NTML_Authentication
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
128 { WinDigestAuthenticationSid
, Digest_Authentication
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
129 { WinSChannelAuthenticationSid
, SChannel_Authentication
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
130 { WinThisOrganizationSid
, This_Organization
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
131 { WinOtherOrganizationSid
, Other_Organization
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
132 { WinBuiltinPerfMonitoringUsersSid
, Performance_Monitor_Users
, BUILTIN
, SidTypeAlias
},
133 { WinBuiltinPerfLoggingUsersSid
, Performance_Log_Users
, BUILTIN
, SidTypeAlias
},
137 /* Interface to ntmarta.dll ***************************************************/
139 NTMARTA NtMartaStatic
= { 0 };
140 static PNTMARTA NtMarta
= NULL
;
142 #define FindNtMartaProc(Name) \
143 NtMartaStatic.Name = (PVOID)GetProcAddress(NtMartaStatic.hDllInstance, \
145 if (NtMartaStatic.Name == NULL) \
147 return GetLastError(); \
152 LoadAndInitializeNtMarta(VOID
)
154 /* this code may be executed simultaneously by multiple threads in case they're
155 trying to initialize the interface at the same time, but that's no problem
156 because the pointers returned by GetProcAddress will be the same. However,
157 only one of the threads will change the NtMarta pointer to the NtMartaStatic
158 structure, the others threads will detect that there were other threads
159 initializing the structure faster and will release the reference to the
162 NtMartaStatic
.hDllInstance
= LoadLibraryW(L
"ntmarta.dll");
163 if (NtMartaStatic
.hDllInstance
== NULL
)
165 return GetLastError();
169 FindNtMartaProc(LookupAccountTrustee
);
170 FindNtMartaProc(LookupAccountName
);
171 FindNtMartaProc(LookupAccountSid
);
172 FindNtMartaProc(SetEntriesInAList
);
173 FindNtMartaProc(ConvertAccessToSecurityDescriptor
);
174 FindNtMartaProc(ConvertSDToAccess
);
175 FindNtMartaProc(ConvertAclToAccess
);
176 FindNtMartaProc(GetAccessForTrustee
);
177 FindNtMartaProc(GetExplicitEntries
);
179 FindNtMartaProc(RewriteGetNamedRights
);
180 FindNtMartaProc(RewriteSetNamedRights
);
181 FindNtMartaProc(RewriteGetHandleRights
);
182 FindNtMartaProc(RewriteSetHandleRights
);
183 FindNtMartaProc(RewriteSetEntriesInAcl
);
184 FindNtMartaProc(RewriteGetExplicitEntriesFromAcl
);
185 FindNtMartaProc(TreeResetNamedSecurityInfo
);
186 FindNtMartaProc(GetInheritanceSource
);
187 FindNtMartaProc(FreeIndexArray
);
189 return ERROR_SUCCESS
;
194 CheckNtMartaPresent(VOID
)
198 if (InterlockedCompareExchangePointer((PVOID
)&NtMarta
,
202 /* we're the first one trying to use ntmarta, initialize it and change
203 the pointer after initialization */
204 ErrorCode
= LoadAndInitializeNtMarta();
206 if (ErrorCode
== ERROR_SUCCESS
)
208 /* try change the NtMarta pointer */
209 if (InterlockedCompareExchangePointer((PVOID
)&NtMarta
,
213 /* another thread initialized ntmarta in the meanwhile, release
214 the reference of the dll loaded. */
215 FreeLibrary(NtMartaStatic
.hDllInstance
);
221 ERR("Failed to initialize ntmarta.dll! Error: 0x%x", ErrorCode
);
227 /* ntmarta was already initialized */
228 ErrorCode
= ERROR_SUCCESS
;
238 if (InterlockedExchangePointer((PVOID
)&NtMarta
,
241 FreeLibrary(NtMartaStatic
.hDllInstance
);
246 /******************************************************************************/
253 AreAllAccessesGranted(DWORD GrantedAccess
,
256 return (BOOL
)RtlAreAllAccessesGranted(GrantedAccess
,
266 AreAnyAccessesGranted(DWORD GrantedAccess
,
269 return (BOOL
)RtlAreAnyAccessesGranted(GrantedAccess
,
274 /************************************************************
275 * ADVAPI_IsLocalComputer
277 * Checks whether the server name indicates local machine.
279 BOOL
ADVAPI_IsLocalComputer(LPCWSTR ServerName
)
281 DWORD dwSize
= MAX_COMPUTERNAME_LENGTH
+ 1;
285 if (!ServerName
|| !ServerName
[0])
288 buf
= HeapAlloc(GetProcessHeap(), 0, dwSize
* sizeof(WCHAR
));
289 Result
= GetComputerNameW(buf
, &dwSize
);
290 if (Result
&& (ServerName
[0] == '\\') && (ServerName
[1] == '\\'))
292 Result
= Result
&& !lstrcmpW(ServerName
, buf
);
293 HeapFree(GetProcessHeap(), 0, buf
);
299 /******************************************************************************
300 * GetFileSecurityA [ADVAPI32.@]
302 * Obtains Specified information about the security of a file or directory.
305 * lpFileName [I] Name of the file to get info for
306 * RequestedInformation [I] SE_ flags from "winnt.h"
307 * pSecurityDescriptor [O] Destination for security information
308 * nLength [I] Length of pSecurityDescriptor
309 * lpnLengthNeeded [O] Destination for length of returned security information
312 * Success: TRUE. pSecurityDescriptor contains the requested information.
313 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
316 * The information returned is constrained by the callers access rights and
323 GetFileSecurityA(LPCSTR lpFileName
,
324 SECURITY_INFORMATION RequestedInformation
,
325 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
327 LPDWORD lpnLengthNeeded
)
329 UNICODE_STRING FileName
;
333 Status
= RtlCreateUnicodeStringFromAsciiz(&FileName
,
335 if (!NT_SUCCESS(Status
))
337 SetLastError(RtlNtStatusToDosError(Status
));
341 bResult
= GetFileSecurityW(FileName
.Buffer
,
342 RequestedInformation
,
347 RtlFreeUnicodeString(&FileName
);
358 GetFileSecurityW(LPCWSTR lpFileName
,
359 SECURITY_INFORMATION RequestedInformation
,
360 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
362 LPDWORD lpnLengthNeeded
)
364 OBJECT_ATTRIBUTES ObjectAttributes
;
365 IO_STATUS_BLOCK StatusBlock
;
366 UNICODE_STRING FileName
;
367 ULONG AccessMask
= 0;
371 TRACE("GetFileSecurityW() called\n");
373 QuerySecurityAccessMask(RequestedInformation
, &AccessMask
);
375 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
380 ERR("Invalid path\n");
381 SetLastError(ERROR_INVALID_NAME
);
385 InitializeObjectAttributes(&ObjectAttributes
,
387 OBJ_CASE_INSENSITIVE
,
391 Status
= NtOpenFile(&FileHandle
,
395 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
398 RtlFreeHeap(RtlGetProcessHeap(),
402 if (!NT_SUCCESS(Status
))
404 ERR("NtOpenFile() failed (Status %lx)\n", Status
);
405 SetLastError(RtlNtStatusToDosError(Status
));
409 Status
= NtQuerySecurityObject(FileHandle
,
410 RequestedInformation
,
415 if (!NT_SUCCESS(Status
))
417 ERR("NtQuerySecurityObject() failed (Status %lx)\n", Status
);
418 SetLastError(RtlNtStatusToDosError(Status
));
431 GetKernelObjectSecurity(HANDLE Handle
,
432 SECURITY_INFORMATION RequestedInformation
,
433 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
435 LPDWORD lpnLengthNeeded
)
439 Status
= NtQuerySecurityObject(Handle
,
440 RequestedInformation
,
444 if (!NT_SUCCESS(Status
))
446 SetLastError(RtlNtStatusToDosError(Status
));
454 /******************************************************************************
455 * SetFileSecurityA [ADVAPI32.@]
456 * Sets the security of a file or directory
462 SetFileSecurityA(LPCSTR lpFileName
,
463 SECURITY_INFORMATION SecurityInformation
,
464 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
466 UNICODE_STRING FileName
;
470 Status
= RtlCreateUnicodeStringFromAsciiz(&FileName
,
472 if (!NT_SUCCESS(Status
))
474 SetLastError(RtlNtStatusToDosError(Status
));
478 bResult
= SetFileSecurityW(FileName
.Buffer
,
480 pSecurityDescriptor
);
482 RtlFreeUnicodeString(&FileName
);
488 /******************************************************************************
489 * SetFileSecurityW [ADVAPI32.@]
490 * Sets the security of a file or directory
496 SetFileSecurityW(LPCWSTR lpFileName
,
497 SECURITY_INFORMATION SecurityInformation
,
498 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
500 OBJECT_ATTRIBUTES ObjectAttributes
;
501 IO_STATUS_BLOCK StatusBlock
;
502 UNICODE_STRING FileName
;
503 ULONG AccessMask
= 0;
507 TRACE("SetFileSecurityW() called\n");
509 SetSecurityAccessMask(SecurityInformation
, &AccessMask
);
511 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
516 ERR("Invalid path\n");
517 SetLastError(ERROR_INVALID_NAME
);
521 InitializeObjectAttributes(&ObjectAttributes
,
523 OBJ_CASE_INSENSITIVE
,
527 Status
= NtOpenFile(&FileHandle
,
531 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
534 RtlFreeHeap(RtlGetProcessHeap(),
538 if (!NT_SUCCESS(Status
))
540 ERR("NtOpenFile() failed (Status %lx)\n", Status
);
541 SetLastError(RtlNtStatusToDosError(Status
));
545 Status
= NtSetSecurityObject(FileHandle
,
547 pSecurityDescriptor
);
550 if (!NT_SUCCESS(Status
))
552 ERR("NtSetSecurityObject() failed (Status %lx)\n", Status
);
553 SetLastError(RtlNtStatusToDosError(Status
));
566 SetKernelObjectSecurity(HANDLE Handle
,
567 SECURITY_INFORMATION SecurityInformation
,
568 PSECURITY_DESCRIPTOR SecurityDescriptor
)
572 Status
= NtSetSecurityObject(Handle
,
575 if (!NT_SUCCESS(Status
))
577 SetLastError(RtlNtStatusToDosError(Status
));
590 ImpersonateAnonymousToken(IN HANDLE ThreadHandle
)
594 Status
= NtImpersonateAnonymousToken(ThreadHandle
);
595 if (!NT_SUCCESS(Status
))
597 SetLastError(RtlNtStatusToDosError(Status
));
610 ImpersonateLoggedOnUser(HANDLE hToken
)
612 SECURITY_QUALITY_OF_SERVICE Qos
;
613 OBJECT_ATTRIBUTES ObjectAttributes
;
620 /* Get the token type */
621 Status
= NtQueryInformationToken(hToken
,
626 if (!NT_SUCCESS(Status
))
628 SetLastError(RtlNtStatusToDosError(Status
));
632 if (Type
== TokenPrimary
)
634 /* Create a duplicate impersonation token */
635 Qos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
636 Qos
.ImpersonationLevel
= SecurityImpersonation
;
637 Qos
.ContextTrackingMode
= SECURITY_DYNAMIC_TRACKING
;
638 Qos
.EffectiveOnly
= FALSE
;
640 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
641 ObjectAttributes
.RootDirectory
= NULL
;
642 ObjectAttributes
.ObjectName
= NULL
;
643 ObjectAttributes
.Attributes
= 0;
644 ObjectAttributes
.SecurityDescriptor
= NULL
;
645 ObjectAttributes
.SecurityQualityOfService
= &Qos
;
647 Status
= NtDuplicateToken(hToken
,
648 TOKEN_IMPERSONATE
| TOKEN_QUERY
,
653 if (!NT_SUCCESS(Status
))
655 SetLastError(RtlNtStatusToDosError(Status
));
663 /* User the original impersonation token */
668 /* Impersonate the the current thread */
669 Status
= NtSetInformationThread(NtCurrentThread(),
670 ThreadImpersonationToken
,
674 if (Duplicated
== TRUE
)
679 if (!NT_SUCCESS(Status
))
681 SetLastError(RtlNtStatusToDosError(Status
));
694 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
698 Status
= RtlImpersonateSelf(ImpersonationLevel
);
699 if (!NT_SUCCESS(Status
))
701 SetLastError(RtlNtStatusToDosError(Status
));
719 Status
= NtSetInformationThread(NtCurrentThread(),
720 ThreadImpersonationToken
,
723 if (!NT_SUCCESS(Status
))
725 SetLastError(RtlNtStatusToDosError(Status
));
733 /******************************************************************************
734 * GetUserNameA [ADVAPI32.@]
736 * Get the current user name.
739 * lpszName [O] Destination for the user name.
740 * lpSize [I/O] Size of lpszName.
747 GetUserNameA(LPSTR lpszName
,
750 UNICODE_STRING NameW
;
754 /* apparently Win doesn't check whether lpSize is valid at all! */
756 NameW
.MaximumLength
= (*lpSize
) * sizeof(WCHAR
);
757 NameW
.Buffer
= LocalAlloc(LMEM_FIXED
, NameW
.MaximumLength
);
758 if(NameW
.Buffer
== NULL
)
760 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
765 NameA
.MaximumLength
= ((*lpSize
) < 0xFFFF ? (USHORT
)(*lpSize
) : 0xFFFF);
766 NameA
.Buffer
= lpszName
;
768 Ret
= GetUserNameW(NameW
.Buffer
,
772 NameW
.Length
= (*lpSize
- 1) * sizeof(WCHAR
);
773 RtlUnicodeStringToAnsiString(&NameA
, &NameW
, FALSE
);
775 *lpSize
= NameA
.Length
+ 1;
778 LocalFree(NameW
.Buffer
);
784 /******************************************************************************
785 * GetUserNameW [ADVAPI32.@]
793 GetUserNameW(LPWSTR lpszName
,
796 HANDLE hToken
= INVALID_HANDLE_VALUE
;
799 TOKEN_USER
* token_user
= NULL
;
801 SID_NAME_USE snu
= SidTypeUser
;
802 WCHAR
* domain_name
= NULL
;
805 if ( !OpenThreadToken ( GetCurrentThread(), TOKEN_QUERY
, FALSE
, &hToken
) )
807 DWORD dwLastError
= GetLastError();
808 if ( dwLastError
!= ERROR_NO_TOKEN
809 && dwLastError
!= ERROR_NO_IMPERSONATION_TOKEN
)
811 /* don't call SetLastError(),
812 as OpenThreadToken() ought to have set one */
815 if ( !OpenProcessToken ( GetCurrentProcess(), TOKEN_QUERY
, &hToken
) )
817 /* don't call SetLastError(),
818 as OpenProcessToken() ought to have set one */
822 tu_buf
= LocalAlloc ( LMEM_FIXED
, 36 );
825 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
826 CloseHandle ( hToken
);
829 if ( !GetTokenInformation ( hToken
, TokenUser
, tu_buf
, 36, &tu_len
) || tu_len
> 36 )
831 LocalFree ( tu_buf
);
832 tu_buf
= LocalAlloc ( LMEM_FIXED
, tu_len
);
835 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
836 CloseHandle ( hToken
);
839 if ( !GetTokenInformation ( hToken
, TokenUser
, tu_buf
, tu_len
, &tu_len
) )
841 /* don't call SetLastError(),
842 as GetTokenInformation() ought to have set one */
843 LocalFree ( tu_buf
);
844 CloseHandle ( hToken
);
848 CloseHandle ( hToken
);
849 token_user
= (TOKEN_USER
*)tu_buf
;
853 domain_name
= LocalAlloc ( LMEM_FIXED
, dn_len
* sizeof(WCHAR
) );
856 LocalFree ( tu_buf
);
857 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
860 if ( !LookupAccountSidW ( NULL
, token_user
->User
.Sid
, lpszName
, &an_len
, domain_name
, &dn_len
, &snu
)
865 LocalFree ( domain_name
);
866 domain_name
= LocalAlloc ( LMEM_FIXED
, dn_len
* sizeof(WCHAR
) );
869 LocalFree ( tu_buf
);
870 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
875 if ( !LookupAccountSidW ( NULL
, token_user
->User
.Sid
, lpszName
, &an_len
, domain_name
, &dn_len
, &snu
) )
877 /* don't call SetLastError(),
878 as LookupAccountSid() ought to have set one */
879 LocalFree ( domain_name
);
880 LocalFree ( tu_buf
);
886 LocalFree ( domain_name
);
887 LocalFree ( tu_buf
);
888 *lpSize
= an_len
+ 1;
893 /******************************************************************************
894 * LookupAccountSidA [ADVAPI32.@]
900 LookupAccountSidA(LPCSTR lpSystemName
,
904 LPSTR lpReferencedDomainName
,
905 LPDWORD cchReferencedDomainName
,
908 UNICODE_STRING NameW
, ReferencedDomainNameW
, SystemNameW
;
909 LPWSTR NameBuffer
= NULL
;
910 LPWSTR ReferencedDomainNameBuffer
= NULL
;
911 DWORD dwName
, dwReferencedDomainName
;
915 * save the buffer sizes the caller passed to us, as they may get modified and
916 * we require the original values when converting back to ansi
919 dwReferencedDomainName
= *cchReferencedDomainName
;
922 * allocate buffers for the unicode strings to receive
927 NameBuffer
= (PWSTR
)LocalAlloc(LMEM_FIXED
, dwName
);
928 if(NameBuffer
== NULL
)
930 SetLastError(ERROR_OUTOFMEMORY
);
937 if(dwReferencedDomainName
> 0)
939 ReferencedDomainNameBuffer
= (PWSTR
)LocalAlloc(LMEM_FIXED
, dwReferencedDomainName
);
940 if(ReferencedDomainNameBuffer
== NULL
)
944 LocalFree(NameBuffer
);
946 SetLastError(ERROR_OUTOFMEMORY
);
951 ReferencedDomainNameBuffer
= NULL
;
954 * convert the system name to unicode - if present
957 if(lpSystemName
!= NULL
)
959 ANSI_STRING SystemNameA
;
961 RtlInitAnsiString(&SystemNameA
, lpSystemName
);
962 RtlAnsiStringToUnicodeString(&SystemNameW
, &SystemNameA
, TRUE
);
965 SystemNameW
.Buffer
= NULL
;
968 * it's time to call the unicode version
971 Ret
= LookupAccountSidW(SystemNameW
.Buffer
,
975 ReferencedDomainNameBuffer
,
976 cchReferencedDomainName
,
981 * convert unicode strings back to ansi, don't forget that we can't convert
982 * more than 0xFFFF (USHORT) characters! Also don't forget to explicitly
983 * terminate the converted string, the Rtl functions don't do that!
990 NameA
.MaximumLength
= ((dwName
<= 0xFFFF) ? (USHORT
)dwName
: 0xFFFF);
991 NameA
.Buffer
= lpName
;
993 RtlInitUnicodeString(&NameW
, NameBuffer
);
994 RtlUnicodeStringToAnsiString(&NameA
, &NameW
, FALSE
);
995 NameA
.Buffer
[NameA
.Length
] = '\0';
998 if(lpReferencedDomainName
!= NULL
)
1000 ANSI_STRING ReferencedDomainNameA
;
1002 ReferencedDomainNameA
.Length
= 0;
1003 ReferencedDomainNameA
.MaximumLength
= ((dwReferencedDomainName
<= 0xFFFF) ?
1004 (USHORT
)dwReferencedDomainName
: 0xFFFF);
1005 ReferencedDomainNameA
.Buffer
= lpReferencedDomainName
;
1007 RtlInitUnicodeString(&ReferencedDomainNameW
, ReferencedDomainNameBuffer
);
1008 RtlUnicodeStringToAnsiString(&ReferencedDomainNameA
, &ReferencedDomainNameW
, FALSE
);
1009 ReferencedDomainNameA
.Buffer
[ReferencedDomainNameA
.Length
] = '\0';
1014 * free previously allocated buffers
1017 if(SystemNameW
.Buffer
!= NULL
)
1019 RtlFreeUnicodeString(&SystemNameW
);
1021 if(NameBuffer
!= NULL
)
1023 LocalFree(NameBuffer
);
1025 if(ReferencedDomainNameBuffer
!= NULL
)
1027 LocalFree(ReferencedDomainNameBuffer
);
1034 /******************************************************************************
1035 * LookupAccountSidW [ADVAPI32.@]
1040 LookupAccountSidW(LPCWSTR pSystemName
,
1042 LPWSTR pAccountName
,
1043 LPDWORD pdwAccountName
,
1045 LPDWORD pdwDomainName
,
1046 PSID_NAME_USE peUse
)
1048 LSA_UNICODE_STRING SystemName
;
1049 LSA_OBJECT_ATTRIBUTES ObjectAttributes
= {0};
1050 LSA_HANDLE PolicyHandle
= NULL
;
1052 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain
= NULL
;
1053 PLSA_TRANSLATED_NAME TranslatedName
= NULL
;
1055 DWORD dwAccountName
, dwDomainName
;
1057 RtlInitUnicodeString ( &SystemName
, pSystemName
);
1058 Status
= LsaOpenPolicy ( &SystemName
, &ObjectAttributes
, POLICY_LOOKUP_NAMES
, &PolicyHandle
);
1059 if ( !NT_SUCCESS(Status
) )
1061 SetLastError ( LsaNtStatusToWinError(Status
) );
1064 Status
= LsaLookupSids ( PolicyHandle
, 1, &pSid
, &ReferencedDomain
, &TranslatedName
);
1066 LsaClose ( PolicyHandle
);
1068 if ( !NT_SUCCESS(Status
) || Status
== STATUS_SOME_NOT_MAPPED
)
1070 SetLastError ( LsaNtStatusToWinError(Status
) );
1077 dwAccountName
= TranslatedName
->Name
.Length
/ sizeof(WCHAR
);
1078 if (ReferencedDomain
&& ReferencedDomain
->Entries
> 0)
1079 dwDomainName
= ReferencedDomain
->Domains
[0].Name
.Length
/ sizeof(WCHAR
);
1083 if (*pdwAccountName
<= dwAccountName
|| *pdwDomainName
<= dwDomainName
)
1085 /* One or two buffers are insufficient, add up a char for NULL termination */
1086 *pdwAccountName
= dwAccountName
+ 1;
1087 *pdwDomainName
= dwDomainName
+ 1;
1091 /* Lengths are sufficient, copy the data */
1093 RtlCopyMemory(pAccountName
, TranslatedName
->Name
.Buffer
, dwAccountName
* sizeof(WCHAR
));
1094 pAccountName
[dwAccountName
] = L
'\0';
1097 RtlCopyMemory(pDomainName
, ReferencedDomain
->Domains
[0].Name
.Buffer
, dwDomainName
* sizeof(WCHAR
));
1098 pDomainName
[dwDomainName
] = L
'\0';
1100 *pdwAccountName
= dwAccountName
;
1101 *pdwDomainName
= dwDomainName
;
1104 *peUse
= TranslatedName
->Use
;
1108 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1111 if ( ReferencedDomain
)
1112 LsaFreeMemory ( ReferencedDomain
);
1113 if ( TranslatedName
)
1114 LsaFreeMemory ( TranslatedName
);
1121 /******************************************************************************
1122 * LookupAccountNameA [ADVAPI32.@]
1128 LookupAccountNameA(LPCSTR SystemName
,
1132 LPSTR ReferencedDomainName
,
1133 LPDWORD hReferencedDomainNameLength
,
1134 PSID_NAME_USE SidNameUse
)
1137 UNICODE_STRING lpSystemW
;
1138 UNICODE_STRING lpAccountW
;
1139 LPWSTR lpReferencedDomainNameW
= NULL
;
1141 RtlCreateUnicodeStringFromAsciiz(&lpSystemW
, SystemName
);
1142 RtlCreateUnicodeStringFromAsciiz(&lpAccountW
, AccountName
);
1144 if (ReferencedDomainName
)
1145 lpReferencedDomainNameW
= HeapAlloc(GetProcessHeap(),
1147 *hReferencedDomainNameLength
* sizeof(WCHAR
));
1149 ret
= LookupAccountNameW(lpSystemW
.Buffer
,
1153 lpReferencedDomainNameW
,
1154 hReferencedDomainNameLength
,
1157 if (ret
&& lpReferencedDomainNameW
)
1159 WideCharToMultiByte(CP_ACP
,
1161 lpReferencedDomainNameW
,
1162 *hReferencedDomainNameLength
+ 1,
1163 ReferencedDomainName
,
1164 *hReferencedDomainNameLength
+ 1,
1169 RtlFreeUnicodeString(&lpSystemW
);
1170 RtlFreeUnicodeString(&lpAccountW
);
1171 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW
);
1177 /******************************************************************************
1178 * LookupAccountNameW [ADVAPI32.@]
1184 LookupAccountNameW(LPCWSTR lpSystemName
,
1185 LPCWSTR lpAccountName
,
1188 LPWSTR ReferencedDomainName
,
1189 LPDWORD cchReferencedDomainName
,
1190 PSID_NAME_USE peUse
)
1192 OBJECT_ATTRIBUTES ObjectAttributes
= {0};
1193 UNICODE_STRING SystemName
;
1194 UNICODE_STRING AccountName
;
1195 LSA_HANDLE PolicyHandle
= NULL
;
1196 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomains
= NULL
;
1197 PLSA_TRANSLATED_SID TranslatedSid
= NULL
;
1199 DWORD dwDomainNameLength
;
1201 UCHAR nSubAuthorities
;
1205 TRACE("%s %s %p %p %p %p %p\n", lpSystemName
, lpAccountName
,
1206 Sid
, cbSid
, ReferencedDomainName
, cchReferencedDomainName
, peUse
);
1208 RtlInitUnicodeString(&SystemName
,
1211 Status
= LsaOpenPolicy(lpSystemName
? &SystemName
: NULL
,
1213 POLICY_LOOKUP_NAMES
,
1215 if (!NT_SUCCESS(Status
))
1217 SetLastError(LsaNtStatusToWinError(Status
));
1221 RtlInitUnicodeString(&AccountName
,
1224 Status
= LsaLookupNames(PolicyHandle
,
1230 LsaClose(PolicyHandle
);
1232 if (!NT_SUCCESS(Status
) || Status
== STATUS_SOME_NOT_MAPPED
)
1234 SetLastError(LsaNtStatusToWinError(Status
));
1239 pDomainSid
= ReferencedDomains
->Domains
[TranslatedSid
->DomainIndex
].Sid
;
1240 nSubAuthorities
= *GetSidSubAuthorityCount(pDomainSid
);
1241 dwSidLength
= GetSidLengthRequired(nSubAuthorities
+ 1);
1243 dwDomainNameLength
= ReferencedDomains
->Domains
->Name
.Length
/ sizeof(WCHAR
);
1245 if (*cbSid
< dwSidLength
||
1246 *cchReferencedDomainName
< dwDomainNameLength
+ 1)
1248 *cbSid
= dwSidLength
;
1249 *cchReferencedDomainName
= dwDomainNameLength
+ 1;
1255 CopySid(*cbSid
, Sid
, pDomainSid
);
1256 *GetSidSubAuthorityCount(Sid
) = nSubAuthorities
+ 1;
1257 *GetSidSubAuthority(Sid
, (DWORD
)nSubAuthorities
) = TranslatedSid
->RelativeId
;
1259 RtlCopyMemory(ReferencedDomainName
, ReferencedDomains
->Domains
->Name
.Buffer
, dwDomainNameLength
* sizeof(WCHAR
));
1260 ReferencedDomainName
[dwDomainNameLength
] = L
'\0';
1262 *cchReferencedDomainName
= dwDomainNameLength
;
1264 *peUse
= TranslatedSid
->Use
;
1269 if (bResult
== FALSE
)
1270 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1273 if (ReferencedDomains
!= NULL
)
1274 LsaFreeMemory(ReferencedDomains
);
1276 if (TranslatedSid
!= NULL
)
1277 LsaFreeMemory(TranslatedSid
);
1283 /**********************************************************************
1284 * LookupPrivilegeValueA EXPORTED
1290 LookupPrivilegeValueA(LPCSTR lpSystemName
,
1294 UNICODE_STRING SystemName
;
1295 UNICODE_STRING Name
;
1298 /* Remote system? */
1299 if (lpSystemName
!= NULL
)
1301 RtlCreateUnicodeStringFromAsciiz(&SystemName
,
1302 (LPSTR
)lpSystemName
);
1305 SystemName
.Buffer
= NULL
;
1307 /* Check the privilege name is not NULL */
1310 SetLastError(ERROR_NO_SUCH_PRIVILEGE
);
1314 RtlCreateUnicodeStringFromAsciiz(&Name
,
1317 Result
= LookupPrivilegeValueW(SystemName
.Buffer
,
1321 RtlFreeUnicodeString(&Name
);
1323 /* Remote system? */
1324 if (SystemName
.Buffer
!= NULL
)
1326 RtlFreeUnicodeString(&SystemName
);
1333 /**********************************************************************
1334 * LookupPrivilegeValueW
1340 LookupPrivilegeValueW(LPCWSTR lpSystemName
,
1341 LPCWSTR lpPrivilegeName
,
1344 OBJECT_ATTRIBUTES ObjectAttributes
= {0};
1345 UNICODE_STRING SystemName
;
1346 UNICODE_STRING PrivilegeName
;
1347 LSA_HANDLE PolicyHandle
= NULL
;
1350 TRACE("%S,%S,%p\n", lpSystemName
, lpPrivilegeName
, lpLuid
);
1352 RtlInitUnicodeString(&SystemName
,
1355 Status
= LsaOpenPolicy(lpSystemName
? &SystemName
: NULL
,
1357 POLICY_LOOKUP_NAMES
,
1359 if (!NT_SUCCESS(Status
))
1361 SetLastError(LsaNtStatusToWinError(Status
));
1365 RtlInitUnicodeString(&PrivilegeName
,
1368 Status
= LsaLookupPrivilegeValue(PolicyHandle
,
1372 LsaClose(PolicyHandle
);
1374 if (!NT_SUCCESS(Status
))
1376 SetLastError(LsaNtStatusToWinError(Status
));
1384 /**********************************************************************
1385 * LookupPrivilegeDisplayNameA EXPORTED
1391 LookupPrivilegeDisplayNameA(LPCSTR lpSystemName
,
1393 LPSTR lpDisplayName
,
1394 LPDWORD cbDisplayName
,
1395 LPDWORD lpLanguageId
)
1397 FIXME("%s() not implemented!\n", __FUNCTION__
);
1398 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1403 /**********************************************************************
1404 * LookupPrivilegeDisplayNameW EXPORTED
1410 LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName
,
1412 LPWSTR lpDisplayName
,
1413 LPDWORD cbDisplayName
,
1414 LPDWORD lpLanguageId
)
1416 FIXME("%s() not implemented!\n", __FUNCTION__
);
1417 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1422 /**********************************************************************
1423 * LookupPrivilegeNameA EXPORTED
1429 LookupPrivilegeNameA(LPCSTR lpSystemName
,
1434 UNICODE_STRING lpSystemNameW
;
1438 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName
), lpLuid
, lpName
, cchName
);
1440 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW
, lpSystemName
);
1441 ret
= LookupPrivilegeNameW(lpSystemNameW
.Buffer
, lpLuid
, NULL
, &wLen
);
1442 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
1444 LPWSTR lpNameW
= HeapAlloc(GetProcessHeap(), 0, wLen
* sizeof(WCHAR
));
1446 ret
= LookupPrivilegeNameW(lpSystemNameW
.Buffer
, lpLuid
, lpNameW
,
1450 /* Windows crashes if cchName is NULL, so will I */
1451 unsigned int len
= WideCharToMultiByte(CP_ACP
, 0, lpNameW
, -1, lpName
,
1452 *cchName
, NULL
, NULL
);
1456 /* WideCharToMultiByte failed */
1459 else if (len
> *cchName
)
1462 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1467 /* WideCharToMultiByte succeeded, output length needs to be
1468 * length not including NULL terminator
1473 HeapFree(GetProcessHeap(), 0, lpNameW
);
1475 RtlFreeUnicodeString(&lpSystemNameW
);
1480 /**********************************************************************
1481 * LookupPrivilegeNameW EXPORTED
1487 LookupPrivilegeNameW(LPCWSTR lpSystemName
,
1492 OBJECT_ATTRIBUTES ObjectAttributes
= {0};
1493 UNICODE_STRING SystemName
;
1494 PUNICODE_STRING PrivilegeName
= NULL
;
1495 LSA_HANDLE PolicyHandle
= NULL
;
1498 TRACE("%S,%p,%p,%p\n", lpSystemName
, lpLuid
, lpName
, cchName
);
1500 RtlInitUnicodeString(&SystemName
,
1503 Status
= LsaOpenPolicy(lpSystemName
? &SystemName
: NULL
,
1505 POLICY_LOOKUP_NAMES
,
1507 if (!NT_SUCCESS(Status
))
1509 SetLastError(LsaNtStatusToWinError(Status
));
1513 Status
= LsaLookupPrivilegeName(PolicyHandle
,
1516 if (NT_SUCCESS(Status
))
1518 if (PrivilegeName
->Length
+ sizeof(WCHAR
) > *cchName
* sizeof(WCHAR
))
1520 Status
= STATUS_BUFFER_TOO_SMALL
;
1522 *cchName
= (PrivilegeName
->Length
+ sizeof(WCHAR
)) / sizeof(WCHAR
);
1526 RtlMoveMemory(lpName
,
1527 PrivilegeName
->Buffer
,
1528 PrivilegeName
->Length
);
1529 lpName
[PrivilegeName
->Length
/ sizeof(WCHAR
)] = 0;
1531 *cchName
= PrivilegeName
->Length
/ sizeof(WCHAR
);
1534 LsaFreeMemory(PrivilegeName
->Buffer
);
1535 LsaFreeMemory(PrivilegeName
);
1538 LsaClose(PolicyHandle
);
1540 if (!NT_SUCCESS(Status
))
1542 SetLastError(LsaNtStatusToWinError(Status
));
1551 pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo
,
1556 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
1558 if ((SecurityInfo
& (OWNER_SECURITY_INFORMATION
|
1559 GROUP_SECURITY_INFORMATION
|
1560 DACL_SECURITY_INFORMATION
|
1561 SACL_SECURITY_INFORMATION
)) &&
1562 ppSecurityDescriptor
== NULL
)
1564 /* if one of the SIDs or ACLs are present, the security descriptor
1566 return ERROR_INVALID_PARAMETER
;
1570 /* reset the pointers unless they're ignored */
1571 if ((SecurityInfo
& OWNER_SECURITY_INFORMATION
) &&
1576 if ((SecurityInfo
& GROUP_SECURITY_INFORMATION
) &&
1581 if ((SecurityInfo
& DACL_SECURITY_INFORMATION
) &&
1586 if ((SecurityInfo
& SACL_SECURITY_INFORMATION
) &&
1592 if (SecurityInfo
& (OWNER_SECURITY_INFORMATION
|
1593 GROUP_SECURITY_INFORMATION
|
1594 DACL_SECURITY_INFORMATION
|
1595 SACL_SECURITY_INFORMATION
))
1597 *ppSecurityDescriptor
= NULL
;
1600 return ERROR_SUCCESS
;
1606 pSetSecurityInfoCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1607 SECURITY_INFORMATION SecurityInfo
,
1613 /* initialize a security descriptor on the stack */
1614 if (!InitializeSecurityDescriptor(pSecurityDescriptor
,
1615 SECURITY_DESCRIPTOR_REVISION
))
1617 return GetLastError();
1620 if (SecurityInfo
& OWNER_SECURITY_INFORMATION
)
1622 if (RtlValidSid(psidOwner
))
1624 if (!SetSecurityDescriptorOwner(pSecurityDescriptor
,
1628 return GetLastError();
1633 return ERROR_INVALID_PARAMETER
;
1637 if (SecurityInfo
& GROUP_SECURITY_INFORMATION
)
1639 if (RtlValidSid(psidGroup
))
1641 if (!SetSecurityDescriptorGroup(pSecurityDescriptor
,
1645 return GetLastError();
1650 return ERROR_INVALID_PARAMETER
;
1654 if (SecurityInfo
& DACL_SECURITY_INFORMATION
)
1658 if (SetSecurityDescriptorDacl(pSecurityDescriptor
,
1663 /* check if the DACL needs to be protected from being
1664 modified by inheritable ACEs */
1665 if (SecurityInfo
& PROTECTED_DACL_SECURITY_INFORMATION
)
1672 return GetLastError();
1678 /* protect the DACL from being modified by inheritable ACEs */
1679 if (!SetSecurityDescriptorControl(pSecurityDescriptor
,
1683 return GetLastError();
1688 if (SecurityInfo
& SACL_SECURITY_INFORMATION
)
1692 if (SetSecurityDescriptorSacl(pSecurityDescriptor
,
1697 /* check if the SACL needs to be protected from being
1698 modified by inheritable ACEs */
1699 if (SecurityInfo
& PROTECTED_SACL_SECURITY_INFORMATION
)
1706 return GetLastError();
1712 /* protect the SACL from being modified by inheritable ACEs */
1713 if (!SetSecurityDescriptorControl(pSecurityDescriptor
,
1717 return GetLastError();
1722 return ERROR_SUCCESS
;
1726 /**********************************************************************
1727 * GetNamedSecurityInfoW EXPORTED
1733 GetNamedSecurityInfoW(LPWSTR pObjectName
,
1734 SE_OBJECT_TYPE ObjectType
,
1735 SECURITY_INFORMATION SecurityInfo
,
1740 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1744 if (pObjectName
!= NULL
)
1746 ErrorCode
= CheckNtMartaPresent();
1747 if (ErrorCode
== ERROR_SUCCESS
)
1749 ErrorCode
= pGetSecurityInfoCheck(SecurityInfo
,
1754 ppSecurityDescriptor
);
1756 if (ErrorCode
== ERROR_SUCCESS
)
1758 /* call the MARTA provider */
1759 ErrorCode
= AccRewriteGetNamedRights(pObjectName
,
1766 ppSecurityDescriptor
);
1771 ErrorCode
= ERROR_INVALID_PARAMETER
;
1777 /**********************************************************************
1778 * GetNamedSecurityInfoA EXPORTED
1784 GetNamedSecurityInfoA(LPSTR pObjectName
,
1785 SE_OBJECT_TYPE ObjectType
,
1786 SECURITY_INFORMATION SecurityInfo
,
1791 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1797 TRACE("%s %d %d %p %p %p %p %p\n", pObjectName
, ObjectType
, SecurityInfo
,
1798 ppsidOwner
, ppsidGroup
, ppDacl
, ppSacl
, ppSecurityDescriptor
);
1802 len
= MultiByteToWideChar( CP_ACP
, 0, pObjectName
, -1, NULL
, 0 );
1803 wstr
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
));
1804 MultiByteToWideChar( CP_ACP
, 0, pObjectName
, -1, wstr
, len
);
1807 r
= GetNamedSecurityInfoW( wstr
, ObjectType
, SecurityInfo
, ppsidOwner
,
1808 ppsidGroup
, ppDacl
, ppSacl
, ppSecurityDescriptor
);
1810 HeapFree( GetProcessHeap(), 0, wstr
);
1816 /**********************************************************************
1817 * SetNamedSecurityInfoW EXPORTED
1823 SetNamedSecurityInfoW(LPWSTR pObjectName
,
1824 SE_OBJECT_TYPE ObjectType
,
1825 SECURITY_INFORMATION SecurityInfo
,
1833 if (pObjectName
!= NULL
)
1835 ErrorCode
= CheckNtMartaPresent();
1836 if (ErrorCode
== ERROR_SUCCESS
)
1838 SECURITY_DESCRIPTOR SecurityDescriptor
;
1840 ErrorCode
= pSetSecurityInfoCheck(&SecurityDescriptor
,
1847 if (ErrorCode
== ERROR_SUCCESS
)
1849 /* call the MARTA provider */
1850 ErrorCode
= AccRewriteSetNamedRights(pObjectName
,
1853 &SecurityDescriptor
);
1858 ErrorCode
= ERROR_INVALID_PARAMETER
;
1864 /**********************************************************************
1865 * SetNamedSecurityInfoA EXPORTED
1871 SetNamedSecurityInfoA(LPSTR pObjectName
,
1872 SE_OBJECT_TYPE ObjectType
,
1873 SECURITY_INFORMATION SecurityInfo
,
1879 UNICODE_STRING ObjectName
;
1883 Status
= RtlCreateUnicodeStringFromAsciiz(&ObjectName
,
1885 if (!NT_SUCCESS(Status
))
1887 return RtlNtStatusToDosError(Status
);
1890 Ret
= SetNamedSecurityInfoW(ObjectName
.Buffer
,
1898 RtlFreeUnicodeString(&ObjectName
);
1904 /**********************************************************************
1905 * GetSecurityInfo EXPORTED
1911 GetSecurityInfo(HANDLE handle
,
1912 SE_OBJECT_TYPE ObjectType
,
1913 SECURITY_INFORMATION SecurityInfo
,
1918 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1924 ErrorCode
= CheckNtMartaPresent();
1925 if (ErrorCode
== ERROR_SUCCESS
)
1927 ErrorCode
= pGetSecurityInfoCheck(SecurityInfo
,
1932 ppSecurityDescriptor
);
1934 if (ErrorCode
== ERROR_SUCCESS
)
1936 /* call the MARTA provider */
1937 ErrorCode
= AccRewriteGetHandleRights(handle
,
1944 ppSecurityDescriptor
);
1949 ErrorCode
= ERROR_INVALID_HANDLE
;
1955 /**********************************************************************
1956 * SetSecurityInfo EXPORTED
1962 SetSecurityInfo(HANDLE handle
,
1963 SE_OBJECT_TYPE ObjectType
,
1964 SECURITY_INFORMATION SecurityInfo
,
1974 ErrorCode
= CheckNtMartaPresent();
1975 if (ErrorCode
== ERROR_SUCCESS
)
1977 SECURITY_DESCRIPTOR SecurityDescriptor
;
1979 ErrorCode
= pSetSecurityInfoCheck(&SecurityDescriptor
,
1986 if (ErrorCode
== ERROR_SUCCESS
)
1988 /* call the MARTA provider */
1989 ErrorCode
= AccRewriteSetHandleRights(handle
,
1992 &SecurityDescriptor
);
1997 ErrorCode
= ERROR_INVALID_HANDLE
;
2003 /******************************************************************************
2004 * GetSecurityInfoExW EXPORTED
2008 GetSecurityInfoExA(HANDLE hObject
,
2009 SE_OBJECT_TYPE ObjectType
,
2010 SECURITY_INFORMATION SecurityInfo
,
2013 PACTRL_ACCESSA
*ppAccessList
,
2014 PACTRL_AUDITA
*ppAuditList
,
2018 FIXME("%s() not implemented!\n", __FUNCTION__
);
2019 return ERROR_BAD_PROVIDER
;
2023 /******************************************************************************
2024 * GetSecurityInfoExW EXPORTED
2028 GetSecurityInfoExW(HANDLE hObject
,
2029 SE_OBJECT_TYPE ObjectType
,
2030 SECURITY_INFORMATION SecurityInfo
,
2033 PACTRL_ACCESSW
*ppAccessList
,
2034 PACTRL_AUDITW
*ppAuditList
,
2038 FIXME("%s() not implemented!\n", __FUNCTION__
);
2039 return ERROR_BAD_PROVIDER
;
2043 /**********************************************************************
2044 * ImpersonateNamedPipeClient EXPORTED
2050 ImpersonateNamedPipeClient(HANDLE hNamedPipe
)
2052 IO_STATUS_BLOCK StatusBlock
;
2055 TRACE("ImpersonateNamedPipeClient() called\n");
2057 Status
= NtFsControlFile(hNamedPipe
,
2062 FSCTL_PIPE_IMPERSONATE
,
2067 if (!NT_SUCCESS(Status
))
2069 SetLastError(RtlNtStatusToDosError(Status
));
2082 CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor
,
2083 PSECURITY_DESCRIPTOR CreatorDescriptor
,
2084 PSECURITY_DESCRIPTOR
*NewDescriptor
,
2085 BOOL IsDirectoryObject
,
2087 PGENERIC_MAPPING GenericMapping
)
2091 Status
= RtlNewSecurityObject(ParentDescriptor
,
2097 if (!NT_SUCCESS(Status
))
2099 SetLastError(RtlNtStatusToDosError(Status
));
2112 CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor
,
2113 PSECURITY_DESCRIPTOR CreatorDescriptor
,
2114 PSECURITY_DESCRIPTOR
* NewDescriptor
,
2116 BOOL IsContainerObject
,
2117 ULONG AutoInheritFlags
,
2119 PGENERIC_MAPPING GenericMapping
)
2121 FIXME("%s() not implemented!\n", __FUNCTION__
);
2131 CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor
,
2132 PSECURITY_DESCRIPTOR CreatorDescriptor
,
2133 PSECURITY_DESCRIPTOR
* NewDescriptor
,
2136 BOOL IsContainerObject
,
2137 ULONG AutoInheritFlags
,
2139 PGENERIC_MAPPING GenericMapping
)
2141 FIXME("%s() not implemented!\n", __FUNCTION__
);
2151 DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR
*ObjectDescriptor
)
2155 Status
= RtlDeleteSecurityObject(ObjectDescriptor
);
2156 if (!NT_SUCCESS(Status
))
2158 SetLastError(RtlNtStatusToDosError(Status
));
2171 GetPrivateObjectSecurity(IN PSECURITY_DESCRIPTOR ObjectDescriptor
,
2172 IN SECURITY_INFORMATION SecurityInformation
,
2173 OUT PSECURITY_DESCRIPTOR ResultantDescriptor OPTIONAL
,
2174 IN DWORD DescriptorLength
,
2175 OUT PDWORD ReturnLength
)
2180 Status
= RtlQuerySecurityObject(ObjectDescriptor
,
2181 SecurityInformation
,
2182 ResultantDescriptor
,
2185 if (!NT_SUCCESS(Status
))
2188 SetLastError(RtlNtStatusToDosError(Status
));
2202 SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation
,
2203 PSECURITY_DESCRIPTOR ModificationDescriptor
,
2204 PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
2205 PGENERIC_MAPPING GenericMapping
,
2210 Status
= RtlSetSecurityObject(SecurityInformation
,
2211 ModificationDescriptor
,
2212 ObjectsSecurityDescriptor
,
2215 if (!NT_SUCCESS(Status
))
2217 SetLastError(RtlNtStatusToDosError(Status
));
2230 TreeResetNamedSecurityInfoW(LPWSTR pObjectName
,
2231 SE_OBJECT_TYPE ObjectType
,
2232 SECURITY_INFORMATION SecurityInfo
,
2238 FN_PROGRESSW fnProgress
,
2239 PROG_INVOKE_SETTING ProgressInvokeSetting
,
2244 if (pObjectName
!= NULL
)
2246 ErrorCode
= CheckNtMartaPresent();
2247 if (ErrorCode
== ERROR_SUCCESS
)
2251 case SE_FILE_OBJECT
:
2252 case SE_REGISTRY_KEY
:
2254 /* check the SecurityInfo flags for sanity (both, the protected
2255 and unprotected dacl/sacl flag must not be passed together) */
2256 if (((SecurityInfo
& DACL_SECURITY_INFORMATION
) &&
2257 (SecurityInfo
& (PROTECTED_DACL_SECURITY_INFORMATION
| UNPROTECTED_DACL_SECURITY_INFORMATION
)) ==
2258 (PROTECTED_DACL_SECURITY_INFORMATION
| UNPROTECTED_DACL_SECURITY_INFORMATION
))
2262 ((SecurityInfo
& SACL_SECURITY_INFORMATION
) &&
2263 (SecurityInfo
& (PROTECTED_SACL_SECURITY_INFORMATION
| UNPROTECTED_SACL_SECURITY_INFORMATION
)) ==
2264 (PROTECTED_SACL_SECURITY_INFORMATION
| UNPROTECTED_SACL_SECURITY_INFORMATION
)))
2266 ErrorCode
= ERROR_INVALID_PARAMETER
;
2270 /* call the MARTA provider */
2271 ErrorCode
= AccTreeResetNamedSecurityInfo(pObjectName
,
2280 ProgressInvokeSetting
,
2286 /* object type not supported */
2287 ErrorCode
= ERROR_INVALID_PARAMETER
;
2293 ErrorCode
= ERROR_INVALID_PARAMETER
;
2298 #ifdef HAS_FN_PROGRESSW
2300 typedef struct _INERNAL_FNPROGRESSW_DATA
2302 FN_PROGRESSA fnProgress
;
2304 } INERNAL_FNPROGRESSW_DATA
, *PINERNAL_FNPROGRESSW_DATA
;
2307 InternalfnProgressW(LPWSTR pObjectName
,
2309 PPROG_INVOKE_SETTING pInvokeSetting
,
2313 PINERNAL_FNPROGRESSW_DATA pifnProgressData
= (PINERNAL_FNPROGRESSW_DATA
)Args
;
2317 ObjectNameSize
= WideCharToMultiByte(CP_ACP
,
2326 if (ObjectNameSize
> 0)
2328 pObjectNameA
= RtlAllocateHeap(RtlGetProcessHeap(),
2331 if (pObjectNameA
!= NULL
)
2333 pObjectNameA
[0] = '\0';
2334 WideCharToMultiByte(CP_ACP
,
2343 pifnProgressData
->fnProgress((LPWSTR
)pObjectNameA
, /* FIXME: wrong cast!! */
2346 pifnProgressData
->Args
,
2349 RtlFreeHeap(RtlGetProcessHeap(),
2363 TreeResetNamedSecurityInfoA(LPSTR pObjectName
,
2364 SE_OBJECT_TYPE ObjectType
,
2365 SECURITY_INFORMATION SecurityInfo
,
2371 FN_PROGRESSA fnProgress
,
2372 PROG_INVOKE_SETTING ProgressInvokeSetting
,
2375 #ifndef HAS_FN_PROGRESSW
2376 /* That's all this function does, at least up to w2k3... Even MS was too
2377 lazy to implement it... */
2378 return ERROR_CALL_NOT_IMPLEMENTED
;
2380 INERNAL_FNPROGRESSW_DATA ifnProgressData
;
2381 UNICODE_STRING ObjectName
;
2385 Status
= RtlCreateUnicodeStringFromAsciiz(&ObjectName
,
2387 if (!NT_SUCCESS(Status
))
2389 return RtlNtStatusToDosError(Status
);
2392 ifnProgressData
.fnProgress
= fnProgress
;
2393 ifnProgressData
.Args
= Args
;
2395 Ret
= TreeResetNamedSecurityInfoW(ObjectName
.Buffer
,
2403 (fnProgress
!= NULL
? InternalfnProgressW
: NULL
),
2404 ProgressInvokeSetting
,
2407 RtlFreeUnicodeString(&ObjectName
);
2413 /******************************************************************************
2414 * SaferCreateLevel [ADVAPI32.@]
2416 BOOL WINAPI
SaferCreateLevel(DWORD ScopeId
, DWORD LevelId
, DWORD OpenFlags
,
2417 SAFER_LEVEL_HANDLE
* LevelHandle
, LPVOID lpReserved
)
2419 FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId
, LevelId
, OpenFlags
, LevelHandle
, lpReserved
);
2423 /******************************************************************************
2424 * SaferGetPolicyInformation [ADVAPI32.@]
2426 BOOL WINAPI
SaferGetPolicyInformation(DWORD scope
, SAFER_POLICY_INFO_CLASS
class, DWORD size
,
2427 PVOID buffer
, PDWORD required
, LPVOID lpReserved
)
2429 FIXME("(%u %u %u %p %p %p) stub\n", scope
, class, size
, buffer
, required
, lpReserved
);
2433 /******************************************************************************
2434 * QueryWindows31FilesMigration [ADVAPI32.@]
2440 QueryWindows31FilesMigration( DWORD x1
)
2442 FIXME("(%d):stub\n",x1
);
2446 /******************************************************************************
2447 * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2456 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1
, DWORD x2
, DWORD x3
,
2459 FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1
,x2
,x3
,x4
);