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
17 WELL_KNOWN_SID_TYPE type
;
20 SID_NAME_USE name_use
;
23 static const WCHAR Account_Operators
[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
24 static const WCHAR Administrator
[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
25 static const WCHAR Administrators
[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
26 static const WCHAR ANONYMOUS_LOGON
[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
27 static const WCHAR Authenticated_Users
[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
28 static const WCHAR Backup_Operators
[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
29 static const WCHAR BATCH
[] = { 'B','A','T','C','H',0 };
30 static const WCHAR Blank
[] = { 0 };
31 static const WCHAR BUILTIN
[] = { 'B','U','I','L','T','I','N',0 };
32 static const WCHAR Cert_Publishers
[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
33 static const WCHAR CREATOR_GROUP
[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
34 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 };
35 static const WCHAR CREATOR_OWNER
[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
36 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 };
37 static const WCHAR DIALUP
[] = { 'D','I','A','L','U','P',0 };
38 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 };
39 static const WCHAR DOMAIN
[] = {'D','O','M','A','I','N',0};
40 static const WCHAR Domain_Admins
[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
41 static const WCHAR Domain_Computers
[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
42 static const WCHAR Domain_Controllers
[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
43 static const WCHAR Domain_Guests
[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
44 static const WCHAR Domain_Users
[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
45 static const WCHAR Enterprise_Admins
[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
46 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 };
47 static const WCHAR Everyone
[] = { 'E','v','e','r','y','o','n','e',0 };
48 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 };
49 static const WCHAR Guest
[] = { 'G','u','e','s','t',0 };
50 static const WCHAR Guests
[] = { 'G','u','e','s','t','s',0 };
51 static const WCHAR INTERACTIVE
[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
52 static const WCHAR LOCAL
[] = { 'L','O','C','A','L',0 };
53 static const WCHAR LOCAL_SERVICE
[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
54 static const WCHAR NETWORK
[] = { 'N','E','T','W','O','R','K',0 };
55 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 };
56 static const WCHAR NETWORK_SERVICE
[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
57 static const WCHAR NT_AUTHORITY
[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
58 static const WCHAR NT_Pseudo_Domain
[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
59 static const WCHAR NTML_Authentication
[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
60 static const WCHAR NULL_SID
[] = { 'N','U','L','L',' ','S','I','D',0 };
61 static const WCHAR Other_Organization
[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
62 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 };
63 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 };
64 static const WCHAR Power_Users
[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
65 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 };
66 static const WCHAR Print_Operators
[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
67 static const WCHAR PROXY
[] = { 'P','R','O','X','Y',0 };
68 static const WCHAR RAS_and_IAS_Servers
[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
69 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 };
70 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 };
71 static const WCHAR Replicators
[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
72 static const WCHAR RESTRICTED
[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
73 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 };
74 static const WCHAR Schema_Admins
[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
75 static const WCHAR SELF
[] = { 'S','E','L','F',0 };
76 static const WCHAR Server_Operators
[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
77 static const WCHAR SERVICE
[] = { 'S','E','R','V','I','C','E',0 };
78 static const WCHAR SYSTEM
[] = { 'S','Y','S','T','E','M',0 };
79 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 };
80 static const WCHAR This_Organization
[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
81 static const WCHAR Users
[] = { 'U','s','e','r','s',0 };
83 static const AccountSid ACCOUNT_SIDS
[] = {
84 { WinNullSid
, NULL_SID
, Blank
, SidTypeWellKnownGroup
},
85 { WinWorldSid
, Everyone
, Blank
, SidTypeWellKnownGroup
},
86 { WinLocalSid
, LOCAL
, Blank
, SidTypeWellKnownGroup
},
87 { WinCreatorOwnerSid
, CREATOR_OWNER
, Blank
, SidTypeWellKnownGroup
},
88 { WinCreatorGroupSid
, CREATOR_GROUP
, Blank
, SidTypeWellKnownGroup
},
89 { WinCreatorOwnerServerSid
, CREATOR_OWNER_SERVER
, Blank
, SidTypeWellKnownGroup
},
90 { WinCreatorGroupServerSid
, CREATOR_GROUP_SERVER
, Blank
, SidTypeWellKnownGroup
},
91 { WinNtAuthoritySid
, NT_Pseudo_Domain
, NT_Pseudo_Domain
, SidTypeDomain
},
92 { WinDialupSid
, DIALUP
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
93 { WinNetworkSid
, NETWORK
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
94 { WinBatchSid
, BATCH
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
95 { WinInteractiveSid
, INTERACTIVE
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
96 { WinServiceSid
, SERVICE
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
97 { WinAnonymousSid
, ANONYMOUS_LOGON
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
98 { WinProxySid
, PROXY
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
99 { WinEnterpriseControllersSid
, ENTERPRISE_DOMAIN_CONTROLLERS
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
100 { WinSelfSid
, SELF
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
101 { WinAuthenticatedUserSid
, Authenticated_Users
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
102 { WinRestrictedCodeSid
, RESTRICTED
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
103 { WinTerminalServerSid
, TERMINAL_SERVER_USER
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
104 { WinRemoteLogonIdSid
, REMOTE_INTERACTIVE_LOGON
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
105 { WinLocalSystemSid
, SYSTEM
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
106 { WinLocalServiceSid
, LOCAL_SERVICE
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
107 { WinNetworkServiceSid
, NETWORK_SERVICE
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
108 { WinBuiltinDomainSid
, BUILTIN
, BUILTIN
, SidTypeDomain
},
109 { WinBuiltinAdministratorsSid
, Administrators
, BUILTIN
, SidTypeAlias
},
110 { WinBuiltinUsersSid
, Users
, BUILTIN
, SidTypeAlias
},
111 { WinBuiltinGuestsSid
, Guests
, BUILTIN
, SidTypeAlias
},
112 { WinBuiltinPowerUsersSid
, Power_Users
, BUILTIN
, SidTypeAlias
},
113 { WinBuiltinAccountOperatorsSid
, Account_Operators
, BUILTIN
, SidTypeAlias
},
114 { WinBuiltinSystemOperatorsSid
, Server_Operators
, BUILTIN
, SidTypeAlias
},
115 { WinBuiltinPrintOperatorsSid
, Print_Operators
, BUILTIN
, SidTypeAlias
},
116 { WinBuiltinBackupOperatorsSid
, Backup_Operators
, BUILTIN
, SidTypeAlias
},
117 { WinBuiltinReplicatorSid
, Replicators
, BUILTIN
, SidTypeAlias
},
118 { WinBuiltinPreWindows2000CompatibleAccessSid
, Pre_Windows_2000_Compatible_Access
, BUILTIN
, SidTypeAlias
},
119 { WinBuiltinRemoteDesktopUsersSid
, Remote_Desktop_Users
, BUILTIN
, SidTypeAlias
},
120 { WinBuiltinNetworkConfigurationOperatorsSid
, Network_Configuration_Operators
, BUILTIN
, SidTypeAlias
},
121 { WinNTLMAuthenticationSid
, NTML_Authentication
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
122 { WinDigestAuthenticationSid
, Digest_Authentication
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
123 { WinSChannelAuthenticationSid
, SChannel_Authentication
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
124 { WinThisOrganizationSid
, This_Organization
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
125 { WinOtherOrganizationSid
, Other_Organization
, NT_AUTHORITY
, SidTypeWellKnownGroup
},
126 { WinBuiltinPerfMonitoringUsersSid
, Performance_Monitor_Users
, BUILTIN
, SidTypeAlias
},
127 { WinBuiltinPerfLoggingUsersSid
, Performance_Log_Users
, BUILTIN
, SidTypeAlias
},
130 /* Interface to ntmarta.dll ***************************************************/
132 NTMARTA NtMartaStatic
= { 0 };
133 static PNTMARTA NtMarta
= NULL
;
135 #define FindNtMartaProc(Name) \
136 NtMartaStatic.Name = (PVOID)GetProcAddress(NtMartaStatic.hDllInstance, \
138 if (NtMartaStatic.Name == NULL) \
140 return GetLastError(); \
145 LoadAndInitializeNtMarta(VOID
)
147 /* this code may be executed simultaneously by multiple threads in case they're
148 trying to initialize the interface at the same time, but that's no problem
149 because the pointers returned by GetProcAddress will be the same. However,
150 only one of the threads will change the NtMarta pointer to the NtMartaStatic
151 structure, the others threads will detect that there were other threads
152 initializing the structure faster and will release the reference to the
155 NtMartaStatic
.hDllInstance
= LoadLibraryW(L
"ntmarta.dll");
156 if (NtMartaStatic
.hDllInstance
== NULL
)
158 return GetLastError();
162 FindNtMartaProc(LookupAccountTrustee
);
163 FindNtMartaProc(LookupAccountName
);
164 FindNtMartaProc(LookupAccountSid
);
165 FindNtMartaProc(SetEntriesInAList
);
166 FindNtMartaProc(ConvertAccessToSecurityDescriptor
);
167 FindNtMartaProc(ConvertSDToAccess
);
168 FindNtMartaProc(ConvertAclToAccess
);
169 FindNtMartaProc(GetAccessForTrustee
);
170 FindNtMartaProc(GetExplicitEntries
);
172 FindNtMartaProc(RewriteGetNamedRights
);
173 FindNtMartaProc(RewriteSetNamedRights
);
174 FindNtMartaProc(RewriteGetHandleRights
);
175 FindNtMartaProc(RewriteSetHandleRights
);
176 FindNtMartaProc(RewriteSetEntriesInAcl
);
177 FindNtMartaProc(RewriteGetExplicitEntriesFromAcl
);
178 FindNtMartaProc(TreeResetNamedSecurityInfo
);
179 FindNtMartaProc(GetInheritanceSource
);
180 FindNtMartaProc(FreeIndexArray
);
182 return ERROR_SUCCESS
;
187 CheckNtMartaPresent(VOID
)
191 if (InterlockedCompareExchangePointer((PVOID
)&NtMarta
,
195 /* we're the first one trying to use ntmarta, initialize it and change
196 the pointer after initialization */
197 ErrorCode
= LoadAndInitializeNtMarta();
199 if (ErrorCode
== ERROR_SUCCESS
)
201 /* try change the NtMarta pointer */
202 if (InterlockedCompareExchangePointer((PVOID
)&NtMarta
,
206 /* another thread initialized ntmarta in the meanwhile, release
207 the reference of the dll loaded. */
208 FreeLibrary(NtMartaStatic
.hDllInstance
);
214 ERR("Failed to initialize ntmarta.dll! Error: 0x%x", ErrorCode
);
220 /* ntmarta was already initialized */
221 ErrorCode
= ERROR_SUCCESS
;
231 if (InterlockedExchangePointer((PVOID
)&NtMarta
,
234 FreeLibrary(NtMartaStatic
.hDllInstance
);
239 /******************************************************************************/
246 AreAllAccessesGranted(DWORD GrantedAccess
,
249 return (BOOL
)RtlAreAllAccessesGranted(GrantedAccess
,
259 AreAnyAccessesGranted(DWORD GrantedAccess
,
262 return (BOOL
)RtlAreAnyAccessesGranted(GrantedAccess
,
267 /******************************************************************************
268 * GetFileSecurityA [ADVAPI32.@]
270 * Obtains Specified information about the security of a file or directory.
273 * lpFileName [I] Name of the file to get info for
274 * RequestedInformation [I] SE_ flags from "winnt.h"
275 * pSecurityDescriptor [O] Destination for security information
276 * nLength [I] Length of pSecurityDescriptor
277 * lpnLengthNeeded [O] Destination for length of returned security information
280 * Success: TRUE. pSecurityDescriptor contains the requested information.
281 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
284 * The information returned is constrained by the callers access rights and
291 GetFileSecurityA(LPCSTR lpFileName
,
292 SECURITY_INFORMATION RequestedInformation
,
293 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
295 LPDWORD lpnLengthNeeded
)
297 UNICODE_STRING FileName
;
301 Status
= RtlCreateUnicodeStringFromAsciiz(&FileName
,
303 if (!NT_SUCCESS(Status
))
305 SetLastError(RtlNtStatusToDosError(Status
));
309 bResult
= GetFileSecurityW(FileName
.Buffer
,
310 RequestedInformation
,
315 RtlFreeUnicodeString(&FileName
);
326 GetFileSecurityW(LPCWSTR lpFileName
,
327 SECURITY_INFORMATION RequestedInformation
,
328 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
330 LPDWORD lpnLengthNeeded
)
332 OBJECT_ATTRIBUTES ObjectAttributes
;
333 IO_STATUS_BLOCK StatusBlock
;
334 UNICODE_STRING FileName
;
335 ULONG AccessMask
= 0;
339 TRACE("GetFileSecurityW() called\n");
341 QuerySecurityAccessMask(RequestedInformation
, &AccessMask
);
343 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
348 ERR("Invalid path\n");
349 SetLastError(ERROR_INVALID_NAME
);
353 InitializeObjectAttributes(&ObjectAttributes
,
355 OBJ_CASE_INSENSITIVE
,
359 Status
= NtOpenFile(&FileHandle
,
363 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
366 RtlFreeHeap(RtlGetProcessHeap(),
370 if (!NT_SUCCESS(Status
))
372 ERR("NtOpenFile() failed (Status %lx)\n", Status
);
373 SetLastError(RtlNtStatusToDosError(Status
));
377 Status
= NtQuerySecurityObject(FileHandle
,
378 RequestedInformation
,
383 if (!NT_SUCCESS(Status
))
385 ERR("NtQuerySecurityObject() failed (Status %lx)\n", Status
);
386 SetLastError(RtlNtStatusToDosError(Status
));
399 GetKernelObjectSecurity(HANDLE Handle
,
400 SECURITY_INFORMATION RequestedInformation
,
401 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
403 LPDWORD lpnLengthNeeded
)
407 Status
= NtQuerySecurityObject(Handle
,
408 RequestedInformation
,
412 if (!NT_SUCCESS(Status
))
414 SetLastError(RtlNtStatusToDosError(Status
));
422 /******************************************************************************
423 * SetFileSecurityA [ADVAPI32.@]
424 * Sets the security of a file or directory
430 SetFileSecurityA(LPCSTR lpFileName
,
431 SECURITY_INFORMATION SecurityInformation
,
432 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
434 UNICODE_STRING FileName
;
438 Status
= RtlCreateUnicodeStringFromAsciiz(&FileName
,
440 if (!NT_SUCCESS(Status
))
442 SetLastError(RtlNtStatusToDosError(Status
));
446 bResult
= SetFileSecurityW(FileName
.Buffer
,
448 pSecurityDescriptor
);
450 RtlFreeUnicodeString(&FileName
);
456 /******************************************************************************
457 * SetFileSecurityW [ADVAPI32.@]
458 * Sets the security of a file or directory
464 SetFileSecurityW(LPCWSTR lpFileName
,
465 SECURITY_INFORMATION SecurityInformation
,
466 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
468 OBJECT_ATTRIBUTES ObjectAttributes
;
469 IO_STATUS_BLOCK StatusBlock
;
470 UNICODE_STRING FileName
;
471 ULONG AccessMask
= 0;
475 TRACE("SetFileSecurityW() called\n");
477 SetSecurityAccessMask(SecurityInformation
, &AccessMask
);
479 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
484 ERR("Invalid path\n");
485 SetLastError(ERROR_INVALID_NAME
);
489 InitializeObjectAttributes(&ObjectAttributes
,
491 OBJ_CASE_INSENSITIVE
,
495 Status
= NtOpenFile(&FileHandle
,
499 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
502 RtlFreeHeap(RtlGetProcessHeap(),
506 if (!NT_SUCCESS(Status
))
508 ERR("NtOpenFile() failed (Status %lx)\n", Status
);
509 SetLastError(RtlNtStatusToDosError(Status
));
513 Status
= NtSetSecurityObject(FileHandle
,
515 pSecurityDescriptor
);
518 if (!NT_SUCCESS(Status
))
520 ERR("NtSetSecurityObject() failed (Status %lx)\n", Status
);
521 SetLastError(RtlNtStatusToDosError(Status
));
534 SetKernelObjectSecurity(HANDLE Handle
,
535 SECURITY_INFORMATION SecurityInformation
,
536 PSECURITY_DESCRIPTOR SecurityDescriptor
)
540 Status
= NtSetSecurityObject(Handle
,
543 if (!NT_SUCCESS(Status
))
545 SetLastError(RtlNtStatusToDosError(Status
));
558 ImpersonateAnonymousToken(IN HANDLE ThreadHandle
)
562 Status
= NtImpersonateAnonymousToken(ThreadHandle
);
563 if (!NT_SUCCESS(Status
))
565 SetLastError(RtlNtStatusToDosError(Status
));
578 ImpersonateLoggedOnUser(HANDLE hToken
)
580 SECURITY_QUALITY_OF_SERVICE Qos
;
581 OBJECT_ATTRIBUTES ObjectAttributes
;
588 /* Get the token type */
589 Status
= NtQueryInformationToken(hToken
,
594 if (!NT_SUCCESS(Status
))
596 SetLastError(RtlNtStatusToDosError(Status
));
600 if (Type
== TokenPrimary
)
602 /* Create a duplicate impersonation token */
603 Qos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
604 Qos
.ImpersonationLevel
= SecurityImpersonation
;
605 Qos
.ContextTrackingMode
= SECURITY_DYNAMIC_TRACKING
;
606 Qos
.EffectiveOnly
= FALSE
;
608 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
609 ObjectAttributes
.RootDirectory
= NULL
;
610 ObjectAttributes
.ObjectName
= NULL
;
611 ObjectAttributes
.Attributes
= 0;
612 ObjectAttributes
.SecurityDescriptor
= NULL
;
613 ObjectAttributes
.SecurityQualityOfService
= &Qos
;
615 Status
= NtDuplicateToken(hToken
,
616 TOKEN_IMPERSONATE
| TOKEN_QUERY
,
621 if (!NT_SUCCESS(Status
))
623 SetLastError(RtlNtStatusToDosError(Status
));
631 /* User the original impersonation token */
636 /* Impersonate the the current thread */
637 Status
= NtSetInformationThread(NtCurrentThread(),
638 ThreadImpersonationToken
,
642 if (Duplicated
== TRUE
)
647 if (!NT_SUCCESS(Status
))
649 SetLastError(RtlNtStatusToDosError(Status
));
662 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
666 Status
= RtlImpersonateSelf(ImpersonationLevel
);
667 if (!NT_SUCCESS(Status
))
669 SetLastError(RtlNtStatusToDosError(Status
));
687 Status
= NtSetInformationThread(NtCurrentThread(),
688 ThreadImpersonationToken
,
691 if (!NT_SUCCESS(Status
))
693 SetLastError(RtlNtStatusToDosError(Status
));
701 /******************************************************************************
702 * GetUserNameA [ADVAPI32.@]
704 * Get the current user name.
707 * lpszName [O] Destination for the user name.
708 * lpSize [I/O] Size of lpszName.
715 GetUserNameA(LPSTR lpszName
,
718 UNICODE_STRING NameW
;
722 /* apparently Win doesn't check whether lpSize is valid at all! */
724 NameW
.MaximumLength
= (*lpSize
) * sizeof(WCHAR
);
725 NameW
.Buffer
= LocalAlloc(LMEM_FIXED
, NameW
.MaximumLength
);
726 if(NameW
.Buffer
== NULL
)
728 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
733 NameA
.MaximumLength
= ((*lpSize
) < 0xFFFF ? (USHORT
)(*lpSize
) : 0xFFFF);
734 NameA
.Buffer
= lpszName
;
736 Ret
= GetUserNameW(NameW
.Buffer
,
740 NameW
.Length
= (*lpSize
- 1) * sizeof(WCHAR
);
741 RtlUnicodeStringToAnsiString(&NameA
, &NameW
, FALSE
);
743 *lpSize
= NameA
.Length
+ 1;
746 LocalFree(NameW
.Buffer
);
752 /******************************************************************************
753 * GetUserNameW [ADVAPI32.@]
761 GetUserNameW(LPWSTR lpszName
,
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
);
794 CloseHandle ( hToken
);
797 if ( !GetTokenInformation ( hToken
, TokenUser
, tu_buf
, 36, &tu_len
) || tu_len
> 36 )
799 LocalFree ( tu_buf
);
800 tu_buf
= LocalAlloc ( LMEM_FIXED
, tu_len
);
803 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
804 CloseHandle ( hToken
);
807 if ( !GetTokenInformation ( hToken
, TokenUser
, tu_buf
, tu_len
, &tu_len
) )
809 /* don't call SetLastError(),
810 as GetTokenInformation() ought to have set one */
811 LocalFree ( tu_buf
);
812 CloseHandle ( hToken
);
816 CloseHandle ( hToken
);
817 token_user
= (TOKEN_USER
*)tu_buf
;
821 domain_name
= LocalAlloc ( LMEM_FIXED
, dn_len
* sizeof(WCHAR
) );
824 LocalFree ( tu_buf
);
825 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
828 if ( !LookupAccountSidW ( NULL
, token_user
->User
.Sid
, lpszName
, &an_len
, domain_name
, &dn_len
, &snu
)
833 LocalFree ( domain_name
);
834 domain_name
= LocalAlloc ( LMEM_FIXED
, dn_len
* sizeof(WCHAR
) );
837 LocalFree ( tu_buf
);
838 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
843 if ( !LookupAccountSidW ( NULL
, token_user
->User
.Sid
, lpszName
, &an_len
, domain_name
, &dn_len
, &snu
) )
845 /* don't call SetLastError(),
846 as LookupAccountSid() ought to have set one */
847 LocalFree ( domain_name
);
848 LocalFree ( tu_buf
);
854 LocalFree ( domain_name
);
855 LocalFree ( tu_buf
);
856 *lpSize
= an_len
+ 1;
861 /******************************************************************************
862 * LookupAccountSidA [ADVAPI32.@]
868 LookupAccountSidA(LPCSTR lpSystemName
,
872 LPSTR lpReferencedDomainName
,
873 LPDWORD cchReferencedDomainName
,
876 UNICODE_STRING NameW
, ReferencedDomainNameW
, SystemNameW
;
877 DWORD szName
, szReferencedDomainName
;
881 * save the buffer sizes the caller passed to us, as they may get modified and
882 * we require the original values when converting back to ansi
885 szReferencedDomainName
= *cchReferencedDomainName
;
888 * allocate buffers for the unicode strings to receive
894 NameW
.MaximumLength
= szName
* sizeof(WCHAR
);
895 NameW
.Buffer
= (PWSTR
)LocalAlloc(LMEM_FIXED
, NameW
.MaximumLength
);
896 if(NameW
.Buffer
== NULL
)
898 SetLastError(ERROR_OUTOFMEMORY
);
905 if(szReferencedDomainName
> 0)
907 ReferencedDomainNameW
.Length
= 0;
908 ReferencedDomainNameW
.MaximumLength
= szReferencedDomainName
* sizeof(WCHAR
);
909 ReferencedDomainNameW
.Buffer
= (PWSTR
)LocalAlloc(LMEM_FIXED
, ReferencedDomainNameW
.MaximumLength
);
910 if(ReferencedDomainNameW
.Buffer
== NULL
)
914 LocalFree(NameW
.Buffer
);
916 SetLastError(ERROR_OUTOFMEMORY
);
921 ReferencedDomainNameW
.Buffer
= NULL
;
924 * convert the system name to unicode - if present
927 if(lpSystemName
!= NULL
)
929 ANSI_STRING SystemNameA
;
931 RtlInitAnsiString(&SystemNameA
, lpSystemName
);
932 RtlAnsiStringToUnicodeString(&SystemNameW
, &SystemNameA
, TRUE
);
935 SystemNameW
.Buffer
= NULL
;
938 * it's time to call the unicode version
941 Ret
= LookupAccountSidW(SystemNameW
.Buffer
,
945 ReferencedDomainNameW
.Buffer
,
946 cchReferencedDomainName
,
951 * convert unicode strings back to ansi, don't forget that we can't convert
952 * more than 0xFFFF (USHORT) characters! Also don't forget to explicitly
953 * terminate the converted string, the Rtl functions don't do that!
960 NameA
.MaximumLength
= ((szName
<= 0xFFFF) ? (USHORT
)szName
: 0xFFFF);
961 NameA
.Buffer
= lpName
;
963 RtlUnicodeStringToAnsiString(&NameA
, &NameW
, FALSE
);
964 NameA
.Buffer
[NameA
.Length
] = '\0';
967 if(lpReferencedDomainName
!= NULL
)
969 ANSI_STRING ReferencedDomainNameA
;
971 ReferencedDomainNameA
.Length
= 0;
972 ReferencedDomainNameA
.MaximumLength
= ((szReferencedDomainName
<= 0xFFFF) ?
973 (USHORT
)szReferencedDomainName
: 0xFFFF);
974 ReferencedDomainNameA
.Buffer
= lpReferencedDomainName
;
976 RtlUnicodeStringToAnsiString(&ReferencedDomainNameA
, &ReferencedDomainNameW
, FALSE
);
977 ReferencedDomainNameA
.Buffer
[ReferencedDomainNameA
.Length
] = '\0';
982 * free previously allocated buffers
985 if(SystemNameW
.Buffer
!= NULL
)
987 RtlFreeUnicodeString(&SystemNameW
);
989 if(NameW
.Buffer
!= NULL
)
991 LocalFree(NameW
.Buffer
);
993 if(ReferencedDomainNameW
.Buffer
!= NULL
)
995 LocalFree(ReferencedDomainNameW
.Buffer
);
1002 /******************************************************************************
1003 * LookupAccountSidW [ADVAPI32.@]
1008 LookupAccountSidW(LPCWSTR pSystemName
,
1010 LPWSTR pAccountName
,
1011 LPDWORD pdwAccountName
,
1013 LPDWORD pdwDomainName
,
1014 PSID_NAME_USE peUse
)
1016 LSA_UNICODE_STRING SystemName
;
1017 LSA_OBJECT_ATTRIBUTES ObjectAttributes
= {0};
1018 LSA_HANDLE PolicyHandle
= NULL
;
1020 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain
= NULL
;
1021 PLSA_TRANSLATED_NAME TranslatedName
= NULL
;
1024 RtlInitUnicodeString ( &SystemName
, pSystemName
);
1025 Status
= LsaOpenPolicy ( &SystemName
, &ObjectAttributes
, POLICY_LOOKUP_NAMES
, &PolicyHandle
);
1026 if ( !NT_SUCCESS(Status
) )
1028 SetLastError ( LsaNtStatusToWinError(Status
) );
1031 Status
= LsaLookupSids ( PolicyHandle
, 1, &pSid
, &ReferencedDomain
, &TranslatedName
);
1033 LsaClose ( PolicyHandle
);
1035 if ( !NT_SUCCESS(Status
) || Status
== STATUS_SOME_NOT_MAPPED
)
1037 SetLastError ( LsaNtStatusToWinError(Status
) );
1043 if ( TranslatedName
)
1045 DWORD dwSrcLen
= TranslatedName
->Name
.Length
/ sizeof(WCHAR
);
1046 if ( *pdwAccountName
<= dwSrcLen
)
1048 *pdwAccountName
= dwSrcLen
+ 1;
1053 *pdwAccountName
= dwSrcLen
;
1056 RtlCopyMemory ( pAccountName
, TranslatedName
->Name
.Buffer
, TranslatedName
->Name
.Length
);
1057 pAccountName
[TranslatedName
->Name
.Length
/ sizeof(WCHAR
)] = L
'\0';
1061 *peUse
= TranslatedName
->Use
;
1064 if ( ReferencedDomain
)
1066 if ( ReferencedDomain
->Entries
> 0 )
1068 DWORD dwSrcLen
= ReferencedDomain
->Domains
[0].Name
.Length
/ sizeof(WCHAR
);
1069 if ( *pdwDomainName
<= dwSrcLen
)
1071 *pdwDomainName
= dwSrcLen
+ 1;
1076 *pdwDomainName
= dwSrcLen
;
1077 RtlCopyMemory ( pDomainName
, ReferencedDomain
->Domains
[0].Name
.Buffer
, ReferencedDomain
->Domains
[0].Name
.Length
);
1078 pDomainName
[ReferencedDomain
->Domains
[0].Name
.Length
/ sizeof(WCHAR
)] = L
'\0';
1084 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1087 if ( ReferencedDomain
)
1088 LsaFreeMemory ( ReferencedDomain
);
1089 if ( TranslatedName
)
1090 LsaFreeMemory ( TranslatedName
);
1097 /******************************************************************************
1098 * LookupAccountNameA [ADVAPI32.@]
1104 LookupAccountNameA(LPCSTR SystemName
,
1108 LPSTR ReferencedDomainName
,
1109 LPDWORD hReferencedDomainNameLength
,
1110 PSID_NAME_USE SidNameUse
)
1113 UNICODE_STRING lpSystemW
;
1114 UNICODE_STRING lpAccountW
;
1115 LPWSTR lpReferencedDomainNameW
= NULL
;
1117 RtlCreateUnicodeStringFromAsciiz(&lpSystemW
, SystemName
);
1118 RtlCreateUnicodeStringFromAsciiz(&lpAccountW
, AccountName
);
1120 if (ReferencedDomainName
)
1121 lpReferencedDomainNameW
= HeapAlloc(GetProcessHeap(),
1123 *hReferencedDomainNameLength
* sizeof(WCHAR
));
1125 ret
= LookupAccountNameW(lpSystemW
.Buffer
,
1129 lpReferencedDomainNameW
,
1130 hReferencedDomainNameLength
,
1133 if (ret
&& lpReferencedDomainNameW
)
1135 WideCharToMultiByte(CP_ACP
,
1137 lpReferencedDomainNameW
,
1138 *hReferencedDomainNameLength
,
1139 ReferencedDomainName
,
1140 *hReferencedDomainNameLength
,
1145 RtlFreeUnicodeString(&lpSystemW
);
1146 RtlFreeUnicodeString(&lpAccountW
);
1147 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW
);
1153 /******************************************************************************
1154 * LookupAccountNameW [ADVAPI32.@]
1160 LookupAccountNameW(LPCWSTR lpSystemName
,
1161 LPCWSTR lpAccountName
,
1164 LPWSTR ReferencedDomainName
,
1165 LPDWORD cchReferencedDomainName
,
1166 PSID_NAME_USE peUse
)
1168 /* Default implementation: Always return a default SID */
1169 SID_IDENTIFIER_AUTHORITY identifierAuthority
= {SECURITY_NT_AUTHORITY
};
1172 static const WCHAR dm
[] = {'D','O','M','A','I','N',0};
1175 TRACE("%s %s %p %p %p %p %p - stub\n", lpSystemName
, lpAccountName
,
1176 Sid
, cbSid
, ReferencedDomainName
, cchReferencedDomainName
, peUse
);
1178 for (i
= 0; i
< (sizeof(ACCOUNT_SIDS
) / sizeof(ACCOUNT_SIDS
[0])); i
++)
1180 if (!wcscmp(lpAccountName
, ACCOUNT_SIDS
[i
].account
))
1182 if (*cchReferencedDomainName
)
1183 *ReferencedDomainName
= '\0';
1184 *cchReferencedDomainName
= 0;
1185 *peUse
= SidTypeWellKnownGroup
;
1186 return CreateWellKnownSid(ACCOUNT_SIDS
[i
].type
, NULL
, Sid
, cbSid
);
1190 ret
= AllocateAndInitializeSid(&identifierAuthority
,
1192 SECURITY_BUILTIN_DOMAIN_RID
,
1193 DOMAIN_ALIAS_RID_ADMINS
,
1200 if (!RtlValidSid(pSid
))
1206 if (Sid
!= NULL
&& (*cbSid
>= GetLengthSid(pSid
)))
1207 CopySid(*cbSid
, Sid
, pSid
);
1209 if (*cbSid
< GetLengthSid(pSid
))
1211 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1215 *cbSid
= GetLengthSid(pSid
);
1217 if (ReferencedDomainName
!= NULL
&& (*cchReferencedDomainName
> wcslen(dm
)))
1218 wcscpy(ReferencedDomainName
, dm
);
1220 if (*cchReferencedDomainName
<= wcslen(dm
))
1222 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1226 *cchReferencedDomainName
= wcslen(dm
)+1;
1234 /**********************************************************************
1235 * LookupPrivilegeValueA EXPORTED
1241 LookupPrivilegeValueA(LPCSTR lpSystemName
,
1245 UNICODE_STRING SystemName
;
1246 UNICODE_STRING Name
;
1249 /* Remote system? */
1250 if (lpSystemName
!= NULL
)
1252 RtlCreateUnicodeStringFromAsciiz(&SystemName
,
1253 (LPSTR
)lpSystemName
);
1256 /* Check the privilege name is not NULL */
1259 SetLastError(ERROR_INVALID_PARAMETER
);
1263 RtlCreateUnicodeStringFromAsciiz(&Name
,
1266 Result
= LookupPrivilegeValueW((lpSystemName
!= NULL
) ? SystemName
.Buffer
: NULL
,
1270 RtlFreeUnicodeString(&Name
);
1272 /* Remote system? */
1273 if (lpSystemName
!= NULL
)
1275 RtlFreeUnicodeString(&SystemName
);
1282 /**********************************************************************
1283 * LookupPrivilegeValueW EXPORTED
1289 LookupPrivilegeValueW(LPCWSTR SystemName
,
1293 static const WCHAR
* const DefaultPrivNames
[] =
1295 L
"SeCreateTokenPrivilege",
1296 L
"SeAssignPrimaryTokenPrivilege",
1297 L
"SeLockMemoryPrivilege",
1298 L
"SeIncreaseQuotaPrivilege",
1299 L
"SeUnsolicitedInputPrivilege",
1300 L
"SeMachineAccountPrivilege",
1302 L
"SeSecurityPrivilege",
1303 L
"SeTakeOwnershipPrivilege",
1304 L
"SeLoadDriverPrivilege",
1305 L
"SeSystemProfilePrivilege",
1306 L
"SeSystemtimePrivilege",
1307 L
"SeProfileSingleProcessPrivilege",
1308 L
"SeIncreaseBasePriorityPrivilege",
1309 L
"SeCreatePagefilePrivilege",
1310 L
"SeCreatePermanentPrivilege",
1311 L
"SeBackupPrivilege",
1312 L
"SeRestorePrivilege",
1313 L
"SeShutdownPrivilege",
1314 L
"SeDebugPrivilege",
1315 L
"SeAuditPrivilege",
1316 L
"SeSystemEnvironmentPrivilege",
1317 L
"SeChangeNotifyPrivilege",
1318 L
"SeRemoteShutdownPrivilege",
1319 L
"SeUndockPrivilege",
1320 L
"SeSyncAgentPrivilege",
1321 L
"SeEnableDelegationPrivilege",
1322 L
"SeManageVolumePrivilege",
1323 L
"SeImpersonatePrivilege",
1324 L
"SeCreateGlobalPrivilege"
1328 if (NULL
!= SystemName
&& L
'\0' != *SystemName
)
1330 FIXME("LookupPrivilegeValueW: not implemented for remote system\n");
1331 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1335 for (Priv
= 0; Priv
< sizeof(DefaultPrivNames
) / sizeof(DefaultPrivNames
[0]); Priv
++)
1337 if (0 == wcscmp(PrivName
, DefaultPrivNames
[Priv
]))
1339 Luid
->LowPart
= Priv
+ 1;
1345 WARN("LookupPrivilegeValueW: no such privilege %S\n", PrivName
);
1346 SetLastError(ERROR_NO_SUCH_PRIVILEGE
);
1351 /**********************************************************************
1352 * LookupPrivilegeDisplayNameA EXPORTED
1358 LookupPrivilegeDisplayNameA(LPCSTR lpSystemName
,
1360 LPSTR lpDisplayName
,
1361 LPDWORD cbDisplayName
,
1362 LPDWORD lpLanguageId
)
1364 FIXME("%s() not implemented!\n", __FUNCTION__
);
1365 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1370 /**********************************************************************
1371 * LookupPrivilegeDisplayNameW EXPORTED
1377 LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName
,
1379 LPWSTR lpDisplayName
,
1380 LPDWORD cbDisplayName
,
1381 LPDWORD lpLanguageId
)
1383 FIXME("%s() not implemented!\n", __FUNCTION__
);
1384 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1389 /**********************************************************************
1390 * LookupPrivilegeNameA EXPORTED
1396 LookupPrivilegeNameA(LPCSTR lpSystemName
,
1401 FIXME("%s() not implemented!\n", __FUNCTION__
);
1402 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1407 /**********************************************************************
1408 * LookupPrivilegeNameW EXPORTED
1414 LookupPrivilegeNameW(LPCWSTR lpSystemName
,
1419 FIXME("%s() not implemented!\n", __FUNCTION__
);
1420 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1426 pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo
,
1431 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
1433 if ((SecurityInfo
& (OWNER_SECURITY_INFORMATION
|
1434 GROUP_SECURITY_INFORMATION
|
1435 DACL_SECURITY_INFORMATION
|
1436 SACL_SECURITY_INFORMATION
)) &&
1437 ppSecurityDescriptor
== NULL
)
1439 /* if one of the SIDs or ACLs are present, the security descriptor
1441 return ERROR_INVALID_PARAMETER
;
1445 /* reset the pointers unless they're ignored */
1446 if ((SecurityInfo
& OWNER_SECURITY_INFORMATION
) &&
1451 if ((SecurityInfo
& GROUP_SECURITY_INFORMATION
) &&
1456 if ((SecurityInfo
& DACL_SECURITY_INFORMATION
) &&
1461 if ((SecurityInfo
& SACL_SECURITY_INFORMATION
) &&
1467 if (SecurityInfo
& (OWNER_SECURITY_INFORMATION
|
1468 GROUP_SECURITY_INFORMATION
|
1469 DACL_SECURITY_INFORMATION
|
1470 SACL_SECURITY_INFORMATION
))
1472 *ppSecurityDescriptor
= NULL
;
1475 return ERROR_SUCCESS
;
1481 pSetSecurityInfoCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1482 SECURITY_INFORMATION SecurityInfo
,
1488 /* initialize a security descriptor on the stack */
1489 if (!InitializeSecurityDescriptor(pSecurityDescriptor
,
1490 SECURITY_DESCRIPTOR_REVISION
))
1492 return GetLastError();
1495 if (SecurityInfo
& OWNER_SECURITY_INFORMATION
)
1497 if (RtlValidSid(psidOwner
))
1499 if (!SetSecurityDescriptorOwner(pSecurityDescriptor
,
1503 return GetLastError();
1508 return ERROR_INVALID_PARAMETER
;
1512 if (SecurityInfo
& GROUP_SECURITY_INFORMATION
)
1514 if (RtlValidSid(psidGroup
))
1516 if (!SetSecurityDescriptorGroup(pSecurityDescriptor
,
1520 return GetLastError();
1525 return ERROR_INVALID_PARAMETER
;
1529 if (SecurityInfo
& DACL_SECURITY_INFORMATION
)
1533 if (SetSecurityDescriptorDacl(pSecurityDescriptor
,
1538 /* check if the DACL needs to be protected from being
1539 modified by inheritable ACEs */
1540 if (SecurityInfo
& PROTECTED_DACL_SECURITY_INFORMATION
)
1547 return GetLastError();
1553 /* protect the DACL from being modified by inheritable ACEs */
1554 if (!SetSecurityDescriptorControl(pSecurityDescriptor
,
1558 return GetLastError();
1563 if (SecurityInfo
& SACL_SECURITY_INFORMATION
)
1567 if (SetSecurityDescriptorSacl(pSecurityDescriptor
,
1572 /* check if the SACL needs to be protected from being
1573 modified by inheritable ACEs */
1574 if (SecurityInfo
& PROTECTED_SACL_SECURITY_INFORMATION
)
1581 return GetLastError();
1587 /* protect the SACL from being modified by inheritable ACEs */
1588 if (!SetSecurityDescriptorControl(pSecurityDescriptor
,
1592 return GetLastError();
1597 return ERROR_SUCCESS
;
1601 /**********************************************************************
1602 * GetNamedSecurityInfoW EXPORTED
1608 GetNamedSecurityInfoW(LPWSTR pObjectName
,
1609 SE_OBJECT_TYPE ObjectType
,
1610 SECURITY_INFORMATION SecurityInfo
,
1615 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1619 if (pObjectName
!= NULL
)
1621 ErrorCode
= CheckNtMartaPresent();
1622 if (ErrorCode
== ERROR_SUCCESS
)
1624 ErrorCode
= pGetSecurityInfoCheck(SecurityInfo
,
1629 ppSecurityDescriptor
);
1631 if (ErrorCode
== ERROR_SUCCESS
)
1633 /* call the MARTA provider */
1634 ErrorCode
= AccRewriteGetNamedRights(pObjectName
,
1641 ppSecurityDescriptor
);
1646 ErrorCode
= ERROR_INVALID_PARAMETER
;
1652 /**********************************************************************
1653 * GetNamedSecurityInfoA EXPORTED
1659 GetNamedSecurityInfoA(LPSTR pObjectName
,
1660 SE_OBJECT_TYPE ObjectType
,
1661 SECURITY_INFORMATION SecurityInfo
,
1666 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1668 UNICODE_STRING ObjectName
;
1672 Status
= RtlCreateUnicodeStringFromAsciiz(&ObjectName
,
1674 if (!NT_SUCCESS(Status
))
1676 return RtlNtStatusToDosError(Status
);
1679 Ret
= GetNamedSecurityInfoW(ObjectName
.Buffer
,
1686 ppSecurityDescriptor
);
1688 RtlFreeUnicodeString(&ObjectName
);
1694 /**********************************************************************
1695 * SetNamedSecurityInfoW EXPORTED
1701 SetNamedSecurityInfoW(LPWSTR pObjectName
,
1702 SE_OBJECT_TYPE ObjectType
,
1703 SECURITY_INFORMATION SecurityInfo
,
1711 if (pObjectName
!= NULL
)
1713 ErrorCode
= CheckNtMartaPresent();
1714 if (ErrorCode
== ERROR_SUCCESS
)
1716 SECURITY_DESCRIPTOR SecurityDescriptor
;
1718 ErrorCode
= pSetSecurityInfoCheck(&SecurityDescriptor
,
1725 if (ErrorCode
== ERROR_SUCCESS
)
1727 /* call the MARTA provider */
1728 ErrorCode
= AccRewriteSetNamedRights(pObjectName
,
1731 &SecurityDescriptor
);
1736 ErrorCode
= ERROR_INVALID_PARAMETER
;
1742 /**********************************************************************
1743 * SetNamedSecurityInfoA EXPORTED
1749 SetNamedSecurityInfoA(LPSTR pObjectName
,
1750 SE_OBJECT_TYPE ObjectType
,
1751 SECURITY_INFORMATION SecurityInfo
,
1757 UNICODE_STRING ObjectName
;
1761 Status
= RtlCreateUnicodeStringFromAsciiz(&ObjectName
,
1763 if (!NT_SUCCESS(Status
))
1765 return RtlNtStatusToDosError(Status
);
1768 Ret
= SetNamedSecurityInfoW(ObjectName
.Buffer
,
1776 RtlFreeUnicodeString(&ObjectName
);
1782 /**********************************************************************
1783 * GetSecurityInfo EXPORTED
1789 GetSecurityInfo(HANDLE handle
,
1790 SE_OBJECT_TYPE ObjectType
,
1791 SECURITY_INFORMATION SecurityInfo
,
1796 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1802 ErrorCode
= CheckNtMartaPresent();
1803 if (ErrorCode
== ERROR_SUCCESS
)
1805 ErrorCode
= pGetSecurityInfoCheck(SecurityInfo
,
1810 ppSecurityDescriptor
);
1812 if (ErrorCode
== ERROR_SUCCESS
)
1814 /* call the MARTA provider */
1815 ErrorCode
= AccRewriteGetHandleRights(handle
,
1822 ppSecurityDescriptor
);
1827 ErrorCode
= ERROR_INVALID_HANDLE
;
1833 /**********************************************************************
1834 * SetSecurityInfo EXPORTED
1840 SetSecurityInfo(HANDLE handle
,
1841 SE_OBJECT_TYPE ObjectType
,
1842 SECURITY_INFORMATION SecurityInfo
,
1852 ErrorCode
= CheckNtMartaPresent();
1853 if (ErrorCode
== ERROR_SUCCESS
)
1855 SECURITY_DESCRIPTOR SecurityDescriptor
;
1857 ErrorCode
= pSetSecurityInfoCheck(&SecurityDescriptor
,
1864 if (ErrorCode
== ERROR_SUCCESS
)
1866 /* call the MARTA provider */
1867 ErrorCode
= AccRewriteSetHandleRights(handle
,
1870 &SecurityDescriptor
);
1875 ErrorCode
= ERROR_INVALID_HANDLE
;
1881 /******************************************************************************
1882 * GetSecurityInfoExW EXPORTED
1886 GetSecurityInfoExA(HANDLE hObject
,
1887 SE_OBJECT_TYPE ObjectType
,
1888 SECURITY_INFORMATION SecurityInfo
,
1891 PACTRL_ACCESSA
*ppAccessList
,
1892 PACTRL_AUDITA
*ppAuditList
,
1896 FIXME("%s() not implemented!\n", __FUNCTION__
);
1897 return ERROR_BAD_PROVIDER
;
1901 /******************************************************************************
1902 * GetSecurityInfoExW EXPORTED
1906 GetSecurityInfoExW(HANDLE hObject
,
1907 SE_OBJECT_TYPE ObjectType
,
1908 SECURITY_INFORMATION SecurityInfo
,
1911 PACTRL_ACCESSW
*ppAccessList
,
1912 PACTRL_AUDITW
*ppAuditList
,
1916 FIXME("%s() not implemented!\n", __FUNCTION__
);
1917 return ERROR_BAD_PROVIDER
;
1921 /**********************************************************************
1922 * ImpersonateNamedPipeClient EXPORTED
1928 ImpersonateNamedPipeClient(HANDLE hNamedPipe
)
1930 IO_STATUS_BLOCK StatusBlock
;
1933 TRACE("ImpersonateNamedPipeClient() called\n");
1935 Status
= NtFsControlFile(hNamedPipe
,
1940 FSCTL_PIPE_IMPERSONATE
,
1945 if (!NT_SUCCESS(Status
))
1947 SetLastError(RtlNtStatusToDosError(Status
));
1960 CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor
,
1961 PSECURITY_DESCRIPTOR CreatorDescriptor
,
1962 PSECURITY_DESCRIPTOR
*NewDescriptor
,
1963 BOOL IsDirectoryObject
,
1965 PGENERIC_MAPPING GenericMapping
)
1969 Status
= RtlNewSecurityObject(ParentDescriptor
,
1975 if (!NT_SUCCESS(Status
))
1977 SetLastError(RtlNtStatusToDosError(Status
));
1990 CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor
,
1991 PSECURITY_DESCRIPTOR CreatorDescriptor
,
1992 PSECURITY_DESCRIPTOR
* NewDescriptor
,
1994 BOOL IsContainerObject
,
1995 ULONG AutoInheritFlags
,
1997 PGENERIC_MAPPING GenericMapping
)
1999 FIXME("%s() not implemented!\n", __FUNCTION__
);
2009 CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor
,
2010 PSECURITY_DESCRIPTOR CreatorDescriptor
,
2011 PSECURITY_DESCRIPTOR
* NewDescriptor
,
2014 BOOL IsContainerObject
,
2015 ULONG AutoInheritFlags
,
2017 PGENERIC_MAPPING GenericMapping
)
2019 FIXME("%s() not implemented!\n", __FUNCTION__
);
2029 DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR
*ObjectDescriptor
)
2033 Status
= RtlDeleteSecurityObject(ObjectDescriptor
);
2034 if (!NT_SUCCESS(Status
))
2036 SetLastError(RtlNtStatusToDosError(Status
));
2049 GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR ObjectDescriptor
,
2050 SECURITY_INFORMATION SecurityInformation
,
2051 PSECURITY_DESCRIPTOR ResultantDescriptor
,
2052 DWORD DescriptorLength
,
2053 PDWORD ReturnLength
)
2057 Status
= RtlQuerySecurityObject(ObjectDescriptor
,
2058 SecurityInformation
,
2059 ResultantDescriptor
,
2062 if (!NT_SUCCESS(Status
))
2064 SetLastError(RtlNtStatusToDosError(Status
));
2077 SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation
,
2078 PSECURITY_DESCRIPTOR ModificationDescriptor
,
2079 PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
2080 PGENERIC_MAPPING GenericMapping
,
2085 Status
= RtlSetSecurityObject(SecurityInformation
,
2086 ModificationDescriptor
,
2087 ObjectsSecurityDescriptor
,
2090 if (!NT_SUCCESS(Status
))
2092 SetLastError(RtlNtStatusToDosError(Status
));
2105 TreeResetNamedSecurityInfoW(LPWSTR pObjectName
,
2106 SE_OBJECT_TYPE ObjectType
,
2107 SECURITY_INFORMATION SecurityInfo
,
2113 FN_PROGRESSW fnProgress
,
2114 PROG_INVOKE_SETTING ProgressInvokeSetting
,
2119 if (pObjectName
!= NULL
)
2121 ErrorCode
= CheckNtMartaPresent();
2122 if (ErrorCode
== ERROR_SUCCESS
)
2126 case SE_FILE_OBJECT
:
2127 case SE_REGISTRY_KEY
:
2129 /* check the SecurityInfo flags for sanity (both, the protected
2130 and unprotected dacl/sacl flag must not be passed together) */
2131 if (((SecurityInfo
& DACL_SECURITY_INFORMATION
) &&
2132 (SecurityInfo
& (PROTECTED_DACL_SECURITY_INFORMATION
| UNPROTECTED_DACL_SECURITY_INFORMATION
)) ==
2133 (PROTECTED_DACL_SECURITY_INFORMATION
| UNPROTECTED_DACL_SECURITY_INFORMATION
))
2137 ((SecurityInfo
& SACL_SECURITY_INFORMATION
) &&
2138 (SecurityInfo
& (PROTECTED_SACL_SECURITY_INFORMATION
| UNPROTECTED_SACL_SECURITY_INFORMATION
)) ==
2139 (PROTECTED_SACL_SECURITY_INFORMATION
| UNPROTECTED_SACL_SECURITY_INFORMATION
)))
2141 ErrorCode
= ERROR_INVALID_PARAMETER
;
2145 /* call the MARTA provider */
2146 ErrorCode
= AccTreeResetNamedSecurityInfo(pObjectName
,
2155 ProgressInvokeSetting
,
2161 /* object type not supported */
2162 ErrorCode
= ERROR_INVALID_PARAMETER
;
2168 ErrorCode
= ERROR_INVALID_PARAMETER
;
2173 #ifdef HAS_FN_PROGRESSW
2175 typedef struct _INERNAL_FNPROGRESSW_DATA
2177 FN_PROGRESSA fnProgress
;
2179 } INERNAL_FNPROGRESSW_DATA
, *PINERNAL_FNPROGRESSW_DATA
;
2182 InternalfnProgressW(LPWSTR pObjectName
,
2184 PPROG_INVOKE_SETTING pInvokeSetting
,
2188 PINERNAL_FNPROGRESSW_DATA pifnProgressData
= (PINERNAL_FNPROGRESSW_DATA
)Args
;
2192 ObjectNameSize
= WideCharToMultiByte(CP_ACP
,
2201 if (ObjectNameSize
> 0)
2203 pObjectNameA
= RtlAllocateHeap(RtlGetProcessHeap(),
2206 if (pObjectNameA
!= NULL
)
2208 pObjectNameA
[0] = '\0';
2209 WideCharToMultiByte(CP_ACP
,
2218 pifnProgressData
->fnProgress((LPWSTR
)pObjectNameA
, /* FIXME: wrong cast!! */
2221 pifnProgressData
->Args
,
2224 RtlFreeHeap(RtlGetProcessHeap(),
2238 TreeResetNamedSecurityInfoA(LPSTR pObjectName
,
2239 SE_OBJECT_TYPE ObjectType
,
2240 SECURITY_INFORMATION SecurityInfo
,
2246 FN_PROGRESSA fnProgress
,
2247 PROG_INVOKE_SETTING ProgressInvokeSetting
,
2250 #ifndef HAS_FN_PROGRESSW
2251 /* That's all this function does, at least up to w2k3... Even MS was too
2252 lazy to implement it... */
2253 return ERROR_CALL_NOT_IMPLEMENTED
;
2255 INERNAL_FNPROGRESSW_DATA ifnProgressData
;
2256 UNICODE_STRING ObjectName
;
2260 Status
= RtlCreateUnicodeStringFromAsciiz(&ObjectName
,
2262 if (!NT_SUCCESS(Status
))
2264 return RtlNtStatusToDosError(Status
);
2267 ifnProgressData
.fnProgress
= fnProgress
;
2268 ifnProgressData
.Args
= Args
;
2270 Ret
= TreeResetNamedSecurityInfoW(ObjectName
.Buffer
,
2278 (fnProgress
!= NULL
? InternalfnProgressW
: NULL
),
2279 ProgressInvokeSetting
,
2282 RtlFreeUnicodeString(&ObjectName
);