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
16 /* Interface to ntmarta.dll ***************************************************/
18 typedef struct _NTMARTA
20 HINSTANCE hDllInstance
;
22 PVOID LookupAccountTrustee
;
23 PVOID LookupAccountName
;
24 PVOID LookupAccountSid
;
25 PVOID SetEntriesInAList
;
26 PVOID ConvertAccessToSecurityDescriptor
;
27 PVOID ConvertSDToAccess
;
28 PVOID ConvertAclToAccess
;
29 PVOID GetAccessForTrustee
;
30 PVOID GetExplicitEntries
;
31 PVOID RewriteGetNamedRights
;
32 PVOID RewriteSetNamedRights
;
34 DWORD (STDCALL
*RewriteGetHandleRights
)(HANDLE handle
,
35 SE_OBJECT_TYPE ObjectType
,
36 SECURITY_INFORMATION SecurityInfo
,
41 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
);
43 DWORD (STDCALL
*RewriteSetHandleRights
)(HANDLE handle
,
44 SE_OBJECT_TYPE ObjectType
,
45 SECURITY_INFORMATION SecurityInfo
,
46 PSECURITY_DESCRIPTOR pSecurityDescriptor
);
48 PVOID RewriteSetEntriesInAcl
;
49 PVOID RewriteGetExplicitEntriesFromAcl
;
50 PVOID TreeResetNamedSecurityInfo
;
51 PVOID GetInheritanceSource
;
55 static NTMARTA NtMartaStatic
= { 0 };
56 static PNTMARTA NtMarta
= NULL
;
58 #define AccLookupAccountTrustee NtMartaStatic.LookupAccountTrustee
59 #define AccLookupAccountName NtMartaStatic.LookupAccountName
60 #define AccLookupAccountSid NtMartaStatic.LookupAccountSid
61 #define AccSetEntriesInAList NtMartaStatic.SetEntriesInAList
62 #define AccConvertAccessToSecurityDescriptor NtMartaStatic.ConvertAccessToSecurityDescriptor
63 #define AccConvertSDToAccess NtMartaStatic.ConvertSDToAccess
64 #define AccConvertAclToAccess NtMartaStatic.ConvertAclToAccess
65 #define AccGetAccessForTrustee NtMartaStatic.GetAccessForTrustee
66 #define AccGetExplicitEntries NtMartaStatic.GetExplicitEntries
67 #define AccRewriteGetNamedRights NtMartaStatic.RewriteGetNamedRights
68 #define AccRewriteSetNamedRights NtMartaStatic.RewriteSetNamedRights
69 #define AccRewriteGetHandleRights NtMartaStatic.RewriteGetHandleRights
70 #define AccRewriteSetHandleRights NtMartaStatic.RewriteSetHandleRights
71 #define AccRewriteSetEntriesInAcl NtMartaStatic.RewriteSetEntriesInAcl
72 #define AccRewriteGetExplicitEntriesFromAcl NtMartaStatic.RewriteGetExplicitEntriesFromAcl
73 #define AccTreeResetNamedSecurityInfo NtMartaStatic.TreeResetNamedSecurityInfo
74 #define AccGetInheritanceSource NtMartaStatic.GetInheritanceSource
75 #define AccFreeIndexArray NtMartaStatic.FreeIndexArray
77 #define FindNtMartaProc(Name) \
78 NtMartaStatic.Name = (PVOID)GetProcAddress(NtMartaStatic.hDllInstance, \
80 if (NtMartaStatic.Name == NULL) \
82 return GetLastError(); \
86 LoadAndInitializeNtMarta(VOID
)
88 /* this code may be executed simultaneously by multiple threads in case they're
89 trying to initialize the interface at the same time, but that's no problem
90 because the pointers returned by GetProcAddress will be the same. However,
91 only one of the threads will change the NtMarta pointer to the NtMartaStatic
92 structure, the others threads will detect that there were other threads
93 initializing the structure faster and will release the reference to the
96 NtMartaStatic
.hDllInstance
= LoadLibraryW(L
"ntmarta.dll");
97 if (NtMartaStatic
.hDllInstance
== NULL
)
99 return GetLastError();
103 FindNtMartaProc(LookupAccountTrustee
);
104 FindNtMartaProc(LookupAccountName
);
105 FindNtMartaProc(LookupAccountSid
);
106 FindNtMartaProc(SetEntriesInAList
);
107 FindNtMartaProc(ConvertAccessToSecurityDescriptor
);
108 FindNtMartaProc(ConvertSDToAccess
);
109 FindNtMartaProc(ConvertAclToAccess
);
110 FindNtMartaProc(GetAccessForTrustee
);
111 FindNtMartaProc(GetExplicitEntries
);
112 FindNtMartaProc(RewriteGetNamedRights
);
113 FindNtMartaProc(RewriteSetNamedRights
);
115 FindNtMartaProc(RewriteGetHandleRights
);
116 FindNtMartaProc(RewriteSetHandleRights
);
118 FindNtMartaProc(RewriteSetEntriesInAcl
);
119 FindNtMartaProc(RewriteGetExplicitEntriesFromAcl
);
120 FindNtMartaProc(TreeResetNamedSecurityInfo
);
121 FindNtMartaProc(GetInheritanceSource
);
122 FindNtMartaProc(FreeIndexArray
);
125 return ERROR_SUCCESS
;
129 CheckNtMartaPresent(VOID
)
135 /* we're the first one trying to use ntmarta, initialize it and change
136 the pointer after initialization */
137 ErrorCode
= LoadAndInitializeNtMarta();
139 if (ErrorCode
== ERROR_SUCCESS
)
141 /* try change the NtMarta pointer */
142 if (InterlockedCompareExchangePointer(&NtMarta
,
146 /* another thread initialized ntmarta in the meanwhile, release
147 the reference of the dll loaded. */
148 FreeLibrary(NtMartaStatic
.hDllInstance
);
154 DPRINT1("Failed to initialize ntmarta.dll! Error: 0x%x", ErrorCode
);
160 /* ntmarta was already initialized */
161 ErrorCode
= ERROR_SUCCESS
;
167 VOID
UnloadNtMarta(VOID
)
169 if (InterlockedExchangePointer(&NtMarta
,
172 FreeLibrary(NtMartaStatic
.hDllInstance
);
176 /******************************************************************************/
182 AreAllAccessesGranted(DWORD GrantedAccess
,
185 return((BOOL
)RtlAreAllAccessesGranted(GrantedAccess
,
194 AreAnyAccessesGranted(DWORD GrantedAccess
,
197 return((BOOL
)RtlAreAnyAccessesGranted(GrantedAccess
,
202 /******************************************************************************
203 * GetFileSecurityA [ADVAPI32.@]
205 * Obtains Specified information about the security of a file or directory.
208 * lpFileName [I] Name of the file to get info for
209 * RequestedInformation [I] SE_ flags from "winnt.h"
210 * pSecurityDescriptor [O] Destination for security information
211 * nLength [I] Length of pSecurityDescriptor
212 * lpnLengthNeeded [O] Destination for length of returned security information
215 * Success: TRUE. pSecurityDescriptor contains the requested information.
216 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
219 * The information returned is constrained by the callers access rights and
225 GetFileSecurityA(LPCSTR lpFileName
,
226 SECURITY_INFORMATION RequestedInformation
,
227 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
229 LPDWORD lpnLengthNeeded
)
231 UNICODE_STRING FileName
;
235 Status
= RtlCreateUnicodeStringFromAsciiz(&FileName
,
237 if (!NT_SUCCESS(Status
))
239 SetLastError(RtlNtStatusToDosError(Status
));
243 bResult
= GetFileSecurityW(FileName
.Buffer
,
244 RequestedInformation
,
249 RtlFreeUnicodeString(&FileName
);
259 GetFileSecurityW(LPCWSTR lpFileName
,
260 SECURITY_INFORMATION RequestedInformation
,
261 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
263 LPDWORD lpnLengthNeeded
)
265 OBJECT_ATTRIBUTES ObjectAttributes
;
266 IO_STATUS_BLOCK StatusBlock
;
267 UNICODE_STRING FileName
;
268 ULONG AccessMask
= 0;
272 DPRINT("GetFileSecurityW() called\n");
274 if (RequestedInformation
&
275 (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION
))
277 AccessMask
|= STANDARD_RIGHTS_READ
;
280 if (RequestedInformation
& SACL_SECURITY_INFORMATION
)
282 AccessMask
|= ACCESS_SYSTEM_SECURITY
;
285 if (!RtlDosPathNameToNtPathName_U((LPWSTR
)lpFileName
,
290 DPRINT("Invalid path\n");
291 SetLastError(ERROR_INVALID_NAME
);
295 InitializeObjectAttributes(&ObjectAttributes
,
297 OBJ_CASE_INSENSITIVE
,
301 Status
= NtOpenFile(&FileHandle
,
305 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
307 if (!NT_SUCCESS(Status
))
309 DPRINT("NtOpenFile() failed (Status %lx)\n", Status
);
310 SetLastError(RtlNtStatusToDosError(Status
));
314 RtlFreeUnicodeString(&FileName
);
316 Status
= NtQuerySecurityObject(FileHandle
,
317 RequestedInformation
,
323 if (!NT_SUCCESS(Status
))
325 DPRINT("NtQuerySecurityObject() failed (Status %lx)\n", Status
);
326 SetLastError(RtlNtStatusToDosError(Status
));
338 GetKernelObjectSecurity(HANDLE Handle
,
339 SECURITY_INFORMATION RequestedInformation
,
340 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
342 LPDWORD lpnLengthNeeded
)
346 Status
= NtQuerySecurityObject(Handle
,
347 RequestedInformation
,
351 if (!NT_SUCCESS(Status
))
353 SetLastError(RtlNtStatusToDosError(Status
));
360 /******************************************************************************
361 * SetFileSecurityA [ADVAPI32.@]
362 * Sets the security of a file or directory
367 SetFileSecurityA (LPCSTR lpFileName
,
368 SECURITY_INFORMATION SecurityInformation
,
369 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
371 UNICODE_STRING FileName
;
375 Status
= RtlCreateUnicodeStringFromAsciiz(&FileName
,
377 if (!NT_SUCCESS(Status
))
379 SetLastError(RtlNtStatusToDosError(Status
));
383 bResult
= SetFileSecurityW(FileName
.Buffer
,
385 pSecurityDescriptor
);
387 RtlFreeUnicodeString(&FileName
);
393 /******************************************************************************
394 * SetFileSecurityW [ADVAPI32.@]
395 * Sets the security of a file or directory
400 SetFileSecurityW (LPCWSTR lpFileName
,
401 SECURITY_INFORMATION SecurityInformation
,
402 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
404 OBJECT_ATTRIBUTES ObjectAttributes
;
405 IO_STATUS_BLOCK StatusBlock
;
406 UNICODE_STRING FileName
;
407 ULONG AccessMask
= 0;
411 DPRINT("SetFileSecurityW() called\n");
413 if (SecurityInformation
&
414 (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
))
416 AccessMask
|= WRITE_OWNER
;
419 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
421 AccessMask
|= WRITE_DAC
;
424 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
426 AccessMask
|= ACCESS_SYSTEM_SECURITY
;
429 if (!RtlDosPathNameToNtPathName_U((LPWSTR
)lpFileName
,
434 DPRINT("Invalid path\n");
435 SetLastError(ERROR_INVALID_NAME
);
439 InitializeObjectAttributes(&ObjectAttributes
,
441 OBJ_CASE_INSENSITIVE
,
445 Status
= NtOpenFile(&FileHandle
,
449 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
451 if (!NT_SUCCESS(Status
))
453 DPRINT("NtOpenFile() failed (Status %lx)\n", Status
);
454 SetLastError(RtlNtStatusToDosError(Status
));
458 RtlFreeUnicodeString(&FileName
);
460 Status
= NtSetSecurityObject(FileHandle
,
462 pSecurityDescriptor
);
465 if (!NT_SUCCESS(Status
))
467 DPRINT("NtSetSecurityObject() failed (Status %lx)\n", Status
);
468 SetLastError(RtlNtStatusToDosError(Status
));
480 SetKernelObjectSecurity(HANDLE Handle
,
481 SECURITY_INFORMATION SecurityInformation
,
482 PSECURITY_DESCRIPTOR SecurityDescriptor
)
486 Status
= NtSetSecurityObject(Handle
,
489 if (!NT_SUCCESS(Status
))
491 SetLastError(RtlNtStatusToDosError(Status
));
502 ImpersonateLoggedOnUser(HANDLE hToken
)
504 SECURITY_QUALITY_OF_SERVICE Qos
;
505 OBJECT_ATTRIBUTES ObjectAttributes
;
512 /* Get the token type */
513 Status
= NtQueryInformationToken (hToken
,
518 if (!NT_SUCCESS(Status
))
520 SetLastError (RtlNtStatusToDosError (Status
));
524 if (Type
== TokenPrimary
)
526 /* Create a duplicate impersonation token */
527 Qos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
528 Qos
.ImpersonationLevel
= SecurityImpersonation
;
529 Qos
.ContextTrackingMode
= SECURITY_DYNAMIC_TRACKING
;
530 Qos
.EffectiveOnly
= FALSE
;
532 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
533 ObjectAttributes
.RootDirectory
= NULL
;
534 ObjectAttributes
.ObjectName
= NULL
;
535 ObjectAttributes
.Attributes
= 0;
536 ObjectAttributes
.SecurityDescriptor
= NULL
;
537 ObjectAttributes
.SecurityQualityOfService
= &Qos
;
539 Status
= NtDuplicateToken (hToken
,
540 TOKEN_IMPERSONATE
| TOKEN_QUERY
,
545 if (!NT_SUCCESS(Status
))
547 SetLastError (RtlNtStatusToDosError (Status
));
555 /* User the original impersonation token */
560 /* Impersonate the the current thread */
561 Status
= NtSetInformationThread (NtCurrentThread (),
562 ThreadImpersonationToken
,
566 if (Duplicated
== TRUE
)
571 if (!NT_SUCCESS(Status
))
573 SetLastError (RtlNtStatusToDosError (Status
));
585 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
589 Status
= RtlImpersonateSelf(ImpersonationLevel
);
590 if (!NT_SUCCESS(Status
))
592 SetLastError(RtlNtStatusToDosError(Status
));
608 Status
= NtSetInformationThread(NtCurrentThread(),
609 ThreadImpersonationToken
,
612 if (!NT_SUCCESS(Status
))
614 SetLastError(RtlNtStatusToDosError(Status
));
621 /******************************************************************************
622 * GetUserNameA [ADVAPI32.@]
624 * Get the current user name.
627 * lpszName [O] Destination for the user name.
628 * lpSize [I/O] Size of lpszName.
634 GetUserNameA( LPSTR lpszName
, LPDWORD lpSize
)
636 UNICODE_STRING NameW
;
640 /* apparently Win doesn't check whether lpSize is valid at all! */
643 NameW
.MaximumLength
= (*lpSize
) * sizeof(WCHAR
);
644 NameW
.Buffer
= LocalAlloc(LMEM_FIXED
, NameW
.MaximumLength
);
645 if(NameW
.Buffer
== NULL
)
647 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
652 NameA
.MaximumLength
= ((*lpSize
) < 0xFFFF ? (USHORT
)(*lpSize
) : 0xFFFF);
653 NameA
.Buffer
= lpszName
;
655 Ret
= GetUserNameW(NameW
.Buffer
,
659 RtlUnicodeStringToAnsiString(&NameA
, &NameW
, FALSE
);
660 NameA
.Buffer
[NameA
.Length
] = '\0';
662 *lpSize
= NameA
.Length
+ 1;
665 LocalFree(NameW
.Buffer
);
670 /******************************************************************************
671 * GetUserNameW [ADVAPI32.@]
678 GetUserNameW ( LPWSTR lpszName
, LPDWORD lpSize
)
680 HANDLE hToken
= INVALID_HANDLE_VALUE
;
683 TOKEN_USER
* token_user
= NULL
;
685 SID_NAME_USE snu
= SidTypeUser
;
686 WCHAR
* domain_name
= NULL
;
689 if ( !OpenThreadToken ( GetCurrentThread(), TOKEN_QUERY
, FALSE
, &hToken
) )
691 DWORD dwLastError
= GetLastError();
692 if ( dwLastError
!= ERROR_NO_TOKEN
693 && dwLastError
!= ERROR_NO_IMPERSONATION_TOKEN
)
695 /* don't call SetLastError(),
696 as OpenThreadToken() ought to have set one */
699 if ( !OpenProcessToken ( GetCurrentProcess(), TOKEN_QUERY
, &hToken
) )
701 /* don't call SetLastError(),
702 as OpenProcessToken() ought to have set one */
706 tu_buf
= LocalAlloc ( LMEM_FIXED
, 36 );
709 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
712 if ( !GetTokenInformation ( hToken
, TokenUser
, tu_buf
, 36, &tu_len
) || tu_len
> 36 )
714 LocalFree ( tu_buf
);
715 tu_buf
= LocalAlloc ( LMEM_FIXED
, tu_len
);
718 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
721 if ( !GetTokenInformation ( hToken
, TokenUser
, tu_buf
, tu_len
, &tu_len
) )
723 /* don't call SetLastError(),
724 as GetTokenInformation() ought to have set one */
725 LocalFree ( tu_buf
);
726 CloseHandle ( hToken
);
730 token_user
= (TOKEN_USER
*)tu_buf
;
734 domain_name
= LocalAlloc ( LMEM_FIXED
, dn_len
* sizeof(WCHAR
) );
737 LocalFree ( tu_buf
);
738 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
741 if ( !LookupAccountSidW ( NULL
, token_user
->User
.Sid
, lpszName
, &an_len
, domain_name
, &dn_len
, &snu
)
746 LocalFree ( domain_name
);
747 domain_name
= LocalAlloc ( LMEM_FIXED
, dn_len
* sizeof(WCHAR
) );
750 LocalFree ( tu_buf
);
751 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
755 if ( !LookupAccountSidW ( NULL
, token_user
->User
.Sid
, lpszName
, &an_len
, domain_name
, &dn_len
, &snu
) )
757 /* don't call SetLastError(),
758 as LookupAccountSid() ought to have set one */
759 LocalFree ( domain_name
);
760 CloseHandle ( hToken
);
765 LocalFree ( domain_name
);
766 LocalFree ( tu_buf
);
767 CloseHandle ( hToken
);
769 if ( an_len
> *lpSize
)
772 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
780 /******************************************************************************
781 * LookupAccountSidA [ADVAPI32.@]
786 LookupAccountSidA (LPCSTR lpSystemName
,
790 LPSTR lpReferencedDomainName
,
791 LPDWORD cchReferencedDomainName
,
794 UNICODE_STRING NameW
, ReferencedDomainNameW
, SystemNameW
;
795 DWORD szName
, szReferencedDomainName
;
799 * save the buffer sizes the caller passed to us, as they may get modified and
800 * we require the original values when converting back to ansi
803 szReferencedDomainName
= *cchReferencedDomainName
;
806 * allocate buffers for the unicode strings to receive
812 NameW
.MaximumLength
= szName
* sizeof(WCHAR
);
813 NameW
.Buffer
= (PWSTR
)LocalAlloc(LMEM_FIXED
, NameW
.MaximumLength
);
814 if(NameW
.Buffer
== NULL
)
816 SetLastError(ERROR_OUTOFMEMORY
);
823 if(szReferencedDomainName
> 0)
825 ReferencedDomainNameW
.Length
= 0;
826 ReferencedDomainNameW
.MaximumLength
= szReferencedDomainName
* sizeof(WCHAR
);
827 ReferencedDomainNameW
.Buffer
= (PWSTR
)LocalAlloc(LMEM_FIXED
, ReferencedDomainNameW
.MaximumLength
);
828 if(ReferencedDomainNameW
.Buffer
== NULL
)
832 LocalFree(NameW
.Buffer
);
834 SetLastError(ERROR_OUTOFMEMORY
);
839 ReferencedDomainNameW
.Buffer
= NULL
;
842 * convert the system name to unicode - if present
845 if(lpSystemName
!= NULL
)
847 ANSI_STRING SystemNameA
;
849 RtlInitAnsiString(&SystemNameA
, lpSystemName
);
850 RtlAnsiStringToUnicodeString(&SystemNameW
, &SystemNameA
, TRUE
);
853 SystemNameW
.Buffer
= NULL
;
856 * it's time to call the unicode version
859 Ret
= LookupAccountSidW(SystemNameW
.Buffer
,
863 ReferencedDomainNameW
.Buffer
,
864 cchReferencedDomainName
,
869 * convert unicode strings back to ansi, don't forget that we can't convert
870 * more than 0xFFFF (USHORT) characters! Also don't forget to explicitly
871 * terminate the converted string, the Rtl functions don't do that!
878 NameA
.MaximumLength
= ((szName
<= 0xFFFF) ? (USHORT
)szName
: 0xFFFF);
879 NameA
.Buffer
= lpName
;
881 RtlUnicodeStringToAnsiString(&NameA
, &NameW
, FALSE
);
882 NameA
.Buffer
[NameA
.Length
] = '\0';
885 if(lpReferencedDomainName
!= NULL
)
887 ANSI_STRING ReferencedDomainNameA
;
889 ReferencedDomainNameA
.Length
= 0;
890 ReferencedDomainNameA
.MaximumLength
= ((szReferencedDomainName
<= 0xFFFF) ?
891 (USHORT
)szReferencedDomainName
: 0xFFFF);
892 ReferencedDomainNameA
.Buffer
= lpReferencedDomainName
;
894 RtlUnicodeStringToAnsiString(&ReferencedDomainNameA
, &ReferencedDomainNameW
, FALSE
);
895 ReferencedDomainNameA
.Buffer
[ReferencedDomainNameA
.Length
] = '\0';
900 * free previously allocated buffers
903 if(SystemNameW
.Buffer
!= NULL
)
905 RtlFreeUnicodeString(&SystemNameW
);
907 if(NameW
.Buffer
!= NULL
)
909 LocalFree(NameW
.Buffer
);
911 if(ReferencedDomainNameW
.Buffer
!= NULL
)
913 LocalFree(ReferencedDomainNameW
.Buffer
);
920 /******************************************************************************
921 * LookupAccountSidW [ADVAPI32.@]
930 LPDWORD pdwAccountName
,
932 LPDWORD pdwDomainName
,
933 PSID_NAME_USE peUse
)
935 LSA_UNICODE_STRING SystemName
;
936 LSA_OBJECT_ATTRIBUTES ObjectAttributes
;
937 LSA_HANDLE PolicyHandle
= INVALID_HANDLE_VALUE
;
939 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain
= NULL
;
940 PLSA_TRANSLATED_NAME TranslatedName
= NULL
;
943 RtlInitUnicodeString ( &SystemName
, pSystemName
);
944 ZeroMemory(&ObjectAttributes
, sizeof(ObjectAttributes
));
945 Status
= LsaOpenPolicy ( &SystemName
, &ObjectAttributes
, POLICY_LOOKUP_NAMES
, &PolicyHandle
);
946 if ( !NT_SUCCESS(Status
) )
948 SetLastError ( LsaNtStatusToWinError(Status
) );
951 Status
= LsaLookupSids ( PolicyHandle
, 1, &pSid
, &ReferencedDomain
, &TranslatedName
);
953 LsaClose ( PolicyHandle
);
955 if ( !NT_SUCCESS(Status
) || Status
== STATUS_SOME_NOT_MAPPED
)
957 SetLastError ( LsaNtStatusToWinError(Status
) );
963 if ( TranslatedName
)
965 DWORD dwSrcLen
= TranslatedName
->Name
.Length
/ sizeof(WCHAR
);
966 if ( *pdwAccountName
<= dwSrcLen
)
968 *pdwAccountName
= dwSrcLen
+ 1;
973 *pdwAccountName
= dwSrcLen
;
974 wcscpy ( pAccountName
, TranslatedName
->Name
.Buffer
);
977 *peUse
= TranslatedName
->Use
;
980 if ( ReferencedDomain
)
982 if ( ReferencedDomain
->Entries
> 0 )
984 DWORD dwSrcLen
= ReferencedDomain
->Domains
[0].Name
.Length
/ sizeof(WCHAR
);
985 if ( *pdwDomainName
<= dwSrcLen
)
987 *pdwDomainName
= dwSrcLen
+ 1;
992 *pdwDomainName
= dwSrcLen
;
993 wcscpy ( pDomainName
, ReferencedDomain
->Domains
[0].Name
.Buffer
);
999 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1002 if ( ReferencedDomain
)
1003 LsaFreeMemory ( ReferencedDomain
);
1004 if ( TranslatedName
)
1005 LsaFreeMemory ( TranslatedName
);
1012 /******************************************************************************
1013 * LookupAccountNameA [ADVAPI32.@]
1018 LookupAccountNameA (LPCSTR SystemName
,
1022 LPSTR ReferencedDomainName
,
1023 LPDWORD hReferencedDomainNameLength
,
1024 PSID_NAME_USE SidNameUse
)
1026 DPRINT1("LookupAccountNameA is unimplemented\n");
1027 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1032 /******************************************************************************
1033 * LookupAccountNameW [ADVAPI32.@]
1038 LookupAccountNameW (LPCWSTR SystemName
,
1039 LPCWSTR AccountName
,
1042 LPWSTR ReferencedDomainName
,
1043 LPDWORD hReferencedDomainNameLength
,
1044 PSID_NAME_USE SidNameUse
)
1046 DPRINT1("LookupAccountNameW is unimplemented\n");
1047 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1052 /**********************************************************************
1053 * LookupPrivilegeValueA EXPORTED
1058 LookupPrivilegeValueA (LPCSTR lpSystemName
,
1062 UNICODE_STRING SystemName
;
1063 UNICODE_STRING Name
;
1066 /* Remote system? */
1067 if (lpSystemName
!= NULL
)
1069 RtlCreateUnicodeStringFromAsciiz (&SystemName
,
1070 (LPSTR
)lpSystemName
);
1073 /* Check the privilege name is not NULL */
1076 SetLastError (ERROR_INVALID_PARAMETER
);
1080 RtlCreateUnicodeStringFromAsciiz (&Name
,
1083 Result
= LookupPrivilegeValueW ((lpSystemName
!= NULL
) ? SystemName
.Buffer
: NULL
,
1087 RtlFreeUnicodeString (&Name
);
1089 /* Remote system? */
1090 if (lpSystemName
!= NULL
)
1092 RtlFreeUnicodeString (&SystemName
);
1099 /**********************************************************************
1100 * LookupPrivilegeValueW EXPORTED
1105 LookupPrivilegeValueW (LPCWSTR SystemName
,
1109 static const WCHAR
* const DefaultPrivNames
[] =
1111 L
"SeCreateTokenPrivilege",
1112 L
"SeAssignPrimaryTokenPrivilege",
1113 L
"SeLockMemoryPrivilege",
1114 L
"SeIncreaseQuotaPrivilege",
1115 L
"SeUnsolicitedInputPrivilege",
1116 L
"SeMachineAccountPrivilege",
1118 L
"SeSecurityPrivilege",
1119 L
"SeTakeOwnershipPrivilege",
1120 L
"SeLoadDriverPrivilege",
1121 L
"SeSystemProfilePrivilege",
1122 L
"SeSystemtimePrivilege",
1123 L
"SeProfileSingleProcessPrivilege",
1124 L
"SeIncreaseBasePriorityPrivilege",
1125 L
"SeCreatePagefilePrivilege",
1126 L
"SeCreatePermanentPrivilege",
1127 L
"SeBackupPrivilege",
1128 L
"SeRestorePrivilege",
1129 L
"SeShutdownPrivilege",
1130 L
"SeDebugPrivilege",
1131 L
"SeAuditPrivilege",
1132 L
"SeSystemEnvironmentPrivilege",
1133 L
"SeChangeNotifyPrivilege",
1134 L
"SeRemoteShutdownPrivilege",
1135 L
"SeUndockPrivilege",
1136 L
"SeSyncAgentPrivilege",
1137 L
"SeEnableDelegationPrivilege",
1138 L
"SeManageVolumePrivilege",
1139 L
"SeImpersonatePrivilege",
1140 L
"SeCreateGlobalPrivilege"
1144 if (NULL
!= SystemName
&& L
'\0' != *SystemName
)
1146 DPRINT1("LookupPrivilegeValueW: not implemented for remote system\n");
1147 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1151 for (Priv
= 0; Priv
< sizeof(DefaultPrivNames
) / sizeof(DefaultPrivNames
[0]); Priv
++)
1153 if (0 == wcscmp(PrivName
, DefaultPrivNames
[Priv
]))
1155 Luid
->LowPart
= Priv
+ 1;
1161 DPRINT1("LookupPrivilegeValueW: no such privilege %S\n", PrivName
);
1162 SetLastError(ERROR_NO_SUCH_PRIVILEGE
);
1167 /**********************************************************************
1168 * LookupPrivilegeDisplayNameA EXPORTED
1173 LookupPrivilegeDisplayNameA (LPCSTR lpSystemName
,
1175 LPSTR lpDisplayName
,
1176 LPDWORD cbDisplayName
,
1177 LPDWORD lpLanguageId
)
1179 DPRINT1("LookupPrivilegeDisplayNameA: stub\n");
1180 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1185 /**********************************************************************
1186 * LookupPrivilegeDisplayNameW EXPORTED
1191 LookupPrivilegeDisplayNameW (LPCWSTR lpSystemName
,
1193 LPWSTR lpDisplayName
,
1194 LPDWORD cbDisplayName
,
1195 LPDWORD lpLanguageId
)
1197 DPRINT1("LookupPrivilegeDisplayNameW: stub\n");
1198 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1203 /**********************************************************************
1204 * LookupPrivilegeNameA EXPORTED
1209 LookupPrivilegeNameA (LPCSTR lpSystemName
,
1214 DPRINT1("LookupPrivilegeNameA: stub\n");
1215 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1220 /**********************************************************************
1221 * LookupPrivilegeNameW EXPORTED
1226 LookupPrivilegeNameW (LPCWSTR lpSystemName
,
1231 DPRINT1("LookupPrivilegeNameW: stub\n");
1232 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1237 /**********************************************************************
1238 * GetNamedSecurityInfoW EXPORTED
1243 GetNamedSecurityInfoW(LPWSTR pObjectName
,
1244 SE_OBJECT_TYPE ObjectType
,
1245 SECURITY_INFORMATION SecurityInfo
,
1250 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1252 DPRINT1("GetNamedSecurityInfoW: stub\n");
1253 return ERROR_CALL_NOT_IMPLEMENTED
;
1257 /**********************************************************************
1258 * GetNamedSecurityInfoA EXPORTED
1263 GetNamedSecurityInfoA(LPSTR pObjectName
,
1264 SE_OBJECT_TYPE ObjectType
,
1265 SECURITY_INFORMATION SecurityInfo
,
1270 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1272 DPRINT1("GetNamedSecurityInfoA: stub\n");
1273 return ERROR_CALL_NOT_IMPLEMENTED
;
1277 /**********************************************************************
1278 * SetNamedSecurityInfoW EXPORTED
1283 SetNamedSecurityInfoW(LPWSTR pObjectName
,
1284 SE_OBJECT_TYPE ObjectType
,
1285 SECURITY_INFORMATION SecurityInfo
,
1291 DPRINT1("SetNamedSecurityInfoW: stub\n");
1292 return ERROR_CALL_NOT_IMPLEMENTED
;
1296 /**********************************************************************
1297 * SetNamedSecurityInfoA EXPORTED
1302 SetNamedSecurityInfoA(LPSTR pObjectName
,
1303 SE_OBJECT_TYPE ObjectType
,
1304 SECURITY_INFORMATION SecurityInfo
,
1310 DPRINT1("SetNamedSecurityInfoA: stub\n");
1311 return ERROR_CALL_NOT_IMPLEMENTED
;
1315 /**********************************************************************
1316 * GetSecurityInfo EXPORTED
1321 GetSecurityInfo(HANDLE handle
,
1322 SE_OBJECT_TYPE ObjectType
,
1323 SECURITY_INFORMATION SecurityInfo
,
1328 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
1334 ErrorCode
= CheckNtMartaPresent();
1335 if (ErrorCode
== ERROR_SUCCESS
)
1337 if ((SecurityInfo
& (OWNER_SECURITY_INFORMATION
|
1338 GROUP_SECURITY_INFORMATION
|
1339 DACL_SECURITY_INFORMATION
|
1340 SACL_SECURITY_INFORMATION
)) &&
1341 ppSecurityDescriptor
== NULL
)
1343 /* if one of the SIDs or ACLs are present, the security descriptor
1345 ErrorCode
= ERROR_INVALID_PARAMETER
;
1349 /* reset the pointers unless they're ignored */
1350 if ((SecurityInfo
& OWNER_SECURITY_INFORMATION
) &&
1355 if ((SecurityInfo
& GROUP_SECURITY_INFORMATION
) &&
1356 *ppsidGroup
!= NULL
)
1360 if ((SecurityInfo
& DACL_SECURITY_INFORMATION
) &&
1365 if ((SecurityInfo
& SACL_SECURITY_INFORMATION
) &&
1371 ErrorCode
= AccRewriteGetHandleRights(handle
,
1378 ppSecurityDescriptor
);
1383 ErrorCode
= ERROR_INVALID_HANDLE
;
1389 /**********************************************************************
1390 * SetSecurityInfo EXPORTED
1396 SetSecurityInfo(HANDLE handle
,
1397 SE_OBJECT_TYPE ObjectType
,
1398 SECURITY_INFORMATION SecurityInfo
,
1408 ErrorCode
= CheckNtMartaPresent();
1409 if (ErrorCode
== ERROR_SUCCESS
)
1411 SECURITY_DESCRIPTOR SecurityDescriptor
;
1413 /* initialize a security descriptor on the stack */
1414 InitializeSecurityDescriptor(&SecurityDescriptor
,
1415 SECURITY_DESCRIPTOR_REVISION
);
1417 if (SecurityInfo
& OWNER_SECURITY_INFORMATION
)
1419 if (RtlValidSid(psidOwner
))
1421 if (!SetSecurityDescriptorOwner(&SecurityDescriptor
,
1425 return GetLastError();
1430 return ERROR_INVALID_PARAMETER
;
1434 if (SecurityInfo
& GROUP_SECURITY_INFORMATION
)
1436 if (RtlValidSid(psidGroup
))
1438 if (!SetSecurityDescriptorGroup(&SecurityDescriptor
,
1442 return GetLastError();
1447 return ERROR_INVALID_PARAMETER
;
1451 if (SecurityInfo
& DACL_SECURITY_INFORMATION
)
1455 if (SetSecurityDescriptorDacl(&SecurityDescriptor
,
1460 /* check if the DACL needs to be protected from being
1461 modified by inheritable ACEs */
1462 if (SecurityInfo
& PROTECTED_DACL_SECURITY_INFORMATION
)
1469 return GetLastError();
1475 /* protect the DACL from being modified by inheritable ACEs */
1476 if (!SetSecurityDescriptorControl(&SecurityDescriptor
,
1480 return GetLastError();
1485 if (SecurityInfo
& SACL_SECURITY_INFORMATION
)
1489 if (SetSecurityDescriptorSacl(&SecurityDescriptor
,
1494 /* check if the SACL needs to be protected from being
1495 modified by inheritable ACEs */
1496 if (SecurityInfo
& PROTECTED_SACL_SECURITY_INFORMATION
)
1503 return GetLastError();
1509 /* protect the SACL from being modified by inheritable ACEs */
1510 if (!SetSecurityDescriptorControl(&SecurityDescriptor
,
1514 return GetLastError();
1519 ErrorCode
= AccRewriteSetHandleRights(handle
,
1522 &SecurityDescriptor
);
1526 ErrorCode
= ERROR_INVALID_HANDLE
;
1532 /******************************************************************************
1533 * GetSecurityInfoExW EXPORTED
1535 DWORD WINAPI
GetSecurityInfoExA(
1537 SE_OBJECT_TYPE ObjectType
,
1538 SECURITY_INFORMATION SecurityInfo
,
1541 PACTRL_ACCESSA
*ppAccessList
,
1542 PACTRL_AUDITA
*ppAuditList
,
1547 DPRINT1("GetSecurityInfoExA stub!\n");
1548 return ERROR_BAD_PROVIDER
;
1552 /******************************************************************************
1553 * GetSecurityInfoExW EXPORTED
1555 DWORD WINAPI
GetSecurityInfoExW(
1557 SE_OBJECT_TYPE ObjectType
,
1558 SECURITY_INFORMATION SecurityInfo
,
1561 PACTRL_ACCESSW
*ppAccessList
,
1562 PACTRL_AUDITW
*ppAuditList
,
1567 DPRINT1("GetSecurityInfoExW stub!\n");
1568 return ERROR_BAD_PROVIDER
;
1572 /**********************************************************************
1573 * ImpersonateNamedPipeClient EXPORTED
1578 ImpersonateNamedPipeClient(HANDLE hNamedPipe
)
1580 IO_STATUS_BLOCK StatusBlock
;
1583 DPRINT("ImpersonateNamedPipeClient() called\n");
1585 Status
= NtFsControlFile(hNamedPipe
,
1590 FSCTL_PIPE_IMPERSONATE
,
1595 if (!NT_SUCCESS(Status
))
1597 SetLastError(RtlNtStatusToDosError(Status
));
1609 CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor
,
1610 PSECURITY_DESCRIPTOR CreatorDescriptor
,
1611 PSECURITY_DESCRIPTOR
*NewDescriptor
,
1612 BOOL IsDirectoryObject
,
1614 PGENERIC_MAPPING GenericMapping
)
1618 Status
= RtlNewSecurityObject(ParentDescriptor
,
1624 if (!NT_SUCCESS(Status
))
1626 SetLastError(RtlNtStatusToDosError(Status
));
1638 DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR
*ObjectDescriptor
)
1642 Status
= RtlDeleteSecurityObject(ObjectDescriptor
);
1643 if (!NT_SUCCESS(Status
))
1645 SetLastError(RtlNtStatusToDosError(Status
));
1657 GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR ObjectDescriptor
,
1658 SECURITY_INFORMATION SecurityInformation
,
1659 PSECURITY_DESCRIPTOR ResultantDescriptor
,
1660 DWORD DescriptorLength
,
1661 PDWORD ReturnLength
)
1665 Status
= RtlQuerySecurityObject(ObjectDescriptor
,
1666 SecurityInformation
,
1667 ResultantDescriptor
,
1670 if (!NT_SUCCESS(Status
))
1672 SetLastError(RtlNtStatusToDosError(Status
));
1684 SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation
,
1685 PSECURITY_DESCRIPTOR ModificationDescriptor
,
1686 PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
1687 PGENERIC_MAPPING GenericMapping
,
1692 Status
= RtlSetSecurityObject(SecurityInformation
,
1693 ModificationDescriptor
,
1694 ObjectsSecurityDescriptor
,
1697 if (!NT_SUCCESS(Status
))
1699 SetLastError(RtlNtStatusToDosError(Status
));