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(&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(&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(&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 if (RequestedInformation
&
342 (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION
))
344 AccessMask
|= READ_CONTROL
;
347 if (RequestedInformation
& SACL_SECURITY_INFORMATION
)
349 AccessMask
|= ACCESS_SYSTEM_SECURITY
;
352 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
357 ERR("Invalid path\n");
358 SetLastError(ERROR_INVALID_NAME
);
362 InitializeObjectAttributes(&ObjectAttributes
,
364 OBJ_CASE_INSENSITIVE
,
368 Status
= NtOpenFile(&FileHandle
,
372 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
375 RtlFreeHeap(RtlGetProcessHeap(),
379 if (!NT_SUCCESS(Status
))
381 ERR("NtOpenFile() failed (Status %lx)\n", Status
);
382 SetLastError(RtlNtStatusToDosError(Status
));
386 Status
= NtQuerySecurityObject(FileHandle
,
387 RequestedInformation
,
392 if (!NT_SUCCESS(Status
))
394 ERR("NtQuerySecurityObject() failed (Status %lx)\n", Status
);
395 SetLastError(RtlNtStatusToDosError(Status
));
408 GetKernelObjectSecurity(HANDLE Handle
,
409 SECURITY_INFORMATION RequestedInformation
,
410 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
412 LPDWORD lpnLengthNeeded
)
416 Status
= NtQuerySecurityObject(Handle
,
417 RequestedInformation
,
421 if (!NT_SUCCESS(Status
))
423 SetLastError(RtlNtStatusToDosError(Status
));
431 /******************************************************************************
432 * SetFileSecurityA [ADVAPI32.@]
433 * Sets the security of a file or directory
439 SetFileSecurityA(LPCSTR lpFileName
,
440 SECURITY_INFORMATION SecurityInformation
,
441 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
443 UNICODE_STRING FileName
;
447 Status
= RtlCreateUnicodeStringFromAsciiz(&FileName
,
449 if (!NT_SUCCESS(Status
))
451 SetLastError(RtlNtStatusToDosError(Status
));
455 bResult
= SetFileSecurityW(FileName
.Buffer
,
457 pSecurityDescriptor
);
459 RtlFreeUnicodeString(&FileName
);
465 /******************************************************************************
466 * SetFileSecurityW [ADVAPI32.@]
467 * Sets the security of a file or directory
473 SetFileSecurityW(LPCWSTR lpFileName
,
474 SECURITY_INFORMATION SecurityInformation
,
475 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
477 OBJECT_ATTRIBUTES ObjectAttributes
;
478 IO_STATUS_BLOCK StatusBlock
;
479 UNICODE_STRING FileName
;
480 ULONG AccessMask
= 0;
484 TRACE("SetFileSecurityW() called\n");
486 if (SecurityInformation
&
487 (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
))
489 AccessMask
|= WRITE_OWNER
;
492 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
494 AccessMask
|= WRITE_DAC
;
497 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
499 AccessMask
|= ACCESS_SYSTEM_SECURITY
;
502 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
507 ERR("Invalid path\n");
508 SetLastError(ERROR_INVALID_NAME
);
512 InitializeObjectAttributes(&ObjectAttributes
,
514 OBJ_CASE_INSENSITIVE
,
518 Status
= NtOpenFile(&FileHandle
,
522 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
525 RtlFreeHeap(RtlGetProcessHeap(),
529 if (!NT_SUCCESS(Status
))
531 ERR("NtOpenFile() failed (Status %lx)\n", Status
);
532 SetLastError(RtlNtStatusToDosError(Status
));
536 Status
= NtSetSecurityObject(FileHandle
,
538 pSecurityDescriptor
);
541 if (!NT_SUCCESS(Status
))
543 ERR("NtSetSecurityObject() failed (Status %lx)\n", Status
);
544 SetLastError(RtlNtStatusToDosError(Status
));
557 SetKernelObjectSecurity(HANDLE Handle
,
558 SECURITY_INFORMATION SecurityInformation
,
559 PSECURITY_DESCRIPTOR SecurityDescriptor
)
563 Status
= NtSetSecurityObject(Handle
,
566 if (!NT_SUCCESS(Status
))
568 SetLastError(RtlNtStatusToDosError(Status
));
581 ImpersonateAnonymousToken(IN HANDLE ThreadHandle
)
585 Status
= NtImpersonateAnonymousToken(ThreadHandle
);
586 if (!NT_SUCCESS(Status
))
588 SetLastError(RtlNtStatusToDosError(Status
));
601 ImpersonateLoggedOnUser(HANDLE hToken
)
603 SECURITY_QUALITY_OF_SERVICE Qos
;
604 OBJECT_ATTRIBUTES ObjectAttributes
;
611 /* Get the token type */
612 Status
= NtQueryInformationToken(hToken
,
617 if (!NT_SUCCESS(Status
))
619 SetLastError(RtlNtStatusToDosError(Status
));
623 if (Type
== TokenPrimary
)
625 /* Create a duplicate impersonation token */
626 Qos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
627 Qos
.ImpersonationLevel
= SecurityImpersonation
;
628 Qos
.ContextTrackingMode
= SECURITY_DYNAMIC_TRACKING
;
629 Qos
.EffectiveOnly
= FALSE
;
631 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
632 ObjectAttributes
.RootDirectory
= NULL
;
633 ObjectAttributes
.ObjectName
= NULL
;
634 ObjectAttributes
.Attributes
= 0;
635 ObjectAttributes
.SecurityDescriptor
= NULL
;
636 ObjectAttributes
.SecurityQualityOfService
= &Qos
;
638 Status
= NtDuplicateToken(hToken
,
639 TOKEN_IMPERSONATE
| TOKEN_QUERY
,
644 if (!NT_SUCCESS(Status
))
646 SetLastError(RtlNtStatusToDosError(Status
));
654 /* User the original impersonation token */
659 /* Impersonate the the current thread */
660 Status
= NtSetInformationThread(NtCurrentThread(),
661 ThreadImpersonationToken
,
665 if (Duplicated
== TRUE
)
670 if (!NT_SUCCESS(Status
))
672 SetLastError(RtlNtStatusToDosError(Status
));
685 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
689 Status
= RtlImpersonateSelf(ImpersonationLevel
);
690 if (!NT_SUCCESS(Status
))
692 SetLastError(RtlNtStatusToDosError(Status
));
710 Status
= NtSetInformationThread(NtCurrentThread(),
711 ThreadImpersonationToken
,
714 if (!NT_SUCCESS(Status
))
716 SetLastError(RtlNtStatusToDosError(Status
));
724 /******************************************************************************
725 * GetUserNameA [ADVAPI32.@]
727 * Get the current user name.
730 * lpszName [O] Destination for the user name.
731 * lpSize [I/O] Size of lpszName.
738 GetUserNameA(LPSTR lpszName
,
741 UNICODE_STRING NameW
;
745 /* apparently Win doesn't check whether lpSize is valid at all! */
747 NameW
.MaximumLength
= (*lpSize
) * sizeof(WCHAR
);
748 NameW
.Buffer
= LocalAlloc(LMEM_FIXED
, NameW
.MaximumLength
);
749 if(NameW
.Buffer
== NULL
)
751 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
756 NameA
.MaximumLength
= ((*lpSize
) < 0xFFFF ? (USHORT
)(*lpSize
) : 0xFFFF);
757 NameA
.Buffer
= lpszName
;
759 Ret
= GetUserNameW(NameW
.Buffer
,
763 NameW
.Length
= (*lpSize
- 1) * sizeof(WCHAR
);
764 RtlUnicodeStringToAnsiString(&NameA
, &NameW
, FALSE
);
766 *lpSize
= NameA
.Length
+ 1;
769 LocalFree(NameW
.Buffer
);
775 /******************************************************************************
776 * GetUserNameW [ADVAPI32.@]
784 GetUserNameW(LPWSTR lpszName
,
787 HANDLE hToken
= INVALID_HANDLE_VALUE
;
790 TOKEN_USER
* token_user
= NULL
;
792 SID_NAME_USE snu
= SidTypeUser
;
793 WCHAR
* domain_name
= NULL
;
796 if ( !OpenThreadToken ( GetCurrentThread(), TOKEN_QUERY
, FALSE
, &hToken
) )
798 DWORD dwLastError
= GetLastError();
799 if ( dwLastError
!= ERROR_NO_TOKEN
800 && dwLastError
!= ERROR_NO_IMPERSONATION_TOKEN
)
802 /* don't call SetLastError(),
803 as OpenThreadToken() ought to have set one */
806 if ( !OpenProcessToken ( GetCurrentProcess(), TOKEN_QUERY
, &hToken
) )
808 /* don't call SetLastError(),
809 as OpenProcessToken() ought to have set one */
813 tu_buf
= LocalAlloc ( LMEM_FIXED
, 36 );
816 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
817 CloseHandle ( hToken
);
820 if ( !GetTokenInformation ( hToken
, TokenUser
, tu_buf
, 36, &tu_len
) || tu_len
> 36 )
822 LocalFree ( tu_buf
);
823 tu_buf
= LocalAlloc ( LMEM_FIXED
, tu_len
);
826 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
827 CloseHandle ( hToken
);
830 if ( !GetTokenInformation ( hToken
, TokenUser
, tu_buf
, tu_len
, &tu_len
) )
832 /* don't call SetLastError(),
833 as GetTokenInformation() ought to have set one */
834 LocalFree ( tu_buf
);
835 CloseHandle ( hToken
);
839 CloseHandle ( hToken
);
840 token_user
= (TOKEN_USER
*)tu_buf
;
844 domain_name
= LocalAlloc ( LMEM_FIXED
, dn_len
* sizeof(WCHAR
) );
847 LocalFree ( tu_buf
);
848 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
851 if ( !LookupAccountSidW ( NULL
, token_user
->User
.Sid
, lpszName
, &an_len
, domain_name
, &dn_len
, &snu
)
856 LocalFree ( domain_name
);
857 domain_name
= LocalAlloc ( LMEM_FIXED
, dn_len
* sizeof(WCHAR
) );
860 LocalFree ( tu_buf
);
861 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
866 if ( !LookupAccountSidW ( NULL
, token_user
->User
.Sid
, lpszName
, &an_len
, domain_name
, &dn_len
, &snu
) )
868 /* don't call SetLastError(),
869 as LookupAccountSid() ought to have set one */
870 LocalFree ( domain_name
);
871 LocalFree ( tu_buf
);
877 LocalFree ( domain_name
);
878 LocalFree ( tu_buf
);
879 *lpSize
= an_len
+ 1;
884 /******************************************************************************
885 * LookupAccountSidA [ADVAPI32.@]
891 LookupAccountSidA(LPCSTR lpSystemName
,
895 LPSTR lpReferencedDomainName
,
896 LPDWORD cchReferencedDomainName
,
899 UNICODE_STRING NameW
, ReferencedDomainNameW
, SystemNameW
;
900 DWORD szName
, szReferencedDomainName
;
904 * save the buffer sizes the caller passed to us, as they may get modified and
905 * we require the original values when converting back to ansi
908 szReferencedDomainName
= *cchReferencedDomainName
;
911 * allocate buffers for the unicode strings to receive
917 NameW
.MaximumLength
= szName
* sizeof(WCHAR
);
918 NameW
.Buffer
= (PWSTR
)LocalAlloc(LMEM_FIXED
, NameW
.MaximumLength
);
919 if(NameW
.Buffer
== NULL
)
921 SetLastError(ERROR_OUTOFMEMORY
);
928 if(szReferencedDomainName
> 0)
930 ReferencedDomainNameW
.Length
= 0;
931 ReferencedDomainNameW
.MaximumLength
= szReferencedDomainName
* sizeof(WCHAR
);
932 ReferencedDomainNameW
.Buffer
= (PWSTR
)LocalAlloc(LMEM_FIXED
, ReferencedDomainNameW
.MaximumLength
);
933 if(ReferencedDomainNameW
.Buffer
== NULL
)
937 LocalFree(NameW
.Buffer
);
939 SetLastError(ERROR_OUTOFMEMORY
);
944 ReferencedDomainNameW
.Buffer
= NULL
;
947 * convert the system name to unicode - if present
950 if(lpSystemName
!= NULL
)
952 ANSI_STRING SystemNameA
;
954 RtlInitAnsiString(&SystemNameA
, lpSystemName
);
955 RtlAnsiStringToUnicodeString(&SystemNameW
, &SystemNameA
, TRUE
);
958 SystemNameW
.Buffer
= NULL
;
961 * it's time to call the unicode version
964 Ret
= LookupAccountSidW(SystemNameW
.Buffer
,
968 ReferencedDomainNameW
.Buffer
,
969 cchReferencedDomainName
,
974 * convert unicode strings back to ansi, don't forget that we can't convert
975 * more than 0xFFFF (USHORT) characters! Also don't forget to explicitly
976 * terminate the converted string, the Rtl functions don't do that!
983 NameA
.MaximumLength
= ((szName
<= 0xFFFF) ? (USHORT
)szName
: 0xFFFF);
984 NameA
.Buffer
= lpName
;
986 RtlUnicodeStringToAnsiString(&NameA
, &NameW
, FALSE
);
987 NameA
.Buffer
[NameA
.Length
] = '\0';
990 if(lpReferencedDomainName
!= NULL
)
992 ANSI_STRING ReferencedDomainNameA
;
994 ReferencedDomainNameA
.Length
= 0;
995 ReferencedDomainNameA
.MaximumLength
= ((szReferencedDomainName
<= 0xFFFF) ?
996 (USHORT
)szReferencedDomainName
: 0xFFFF);
997 ReferencedDomainNameA
.Buffer
= lpReferencedDomainName
;
999 RtlUnicodeStringToAnsiString(&ReferencedDomainNameA
, &ReferencedDomainNameW
, FALSE
);
1000 ReferencedDomainNameA
.Buffer
[ReferencedDomainNameA
.Length
] = '\0';
1005 * free previously allocated buffers
1008 if(SystemNameW
.Buffer
!= NULL
)
1010 RtlFreeUnicodeString(&SystemNameW
);
1012 if(NameW
.Buffer
!= NULL
)
1014 LocalFree(NameW
.Buffer
);
1016 if(ReferencedDomainNameW
.Buffer
!= NULL
)
1018 LocalFree(ReferencedDomainNameW
.Buffer
);
1025 /******************************************************************************
1026 * LookupAccountSidW [ADVAPI32.@]
1031 LookupAccountSidW(LPCWSTR pSystemName
,
1033 LPWSTR pAccountName
,
1034 LPDWORD pdwAccountName
,
1036 LPDWORD pdwDomainName
,
1037 PSID_NAME_USE peUse
)
1039 LSA_UNICODE_STRING SystemName
;
1040 LSA_OBJECT_ATTRIBUTES ObjectAttributes
= {0};
1041 LSA_HANDLE PolicyHandle
= NULL
;
1043 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain
= NULL
;
1044 PLSA_TRANSLATED_NAME TranslatedName
= NULL
;
1047 RtlInitUnicodeString ( &SystemName
, pSystemName
);
1048 Status
= LsaOpenPolicy ( &SystemName
, &ObjectAttributes
, POLICY_LOOKUP_NAMES
, &PolicyHandle
);
1049 if ( !NT_SUCCESS(Status
) )
1051 SetLastError ( LsaNtStatusToWinError(Status
) );
1054 Status
= LsaLookupSids ( PolicyHandle
, 1, &pSid
, &ReferencedDomain
, &TranslatedName
);
1056 LsaClose ( PolicyHandle
);
1058 if ( !NT_SUCCESS(Status
) || Status
== STATUS_SOME_NOT_MAPPED
)
1060 SetLastError ( LsaNtStatusToWinError(Status
) );
1066 if ( TranslatedName
)
1068 DWORD dwSrcLen
= TranslatedName
->Name
.Length
/ sizeof(WCHAR
);
1069 if ( *pdwAccountName
<= dwSrcLen
)
1071 *pdwAccountName
= dwSrcLen
+ 1;
1076 *pdwAccountName
= dwSrcLen
;
1079 RtlCopyMemory ( pAccountName
, TranslatedName
->Name
.Buffer
, TranslatedName
->Name
.Length
);
1080 pAccountName
[TranslatedName
->Name
.Length
/ sizeof(WCHAR
)] = L
'\0';
1084 *peUse
= TranslatedName
->Use
;
1087 if ( ReferencedDomain
)
1089 if ( ReferencedDomain
->Entries
> 0 )
1091 DWORD dwSrcLen
= ReferencedDomain
->Domains
[0].Name
.Length
/ sizeof(WCHAR
);
1092 if ( *pdwDomainName
<= dwSrcLen
)
1094 *pdwDomainName
= dwSrcLen
+ 1;
1099 *pdwDomainName
= dwSrcLen
;
1100 RtlCopyMemory ( pDomainName
, ReferencedDomain
->Domains
[0].Name
.Buffer
, ReferencedDomain
->Domains
[0].Name
.Length
);
1101 pDomainName
[ReferencedDomain
->Domains
[0].Name
.Length
/ sizeof(WCHAR
)] = L
'\0';
1107 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1110 if ( ReferencedDomain
)
1111 LsaFreeMemory ( ReferencedDomain
);
1112 if ( TranslatedName
)
1113 LsaFreeMemory ( TranslatedName
);
1120 /******************************************************************************
1121 * LookupAccountNameA [ADVAPI32.@]
1127 LookupAccountNameA(LPCSTR SystemName
,
1131 LPSTR ReferencedDomainName
,
1132 LPDWORD hReferencedDomainNameLength
,
1133 PSID_NAME_USE SidNameUse
)
1136 UNICODE_STRING lpSystemW
;
1137 UNICODE_STRING lpAccountW
;
1138 LPWSTR lpReferencedDomainNameW
= NULL
;
1140 RtlCreateUnicodeStringFromAsciiz(&lpSystemW
, SystemName
);
1141 RtlCreateUnicodeStringFromAsciiz(&lpAccountW
, AccountName
);
1143 if (ReferencedDomainName
)
1144 lpReferencedDomainNameW
= HeapAlloc(GetProcessHeap(),
1146 *hReferencedDomainNameLength
* sizeof(WCHAR
));
1148 ret
= LookupAccountNameW(lpSystemW
.Buffer
,
1152 lpReferencedDomainNameW
,
1153 hReferencedDomainNameLength
,
1156 if (ret
&& lpReferencedDomainNameW
)
1158 WideCharToMultiByte(CP_ACP
,
1160 lpReferencedDomainNameW
,
1161 *hReferencedDomainNameLength
,
1162 ReferencedDomainName
,
1163 *hReferencedDomainNameLength
,
1168 RtlFreeUnicodeString(&lpSystemW
);
1169 RtlFreeUnicodeString(&lpAccountW
);
1170 HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW
);
1176 /******************************************************************************
1177 * LookupAccountNameW [ADVAPI32.@]
1183 LookupAccountNameW(LPCWSTR lpSystemName
,
1184 LPCWSTR lpAccountName
,
1187 LPWSTR ReferencedDomainName
,
1188 LPDWORD cchReferencedDomainName
,
1189 PSID_NAME_USE peUse
)
1191 /* Default implementation: Always return a default SID */
1192 SID_IDENTIFIER_AUTHORITY identifierAuthority
= {SECURITY_NT_AUTHORITY
};
1195 static const WCHAR dm
[] = {'D','O','M','A','I','N',0};
1198 TRACE("%s %s %p %p %p %p %p - stub\n", lpSystemName
, lpAccountName
,
1199 Sid
, cbSid
, ReferencedDomainName
, cchReferencedDomainName
, peUse
);
1201 for (i
= 0; i
< (sizeof(ACCOUNT_SIDS
) / sizeof(ACCOUNT_SIDS
[0])); i
++)
1203 if (!wcscmp(lpAccountName
, ACCOUNT_SIDS
[i
].account
))
1205 if (*cchReferencedDomainName
)
1206 *ReferencedDomainName
= '\0';
1207 *cchReferencedDomainName
= 0;
1208 *peUse
= SidTypeWellKnownGroup
;
1209 return CreateWellKnownSid(ACCOUNT_SIDS
[i
].type
, NULL
, Sid
, cbSid
);
1213 ret
= AllocateAndInitializeSid(&identifierAuthority
,
1215 SECURITY_BUILTIN_DOMAIN_RID
,
1216 DOMAIN_ALIAS_RID_ADMINS
,
1223 if (!RtlValidSid(pSid
))
1229 if (Sid
!= NULL
&& (*cbSid
>= GetLengthSid(pSid
)))
1230 CopySid(*cbSid
, Sid
, pSid
);
1232 if (*cbSid
< GetLengthSid(pSid
))
1234 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1238 *cbSid
= GetLengthSid(pSid
);
1240 if (ReferencedDomainName
!= NULL
&& (*cchReferencedDomainName
> wcslen(dm
)))
1241 wcscpy(ReferencedDomainName
, dm
);
1243 if (*cchReferencedDomainName
<= wcslen(dm
))
1245 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1249 *cchReferencedDomainName
= wcslen(dm
)+1;
1257 /**********************************************************************
1258 * LookupPrivilegeValueA EXPORTED
1264 LookupPrivilegeValueA(LPCSTR lpSystemName
,
1268 UNICODE_STRING SystemName
;
1269 UNICODE_STRING Name
;
1272 /* Remote system? */
1273 if (lpSystemName
!= NULL
)
1275 RtlCreateUnicodeStringFromAsciiz(&SystemName
,
1276 (LPSTR
)lpSystemName
);
1279 /* Check the privilege name is not NULL */
1282 SetLastError(ERROR_INVALID_PARAMETER
);
1286 RtlCreateUnicodeStringFromAsciiz(&Name
,
1289 Result
= LookupPrivilegeValueW((lpSystemName
!= NULL
) ? SystemName
.Buffer
: NULL
,
1293 RtlFreeUnicodeString(&Name
);
1295 /* Remote system? */
1296 if (lpSystemName
!= NULL
)
1298 RtlFreeUnicodeString(&SystemName
);
1305 /**********************************************************************
1306 * LookupPrivilegeValueW EXPORTED
1312 LookupPrivilegeValueW(LPCWSTR SystemName
,
1316 static const WCHAR
* const DefaultPrivNames
[] =
1318 L
"SeCreateTokenPrivilege",
1319 L
"SeAssignPrimaryTokenPrivilege",
1320 L
"SeLockMemoryPrivilege",
1321 L
"SeIncreaseQuotaPrivilege",
1322 L
"SeUnsolicitedInputPrivilege",
1323 L
"SeMachineAccountPrivilege",
1325 L
"SeSecurityPrivilege",
1326 L
"SeTakeOwnershipPrivilege",
1327 L
"SeLoadDriverPrivilege",
1328 L
"SeSystemProfilePrivilege",
1329 L
"SeSystemtimePrivilege",
1330 L
"SeProfileSingleProcessPrivilege",
1331 L
"SeIncreaseBasePriorityPrivilege",
1332 L
"SeCreatePagefilePrivilege",
1333 L
"SeCreatePermanentPrivilege",
1334 L
"SeBackupPrivilege",
1335 L
"SeRestorePrivilege",
1336 L
"SeShutdownPrivilege",
1337 L
"SeDebugPrivilege",
1338 L
"SeAuditPrivilege",
1339 L
"SeSystemEnvironmentPrivilege",
1340 L
"SeChangeNotifyPrivilege",
1341 L
"SeRemoteShutdownPrivilege",
1342 L
"SeUndockPrivilege",
1343 L
"SeSyncAgentPrivilege",
1344 L
"SeEnableDelegationPrivilege",
1345 L
"SeManageVolumePrivilege",
1346 L
"SeImpersonatePrivilege",
1347 L
"SeCreateGlobalPrivilege"
1351 if (NULL
!= SystemName
&& L
'\0' != *SystemName
)
1353 FIXME("LookupPrivilegeValueW: not implemented for remote system\n");
1354 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1358 for (Priv
= 0; Priv
< sizeof(DefaultPrivNames
) / sizeof(DefaultPrivNames
[0]); Priv
++)
1360 if (0 == wcscmp(PrivName
, DefaultPrivNames
[Priv
]))
1362 Luid
->LowPart
= Priv
+ 1;
1368 WARN("LookupPrivilegeValueW: no such privilege %S\n", PrivName
);
1369 SetLastError(ERROR_NO_SUCH_PRIVILEGE
);
1374 /**********************************************************************
1375 * LookupPrivilegeDisplayNameA EXPORTED
1381 LookupPrivilegeDisplayNameA(LPCSTR lpSystemName
,
1383 LPSTR lpDisplayName
,
1384 LPDWORD cbDisplayName
,
1385 LPDWORD lpLanguageId
)
1387 FIXME("%s() not implemented!\n", __FUNCTION__
);
1388 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1393 /**********************************************************************
1394 * LookupPrivilegeDisplayNameW EXPORTED
1400 LookupPrivilegeDisplayNameW(LPCWSTR lpSystemName
,
1402 LPWSTR lpDisplayName
,
1403 LPDWORD cbDisplayName
,
1404 LPDWORD lpLanguageId
)
1406 FIXME("%s() not implemented!\n", __FUNCTION__
);
1407 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1412 /**********************************************************************
1413 * LookupPrivilegeNameA EXPORTED
1419 LookupPrivilegeNameA(LPCSTR lpSystemName
,
1424 FIXME("%s() not implemented!\n", __FUNCTION__
);
1425 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1430 /**********************************************************************
1431 * LookupPrivilegeNameW EXPORTED
1437 LookupPrivilegeNameW(LPCWSTR lpSystemName
,
1442 FIXME("%s() not implemented!\n", __FUNCTION__
);
1443 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1449 pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo
,
1454 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
1456 if ((SecurityInfo
& (OWNER_SECURITY_INFORMATION
|
1457 GROUP_SECURITY_INFORMATION
|
1458 DACL_SECURITY_INFORMATION
|
1459 SACL_SECURITY_INFORMATION
)) &&
1460 ppSecurityDescriptor
== NULL
)
1462 /* if one of the SIDs or ACLs are present, the security descriptor
1464 return ERROR_INVALID_PARAMETER
;
1468 /* reset the pointers unless they're ignored */
1469 if ((SecurityInfo
& OWNER_SECURITY_INFORMATION
) &&
1474 if ((SecurityInfo
& GROUP_SECURITY_INFORMATION
) &&
1479 if ((SecurityInfo
& DACL_SECURITY_INFORMATION
) &&
1484 if ((SecurityInfo
& SACL_SECURITY_INFORMATION
) &&
1490 if (SecurityInfo
& (OWNER_SECURITY_INFORMATION
|
1491 GROUP_SECURITY_INFORMATION
|
1492 DACL_SECURITY_INFORMATION
|
1493 SACL_SECURITY_INFORMATION
))
1495 *ppSecurityDescriptor
= NULL
;
1498 return ERROR_SUCCESS
;
1504 pSetSecurityInfoCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1505 SECURITY_INFORMATION SecurityInfo
,
1511 /* initialize a security descriptor on the stack */
1512 if (!InitializeSecurityDescriptor(pSecurityDescriptor
,
1513 SECURITY_DESCRIPTOR_REVISION
))
1515 return GetLastError();
1518 if (SecurityInfo
& OWNER_SECURITY_INFORMATION
)
1520 if (RtlValidSid(psidOwner
))
1522 if (!SetSecurityDescriptorOwner(pSecurityDescriptor
,
1526 return GetLastError();
1531 return ERROR_INVALID_PARAMETER
;
1535 if (SecurityInfo
& GROUP_SECURITY_INFORMATION
)
1537 if (RtlValidSid(psidGroup
))
1539 if (!SetSecurityDescriptorGroup(pSecurityDescriptor
,
1543 return GetLastError();
1548 return ERROR_INVALID_PARAMETER
;
1552 if (SecurityInfo
& DACL_SECURITY_INFORMATION
)
1556 if (SetSecurityDescriptorDacl(pSecurityDescriptor
,
1561 /* check if the DACL needs to be protected from being
1562 modified by inheritable ACEs */
1563 if (SecurityInfo
& PROTECTED_DACL_SECURITY_INFORMATION
)
1570 return GetLastError();
1576 /* protect the DACL from being modified by inheritable ACEs */
1577 if (!SetSecurityDescriptorControl(pSecurityDescriptor
,
1581 return GetLastError();
1586 if (SecurityInfo
& SACL_SECURITY_INFORMATION
)
1590 if (SetSecurityDescriptorSacl(pSecurityDescriptor
,
1595 /* check if the SACL needs to be protected from being
1596 modified by inheritable ACEs */
1597 if (SecurityInfo
& PROTECTED_SACL_SECURITY_INFORMATION
)
1604 return GetLastError();
1610 /* protect the SACL from being modified by inheritable ACEs */
1611 if (!SetSecurityDescriptorControl(pSecurityDescriptor
,
1615 return GetLastError();
1620 return ERROR_SUCCESS
;
1624 /**********************************************************************
1625 * GetNamedSecurityInfoW EXPORTED
1631 GetNamedSecurityInfoW(LPWSTR pObjectName
,
1632 SE_OBJECT_TYPE ObjectType
,
1633 SECURITY_INFORMATION SecurityInfo
,
1638 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1642 if (pObjectName
!= NULL
)
1644 ErrorCode
= CheckNtMartaPresent();
1645 if (ErrorCode
== ERROR_SUCCESS
)
1647 ErrorCode
= pGetSecurityInfoCheck(SecurityInfo
,
1652 ppSecurityDescriptor
);
1654 if (ErrorCode
== ERROR_SUCCESS
)
1656 /* call the MARTA provider */
1657 ErrorCode
= AccRewriteGetNamedRights(pObjectName
,
1664 ppSecurityDescriptor
);
1669 ErrorCode
= ERROR_INVALID_PARAMETER
;
1675 /**********************************************************************
1676 * GetNamedSecurityInfoA EXPORTED
1682 GetNamedSecurityInfoA(LPSTR pObjectName
,
1683 SE_OBJECT_TYPE ObjectType
,
1684 SECURITY_INFORMATION SecurityInfo
,
1689 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1691 UNICODE_STRING ObjectName
;
1695 Status
= RtlCreateUnicodeStringFromAsciiz(&ObjectName
,
1697 if (!NT_SUCCESS(Status
))
1699 return RtlNtStatusToDosError(Status
);
1702 Ret
= GetNamedSecurityInfoW(ObjectName
.Buffer
,
1709 ppSecurityDescriptor
);
1711 RtlFreeUnicodeString(&ObjectName
);
1717 /**********************************************************************
1718 * SetNamedSecurityInfoW EXPORTED
1724 SetNamedSecurityInfoW(LPWSTR pObjectName
,
1725 SE_OBJECT_TYPE ObjectType
,
1726 SECURITY_INFORMATION SecurityInfo
,
1734 if (pObjectName
!= NULL
)
1736 ErrorCode
= CheckNtMartaPresent();
1737 if (ErrorCode
== ERROR_SUCCESS
)
1739 SECURITY_DESCRIPTOR SecurityDescriptor
;
1741 ErrorCode
= pSetSecurityInfoCheck(&SecurityDescriptor
,
1748 if (ErrorCode
== ERROR_SUCCESS
)
1750 /* call the MARTA provider */
1751 ErrorCode
= AccRewriteSetNamedRights(pObjectName
,
1754 &SecurityDescriptor
);
1759 ErrorCode
= ERROR_INVALID_PARAMETER
;
1765 /**********************************************************************
1766 * SetNamedSecurityInfoA EXPORTED
1772 SetNamedSecurityInfoA(LPSTR pObjectName
,
1773 SE_OBJECT_TYPE ObjectType
,
1774 SECURITY_INFORMATION SecurityInfo
,
1780 UNICODE_STRING ObjectName
;
1784 Status
= RtlCreateUnicodeStringFromAsciiz(&ObjectName
,
1786 if (!NT_SUCCESS(Status
))
1788 return RtlNtStatusToDosError(Status
);
1791 Ret
= SetNamedSecurityInfoW(ObjectName
.Buffer
,
1799 RtlFreeUnicodeString(&ObjectName
);
1805 /**********************************************************************
1806 * GetSecurityInfo EXPORTED
1812 GetSecurityInfo(HANDLE handle
,
1813 SE_OBJECT_TYPE ObjectType
,
1814 SECURITY_INFORMATION SecurityInfo
,
1819 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1825 ErrorCode
= CheckNtMartaPresent();
1826 if (ErrorCode
== ERROR_SUCCESS
)
1828 ErrorCode
= pGetSecurityInfoCheck(SecurityInfo
,
1833 ppSecurityDescriptor
);
1835 if (ErrorCode
== ERROR_SUCCESS
)
1837 /* call the MARTA provider */
1838 ErrorCode
= AccRewriteGetHandleRights(handle
,
1845 ppSecurityDescriptor
);
1850 ErrorCode
= ERROR_INVALID_HANDLE
;
1856 /**********************************************************************
1857 * SetSecurityInfo EXPORTED
1863 SetSecurityInfo(HANDLE handle
,
1864 SE_OBJECT_TYPE ObjectType
,
1865 SECURITY_INFORMATION SecurityInfo
,
1875 ErrorCode
= CheckNtMartaPresent();
1876 if (ErrorCode
== ERROR_SUCCESS
)
1878 SECURITY_DESCRIPTOR SecurityDescriptor
;
1880 ErrorCode
= pSetSecurityInfoCheck(&SecurityDescriptor
,
1887 if (ErrorCode
== ERROR_SUCCESS
)
1889 /* call the MARTA provider */
1890 ErrorCode
= AccRewriteSetHandleRights(handle
,
1893 &SecurityDescriptor
);
1898 ErrorCode
= ERROR_INVALID_HANDLE
;
1904 /******************************************************************************
1905 * GetSecurityInfoExW EXPORTED
1909 GetSecurityInfoExA(HANDLE hObject
,
1910 SE_OBJECT_TYPE ObjectType
,
1911 SECURITY_INFORMATION SecurityInfo
,
1914 PACTRL_ACCESSA
*ppAccessList
,
1915 PACTRL_AUDITA
*ppAuditList
,
1919 FIXME("%s() not implemented!\n", __FUNCTION__
);
1920 return ERROR_BAD_PROVIDER
;
1924 /******************************************************************************
1925 * GetSecurityInfoExW EXPORTED
1929 GetSecurityInfoExW(HANDLE hObject
,
1930 SE_OBJECT_TYPE ObjectType
,
1931 SECURITY_INFORMATION SecurityInfo
,
1934 PACTRL_ACCESSW
*ppAccessList
,
1935 PACTRL_AUDITW
*ppAuditList
,
1939 FIXME("%s() not implemented!\n", __FUNCTION__
);
1940 return ERROR_BAD_PROVIDER
;
1944 /**********************************************************************
1945 * ImpersonateNamedPipeClient EXPORTED
1951 ImpersonateNamedPipeClient(HANDLE hNamedPipe
)
1953 IO_STATUS_BLOCK StatusBlock
;
1956 TRACE("ImpersonateNamedPipeClient() called\n");
1958 Status
= NtFsControlFile(hNamedPipe
,
1963 FSCTL_PIPE_IMPERSONATE
,
1968 if (!NT_SUCCESS(Status
))
1970 SetLastError(RtlNtStatusToDosError(Status
));
1983 CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor
,
1984 PSECURITY_DESCRIPTOR CreatorDescriptor
,
1985 PSECURITY_DESCRIPTOR
*NewDescriptor
,
1986 BOOL IsDirectoryObject
,
1988 PGENERIC_MAPPING GenericMapping
)
1992 Status
= RtlNewSecurityObject(ParentDescriptor
,
1998 if (!NT_SUCCESS(Status
))
2000 SetLastError(RtlNtStatusToDosError(Status
));
2013 CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor
,
2014 PSECURITY_DESCRIPTOR CreatorDescriptor
,
2015 PSECURITY_DESCRIPTOR
* NewDescriptor
,
2017 BOOL IsContainerObject
,
2018 ULONG AutoInheritFlags
,
2020 PGENERIC_MAPPING GenericMapping
)
2022 FIXME("%s() not implemented!\n", __FUNCTION__
);
2032 CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor
,
2033 PSECURITY_DESCRIPTOR CreatorDescriptor
,
2034 PSECURITY_DESCRIPTOR
* NewDescriptor
,
2037 BOOL IsContainerObject
,
2038 ULONG AutoInheritFlags
,
2040 PGENERIC_MAPPING GenericMapping
)
2042 FIXME("%s() not implemented!\n", __FUNCTION__
);
2052 DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR
*ObjectDescriptor
)
2056 Status
= RtlDeleteSecurityObject(ObjectDescriptor
);
2057 if (!NT_SUCCESS(Status
))
2059 SetLastError(RtlNtStatusToDosError(Status
));
2072 GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR ObjectDescriptor
,
2073 SECURITY_INFORMATION SecurityInformation
,
2074 PSECURITY_DESCRIPTOR ResultantDescriptor
,
2075 DWORD DescriptorLength
,
2076 PDWORD ReturnLength
)
2080 Status
= RtlQuerySecurityObject(ObjectDescriptor
,
2081 SecurityInformation
,
2082 ResultantDescriptor
,
2085 if (!NT_SUCCESS(Status
))
2087 SetLastError(RtlNtStatusToDosError(Status
));
2100 SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation
,
2101 PSECURITY_DESCRIPTOR ModificationDescriptor
,
2102 PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
2103 PGENERIC_MAPPING GenericMapping
,
2108 Status
= RtlSetSecurityObject(SecurityInformation
,
2109 ModificationDescriptor
,
2110 ObjectsSecurityDescriptor
,
2113 if (!NT_SUCCESS(Status
))
2115 SetLastError(RtlNtStatusToDosError(Status
));
2128 TreeResetNamedSecurityInfoW(LPWSTR pObjectName
,
2129 SE_OBJECT_TYPE ObjectType
,
2130 SECURITY_INFORMATION SecurityInfo
,
2136 FN_PROGRESSW fnProgress
,
2137 PROG_INVOKE_SETTING ProgressInvokeSetting
,
2142 if (pObjectName
!= NULL
)
2144 ErrorCode
= CheckNtMartaPresent();
2145 if (ErrorCode
== ERROR_SUCCESS
)
2149 case SE_FILE_OBJECT
:
2150 case SE_REGISTRY_KEY
:
2152 /* check the SecurityInfo flags for sanity (both, the protected
2153 and unprotected dacl/sacl flag must not be passed together) */
2154 if (((SecurityInfo
& DACL_SECURITY_INFORMATION
) &&
2155 (SecurityInfo
& (PROTECTED_DACL_SECURITY_INFORMATION
| UNPROTECTED_DACL_SECURITY_INFORMATION
)) ==
2156 (PROTECTED_DACL_SECURITY_INFORMATION
| UNPROTECTED_DACL_SECURITY_INFORMATION
))
2160 ((SecurityInfo
& SACL_SECURITY_INFORMATION
) &&
2161 (SecurityInfo
& (PROTECTED_SACL_SECURITY_INFORMATION
| UNPROTECTED_SACL_SECURITY_INFORMATION
)) ==
2162 (PROTECTED_SACL_SECURITY_INFORMATION
| UNPROTECTED_SACL_SECURITY_INFORMATION
)))
2164 ErrorCode
= ERROR_INVALID_PARAMETER
;
2168 /* call the MARTA provider */
2169 ErrorCode
= AccTreeResetNamedSecurityInfo(pObjectName
,
2178 ProgressInvokeSetting
,
2184 /* object type not supported */
2185 ErrorCode
= ERROR_INVALID_PARAMETER
;
2191 ErrorCode
= ERROR_INVALID_PARAMETER
;
2196 #ifdef HAS_FN_PROGRESSW
2198 typedef struct _INERNAL_FNPROGRESSW_DATA
2200 FN_PROGRESSA fnProgress
;
2202 } INERNAL_FNPROGRESSW_DATA
, *PINERNAL_FNPROGRESSW_DATA
;
2205 InternalfnProgressW(LPWSTR pObjectName
,
2207 PPROG_INVOKE_SETTING pInvokeSetting
,
2211 PINERNAL_FNPROGRESSW_DATA pifnProgressData
= (PINERNAL_FNPROGRESSW_DATA
)Args
;
2215 ObjectNameSize
= WideCharToMultiByte(CP_ACP
,
2224 if (ObjectNameSize
> 0)
2226 pObjectNameA
= RtlAllocateHeap(RtlGetProcessHeap(),
2229 if (pObjectNameA
!= NULL
)
2231 pObjectNameA
[0] = '\0';
2232 WideCharToMultiByte(CP_ACP
,
2241 pifnProgressData
->fnProgress((LPWSTR
)pObjectNameA
, /* FIXME: wrong cast!! */
2244 pifnProgressData
->Args
,
2247 RtlFreeHeap(RtlGetProcessHeap(),
2261 TreeResetNamedSecurityInfoA(LPSTR pObjectName
,
2262 SE_OBJECT_TYPE ObjectType
,
2263 SECURITY_INFORMATION SecurityInfo
,
2269 FN_PROGRESSA fnProgress
,
2270 PROG_INVOKE_SETTING ProgressInvokeSetting
,
2273 #ifndef HAS_FN_PROGRESSW
2274 /* That's all this function does, at least up to w2k3... Even MS was too
2275 lazy to implement it... */
2276 return ERROR_CALL_NOT_IMPLEMENTED
;
2278 INERNAL_FNPROGRESSW_DATA ifnProgressData
;
2279 UNICODE_STRING ObjectName
;
2283 Status
= RtlCreateUnicodeStringFromAsciiz(&ObjectName
,
2285 if (!NT_SUCCESS(Status
))
2287 return RtlNtStatusToDosError(Status
);
2290 ifnProgressData
.fnProgress
= fnProgress
;
2291 ifnProgressData
.Args
= Args
;
2293 Ret
= TreeResetNamedSecurityInfoW(ObjectName
.Buffer
,
2301 (fnProgress
!= NULL
? InternalfnProgressW
: NULL
),
2302 ProgressInvokeSetting
,
2305 RtlFreeUnicodeString(&ObjectName
);