2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/advapi32/sec/misc.c
5 * PURPOSE: Miscellaneous security functions (some ported from Wine)
9 #include "wine/debug.h"
11 WINE_DEFAULT_DEBUG_CHANNEL(advapi
);
13 /* Needed for LookupAccountNameW implementation from Wine */
15 typedef struct _AccountSid
{
16 WELL_KNOWN_SID_TYPE type
;
19 SID_NAME_USE name_use
;
22 static const WCHAR Account_Operators
[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
23 static const WCHAR Administrator
[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
24 static const WCHAR Administrators
[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
25 static const WCHAR ANONYMOUS_LOGON
[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
26 static const WCHAR Authenticated_Users
[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
27 static const WCHAR Backup_Operators
[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
28 static const WCHAR BATCH
[] = { 'B','A','T','C','H',0 };
29 static const WCHAR Blank
[] = { 0 };
30 static const WCHAR BUILTIN
[] = { 'B','U','I','L','T','I','N',0 };
31 static const WCHAR Cert_Publishers
[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
32 static const WCHAR CREATOR_GROUP
[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
33 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 };
34 static const WCHAR CREATOR_OWNER
[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
35 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 };
36 static const WCHAR DIALUP
[] = { 'D','I','A','L','U','P',0 };
37 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 };
38 static const WCHAR DOMAIN
[] = {'D','O','M','A','I','N',0};
39 static const WCHAR Domain_Admins
[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
40 static const WCHAR Domain_Computers
[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
41 static const WCHAR Domain_Controllers
[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
42 static const WCHAR Domain_Guests
[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
43 static const WCHAR Domain_Users
[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
44 static const WCHAR Enterprise_Admins
[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
45 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 };
46 static const WCHAR Everyone
[] = { 'E','v','e','r','y','o','n','e',0 };
47 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 };
48 static const WCHAR Guest
[] = { 'G','u','e','s','t',0 };
49 static const WCHAR Guests
[] = { 'G','u','e','s','t','s',0 };
50 static const WCHAR INTERACTIVE
[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
51 static const WCHAR LOCAL
[] = { 'L','O','C','A','L',0 };
52 static const WCHAR LOCAL_SERVICE
[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
53 static const WCHAR NETWORK
[] = { 'N','E','T','W','O','R','K',0 };
54 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 };
55 static const WCHAR NETWORK_SERVICE
[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
56 static const WCHAR NT_AUTHORITY
[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
57 static const WCHAR NT_Pseudo_Domain
[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
58 static const WCHAR NTML_Authentication
[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
59 static const WCHAR NULL_SID
[] = { 'N','U','L','L',' ','S','I','D',0 };
60 static const WCHAR Other_Organization
[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
61 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 };
62 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 };
63 static const WCHAR Power_Users
[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
64 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 };
65 static const WCHAR Print_Operators
[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
66 static const WCHAR PROXY
[] = { 'P','R','O','X','Y',0 };
67 static const WCHAR RAS_and_IAS_Servers
[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
68 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 };
69 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 };
70 static const WCHAR Replicators
[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
71 static const WCHAR RESTRICTED
[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
72 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 };
73 static const WCHAR Schema_Admins
[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
74 static const WCHAR SELF
[] = { 'S','E','L','F',0 };
75 static const WCHAR Server_Operators
[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
76 static const WCHAR SERVICE
[] = { 'S','E','R','V','I','C','E',0 };
77 static const WCHAR SYSTEM
[] = { 'S','Y','S','T','E','M',0 };
78 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 };
79 static const WCHAR This_Organization
[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
80 static const WCHAR Users
[] = { 'U','s','e','r','s',0 };
82 static const AccountSid ACCOUNT_SIDS
[] = {
83 { WinNullSid
, NULL_SID
, Blank
, SidTypeWellKnownGroup
},
84 { WinWorldSid
, Everyone
, Blank
, SidTypeWellKnownGroup
},
85 { WinLocalSid
, LOCAL
, Blank
, SidTypeWellKnownGroup
},
86 { WinCreatorOwnerSid
, CREATOR_OWNER
, Blank
, SidTypeWellKnownGroup
},
87 { WinCreatorGroupSid
, CREATOR_GROUP
, Blank
, SidTypeWellKnownGroup
},
88 { WinCreatorOwnerServerSid
, CREATOR_OWNER_SERVER
, Blank
, SidTypeWellKnownGroup
},
89 { WinCreatorGroupServerSid
, CREATOR_GROUP_SERVER
, Blank
, SidTypeWellKnownGroup
},
90 { WinNtAuthoritySid
, NT_Pseudo_Domain
, NT_Pseudo_Domain
, SidTypeDomain
},
91 { WinDialupSid
, DIALUP
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
92 { WinNetworkSid
, NETWORK
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
93 { WinBatchSid
, BATCH
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
94 { WinInteractiveSid
, INTERACTIVE
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
95 { WinServiceSid
, SERVICE
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
96 { WinAnonymousSid
, ANONYMOUS_LOGON
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
97 { WinProxySid
, PROXY
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
98 { WinEnterpriseControllersSid
, ENTERPRISE_DOMAIN_CONTROLLERS
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
99 { WinSelfSid
, SELF
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
100 { WinAuthenticatedUserSid
, Authenticated_Users
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
101 { WinRestrictedCodeSid
, RESTRICTED
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
102 { WinTerminalServerSid
, TERMINAL_SERVER_USER
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
103 { WinRemoteLogonIdSid
, REMOTE_INTERACTIVE_LOGON
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
104 { WinLocalSystemSid
, SYSTEM
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
105 { WinLocalServiceSid
, LOCAL_SERVICE
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
106 { WinNetworkServiceSid
, NETWORK_SERVICE
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
107 { WinBuiltinDomainSid
, BUILTIN
, BUILTIN
, SidTypeDomain
},
108 { WinBuiltinAdministratorsSid
, Administrators
, BUILTIN
, SidTypeAlias
},
109 { WinBuiltinUsersSid
, Users
, BUILTIN
, SidTypeAlias
},
110 { WinBuiltinGuestsSid
, Guests
, BUILTIN
, SidTypeAlias
},
111 { WinBuiltinPowerUsersSid
, Power_Users
, BUILTIN
, SidTypeAlias
},
112 { WinBuiltinAccountOperatorsSid
, Account_Operators
, BUILTIN
, SidTypeAlias
},
113 { WinBuiltinSystemOperatorsSid
, Server_Operators
, BUILTIN
, SidTypeAlias
},
114 { WinBuiltinPrintOperatorsSid
, Print_Operators
, BUILTIN
, SidTypeAlias
},
115 { WinBuiltinBackupOperatorsSid
, Backup_Operators
, BUILTIN
, SidTypeAlias
},
116 { WinBuiltinReplicatorSid
, Replicators
, BUILTIN
, SidTypeAlias
},
117 { WinBuiltinPreWindows2000CompatibleAccessSid
, Pre_Windows_2000_Compatible_Access
, BUILTIN
, SidTypeAlias
},
118 { WinBuiltinRemoteDesktopUsersSid
, Remote_Desktop_Users
, BUILTIN
, SidTypeAlias
},
119 { WinBuiltinNetworkConfigurationOperatorsSid
, Network_Configuration_Operators
, BUILTIN
, SidTypeAlias
},
120 { WinNTLMAuthenticationSid
, NTML_Authentication
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
121 { WinDigestAuthenticationSid
, Digest_Authentication
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
122 { WinSChannelAuthenticationSid
, SChannel_Authentication
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
123 { WinThisOrganizationSid
, This_Organization
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
124 { WinOtherOrganizationSid
, Other_Organization
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
125 { WinBuiltinPerfMonitoringUsersSid
, Performance_Monitor_Users
, BUILTIN
, SidTypeAlias
},
126 { WinBuiltinPerfLoggingUsersSid
, Performance_Log_Users
, BUILTIN
, SidTypeAlias
},
129 /* Interface to ntmarta.dll ***************************************************/
131 NTMARTA NtMartaStatic
= { 0 };
132 static PNTMARTA NtMarta
= NULL
;
134 #define FindNtMartaProc(Name) \
135 NtMartaStatic.Name = (PVOID)GetProcAddress(NtMartaStatic.hDllInstance, \
137 if (NtMartaStatic.Name == NULL) \
139 return GetLastError(); \
143 LoadAndInitializeNtMarta(VOID
)
145 /* this code may be executed simultaneously by multiple threads in case they're
146 trying to initialize the interface at the same time, but that's no problem
147 because the pointers returned by GetProcAddress will be the same. However,
148 only one of the threads will change the NtMarta pointer to the NtMartaStatic
149 structure, the others threads will detect that there were other threads
150 initializing the structure faster and will release the reference to the
153 NtMartaStatic
.hDllInstance
= LoadLibraryW(L
"ntmarta.dll");
154 if (NtMartaStatic
.hDllInstance
== NULL
)
156 return GetLastError();
160 FindNtMartaProc(LookupAccountTrustee
);
161 FindNtMartaProc(LookupAccountName
);
162 FindNtMartaProc(LookupAccountSid
);
163 FindNtMartaProc(SetEntriesInAList
);
164 FindNtMartaProc(ConvertAccessToSecurityDescriptor
);
165 FindNtMartaProc(ConvertSDToAccess
);
166 FindNtMartaProc(ConvertAclToAccess
);
167 FindNtMartaProc(GetAccessForTrustee
);
168 FindNtMartaProc(GetExplicitEntries
);
170 FindNtMartaProc(RewriteGetNamedRights
);
171 FindNtMartaProc(RewriteSetNamedRights
);
172 FindNtMartaProc(RewriteGetHandleRights
);
173 FindNtMartaProc(RewriteSetHandleRights
);
174 FindNtMartaProc(RewriteSetEntriesInAcl
);
175 FindNtMartaProc(RewriteGetExplicitEntriesFromAcl
);
176 FindNtMartaProc(TreeResetNamedSecurityInfo
);
177 FindNtMartaProc(GetInheritanceSource
);
178 FindNtMartaProc(FreeIndexArray
);
180 return ERROR_SUCCESS
;
184 CheckNtMartaPresent(VOID
)
188 if (InterlockedCompareExchangePointer(&NtMarta
,
192 /* we're the first one trying to use ntmarta, initialize it and change
193 the pointer after initialization */
194 ErrorCode
= LoadAndInitializeNtMarta();
196 if (ErrorCode
== ERROR_SUCCESS
)
198 /* try change the NtMarta pointer */
199 if (InterlockedCompareExchangePointer(&NtMarta
,
203 /* another thread initialized ntmarta in the meanwhile, release
204 the reference of the dll loaded. */
205 FreeLibrary(NtMartaStatic
.hDllInstance
);
211 ERR("Failed to initialize ntmarta.dll! Error: 0x%x", ErrorCode
);
217 /* ntmarta was already initialized */
218 ErrorCode
= ERROR_SUCCESS
;
224 VOID
UnloadNtMarta(VOID
)
226 if (InterlockedExchangePointer(&NtMarta
,
229 FreeLibrary(NtMartaStatic
.hDllInstance
);
233 /******************************************************************************/
239 AreAllAccessesGranted(DWORD GrantedAccess
,
242 return((BOOL
)RtlAreAllAccessesGranted(GrantedAccess
,
251 AreAnyAccessesGranted(DWORD GrantedAccess
,
254 return((BOOL
)RtlAreAnyAccessesGranted(GrantedAccess
,
259 /******************************************************************************
260 * GetFileSecurityA [ADVAPI32.@]
262 * Obtains Specified information about the security of a file or directory.
265 * lpFileName [I] Name of the file to get info for
266 * RequestedInformation [I] SE_ flags from "winnt.h"
267 * pSecurityDescriptor [O] Destination for security information
268 * nLength [I] Length of pSecurityDescriptor
269 * lpnLengthNeeded [O] Destination for length of returned security information
272 * Success: TRUE. pSecurityDescriptor contains the requested information.
273 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
276 * The information returned is constrained by the callers access rights and
282 GetFileSecurityA(LPCSTR lpFileName
,
283 SECURITY_INFORMATION RequestedInformation
,
284 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
286 LPDWORD lpnLengthNeeded
)
288 UNICODE_STRING FileName
;
292 Status
= RtlCreateUnicodeStringFromAsciiz(&FileName
,
294 if (!NT_SUCCESS(Status
))
296 SetLastError(RtlNtStatusToDosError(Status
));
300 bResult
= GetFileSecurityW(FileName
.Buffer
,
301 RequestedInformation
,
306 RtlFreeUnicodeString(&FileName
);
316 GetFileSecurityW(LPCWSTR lpFileName
,
317 SECURITY_INFORMATION RequestedInformation
,
318 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
320 LPDWORD lpnLengthNeeded
)
322 OBJECT_ATTRIBUTES ObjectAttributes
;
323 IO_STATUS_BLOCK StatusBlock
;
324 UNICODE_STRING FileName
;
325 ULONG AccessMask
= 0;
329 TRACE("GetFileSecurityW() called\n");
331 if (RequestedInformation
&
332 (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION
))
334 AccessMask
|= READ_CONTROL
;
337 if (RequestedInformation
& SACL_SECURITY_INFORMATION
)
339 AccessMask
|= ACCESS_SYSTEM_SECURITY
;
342 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
347 ERR("Invalid path\n");
348 SetLastError(ERROR_INVALID_NAME
);
352 InitializeObjectAttributes(&ObjectAttributes
,
354 OBJ_CASE_INSENSITIVE
,
358 Status
= NtOpenFile(&FileHandle
,
362 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
365 RtlFreeHeap(RtlGetProcessHeap(),
369 if (!NT_SUCCESS(Status
))
371 ERR("NtOpenFile() failed (Status %lx)\n", Status
);
372 SetLastError(RtlNtStatusToDosError(Status
));
376 Status
= NtQuerySecurityObject(FileHandle
,
377 RequestedInformation
,
383 if (!NT_SUCCESS(Status
))
385 ERR("NtQuerySecurityObject() failed (Status %lx)\n", Status
);
386 SetLastError(RtlNtStatusToDosError(Status
));
398 GetKernelObjectSecurity(HANDLE Handle
,
399 SECURITY_INFORMATION RequestedInformation
,
400 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
402 LPDWORD lpnLengthNeeded
)
406 Status
= NtQuerySecurityObject(Handle
,
407 RequestedInformation
,
411 if (!NT_SUCCESS(Status
))
413 SetLastError(RtlNtStatusToDosError(Status
));
420 /******************************************************************************
421 * SetFileSecurityA [ADVAPI32.@]
422 * Sets the security of a file or directory
427 SetFileSecurityA (LPCSTR lpFileName
,
428 SECURITY_INFORMATION SecurityInformation
,
429 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
431 UNICODE_STRING FileName
;
435 Status
= RtlCreateUnicodeStringFromAsciiz(&FileName
,
437 if (!NT_SUCCESS(Status
))
439 SetLastError(RtlNtStatusToDosError(Status
));
443 bResult
= SetFileSecurityW(FileName
.Buffer
,
445 pSecurityDescriptor
);
447 RtlFreeUnicodeString(&FileName
);
453 /******************************************************************************
454 * SetFileSecurityW [ADVAPI32.@]
455 * Sets the security of a file or directory
460 SetFileSecurityW (LPCWSTR lpFileName
,
461 SECURITY_INFORMATION SecurityInformation
,
462 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
464 OBJECT_ATTRIBUTES ObjectAttributes
;
465 IO_STATUS_BLOCK StatusBlock
;
466 UNICODE_STRING FileName
;
467 ULONG AccessMask
= 0;
471 TRACE("SetFileSecurityW() called\n");
473 if (SecurityInformation
&
474 (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
))
476 AccessMask
|= WRITE_OWNER
;
479 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
481 AccessMask
|= WRITE_DAC
;
484 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
486 AccessMask
|= ACCESS_SYSTEM_SECURITY
;
489 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
494 ERR("Invalid path\n");
495 SetLastError(ERROR_INVALID_NAME
);
499 InitializeObjectAttributes(&ObjectAttributes
,
501 OBJ_CASE_INSENSITIVE
,
505 Status
= NtOpenFile(&FileHandle
,
509 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
512 RtlFreeHeap(RtlGetProcessHeap(),
516 if (!NT_SUCCESS(Status
))
518 ERR("NtOpenFile() failed (Status %lx)\n", Status
);
519 SetLastError(RtlNtStatusToDosError(Status
));
523 Status
= NtSetSecurityObject(FileHandle
,
525 pSecurityDescriptor
);
528 if (!NT_SUCCESS(Status
))
530 ERR("NtSetSecurityObject() failed (Status %lx)\n", Status
);
531 SetLastError(RtlNtStatusToDosError(Status
));
543 SetKernelObjectSecurity(HANDLE Handle
,
544 SECURITY_INFORMATION SecurityInformation
,
545 PSECURITY_DESCRIPTOR SecurityDescriptor
)
549 Status
= NtSetSecurityObject(Handle
,
552 if (!NT_SUCCESS(Status
))
554 SetLastError(RtlNtStatusToDosError(Status
));
566 ImpersonateAnonymousToken(IN HANDLE ThreadHandle
)
570 Status
= NtImpersonateAnonymousToken(ThreadHandle
);
572 if (!NT_SUCCESS(Status
))
574 SetLastError(RtlNtStatusToDosError(Status
));
586 ImpersonateLoggedOnUser(HANDLE hToken
)
588 SECURITY_QUALITY_OF_SERVICE Qos
;
589 OBJECT_ATTRIBUTES ObjectAttributes
;
596 /* Get the token type */
597 Status
= NtQueryInformationToken (hToken
,
602 if (!NT_SUCCESS(Status
))
604 SetLastError (RtlNtStatusToDosError (Status
));
608 if (Type
== TokenPrimary
)
610 /* Create a duplicate impersonation token */
611 Qos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
612 Qos
.ImpersonationLevel
= SecurityImpersonation
;
613 Qos
.ContextTrackingMode
= SECURITY_DYNAMIC_TRACKING
;
614 Qos
.EffectiveOnly
= FALSE
;
616 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
617 ObjectAttributes
.RootDirectory
= NULL
;
618 ObjectAttributes
.ObjectName
= NULL
;
619 ObjectAttributes
.Attributes
= 0;
620 ObjectAttributes
.SecurityDescriptor
= NULL
;
621 ObjectAttributes
.SecurityQualityOfService
= &Qos
;
623 Status
= NtDuplicateToken (hToken
,
624 TOKEN_IMPERSONATE
| TOKEN_QUERY
,
629 if (!NT_SUCCESS(Status
))
631 SetLastError (RtlNtStatusToDosError (Status
));
639 /* User the original impersonation token */
644 /* Impersonate the the current thread */
645 Status
= NtSetInformationThread (NtCurrentThread (),
646 ThreadImpersonationToken
,
650 if (Duplicated
== TRUE
)
655 if (!NT_SUCCESS(Status
))
657 SetLastError (RtlNtStatusToDosError (Status
));
669 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
673 Status
= RtlImpersonateSelf(ImpersonationLevel
);
674 if (!NT_SUCCESS(Status
))
676 SetLastError(RtlNtStatusToDosError(Status
));
692 Status
= NtSetInformationThread(NtCurrentThread(),
693 ThreadImpersonationToken
,
696 if (!NT_SUCCESS(Status
))
698 SetLastError(RtlNtStatusToDosError(Status
));
705 /******************************************************************************
706 * GetUserNameA [ADVAPI32.@]
708 * Get the current user name.
711 * lpszName [O] Destination for the user name.
712 * lpSize [I/O] Size of lpszName.
718 GetUserNameA( LPSTR lpszName
, LPDWORD lpSize
)
720 UNICODE_STRING NameW
;
724 /* apparently Win doesn't check whether lpSize is valid at all! */
727 NameW
.MaximumLength
= (*lpSize
) * sizeof(WCHAR
);
728 NameW
.Buffer
= LocalAlloc(LMEM_FIXED
, NameW
.MaximumLength
);
729 if(NameW
.Buffer
== NULL
)
731 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
736 NameA
.MaximumLength
= ((*lpSize
) < 0xFFFF ? (USHORT
)(*lpSize
) : 0xFFFF);
737 NameA
.Buffer
= lpszName
;
739 Ret
= GetUserNameW(NameW
.Buffer
,
743 RtlUnicodeStringToAnsiString(&NameA
, &NameW
, FALSE
);
744 NameA
.Buffer
[NameA
.Length
] = '\0';
746 *lpSize
= NameA
.Length
+ 1;
749 LocalFree(NameW
.Buffer
);
754 /******************************************************************************
755 * GetUserNameW [ADVAPI32.@]
762 GetUserNameW ( LPWSTR lpszName
, LPDWORD lpSize
)
764 HANDLE hToken
= INVALID_HANDLE_VALUE
;
767 TOKEN_USER
* token_user
= NULL
;
769 SID_NAME_USE snu
= SidTypeUser
;
770 WCHAR
* domain_name
= NULL
;
773 if ( !OpenThreadToken ( GetCurrentThread(), TOKEN_QUERY
, FALSE
, &hToken
) )
775 DWORD dwLastError
= GetLastError();
776 if ( dwLastError
!= ERROR_NO_TOKEN
777 && dwLastError
!= ERROR_NO_IMPERSONATION_TOKEN
)
779 /* don't call SetLastError(),
780 as OpenThreadToken() ought to have set one */
783 if ( !OpenProcessToken ( GetCurrentProcess(), TOKEN_QUERY
, &hToken
) )
785 /* don't call SetLastError(),
786 as OpenProcessToken() ought to have set one */
790 tu_buf
= LocalAlloc ( LMEM_FIXED
, 36 );
793 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
796 if ( !GetTokenInformation ( hToken
, TokenUser
, tu_buf
, 36, &tu_len
) || tu_len
> 36 )
798 LocalFree ( tu_buf
);
799 tu_buf
= LocalAlloc ( LMEM_FIXED
, tu_len
);
802 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
805 if ( !GetTokenInformation ( hToken
, TokenUser
, tu_buf
, tu_len
, &tu_len
) )
807 /* don't call SetLastError(),
808 as GetTokenInformation() ought to have set one */
809 LocalFree ( tu_buf
);
810 CloseHandle ( hToken
);
814 token_user
= (TOKEN_USER
*)tu_buf
;
818 domain_name
= LocalAlloc ( LMEM_FIXED
, dn_len
* sizeof(WCHAR
) );
821 LocalFree ( tu_buf
);
822 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
825 if ( !LookupAccountSidW ( NULL
, token_user
->User
.Sid
, lpszName
, &an_len
, domain_name
, &dn_len
, &snu
)
830 LocalFree ( domain_name
);
831 domain_name
= LocalAlloc ( LMEM_FIXED
, dn_len
* sizeof(WCHAR
) );
834 LocalFree ( tu_buf
);
835 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
839 if ( !LookupAccountSidW ( NULL
, token_user
->User
.Sid
, lpszName
, &an_len
, domain_name
, &dn_len
, &snu
) )
841 /* don't call SetLastError(),
842 as LookupAccountSid() ought to have set one */
843 LocalFree ( domain_name
);
844 CloseHandle ( hToken
);
849 LocalFree ( domain_name
);
850 LocalFree ( tu_buf
);
851 CloseHandle ( hToken
);
853 if ( an_len
> *lpSize
)
856 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
864 /******************************************************************************
865 * LookupAccountSidA [ADVAPI32.@]
870 LookupAccountSidA (LPCSTR lpSystemName
,
874 LPSTR lpReferencedDomainName
,
875 LPDWORD cchReferencedDomainName
,
878 UNICODE_STRING NameW
, ReferencedDomainNameW
, SystemNameW
;
879 DWORD szName
, szReferencedDomainName
;
883 * save the buffer sizes the caller passed to us, as they may get modified and
884 * we require the original values when converting back to ansi
887 szReferencedDomainName
= *cchReferencedDomainName
;
890 * allocate buffers for the unicode strings to receive
896 NameW
.MaximumLength
= szName
* sizeof(WCHAR
);
897 NameW
.Buffer
= (PWSTR
)LocalAlloc(LMEM_FIXED
, NameW
.MaximumLength
);
898 if(NameW
.Buffer
== NULL
)
900 SetLastError(ERROR_OUTOFMEMORY
);
907 if(szReferencedDomainName
> 0)
909 ReferencedDomainNameW
.Length
= 0;
910 ReferencedDomainNameW
.MaximumLength
= szReferencedDomainName
* sizeof(WCHAR
);
911 ReferencedDomainNameW
.Buffer
= (PWSTR
)LocalAlloc(LMEM_FIXED
, ReferencedDomainNameW
.MaximumLength
);
912 if(ReferencedDomainNameW
.Buffer
== NULL
)
916 LocalFree(NameW
.Buffer
);
918 SetLastError(ERROR_OUTOFMEMORY
);
923 ReferencedDomainNameW
.Buffer
= NULL
;
926 * convert the system name to unicode - if present
929 if(lpSystemName
!= NULL
)
931 ANSI_STRING SystemNameA
;
933 RtlInitAnsiString(&SystemNameA
, lpSystemName
);
934 RtlAnsiStringToUnicodeString(&SystemNameW
, &SystemNameA
, TRUE
);
937 SystemNameW
.Buffer
= NULL
;
940 * it's time to call the unicode version
943 Ret
= LookupAccountSidW(SystemNameW
.Buffer
,
947 ReferencedDomainNameW
.Buffer
,
948 cchReferencedDomainName
,
953 * convert unicode strings back to ansi, don't forget that we can't convert
954 * more than 0xFFFF (USHORT) characters! Also don't forget to explicitly
955 * terminate the converted string, the Rtl functions don't do that!
962 NameA
.MaximumLength
= ((szName
<= 0xFFFF) ? (USHORT
)szName
: 0xFFFF);
963 NameA
.Buffer
= lpName
;
965 RtlUnicodeStringToAnsiString(&NameA
, &NameW
, FALSE
);
966 NameA
.Buffer
[NameA
.Length
] = '\0';
969 if(lpReferencedDomainName
!= NULL
)
971 ANSI_STRING ReferencedDomainNameA
;
973 ReferencedDomainNameA
.Length
= 0;
974 ReferencedDomainNameA
.MaximumLength
= ((szReferencedDomainName
<= 0xFFFF) ?
975 (USHORT
)szReferencedDomainName
: 0xFFFF);
976 ReferencedDomainNameA
.Buffer
= lpReferencedDomainName
;
978 RtlUnicodeStringToAnsiString(&ReferencedDomainNameA
, &ReferencedDomainNameW
, FALSE
);
979 ReferencedDomainNameA
.Buffer
[ReferencedDomainNameA
.Length
] = '\0';
984 * free previously allocated buffers
987 if(SystemNameW
.Buffer
!= NULL
)
989 RtlFreeUnicodeString(&SystemNameW
);
991 if(NameW
.Buffer
!= NULL
)
993 LocalFree(NameW
.Buffer
);
995 if(ReferencedDomainNameW
.Buffer
!= NULL
)
997 LocalFree(ReferencedDomainNameW
.Buffer
);
1004 /******************************************************************************
1005 * LookupAccountSidW [ADVAPI32.@]
1011 LPCWSTR pSystemName
,
1013 LPWSTR pAccountName
,
1014 LPDWORD pdwAccountName
,
1016 LPDWORD pdwDomainName
,
1017 PSID_NAME_USE peUse
)
1019 LSA_UNICODE_STRING SystemName
;
1020 LSA_OBJECT_ATTRIBUTES ObjectAttributes
= {0};
1021 LSA_HANDLE PolicyHandle
= NULL
;
1023 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain
= NULL
;
1024 PLSA_TRANSLATED_NAME TranslatedName
= NULL
;
1027 RtlInitUnicodeString ( &SystemName
, pSystemName
);
1028 Status
= LsaOpenPolicy ( &SystemName
, &ObjectAttributes
, POLICY_LOOKUP_NAMES
, &PolicyHandle
);
1029 if ( !NT_SUCCESS(Status
) )
1031 SetLastError ( LsaNtStatusToWinError(Status
) );
1034 Status
= LsaLookupSids ( PolicyHandle
, 1, &pSid
, &ReferencedDomain
, &TranslatedName
);
1036 LsaClose ( PolicyHandle
);
1038 if ( !NT_SUCCESS(Status
) || Status
== STATUS_SOME_NOT_MAPPED
)
1040 SetLastError ( LsaNtStatusToWinError(Status
) );
1046 if ( TranslatedName
)
1048 DWORD dwSrcLen
= TranslatedName
->Name
.Length
/ sizeof(WCHAR
);
1049 if ( *pdwAccountName
<= dwSrcLen
)
1051 *pdwAccountName
= dwSrcLen
+ 1;
1056 *pdwAccountName
= dwSrcLen
;
1059 RtlCopyMemory ( pAccountName
, TranslatedName
->Name
.Buffer
, TranslatedName
->Name
.Length
);
1060 pAccountName
[TranslatedName
->Name
.Length
/ sizeof(WCHAR
)] = L
'\0';
1064 *peUse
= TranslatedName
->Use
;
1067 if ( ReferencedDomain
)
1069 if ( ReferencedDomain
->Entries
> 0 )
1071 DWORD dwSrcLen
= ReferencedDomain
->Domains
[0].Name
.Length
/ sizeof(WCHAR
);
1072 if ( *pdwDomainName
<= dwSrcLen
)
1074 *pdwDomainName
= dwSrcLen
+ 1;
1079 *pdwDomainName
= dwSrcLen
;
1080 RtlCopyMemory ( pDomainName
, ReferencedDomain
->Domains
[0].Name
.Buffer
, ReferencedDomain
->Domains
[0].Name
.Length
);
1081 pDomainName
[ReferencedDomain
->Domains
[0].Name
.Length
/ sizeof(WCHAR
)] = L
'\0';
1087 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1090 if ( ReferencedDomain
)
1091 LsaFreeMemory ( ReferencedDomain
);
1092 if ( TranslatedName
)
1093 LsaFreeMemory ( TranslatedName
);
1100 /******************************************************************************
1101 * LookupAccountNameA [ADVAPI32.@]
1106 LookupAccountNameA (LPCSTR SystemName
,
1110 LPSTR ReferencedDomainName
,
1111 LPDWORD hReferencedDomainNameLength
,
1112 PSID_NAME_USE SidNameUse
)
1115 UNICODE_STRING lpSystemW
;
1116 UNICODE_STRING lpAccountW
;
1117 LPWSTR lpReferencedDomainNameW
= NULL
;
1119 RtlCreateUnicodeStringFromAsciiz(&lpSystemW
, SystemName
);
1120 RtlCreateUnicodeStringFromAsciiz(&lpAccountW
, AccountName
);
1122 if (ReferencedDomainName
)
1123 lpReferencedDomainNameW
= HeapAlloc(GetProcessHeap(), 0, *hReferencedDomainNameLength
* sizeof(WCHAR
));
1125 ret
= LookupAccountNameW(lpSystemW
.Buffer
, lpAccountW
.Buffer
, Sid
, SidLength
, lpReferencedDomainNameW
,
1126 hReferencedDomainNameLength
, SidNameUse
);
1128 if (ret
&& lpReferencedDomainNameW
)
1130 WideCharToMultiByte(CP_ACP
, 0, lpReferencedDomainNameW
, *hReferencedDomainNameLength
,
1131 ReferencedDomainName
, *hReferencedDomainNameLength
, NULL
, NULL
);
1134 RtlFreeUnicodeString(&lpSystemW
);
1135 RtlFreeUnicodeString(&lpAccountW
);
1136 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW
);
1142 /******************************************************************************
1143 * LookupAccountNameW [ADVAPI32.@]
1147 BOOL WINAPI
LookupAccountNameW(LPCWSTR lpSystemName
, LPCWSTR lpAccountName
, PSID Sid
,
1148 LPDWORD cbSid
, LPWSTR ReferencedDomainName
,
1149 LPDWORD cchReferencedDomainName
, PSID_NAME_USE peUse
)
1151 /* Default implementation: Always return a default SID */
1152 SID_IDENTIFIER_AUTHORITY identifierAuthority
= {SECURITY_NT_AUTHORITY
};
1155 static const WCHAR dm
[] = {'D','O','M','A','I','N',0};
1158 TRACE("%s %s %p %p %p %p %p - stub\n", lpSystemName
, lpAccountName
,
1159 Sid
, cbSid
, ReferencedDomainName
, cchReferencedDomainName
, peUse
);
1161 for (i
= 0; i
< (sizeof(ACCOUNT_SIDS
) / sizeof(ACCOUNT_SIDS
[0])); i
++)
1163 if (!wcscmp(lpAccountName
, ACCOUNT_SIDS
[i
].account
))
1165 if (*cchReferencedDomainName
)
1166 *ReferencedDomainName
= '\0';
1167 *cchReferencedDomainName
= 0;
1168 *peUse
= SidTypeWellKnownGroup
;
1169 return CreateWellKnownSid(ACCOUNT_SIDS
[i
].type
, NULL
, Sid
, cbSid
);
1173 ret
= AllocateAndInitializeSid(&identifierAuthority
,
1175 SECURITY_BUILTIN_DOMAIN_RID
,
1176 DOMAIN_ALIAS_RID_ADMINS
,
1183 if (!RtlValidSid(pSid
))
1189 if (Sid
!= NULL
&& (*cbSid
>= GetLengthSid(pSid
)))
1190 CopySid(*cbSid
, Sid
, pSid
);
1191 if (*cbSid
< GetLengthSid(pSid
))
1193 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1196 *cbSid
= GetLengthSid(pSid
);
1198 if (ReferencedDomainName
!= NULL
&& (*cchReferencedDomainName
> wcslen(dm
)))
1199 wcscpy(ReferencedDomainName
, dm
);
1201 if (*cchReferencedDomainName
<= wcslen(dm
))
1203 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1207 *cchReferencedDomainName
= wcslen(dm
)+1;
1215 /**********************************************************************
1216 * LookupPrivilegeValueA EXPORTED
1221 LookupPrivilegeValueA (LPCSTR lpSystemName
,
1225 UNICODE_STRING SystemName
;
1226 UNICODE_STRING Name
;
1229 /* Remote system? */
1230 if (lpSystemName
!= NULL
)
1232 RtlCreateUnicodeStringFromAsciiz (&SystemName
,
1233 (LPSTR
)lpSystemName
);
1236 /* Check the privilege name is not NULL */
1239 SetLastError (ERROR_INVALID_PARAMETER
);
1243 RtlCreateUnicodeStringFromAsciiz (&Name
,
1246 Result
= LookupPrivilegeValueW ((lpSystemName
!= NULL
) ? SystemName
.Buffer
: NULL
,
1250 RtlFreeUnicodeString (&Name
);
1252 /* Remote system? */
1253 if (lpSystemName
!= NULL
)
1255 RtlFreeUnicodeString (&SystemName
);
1262 /**********************************************************************
1263 * LookupPrivilegeValueW EXPORTED
1268 LookupPrivilegeValueW (LPCWSTR SystemName
,
1272 static const WCHAR
* const DefaultPrivNames
[] =
1274 L
"SeCreateTokenPrivilege",
1275 L
"SeAssignPrimaryTokenPrivilege",
1276 L
"SeLockMemoryPrivilege",
1277 L
"SeIncreaseQuotaPrivilege",
1278 L
"SeUnsolicitedInputPrivilege",
1279 L
"SeMachineAccountPrivilege",
1281 L
"SeSecurityPrivilege",
1282 L
"SeTakeOwnershipPrivilege",
1283 L
"SeLoadDriverPrivilege",
1284 L
"SeSystemProfilePrivilege",
1285 L
"SeSystemtimePrivilege",
1286 L
"SeProfileSingleProcessPrivilege",
1287 L
"SeIncreaseBasePriorityPrivilege",
1288 L
"SeCreatePagefilePrivilege",
1289 L
"SeCreatePermanentPrivilege",
1290 L
"SeBackupPrivilege",
1291 L
"SeRestorePrivilege",
1292 L
"SeShutdownPrivilege",
1293 L
"SeDebugPrivilege",
1294 L
"SeAuditPrivilege",
1295 L
"SeSystemEnvironmentPrivilege",
1296 L
"SeChangeNotifyPrivilege",
1297 L
"SeRemoteShutdownPrivilege",
1298 L
"SeUndockPrivilege",
1299 L
"SeSyncAgentPrivilege",
1300 L
"SeEnableDelegationPrivilege",
1301 L
"SeManageVolumePrivilege",
1302 L
"SeImpersonatePrivilege",
1303 L
"SeCreateGlobalPrivilege"
1307 if (NULL
!= SystemName
&& L
'\0' != *SystemName
)
1309 FIXME("LookupPrivilegeValueW: not implemented for remote system\n");
1310 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1314 for (Priv
= 0; Priv
< sizeof(DefaultPrivNames
) / sizeof(DefaultPrivNames
[0]); Priv
++)
1316 if (0 == wcscmp(PrivName
, DefaultPrivNames
[Priv
]))
1318 Luid
->LowPart
= Priv
+ 1;
1324 WARN("LookupPrivilegeValueW: no such privilege %S\n", PrivName
);
1325 SetLastError(ERROR_NO_SUCH_PRIVILEGE
);
1330 /**********************************************************************
1331 * LookupPrivilegeDisplayNameA EXPORTED
1336 LookupPrivilegeDisplayNameA (LPCSTR lpSystemName
,
1338 LPSTR lpDisplayName
,
1339 LPDWORD cbDisplayName
,
1340 LPDWORD lpLanguageId
)
1342 FIXME("%s() not implemented!\n", __FUNCTION__
);
1343 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1348 /**********************************************************************
1349 * LookupPrivilegeDisplayNameW EXPORTED
1354 LookupPrivilegeDisplayNameW (LPCWSTR lpSystemName
,
1356 LPWSTR lpDisplayName
,
1357 LPDWORD cbDisplayName
,
1358 LPDWORD lpLanguageId
)
1360 FIXME("%s() not implemented!\n", __FUNCTION__
);
1361 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1366 /**********************************************************************
1367 * LookupPrivilegeNameA EXPORTED
1372 LookupPrivilegeNameA (LPCSTR lpSystemName
,
1377 FIXME("%s() not implemented!\n", __FUNCTION__
);
1378 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1383 /**********************************************************************
1384 * LookupPrivilegeNameW EXPORTED
1389 LookupPrivilegeNameW (LPCWSTR lpSystemName
,
1394 FIXME("%s() not implemented!\n", __FUNCTION__
);
1395 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1401 pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo
,
1406 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
1408 if ((SecurityInfo
& (OWNER_SECURITY_INFORMATION
|
1409 GROUP_SECURITY_INFORMATION
|
1410 DACL_SECURITY_INFORMATION
|
1411 SACL_SECURITY_INFORMATION
)) &&
1412 ppSecurityDescriptor
== NULL
)
1414 /* if one of the SIDs or ACLs are present, the security descriptor
1416 return ERROR_INVALID_PARAMETER
;
1420 /* reset the pointers unless they're ignored */
1421 if ((SecurityInfo
& OWNER_SECURITY_INFORMATION
) &&
1426 if ((SecurityInfo
& GROUP_SECURITY_INFORMATION
) &&
1431 if ((SecurityInfo
& DACL_SECURITY_INFORMATION
) &&
1436 if ((SecurityInfo
& SACL_SECURITY_INFORMATION
) &&
1442 if (SecurityInfo
& (OWNER_SECURITY_INFORMATION
|
1443 GROUP_SECURITY_INFORMATION
|
1444 DACL_SECURITY_INFORMATION
|
1445 SACL_SECURITY_INFORMATION
))
1447 *ppSecurityDescriptor
= NULL
;
1450 return ERROR_SUCCESS
;
1456 pSetSecurityInfoCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1457 SECURITY_INFORMATION SecurityInfo
,
1463 /* initialize a security descriptor on the stack */
1464 if (!InitializeSecurityDescriptor(pSecurityDescriptor
,
1465 SECURITY_DESCRIPTOR_REVISION
))
1467 return GetLastError();
1470 if (SecurityInfo
& OWNER_SECURITY_INFORMATION
)
1472 if (RtlValidSid(psidOwner
))
1474 if (!SetSecurityDescriptorOwner(pSecurityDescriptor
,
1478 return GetLastError();
1483 return ERROR_INVALID_PARAMETER
;
1487 if (SecurityInfo
& GROUP_SECURITY_INFORMATION
)
1489 if (RtlValidSid(psidGroup
))
1491 if (!SetSecurityDescriptorGroup(pSecurityDescriptor
,
1495 return GetLastError();
1500 return ERROR_INVALID_PARAMETER
;
1504 if (SecurityInfo
& DACL_SECURITY_INFORMATION
)
1508 if (SetSecurityDescriptorDacl(pSecurityDescriptor
,
1513 /* check if the DACL needs to be protected from being
1514 modified by inheritable ACEs */
1515 if (SecurityInfo
& PROTECTED_DACL_SECURITY_INFORMATION
)
1522 return GetLastError();
1528 /* protect the DACL from being modified by inheritable ACEs */
1529 if (!SetSecurityDescriptorControl(pSecurityDescriptor
,
1533 return GetLastError();
1538 if (SecurityInfo
& SACL_SECURITY_INFORMATION
)
1542 if (SetSecurityDescriptorSacl(pSecurityDescriptor
,
1547 /* check if the SACL needs to be protected from being
1548 modified by inheritable ACEs */
1549 if (SecurityInfo
& PROTECTED_SACL_SECURITY_INFORMATION
)
1556 return GetLastError();
1562 /* protect the SACL from being modified by inheritable ACEs */
1563 if (!SetSecurityDescriptorControl(pSecurityDescriptor
,
1567 return GetLastError();
1572 return ERROR_SUCCESS
;
1576 /**********************************************************************
1577 * GetNamedSecurityInfoW EXPORTED
1582 GetNamedSecurityInfoW(LPWSTR pObjectName
,
1583 SE_OBJECT_TYPE ObjectType
,
1584 SECURITY_INFORMATION SecurityInfo
,
1589 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1593 if (pObjectName
!= NULL
)
1595 ErrorCode
= CheckNtMartaPresent();
1596 if (ErrorCode
== ERROR_SUCCESS
)
1598 ErrorCode
= pGetSecurityInfoCheck(SecurityInfo
,
1603 ppSecurityDescriptor
);
1605 if (ErrorCode
== ERROR_SUCCESS
)
1607 /* call the MARTA provider */
1608 ErrorCode
= AccRewriteGetNamedRights(pObjectName
,
1615 ppSecurityDescriptor
);
1620 ErrorCode
= ERROR_INVALID_PARAMETER
;
1626 /**********************************************************************
1627 * GetNamedSecurityInfoA EXPORTED
1632 GetNamedSecurityInfoA(LPSTR pObjectName
,
1633 SE_OBJECT_TYPE ObjectType
,
1634 SECURITY_INFORMATION SecurityInfo
,
1639 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1641 UNICODE_STRING ObjectName
;
1645 Status
= RtlCreateUnicodeStringFromAsciiz(&ObjectName
,
1647 if (!NT_SUCCESS(Status
))
1649 return RtlNtStatusToDosError(Status
);
1652 Ret
= GetNamedSecurityInfoW(ObjectName
.Buffer
,
1659 ppSecurityDescriptor
);
1661 RtlFreeUnicodeString(&ObjectName
);
1667 /**********************************************************************
1668 * SetNamedSecurityInfoW EXPORTED
1673 SetNamedSecurityInfoW(LPWSTR pObjectName
,
1674 SE_OBJECT_TYPE ObjectType
,
1675 SECURITY_INFORMATION SecurityInfo
,
1683 if (pObjectName
!= NULL
)
1685 ErrorCode
= CheckNtMartaPresent();
1686 if (ErrorCode
== ERROR_SUCCESS
)
1688 SECURITY_DESCRIPTOR SecurityDescriptor
;
1690 ErrorCode
= pSetSecurityInfoCheck(&SecurityDescriptor
,
1697 if (ErrorCode
== ERROR_SUCCESS
)
1699 /* call the MARTA provider */
1700 ErrorCode
= AccRewriteSetNamedRights(pObjectName
,
1703 &SecurityDescriptor
);
1708 ErrorCode
= ERROR_INVALID_PARAMETER
;
1714 /**********************************************************************
1715 * SetNamedSecurityInfoA EXPORTED
1720 SetNamedSecurityInfoA(LPSTR pObjectName
,
1721 SE_OBJECT_TYPE ObjectType
,
1722 SECURITY_INFORMATION SecurityInfo
,
1728 UNICODE_STRING ObjectName
;
1732 Status
= RtlCreateUnicodeStringFromAsciiz(&ObjectName
,
1734 if (!NT_SUCCESS(Status
))
1736 return RtlNtStatusToDosError(Status
);
1739 Ret
= SetNamedSecurityInfoW(ObjectName
.Buffer
,
1747 RtlFreeUnicodeString(&ObjectName
);
1753 /**********************************************************************
1754 * GetSecurityInfo EXPORTED
1759 GetSecurityInfo(HANDLE handle
,
1760 SE_OBJECT_TYPE ObjectType
,
1761 SECURITY_INFORMATION SecurityInfo
,
1766 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
1772 ErrorCode
= CheckNtMartaPresent();
1773 if (ErrorCode
== ERROR_SUCCESS
)
1775 ErrorCode
= pGetSecurityInfoCheck(SecurityInfo
,
1780 ppSecurityDescriptor
);
1782 if (ErrorCode
== ERROR_SUCCESS
)
1784 /* call the MARTA provider */
1785 ErrorCode
= AccRewriteGetHandleRights(handle
,
1792 ppSecurityDescriptor
);
1797 ErrorCode
= ERROR_INVALID_HANDLE
;
1803 /**********************************************************************
1804 * SetSecurityInfo EXPORTED
1810 SetSecurityInfo(HANDLE handle
,
1811 SE_OBJECT_TYPE ObjectType
,
1812 SECURITY_INFORMATION SecurityInfo
,
1822 ErrorCode
= CheckNtMartaPresent();
1823 if (ErrorCode
== ERROR_SUCCESS
)
1825 SECURITY_DESCRIPTOR SecurityDescriptor
;
1827 ErrorCode
= pSetSecurityInfoCheck(&SecurityDescriptor
,
1834 if (ErrorCode
== ERROR_SUCCESS
)
1836 /* call the MARTA provider */
1837 ErrorCode
= AccRewriteSetHandleRights(handle
,
1840 &SecurityDescriptor
);
1845 ErrorCode
= ERROR_INVALID_HANDLE
;
1851 /******************************************************************************
1852 * GetSecurityInfoExW EXPORTED
1854 DWORD WINAPI
GetSecurityInfoExA(
1856 SE_OBJECT_TYPE ObjectType
,
1857 SECURITY_INFORMATION SecurityInfo
,
1860 PACTRL_ACCESSA
*ppAccessList
,
1861 PACTRL_AUDITA
*ppAuditList
,
1866 FIXME("%s() not implemented!\n", __FUNCTION__
);
1867 return ERROR_BAD_PROVIDER
;
1871 /******************************************************************************
1872 * GetSecurityInfoExW EXPORTED
1874 DWORD WINAPI
GetSecurityInfoExW(
1876 SE_OBJECT_TYPE ObjectType
,
1877 SECURITY_INFORMATION SecurityInfo
,
1880 PACTRL_ACCESSW
*ppAccessList
,
1881 PACTRL_AUDITW
*ppAuditList
,
1886 FIXME("%s() not implemented!\n", __FUNCTION__
);
1887 return ERROR_BAD_PROVIDER
;
1891 /**********************************************************************
1892 * ImpersonateNamedPipeClient EXPORTED
1897 ImpersonateNamedPipeClient(HANDLE hNamedPipe
)
1899 IO_STATUS_BLOCK StatusBlock
;
1902 TRACE("ImpersonateNamedPipeClient() called\n");
1904 Status
= NtFsControlFile(hNamedPipe
,
1909 FSCTL_PIPE_IMPERSONATE
,
1914 if (!NT_SUCCESS(Status
))
1916 SetLastError(RtlNtStatusToDosError(Status
));
1928 CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor
,
1929 PSECURITY_DESCRIPTOR CreatorDescriptor
,
1930 PSECURITY_DESCRIPTOR
*NewDescriptor
,
1931 BOOL IsDirectoryObject
,
1933 PGENERIC_MAPPING GenericMapping
)
1937 Status
= RtlNewSecurityObject(ParentDescriptor
,
1943 if (!NT_SUCCESS(Status
))
1945 SetLastError(RtlNtStatusToDosError(Status
));
1957 CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor
,
1958 PSECURITY_DESCRIPTOR CreatorDescriptor
,
1959 PSECURITY_DESCRIPTOR
* NewDescriptor
,
1961 BOOL IsContainerObject
,
1962 ULONG AutoInheritFlags
,
1964 PGENERIC_MAPPING GenericMapping
)
1966 FIXME("%s() not implemented!\n", __FUNCTION__
);
1975 CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor
,
1976 PSECURITY_DESCRIPTOR CreatorDescriptor
,
1977 PSECURITY_DESCRIPTOR
* NewDescriptor
,
1980 BOOL IsContainerObject
,
1981 ULONG AutoInheritFlags
,
1983 PGENERIC_MAPPING GenericMapping
)
1985 FIXME("%s() not implemented!\n", __FUNCTION__
);
1994 DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR
*ObjectDescriptor
)
1998 Status
= RtlDeleteSecurityObject(ObjectDescriptor
);
1999 if (!NT_SUCCESS(Status
))
2001 SetLastError(RtlNtStatusToDosError(Status
));
2013 GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR ObjectDescriptor
,
2014 SECURITY_INFORMATION SecurityInformation
,
2015 PSECURITY_DESCRIPTOR ResultantDescriptor
,
2016 DWORD DescriptorLength
,
2017 PDWORD ReturnLength
)
2021 Status
= RtlQuerySecurityObject(ObjectDescriptor
,
2022 SecurityInformation
,
2023 ResultantDescriptor
,
2026 if (!NT_SUCCESS(Status
))
2028 SetLastError(RtlNtStatusToDosError(Status
));
2040 SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation
,
2041 PSECURITY_DESCRIPTOR ModificationDescriptor
,
2042 PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
2043 PGENERIC_MAPPING GenericMapping
,
2048 Status
= RtlSetSecurityObject(SecurityInformation
,
2049 ModificationDescriptor
,
2050 ObjectsSecurityDescriptor
,
2053 if (!NT_SUCCESS(Status
))
2055 SetLastError(RtlNtStatusToDosError(Status
));
2067 TreeResetNamedSecurityInfoW(LPWSTR pObjectName
,
2068 SE_OBJECT_TYPE ObjectType
,
2069 SECURITY_INFORMATION SecurityInfo
,
2075 FN_PROGRESSW fnProgress
,
2076 PROG_INVOKE_SETTING ProgressInvokeSetting
,
2081 if (pObjectName
!= NULL
)
2083 ErrorCode
= CheckNtMartaPresent();
2084 if (ErrorCode
== ERROR_SUCCESS
)
2088 case SE_FILE_OBJECT
:
2089 case SE_REGISTRY_KEY
:
2091 /* check the SecurityInfo flags for sanity (both, the protected
2092 and unprotected dacl/sacl flag must not be passed together) */
2093 if (((SecurityInfo
& DACL_SECURITY_INFORMATION
) &&
2094 (SecurityInfo
& (PROTECTED_DACL_SECURITY_INFORMATION
| UNPROTECTED_DACL_SECURITY_INFORMATION
)) ==
2095 (PROTECTED_DACL_SECURITY_INFORMATION
| UNPROTECTED_DACL_SECURITY_INFORMATION
))
2099 ((SecurityInfo
& SACL_SECURITY_INFORMATION
) &&
2100 (SecurityInfo
& (PROTECTED_SACL_SECURITY_INFORMATION
| UNPROTECTED_SACL_SECURITY_INFORMATION
)) ==
2101 (PROTECTED_SACL_SECURITY_INFORMATION
| UNPROTECTED_SACL_SECURITY_INFORMATION
)))
2103 ErrorCode
= ERROR_INVALID_PARAMETER
;
2107 /* call the MARTA provider */
2108 ErrorCode
= AccTreeResetNamedSecurityInfo(pObjectName
,
2117 ProgressInvokeSetting
,
2123 /* object type not supported */
2124 ErrorCode
= ERROR_INVALID_PARAMETER
;
2130 ErrorCode
= ERROR_INVALID_PARAMETER
;
2135 #ifdef HAS_FN_PROGRESSW
2137 typedef struct _INERNAL_FNPROGRESSW_DATA
2139 FN_PROGRESSA fnProgress
;
2141 } INERNAL_FNPROGRESSW_DATA
, *PINERNAL_FNPROGRESSW_DATA
;
2144 InternalfnProgressW(LPWSTR pObjectName
,
2146 PPROG_INVOKE_SETTING pInvokeSetting
,
2150 PINERNAL_FNPROGRESSW_DATA pifnProgressData
= (PINERNAL_FNPROGRESSW_DATA
)Args
;
2154 ObjectNameSize
= WideCharToMultiByte(CP_ACP
,
2163 if (ObjectNameSize
> 0)
2165 pObjectNameA
= RtlAllocateHeap(RtlGetProcessHeap(),
2168 if (pObjectNameA
!= NULL
)
2170 pObjectNameA
[0] = '\0';
2171 WideCharToMultiByte(CP_ACP
,
2180 pifnProgressData
->fnProgress((LPWSTR
)pObjectNameA
, /* FIXME: wrong cast!! */
2183 pifnProgressData
->Args
,
2186 RtlFreeHeap(RtlGetProcessHeap(),
2199 TreeResetNamedSecurityInfoA(LPSTR pObjectName
,
2200 SE_OBJECT_TYPE ObjectType
,
2201 SECURITY_INFORMATION SecurityInfo
,
2207 FN_PROGRESSA fnProgress
,
2208 PROG_INVOKE_SETTING ProgressInvokeSetting
,
2211 #ifndef HAS_FN_PROGRESSW
2212 /* That's all this function does, at least up to w2k3... Even MS was too
2213 lazy to implement it... */
2214 return ERROR_CALL_NOT_IMPLEMENTED
;
2216 INERNAL_FNPROGRESSW_DATA ifnProgressData
;
2217 UNICODE_STRING ObjectName
;
2221 Status
= RtlCreateUnicodeStringFromAsciiz(&ObjectName
,
2223 if (!NT_SUCCESS(Status
))
2225 return RtlNtStatusToDosError(Status
);
2228 ifnProgressData
.fnProgress
= fnProgress
;
2229 ifnProgressData
.Args
= Args
;
2231 Ret
= TreeResetNamedSecurityInfoW(ObjectName
.Buffer
,
2239 (fnProgress
!= NULL
? InternalfnProgressW
: NULL
),
2240 ProgressInvokeSetting
,
2243 RtlFreeUnicodeString(&ObjectName
);