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 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 UNICODE_STRING lpSystemNameW
;
1405 TRACE("%s %p %p %p\n", debugstr_a(lpSystemName
), lpLuid
, lpName
, cchName
);
1407 RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW
, lpSystemName
);
1408 ret
= LookupPrivilegeNameW(lpSystemNameW
.Buffer
, lpLuid
, NULL
, &wLen
);
1409 if (!ret
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
1411 LPWSTR lpNameW
= HeapAlloc(GetProcessHeap(), 0, wLen
* sizeof(WCHAR
));
1413 ret
= LookupPrivilegeNameW(lpSystemNameW
.Buffer
, lpLuid
, lpNameW
,
1417 /* Windows crashes if cchName is NULL, so will I */
1418 unsigned int len
= WideCharToMultiByte(CP_ACP
, 0, lpNameW
, -1, lpName
,
1419 *cchName
, NULL
, NULL
);
1423 /* WideCharToMultiByte failed */
1426 else if (len
> *cchName
)
1429 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1434 /* WideCharToMultiByte succeeded, output length needs to be
1435 * length not including NULL terminator
1440 HeapFree(GetProcessHeap(), 0, lpNameW
);
1442 RtlFreeUnicodeString(&lpSystemNameW
);
1447 /**********************************************************************
1448 * LookupPrivilegeNameW EXPORTED
1454 LookupPrivilegeNameW(LPCWSTR lpSystemName
,
1459 FIXME("%s() not implemented!\n", __FUNCTION__
);
1460 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1466 pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo
,
1471 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
1473 if ((SecurityInfo
& (OWNER_SECURITY_INFORMATION
|
1474 GROUP_SECURITY_INFORMATION
|
1475 DACL_SECURITY_INFORMATION
|
1476 SACL_SECURITY_INFORMATION
)) &&
1477 ppSecurityDescriptor
== NULL
)
1479 /* if one of the SIDs or ACLs are present, the security descriptor
1481 return ERROR_INVALID_PARAMETER
;
1485 /* reset the pointers unless they're ignored */
1486 if ((SecurityInfo
& OWNER_SECURITY_INFORMATION
) &&
1491 if ((SecurityInfo
& GROUP_SECURITY_INFORMATION
) &&
1496 if ((SecurityInfo
& DACL_SECURITY_INFORMATION
) &&
1501 if ((SecurityInfo
& SACL_SECURITY_INFORMATION
) &&
1507 if (SecurityInfo
& (OWNER_SECURITY_INFORMATION
|
1508 GROUP_SECURITY_INFORMATION
|
1509 DACL_SECURITY_INFORMATION
|
1510 SACL_SECURITY_INFORMATION
))
1512 *ppSecurityDescriptor
= NULL
;
1515 return ERROR_SUCCESS
;
1521 pSetSecurityInfoCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1522 SECURITY_INFORMATION SecurityInfo
,
1528 /* initialize a security descriptor on the stack */
1529 if (!InitializeSecurityDescriptor(pSecurityDescriptor
,
1530 SECURITY_DESCRIPTOR_REVISION
))
1532 return GetLastError();
1535 if (SecurityInfo
& OWNER_SECURITY_INFORMATION
)
1537 if (RtlValidSid(psidOwner
))
1539 if (!SetSecurityDescriptorOwner(pSecurityDescriptor
,
1543 return GetLastError();
1548 return ERROR_INVALID_PARAMETER
;
1552 if (SecurityInfo
& GROUP_SECURITY_INFORMATION
)
1554 if (RtlValidSid(psidGroup
))
1556 if (!SetSecurityDescriptorGroup(pSecurityDescriptor
,
1560 return GetLastError();
1565 return ERROR_INVALID_PARAMETER
;
1569 if (SecurityInfo
& DACL_SECURITY_INFORMATION
)
1573 if (SetSecurityDescriptorDacl(pSecurityDescriptor
,
1578 /* check if the DACL needs to be protected from being
1579 modified by inheritable ACEs */
1580 if (SecurityInfo
& PROTECTED_DACL_SECURITY_INFORMATION
)
1587 return GetLastError();
1593 /* protect the DACL from being modified by inheritable ACEs */
1594 if (!SetSecurityDescriptorControl(pSecurityDescriptor
,
1598 return GetLastError();
1603 if (SecurityInfo
& SACL_SECURITY_INFORMATION
)
1607 if (SetSecurityDescriptorSacl(pSecurityDescriptor
,
1612 /* check if the SACL needs to be protected from being
1613 modified by inheritable ACEs */
1614 if (SecurityInfo
& PROTECTED_SACL_SECURITY_INFORMATION
)
1621 return GetLastError();
1627 /* protect the SACL from being modified by inheritable ACEs */
1628 if (!SetSecurityDescriptorControl(pSecurityDescriptor
,
1632 return GetLastError();
1637 return ERROR_SUCCESS
;
1641 /**********************************************************************
1642 * GetNamedSecurityInfoW EXPORTED
1648 GetNamedSecurityInfoW(LPWSTR pObjectName
,
1649 SE_OBJECT_TYPE ObjectType
,
1650 SECURITY_INFORMATION SecurityInfo
,
1655 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1659 if (pObjectName
!= NULL
)
1661 ErrorCode
= CheckNtMartaPresent();
1662 if (ErrorCode
== ERROR_SUCCESS
)
1664 ErrorCode
= pGetSecurityInfoCheck(SecurityInfo
,
1669 ppSecurityDescriptor
);
1671 if (ErrorCode
== ERROR_SUCCESS
)
1673 /* call the MARTA provider */
1674 ErrorCode
= AccRewriteGetNamedRights(pObjectName
,
1681 ppSecurityDescriptor
);
1686 ErrorCode
= ERROR_INVALID_PARAMETER
;
1692 /**********************************************************************
1693 * GetNamedSecurityInfoA EXPORTED
1699 GetNamedSecurityInfoA(LPSTR pObjectName
,
1700 SE_OBJECT_TYPE ObjectType
,
1701 SECURITY_INFORMATION SecurityInfo
,
1706 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1708 UNICODE_STRING ObjectName
;
1712 Status
= RtlCreateUnicodeStringFromAsciiz(&ObjectName
,
1714 if (!NT_SUCCESS(Status
))
1716 return RtlNtStatusToDosError(Status
);
1719 Ret
= GetNamedSecurityInfoW(ObjectName
.Buffer
,
1726 ppSecurityDescriptor
);
1728 RtlFreeUnicodeString(&ObjectName
);
1734 /**********************************************************************
1735 * SetNamedSecurityInfoW EXPORTED
1741 SetNamedSecurityInfoW(LPWSTR pObjectName
,
1742 SE_OBJECT_TYPE ObjectType
,
1743 SECURITY_INFORMATION SecurityInfo
,
1751 if (pObjectName
!= NULL
)
1753 ErrorCode
= CheckNtMartaPresent();
1754 if (ErrorCode
== ERROR_SUCCESS
)
1756 SECURITY_DESCRIPTOR SecurityDescriptor
;
1758 ErrorCode
= pSetSecurityInfoCheck(&SecurityDescriptor
,
1765 if (ErrorCode
== ERROR_SUCCESS
)
1767 /* call the MARTA provider */
1768 ErrorCode
= AccRewriteSetNamedRights(pObjectName
,
1771 &SecurityDescriptor
);
1776 ErrorCode
= ERROR_INVALID_PARAMETER
;
1782 /**********************************************************************
1783 * SetNamedSecurityInfoA EXPORTED
1789 SetNamedSecurityInfoA(LPSTR pObjectName
,
1790 SE_OBJECT_TYPE ObjectType
,
1791 SECURITY_INFORMATION SecurityInfo
,
1797 UNICODE_STRING ObjectName
;
1801 Status
= RtlCreateUnicodeStringFromAsciiz(&ObjectName
,
1803 if (!NT_SUCCESS(Status
))
1805 return RtlNtStatusToDosError(Status
);
1808 Ret
= SetNamedSecurityInfoW(ObjectName
.Buffer
,
1816 RtlFreeUnicodeString(&ObjectName
);
1822 /**********************************************************************
1823 * GetSecurityInfo EXPORTED
1829 GetSecurityInfo(HANDLE handle
,
1830 SE_OBJECT_TYPE ObjectType
,
1831 SECURITY_INFORMATION SecurityInfo
,
1836 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1842 ErrorCode
= CheckNtMartaPresent();
1843 if (ErrorCode
== ERROR_SUCCESS
)
1845 ErrorCode
= pGetSecurityInfoCheck(SecurityInfo
,
1850 ppSecurityDescriptor
);
1852 if (ErrorCode
== ERROR_SUCCESS
)
1854 /* call the MARTA provider */
1855 ErrorCode
= AccRewriteGetHandleRights(handle
,
1862 ppSecurityDescriptor
);
1867 ErrorCode
= ERROR_INVALID_HANDLE
;
1873 /**********************************************************************
1874 * SetSecurityInfo EXPORTED
1880 SetSecurityInfo(HANDLE handle
,
1881 SE_OBJECT_TYPE ObjectType
,
1882 SECURITY_INFORMATION SecurityInfo
,
1892 ErrorCode
= CheckNtMartaPresent();
1893 if (ErrorCode
== ERROR_SUCCESS
)
1895 SECURITY_DESCRIPTOR SecurityDescriptor
;
1897 ErrorCode
= pSetSecurityInfoCheck(&SecurityDescriptor
,
1904 if (ErrorCode
== ERROR_SUCCESS
)
1906 /* call the MARTA provider */
1907 ErrorCode
= AccRewriteSetHandleRights(handle
,
1910 &SecurityDescriptor
);
1915 ErrorCode
= ERROR_INVALID_HANDLE
;
1921 /******************************************************************************
1922 * GetSecurityInfoExW EXPORTED
1926 GetSecurityInfoExA(HANDLE hObject
,
1927 SE_OBJECT_TYPE ObjectType
,
1928 SECURITY_INFORMATION SecurityInfo
,
1931 PACTRL_ACCESSA
*ppAccessList
,
1932 PACTRL_AUDITA
*ppAuditList
,
1936 FIXME("%s() not implemented!\n", __FUNCTION__
);
1937 return ERROR_BAD_PROVIDER
;
1941 /******************************************************************************
1942 * GetSecurityInfoExW EXPORTED
1946 GetSecurityInfoExW(HANDLE hObject
,
1947 SE_OBJECT_TYPE ObjectType
,
1948 SECURITY_INFORMATION SecurityInfo
,
1951 PACTRL_ACCESSW
*ppAccessList
,
1952 PACTRL_AUDITW
*ppAuditList
,
1956 FIXME("%s() not implemented!\n", __FUNCTION__
);
1957 return ERROR_BAD_PROVIDER
;
1961 /**********************************************************************
1962 * ImpersonateNamedPipeClient EXPORTED
1968 ImpersonateNamedPipeClient(HANDLE hNamedPipe
)
1970 IO_STATUS_BLOCK StatusBlock
;
1973 TRACE("ImpersonateNamedPipeClient() called\n");
1975 Status
= NtFsControlFile(hNamedPipe
,
1980 FSCTL_PIPE_IMPERSONATE
,
1985 if (!NT_SUCCESS(Status
))
1987 SetLastError(RtlNtStatusToDosError(Status
));
2000 CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor
,
2001 PSECURITY_DESCRIPTOR CreatorDescriptor
,
2002 PSECURITY_DESCRIPTOR
*NewDescriptor
,
2003 BOOL IsDirectoryObject
,
2005 PGENERIC_MAPPING GenericMapping
)
2009 Status
= RtlNewSecurityObject(ParentDescriptor
,
2015 if (!NT_SUCCESS(Status
))
2017 SetLastError(RtlNtStatusToDosError(Status
));
2030 CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor
,
2031 PSECURITY_DESCRIPTOR CreatorDescriptor
,
2032 PSECURITY_DESCRIPTOR
* NewDescriptor
,
2034 BOOL IsContainerObject
,
2035 ULONG AutoInheritFlags
,
2037 PGENERIC_MAPPING GenericMapping
)
2039 FIXME("%s() not implemented!\n", __FUNCTION__
);
2049 CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor
,
2050 PSECURITY_DESCRIPTOR CreatorDescriptor
,
2051 PSECURITY_DESCRIPTOR
* NewDescriptor
,
2054 BOOL IsContainerObject
,
2055 ULONG AutoInheritFlags
,
2057 PGENERIC_MAPPING GenericMapping
)
2059 FIXME("%s() not implemented!\n", __FUNCTION__
);
2069 DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR
*ObjectDescriptor
)
2073 Status
= RtlDeleteSecurityObject(ObjectDescriptor
);
2074 if (!NT_SUCCESS(Status
))
2076 SetLastError(RtlNtStatusToDosError(Status
));
2089 GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR ObjectDescriptor
,
2090 SECURITY_INFORMATION SecurityInformation
,
2091 PSECURITY_DESCRIPTOR ResultantDescriptor
,
2092 DWORD DescriptorLength
,
2093 PDWORD ReturnLength
)
2097 Status
= RtlQuerySecurityObject(ObjectDescriptor
,
2098 SecurityInformation
,
2099 ResultantDescriptor
,
2102 if (!NT_SUCCESS(Status
))
2104 SetLastError(RtlNtStatusToDosError(Status
));
2117 SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation
,
2118 PSECURITY_DESCRIPTOR ModificationDescriptor
,
2119 PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
2120 PGENERIC_MAPPING GenericMapping
,
2125 Status
= RtlSetSecurityObject(SecurityInformation
,
2126 ModificationDescriptor
,
2127 ObjectsSecurityDescriptor
,
2130 if (!NT_SUCCESS(Status
))
2132 SetLastError(RtlNtStatusToDosError(Status
));
2145 TreeResetNamedSecurityInfoW(LPWSTR pObjectName
,
2146 SE_OBJECT_TYPE ObjectType
,
2147 SECURITY_INFORMATION SecurityInfo
,
2153 FN_PROGRESSW fnProgress
,
2154 PROG_INVOKE_SETTING ProgressInvokeSetting
,
2159 if (pObjectName
!= NULL
)
2161 ErrorCode
= CheckNtMartaPresent();
2162 if (ErrorCode
== ERROR_SUCCESS
)
2166 case SE_FILE_OBJECT
:
2167 case SE_REGISTRY_KEY
:
2169 /* check the SecurityInfo flags for sanity (both, the protected
2170 and unprotected dacl/sacl flag must not be passed together) */
2171 if (((SecurityInfo
& DACL_SECURITY_INFORMATION
) &&
2172 (SecurityInfo
& (PROTECTED_DACL_SECURITY_INFORMATION
| UNPROTECTED_DACL_SECURITY_INFORMATION
)) ==
2173 (PROTECTED_DACL_SECURITY_INFORMATION
| UNPROTECTED_DACL_SECURITY_INFORMATION
))
2177 ((SecurityInfo
& SACL_SECURITY_INFORMATION
) &&
2178 (SecurityInfo
& (PROTECTED_SACL_SECURITY_INFORMATION
| UNPROTECTED_SACL_SECURITY_INFORMATION
)) ==
2179 (PROTECTED_SACL_SECURITY_INFORMATION
| UNPROTECTED_SACL_SECURITY_INFORMATION
)))
2181 ErrorCode
= ERROR_INVALID_PARAMETER
;
2185 /* call the MARTA provider */
2186 ErrorCode
= AccTreeResetNamedSecurityInfo(pObjectName
,
2195 ProgressInvokeSetting
,
2201 /* object type not supported */
2202 ErrorCode
= ERROR_INVALID_PARAMETER
;
2208 ErrorCode
= ERROR_INVALID_PARAMETER
;
2213 #ifdef HAS_FN_PROGRESSW
2215 typedef struct _INERNAL_FNPROGRESSW_DATA
2217 FN_PROGRESSA fnProgress
;
2219 } INERNAL_FNPROGRESSW_DATA
, *PINERNAL_FNPROGRESSW_DATA
;
2222 InternalfnProgressW(LPWSTR pObjectName
,
2224 PPROG_INVOKE_SETTING pInvokeSetting
,
2228 PINERNAL_FNPROGRESSW_DATA pifnProgressData
= (PINERNAL_FNPROGRESSW_DATA
)Args
;
2232 ObjectNameSize
= WideCharToMultiByte(CP_ACP
,
2241 if (ObjectNameSize
> 0)
2243 pObjectNameA
= RtlAllocateHeap(RtlGetProcessHeap(),
2246 if (pObjectNameA
!= NULL
)
2248 pObjectNameA
[0] = '\0';
2249 WideCharToMultiByte(CP_ACP
,
2258 pifnProgressData
->fnProgress((LPWSTR
)pObjectNameA
, /* FIXME: wrong cast!! */
2261 pifnProgressData
->Args
,
2264 RtlFreeHeap(RtlGetProcessHeap(),
2278 TreeResetNamedSecurityInfoA(LPSTR pObjectName
,
2279 SE_OBJECT_TYPE ObjectType
,
2280 SECURITY_INFORMATION SecurityInfo
,
2286 FN_PROGRESSA fnProgress
,
2287 PROG_INVOKE_SETTING ProgressInvokeSetting
,
2290 #ifndef HAS_FN_PROGRESSW
2291 /* That's all this function does, at least up to w2k3... Even MS was too
2292 lazy to implement it... */
2293 return ERROR_CALL_NOT_IMPLEMENTED
;
2295 INERNAL_FNPROGRESSW_DATA ifnProgressData
;
2296 UNICODE_STRING ObjectName
;
2300 Status
= RtlCreateUnicodeStringFromAsciiz(&ObjectName
,
2302 if (!NT_SUCCESS(Status
))
2304 return RtlNtStatusToDosError(Status
);
2307 ifnProgressData
.fnProgress
= fnProgress
;
2308 ifnProgressData
.Args
= Args
;
2310 Ret
= TreeResetNamedSecurityInfoW(ObjectName
.Buffer
,
2318 (fnProgress
!= NULL
? InternalfnProgressW
: NULL
),
2319 ProgressInvokeSetting
,
2322 RtlFreeUnicodeString(&ObjectName
);