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 NTMARTA NtMartaStatic
= { 0 };
19 static PNTMARTA NtMarta
= NULL
;
21 #define FindNtMartaProc(Name) \
22 NtMartaStatic.Name = (PVOID)GetProcAddress(NtMartaStatic.hDllInstance, \
24 if (NtMartaStatic.Name == NULL) \
26 return GetLastError(); \
30 LoadAndInitializeNtMarta(VOID
)
32 /* this code may be executed simultaneously by multiple threads in case they're
33 trying to initialize the interface at the same time, but that's no problem
34 because the pointers returned by GetProcAddress will be the same. However,
35 only one of the threads will change the NtMarta pointer to the NtMartaStatic
36 structure, the others threads will detect that there were other threads
37 initializing the structure faster and will release the reference to the
40 NtMartaStatic
.hDllInstance
= LoadLibraryW(L
"ntmarta.dll");
41 if (NtMartaStatic
.hDllInstance
== NULL
)
43 return GetLastError();
47 FindNtMartaProc(LookupAccountTrustee
);
48 FindNtMartaProc(LookupAccountName
);
49 FindNtMartaProc(LookupAccountSid
);
50 FindNtMartaProc(SetEntriesInAList
);
51 FindNtMartaProc(ConvertAccessToSecurityDescriptor
);
52 FindNtMartaProc(ConvertSDToAccess
);
53 FindNtMartaProc(ConvertAclToAccess
);
54 FindNtMartaProc(GetAccessForTrustee
);
55 FindNtMartaProc(GetExplicitEntries
);
57 FindNtMartaProc(RewriteGetNamedRights
);
58 FindNtMartaProc(RewriteSetNamedRights
);
59 FindNtMartaProc(RewriteGetHandleRights
);
60 FindNtMartaProc(RewriteSetHandleRights
);
61 FindNtMartaProc(RewriteSetEntriesInAcl
);
63 FindNtMartaProc(RewriteGetExplicitEntriesFromAcl
);
64 FindNtMartaProc(TreeResetNamedSecurityInfo
);
66 FindNtMartaProc(GetInheritanceSource
);
67 FindNtMartaProc(FreeIndexArray
);
73 CheckNtMartaPresent(VOID
)
79 /* we're the first one trying to use ntmarta, initialize it and change
80 the pointer after initialization */
81 ErrorCode
= LoadAndInitializeNtMarta();
83 if (ErrorCode
== ERROR_SUCCESS
)
85 /* try change the NtMarta pointer */
86 if (InterlockedCompareExchangePointer(&NtMarta
,
90 /* another thread initialized ntmarta in the meanwhile, release
91 the reference of the dll loaded. */
92 FreeLibrary(NtMartaStatic
.hDllInstance
);
98 DPRINT1("Failed to initialize ntmarta.dll! Error: 0x%x", ErrorCode
);
104 /* ntmarta was already initialized */
105 ErrorCode
= ERROR_SUCCESS
;
111 VOID
UnloadNtMarta(VOID
)
113 if (InterlockedExchangePointer(&NtMarta
,
116 FreeLibrary(NtMartaStatic
.hDllInstance
);
120 /******************************************************************************/
126 AreAllAccessesGranted(DWORD GrantedAccess
,
129 return((BOOL
)RtlAreAllAccessesGranted(GrantedAccess
,
138 AreAnyAccessesGranted(DWORD GrantedAccess
,
141 return((BOOL
)RtlAreAnyAccessesGranted(GrantedAccess
,
146 /******************************************************************************
147 * GetFileSecurityA [ADVAPI32.@]
149 * Obtains Specified information about the security of a file or directory.
152 * lpFileName [I] Name of the file to get info for
153 * RequestedInformation [I] SE_ flags from "winnt.h"
154 * pSecurityDescriptor [O] Destination for security information
155 * nLength [I] Length of pSecurityDescriptor
156 * lpnLengthNeeded [O] Destination for length of returned security information
159 * Success: TRUE. pSecurityDescriptor contains the requested information.
160 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
163 * The information returned is constrained by the callers access rights and
169 GetFileSecurityA(LPCSTR lpFileName
,
170 SECURITY_INFORMATION RequestedInformation
,
171 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
173 LPDWORD lpnLengthNeeded
)
175 UNICODE_STRING FileName
;
179 Status
= RtlCreateUnicodeStringFromAsciiz(&FileName
,
181 if (!NT_SUCCESS(Status
))
183 SetLastError(RtlNtStatusToDosError(Status
));
187 bResult
= GetFileSecurityW(FileName
.Buffer
,
188 RequestedInformation
,
193 RtlFreeUnicodeString(&FileName
);
203 GetFileSecurityW(LPCWSTR lpFileName
,
204 SECURITY_INFORMATION RequestedInformation
,
205 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
207 LPDWORD lpnLengthNeeded
)
209 OBJECT_ATTRIBUTES ObjectAttributes
;
210 IO_STATUS_BLOCK StatusBlock
;
211 UNICODE_STRING FileName
;
212 ULONG AccessMask
= 0;
216 DPRINT("GetFileSecurityW() called\n");
218 if (RequestedInformation
&
219 (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION
))
221 AccessMask
|= STANDARD_RIGHTS_READ
;
224 if (RequestedInformation
& SACL_SECURITY_INFORMATION
)
226 AccessMask
|= ACCESS_SYSTEM_SECURITY
;
229 if (!RtlDosPathNameToNtPathName_U((LPWSTR
)lpFileName
,
234 DPRINT("Invalid path\n");
235 SetLastError(ERROR_INVALID_NAME
);
239 InitializeObjectAttributes(&ObjectAttributes
,
241 OBJ_CASE_INSENSITIVE
,
245 Status
= NtOpenFile(&FileHandle
,
249 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
251 if (!NT_SUCCESS(Status
))
253 DPRINT("NtOpenFile() failed (Status %lx)\n", Status
);
254 SetLastError(RtlNtStatusToDosError(Status
));
258 RtlFreeUnicodeString(&FileName
);
260 Status
= NtQuerySecurityObject(FileHandle
,
261 RequestedInformation
,
267 if (!NT_SUCCESS(Status
))
269 DPRINT("NtQuerySecurityObject() failed (Status %lx)\n", Status
);
270 SetLastError(RtlNtStatusToDosError(Status
));
282 GetKernelObjectSecurity(HANDLE Handle
,
283 SECURITY_INFORMATION RequestedInformation
,
284 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
286 LPDWORD lpnLengthNeeded
)
290 Status
= NtQuerySecurityObject(Handle
,
291 RequestedInformation
,
295 if (!NT_SUCCESS(Status
))
297 SetLastError(RtlNtStatusToDosError(Status
));
304 /******************************************************************************
305 * SetFileSecurityA [ADVAPI32.@]
306 * Sets the security of a file or directory
311 SetFileSecurityA (LPCSTR lpFileName
,
312 SECURITY_INFORMATION SecurityInformation
,
313 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
315 UNICODE_STRING FileName
;
319 Status
= RtlCreateUnicodeStringFromAsciiz(&FileName
,
321 if (!NT_SUCCESS(Status
))
323 SetLastError(RtlNtStatusToDosError(Status
));
327 bResult
= SetFileSecurityW(FileName
.Buffer
,
329 pSecurityDescriptor
);
331 RtlFreeUnicodeString(&FileName
);
337 /******************************************************************************
338 * SetFileSecurityW [ADVAPI32.@]
339 * Sets the security of a file or directory
344 SetFileSecurityW (LPCWSTR lpFileName
,
345 SECURITY_INFORMATION SecurityInformation
,
346 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
348 OBJECT_ATTRIBUTES ObjectAttributes
;
349 IO_STATUS_BLOCK StatusBlock
;
350 UNICODE_STRING FileName
;
351 ULONG AccessMask
= 0;
355 DPRINT("SetFileSecurityW() called\n");
357 if (SecurityInformation
&
358 (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
))
360 AccessMask
|= WRITE_OWNER
;
363 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
365 AccessMask
|= WRITE_DAC
;
368 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
370 AccessMask
|= ACCESS_SYSTEM_SECURITY
;
373 if (!RtlDosPathNameToNtPathName_U((LPWSTR
)lpFileName
,
378 DPRINT("Invalid path\n");
379 SetLastError(ERROR_INVALID_NAME
);
383 InitializeObjectAttributes(&ObjectAttributes
,
385 OBJ_CASE_INSENSITIVE
,
389 Status
= NtOpenFile(&FileHandle
,
393 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
395 if (!NT_SUCCESS(Status
))
397 DPRINT("NtOpenFile() failed (Status %lx)\n", Status
);
398 SetLastError(RtlNtStatusToDosError(Status
));
402 RtlFreeUnicodeString(&FileName
);
404 Status
= NtSetSecurityObject(FileHandle
,
406 pSecurityDescriptor
);
409 if (!NT_SUCCESS(Status
))
411 DPRINT("NtSetSecurityObject() failed (Status %lx)\n", Status
);
412 SetLastError(RtlNtStatusToDosError(Status
));
424 SetKernelObjectSecurity(HANDLE Handle
,
425 SECURITY_INFORMATION SecurityInformation
,
426 PSECURITY_DESCRIPTOR SecurityDescriptor
)
430 Status
= NtSetSecurityObject(Handle
,
433 if (!NT_SUCCESS(Status
))
435 SetLastError(RtlNtStatusToDosError(Status
));
446 ImpersonateLoggedOnUser(HANDLE hToken
)
448 SECURITY_QUALITY_OF_SERVICE Qos
;
449 OBJECT_ATTRIBUTES ObjectAttributes
;
456 /* Get the token type */
457 Status
= NtQueryInformationToken (hToken
,
462 if (!NT_SUCCESS(Status
))
464 SetLastError (RtlNtStatusToDosError (Status
));
468 if (Type
== TokenPrimary
)
470 /* Create a duplicate impersonation token */
471 Qos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
472 Qos
.ImpersonationLevel
= SecurityImpersonation
;
473 Qos
.ContextTrackingMode
= SECURITY_DYNAMIC_TRACKING
;
474 Qos
.EffectiveOnly
= FALSE
;
476 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
477 ObjectAttributes
.RootDirectory
= NULL
;
478 ObjectAttributes
.ObjectName
= NULL
;
479 ObjectAttributes
.Attributes
= 0;
480 ObjectAttributes
.SecurityDescriptor
= NULL
;
481 ObjectAttributes
.SecurityQualityOfService
= &Qos
;
483 Status
= NtDuplicateToken (hToken
,
484 TOKEN_IMPERSONATE
| TOKEN_QUERY
,
489 if (!NT_SUCCESS(Status
))
491 SetLastError (RtlNtStatusToDosError (Status
));
499 /* User the original impersonation token */
504 /* Impersonate the the current thread */
505 Status
= NtSetInformationThread (NtCurrentThread (),
506 ThreadImpersonationToken
,
510 if (Duplicated
== TRUE
)
515 if (!NT_SUCCESS(Status
))
517 SetLastError (RtlNtStatusToDosError (Status
));
529 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
533 Status
= RtlImpersonateSelf(ImpersonationLevel
);
534 if (!NT_SUCCESS(Status
))
536 SetLastError(RtlNtStatusToDosError(Status
));
552 Status
= NtSetInformationThread(NtCurrentThread(),
553 ThreadImpersonationToken
,
556 if (!NT_SUCCESS(Status
))
558 SetLastError(RtlNtStatusToDosError(Status
));
565 /******************************************************************************
566 * GetUserNameA [ADVAPI32.@]
568 * Get the current user name.
571 * lpszName [O] Destination for the user name.
572 * lpSize [I/O] Size of lpszName.
578 GetUserNameA( LPSTR lpszName
, LPDWORD lpSize
)
580 UNICODE_STRING NameW
;
584 /* apparently Win doesn't check whether lpSize is valid at all! */
587 NameW
.MaximumLength
= (*lpSize
) * sizeof(WCHAR
);
588 NameW
.Buffer
= LocalAlloc(LMEM_FIXED
, NameW
.MaximumLength
);
589 if(NameW
.Buffer
== NULL
)
591 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
596 NameA
.MaximumLength
= ((*lpSize
) < 0xFFFF ? (USHORT
)(*lpSize
) : 0xFFFF);
597 NameA
.Buffer
= lpszName
;
599 Ret
= GetUserNameW(NameW
.Buffer
,
603 RtlUnicodeStringToAnsiString(&NameA
, &NameW
, FALSE
);
604 NameA
.Buffer
[NameA
.Length
] = '\0';
606 *lpSize
= NameA
.Length
+ 1;
609 LocalFree(NameW
.Buffer
);
614 /******************************************************************************
615 * GetUserNameW [ADVAPI32.@]
622 GetUserNameW ( LPWSTR lpszName
, LPDWORD lpSize
)
624 HANDLE hToken
= INVALID_HANDLE_VALUE
;
627 TOKEN_USER
* token_user
= NULL
;
629 SID_NAME_USE snu
= SidTypeUser
;
630 WCHAR
* domain_name
= NULL
;
633 if ( !OpenThreadToken ( GetCurrentThread(), TOKEN_QUERY
, FALSE
, &hToken
) )
635 DWORD dwLastError
= GetLastError();
636 if ( dwLastError
!= ERROR_NO_TOKEN
637 && dwLastError
!= ERROR_NO_IMPERSONATION_TOKEN
)
639 /* don't call SetLastError(),
640 as OpenThreadToken() ought to have set one */
643 if ( !OpenProcessToken ( GetCurrentProcess(), TOKEN_QUERY
, &hToken
) )
645 /* don't call SetLastError(),
646 as OpenProcessToken() ought to have set one */
650 tu_buf
= LocalAlloc ( LMEM_FIXED
, 36 );
653 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
656 if ( !GetTokenInformation ( hToken
, TokenUser
, tu_buf
, 36, &tu_len
) || tu_len
> 36 )
658 LocalFree ( tu_buf
);
659 tu_buf
= LocalAlloc ( LMEM_FIXED
, tu_len
);
662 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
665 if ( !GetTokenInformation ( hToken
, TokenUser
, tu_buf
, tu_len
, &tu_len
) )
667 /* don't call SetLastError(),
668 as GetTokenInformation() ought to have set one */
669 LocalFree ( tu_buf
);
670 CloseHandle ( hToken
);
674 token_user
= (TOKEN_USER
*)tu_buf
;
678 domain_name
= LocalAlloc ( LMEM_FIXED
, dn_len
* sizeof(WCHAR
) );
681 LocalFree ( tu_buf
);
682 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
685 if ( !LookupAccountSidW ( NULL
, token_user
->User
.Sid
, lpszName
, &an_len
, domain_name
, &dn_len
, &snu
)
690 LocalFree ( domain_name
);
691 domain_name
= LocalAlloc ( LMEM_FIXED
, dn_len
* sizeof(WCHAR
) );
694 LocalFree ( tu_buf
);
695 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
699 if ( !LookupAccountSidW ( NULL
, token_user
->User
.Sid
, lpszName
, &an_len
, domain_name
, &dn_len
, &snu
) )
701 /* don't call SetLastError(),
702 as LookupAccountSid() ought to have set one */
703 LocalFree ( domain_name
);
704 CloseHandle ( hToken
);
709 LocalFree ( domain_name
);
710 LocalFree ( tu_buf
);
711 CloseHandle ( hToken
);
713 if ( an_len
> *lpSize
)
716 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
724 /******************************************************************************
725 * LookupAccountSidA [ADVAPI32.@]
730 LookupAccountSidA (LPCSTR lpSystemName
,
734 LPSTR lpReferencedDomainName
,
735 LPDWORD cchReferencedDomainName
,
738 UNICODE_STRING NameW
, ReferencedDomainNameW
, SystemNameW
;
739 DWORD szName
, szReferencedDomainName
;
743 * save the buffer sizes the caller passed to us, as they may get modified and
744 * we require the original values when converting back to ansi
747 szReferencedDomainName
= *cchReferencedDomainName
;
750 * allocate buffers for the unicode strings to receive
756 NameW
.MaximumLength
= szName
* sizeof(WCHAR
);
757 NameW
.Buffer
= (PWSTR
)LocalAlloc(LMEM_FIXED
, NameW
.MaximumLength
);
758 if(NameW
.Buffer
== NULL
)
760 SetLastError(ERROR_OUTOFMEMORY
);
767 if(szReferencedDomainName
> 0)
769 ReferencedDomainNameW
.Length
= 0;
770 ReferencedDomainNameW
.MaximumLength
= szReferencedDomainName
* sizeof(WCHAR
);
771 ReferencedDomainNameW
.Buffer
= (PWSTR
)LocalAlloc(LMEM_FIXED
, ReferencedDomainNameW
.MaximumLength
);
772 if(ReferencedDomainNameW
.Buffer
== NULL
)
776 LocalFree(NameW
.Buffer
);
778 SetLastError(ERROR_OUTOFMEMORY
);
783 ReferencedDomainNameW
.Buffer
= NULL
;
786 * convert the system name to unicode - if present
789 if(lpSystemName
!= NULL
)
791 ANSI_STRING SystemNameA
;
793 RtlInitAnsiString(&SystemNameA
, lpSystemName
);
794 RtlAnsiStringToUnicodeString(&SystemNameW
, &SystemNameA
, TRUE
);
797 SystemNameW
.Buffer
= NULL
;
800 * it's time to call the unicode version
803 Ret
= LookupAccountSidW(SystemNameW
.Buffer
,
807 ReferencedDomainNameW
.Buffer
,
808 cchReferencedDomainName
,
813 * convert unicode strings back to ansi, don't forget that we can't convert
814 * more than 0xFFFF (USHORT) characters! Also don't forget to explicitly
815 * terminate the converted string, the Rtl functions don't do that!
822 NameA
.MaximumLength
= ((szName
<= 0xFFFF) ? (USHORT
)szName
: 0xFFFF);
823 NameA
.Buffer
= lpName
;
825 RtlUnicodeStringToAnsiString(&NameA
, &NameW
, FALSE
);
826 NameA
.Buffer
[NameA
.Length
] = '\0';
829 if(lpReferencedDomainName
!= NULL
)
831 ANSI_STRING ReferencedDomainNameA
;
833 ReferencedDomainNameA
.Length
= 0;
834 ReferencedDomainNameA
.MaximumLength
= ((szReferencedDomainName
<= 0xFFFF) ?
835 (USHORT
)szReferencedDomainName
: 0xFFFF);
836 ReferencedDomainNameA
.Buffer
= lpReferencedDomainName
;
838 RtlUnicodeStringToAnsiString(&ReferencedDomainNameA
, &ReferencedDomainNameW
, FALSE
);
839 ReferencedDomainNameA
.Buffer
[ReferencedDomainNameA
.Length
] = '\0';
844 * free previously allocated buffers
847 if(SystemNameW
.Buffer
!= NULL
)
849 RtlFreeUnicodeString(&SystemNameW
);
851 if(NameW
.Buffer
!= NULL
)
853 LocalFree(NameW
.Buffer
);
855 if(ReferencedDomainNameW
.Buffer
!= NULL
)
857 LocalFree(ReferencedDomainNameW
.Buffer
);
864 /******************************************************************************
865 * LookupAccountSidW [ADVAPI32.@]
874 LPDWORD pdwAccountName
,
876 LPDWORD pdwDomainName
,
877 PSID_NAME_USE peUse
)
879 LSA_UNICODE_STRING SystemName
;
880 LSA_OBJECT_ATTRIBUTES ObjectAttributes
;
881 LSA_HANDLE PolicyHandle
= INVALID_HANDLE_VALUE
;
883 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain
= NULL
;
884 PLSA_TRANSLATED_NAME TranslatedName
= NULL
;
887 RtlInitUnicodeString ( &SystemName
, pSystemName
);
888 ZeroMemory(&ObjectAttributes
, sizeof(ObjectAttributes
));
889 Status
= LsaOpenPolicy ( &SystemName
, &ObjectAttributes
, POLICY_LOOKUP_NAMES
, &PolicyHandle
);
890 if ( !NT_SUCCESS(Status
) )
892 SetLastError ( LsaNtStatusToWinError(Status
) );
895 Status
= LsaLookupSids ( PolicyHandle
, 1, &pSid
, &ReferencedDomain
, &TranslatedName
);
897 LsaClose ( PolicyHandle
);
899 if ( !NT_SUCCESS(Status
) || Status
== STATUS_SOME_NOT_MAPPED
)
901 SetLastError ( LsaNtStatusToWinError(Status
) );
907 if ( TranslatedName
)
909 DWORD dwSrcLen
= TranslatedName
->Name
.Length
/ sizeof(WCHAR
);
910 if ( *pdwAccountName
<= dwSrcLen
)
912 *pdwAccountName
= dwSrcLen
+ 1;
917 *pdwAccountName
= dwSrcLen
;
918 wcscpy ( pAccountName
, TranslatedName
->Name
.Buffer
);
921 *peUse
= TranslatedName
->Use
;
924 if ( ReferencedDomain
)
926 if ( ReferencedDomain
->Entries
> 0 )
928 DWORD dwSrcLen
= ReferencedDomain
->Domains
[0].Name
.Length
/ sizeof(WCHAR
);
929 if ( *pdwDomainName
<= dwSrcLen
)
931 *pdwDomainName
= dwSrcLen
+ 1;
936 *pdwDomainName
= dwSrcLen
;
937 wcscpy ( pDomainName
, ReferencedDomain
->Domains
[0].Name
.Buffer
);
943 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
946 if ( ReferencedDomain
)
947 LsaFreeMemory ( ReferencedDomain
);
948 if ( TranslatedName
)
949 LsaFreeMemory ( TranslatedName
);
956 /******************************************************************************
957 * LookupAccountNameA [ADVAPI32.@]
962 LookupAccountNameA (LPCSTR SystemName
,
966 LPSTR ReferencedDomainName
,
967 LPDWORD hReferencedDomainNameLength
,
968 PSID_NAME_USE SidNameUse
)
970 DPRINT1("LookupAccountNameA is unimplemented\n");
971 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
976 /******************************************************************************
977 * LookupAccountNameW [ADVAPI32.@]
982 LookupAccountNameW (LPCWSTR SystemName
,
986 LPWSTR ReferencedDomainName
,
987 LPDWORD hReferencedDomainNameLength
,
988 PSID_NAME_USE SidNameUse
)
990 DPRINT1("LookupAccountNameW is unimplemented\n");
991 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
996 /**********************************************************************
997 * LookupPrivilegeValueA EXPORTED
1002 LookupPrivilegeValueA (LPCSTR lpSystemName
,
1006 UNICODE_STRING SystemName
;
1007 UNICODE_STRING Name
;
1010 /* Remote system? */
1011 if (lpSystemName
!= NULL
)
1013 RtlCreateUnicodeStringFromAsciiz (&SystemName
,
1014 (LPSTR
)lpSystemName
);
1017 /* Check the privilege name is not NULL */
1020 SetLastError (ERROR_INVALID_PARAMETER
);
1024 RtlCreateUnicodeStringFromAsciiz (&Name
,
1027 Result
= LookupPrivilegeValueW ((lpSystemName
!= NULL
) ? SystemName
.Buffer
: NULL
,
1031 RtlFreeUnicodeString (&Name
);
1033 /* Remote system? */
1034 if (lpSystemName
!= NULL
)
1036 RtlFreeUnicodeString (&SystemName
);
1043 /**********************************************************************
1044 * LookupPrivilegeValueW EXPORTED
1049 LookupPrivilegeValueW (LPCWSTR SystemName
,
1053 static const WCHAR
* const DefaultPrivNames
[] =
1055 L
"SeCreateTokenPrivilege",
1056 L
"SeAssignPrimaryTokenPrivilege",
1057 L
"SeLockMemoryPrivilege",
1058 L
"SeIncreaseQuotaPrivilege",
1059 L
"SeUnsolicitedInputPrivilege",
1060 L
"SeMachineAccountPrivilege",
1062 L
"SeSecurityPrivilege",
1063 L
"SeTakeOwnershipPrivilege",
1064 L
"SeLoadDriverPrivilege",
1065 L
"SeSystemProfilePrivilege",
1066 L
"SeSystemtimePrivilege",
1067 L
"SeProfileSingleProcessPrivilege",
1068 L
"SeIncreaseBasePriorityPrivilege",
1069 L
"SeCreatePagefilePrivilege",
1070 L
"SeCreatePermanentPrivilege",
1071 L
"SeBackupPrivilege",
1072 L
"SeRestorePrivilege",
1073 L
"SeShutdownPrivilege",
1074 L
"SeDebugPrivilege",
1075 L
"SeAuditPrivilege",
1076 L
"SeSystemEnvironmentPrivilege",
1077 L
"SeChangeNotifyPrivilege",
1078 L
"SeRemoteShutdownPrivilege",
1079 L
"SeUndockPrivilege",
1080 L
"SeSyncAgentPrivilege",
1081 L
"SeEnableDelegationPrivilege",
1082 L
"SeManageVolumePrivilege",
1083 L
"SeImpersonatePrivilege",
1084 L
"SeCreateGlobalPrivilege"
1088 if (NULL
!= SystemName
&& L
'\0' != *SystemName
)
1090 DPRINT1("LookupPrivilegeValueW: not implemented for remote system\n");
1091 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1095 for (Priv
= 0; Priv
< sizeof(DefaultPrivNames
) / sizeof(DefaultPrivNames
[0]); Priv
++)
1097 if (0 == wcscmp(PrivName
, DefaultPrivNames
[Priv
]))
1099 Luid
->LowPart
= Priv
+ 1;
1105 DPRINT1("LookupPrivilegeValueW: no such privilege %S\n", PrivName
);
1106 SetLastError(ERROR_NO_SUCH_PRIVILEGE
);
1111 /**********************************************************************
1112 * LookupPrivilegeDisplayNameA EXPORTED
1117 LookupPrivilegeDisplayNameA (LPCSTR lpSystemName
,
1119 LPSTR lpDisplayName
,
1120 LPDWORD cbDisplayName
,
1121 LPDWORD lpLanguageId
)
1123 DPRINT1("LookupPrivilegeDisplayNameA: stub\n");
1124 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1129 /**********************************************************************
1130 * LookupPrivilegeDisplayNameW EXPORTED
1135 LookupPrivilegeDisplayNameW (LPCWSTR lpSystemName
,
1137 LPWSTR lpDisplayName
,
1138 LPDWORD cbDisplayName
,
1139 LPDWORD lpLanguageId
)
1141 DPRINT1("LookupPrivilegeDisplayNameW: stub\n");
1142 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1147 /**********************************************************************
1148 * LookupPrivilegeNameA EXPORTED
1153 LookupPrivilegeNameA (LPCSTR lpSystemName
,
1158 DPRINT1("LookupPrivilegeNameA: stub\n");
1159 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1164 /**********************************************************************
1165 * LookupPrivilegeNameW EXPORTED
1170 LookupPrivilegeNameW (LPCWSTR lpSystemName
,
1175 DPRINT1("LookupPrivilegeNameW: stub\n");
1176 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1182 pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo
,
1187 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
1189 if ((SecurityInfo
& (OWNER_SECURITY_INFORMATION
|
1190 GROUP_SECURITY_INFORMATION
|
1191 DACL_SECURITY_INFORMATION
|
1192 SACL_SECURITY_INFORMATION
)) &&
1193 ppSecurityDescriptor
== NULL
)
1195 /* if one of the SIDs or ACLs are present, the security descriptor
1197 return ERROR_INVALID_PARAMETER
;
1201 /* reset the pointers unless they're ignored */
1202 if ((SecurityInfo
& OWNER_SECURITY_INFORMATION
) &&
1207 if ((SecurityInfo
& GROUP_SECURITY_INFORMATION
) &&
1208 *ppsidGroup
!= NULL
)
1212 if ((SecurityInfo
& DACL_SECURITY_INFORMATION
) &&
1217 if ((SecurityInfo
& SACL_SECURITY_INFORMATION
) &&
1223 if (SecurityInfo
& (OWNER_SECURITY_INFORMATION
|
1224 GROUP_SECURITY_INFORMATION
|
1225 DACL_SECURITY_INFORMATION
|
1226 SACL_SECURITY_INFORMATION
))
1228 *ppSecurityDescriptor
= NULL
;
1231 return ERROR_SUCCESS
;
1237 pSetSecurityInfoCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1238 SECURITY_INFORMATION SecurityInfo
,
1244 /* initialize a security descriptor on the stack */
1245 if (!InitializeSecurityDescriptor(pSecurityDescriptor
,
1246 SECURITY_DESCRIPTOR_REVISION
))
1248 return GetLastError();
1251 if (SecurityInfo
& OWNER_SECURITY_INFORMATION
)
1253 if (RtlValidSid(psidOwner
))
1255 if (!SetSecurityDescriptorOwner(pSecurityDescriptor
,
1259 return GetLastError();
1264 return ERROR_INVALID_PARAMETER
;
1268 if (SecurityInfo
& GROUP_SECURITY_INFORMATION
)
1270 if (RtlValidSid(psidGroup
))
1272 if (!SetSecurityDescriptorGroup(pSecurityDescriptor
,
1276 return GetLastError();
1281 return ERROR_INVALID_PARAMETER
;
1285 if (SecurityInfo
& DACL_SECURITY_INFORMATION
)
1289 if (SetSecurityDescriptorDacl(pSecurityDescriptor
,
1294 /* check if the DACL needs to be protected from being
1295 modified by inheritable ACEs */
1296 if (SecurityInfo
& PROTECTED_DACL_SECURITY_INFORMATION
)
1303 return GetLastError();
1309 /* protect the DACL from being modified by inheritable ACEs */
1310 if (!SetSecurityDescriptorControl(pSecurityDescriptor
,
1314 return GetLastError();
1319 if (SecurityInfo
& SACL_SECURITY_INFORMATION
)
1323 if (SetSecurityDescriptorSacl(pSecurityDescriptor
,
1328 /* check if the SACL needs to be protected from being
1329 modified by inheritable ACEs */
1330 if (SecurityInfo
& PROTECTED_SACL_SECURITY_INFORMATION
)
1337 return GetLastError();
1343 /* protect the SACL from being modified by inheritable ACEs */
1344 if (!SetSecurityDescriptorControl(pSecurityDescriptor
,
1348 return GetLastError();
1353 return ERROR_SUCCESS
;
1357 /**********************************************************************
1358 * GetNamedSecurityInfoW EXPORTED
1363 GetNamedSecurityInfoW(LPWSTR pObjectName
,
1364 SE_OBJECT_TYPE ObjectType
,
1365 SECURITY_INFORMATION SecurityInfo
,
1370 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1374 if (pObjectName
!= NULL
)
1376 ErrorCode
= CheckNtMartaPresent();
1377 if (ErrorCode
== ERROR_SUCCESS
)
1379 ErrorCode
= pGetSecurityInfoCheck(SecurityInfo
,
1384 ppSecurityDescriptor
);
1386 if (ErrorCode
== ERROR_SUCCESS
)
1388 /* call the MARTA provider */
1389 ErrorCode
= AccRewriteGetNamedRights(pObjectName
,
1396 ppSecurityDescriptor
);
1401 ErrorCode
= ERROR_INVALID_PARAMETER
;
1407 /**********************************************************************
1408 * GetNamedSecurityInfoA EXPORTED
1413 GetNamedSecurityInfoA(LPSTR pObjectName
,
1414 SE_OBJECT_TYPE ObjectType
,
1415 SECURITY_INFORMATION SecurityInfo
,
1420 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1422 UNICODE_STRING ObjectName
;
1426 Status
= RtlCreateUnicodeStringFromAsciiz(&ObjectName
,
1428 if (!NT_SUCCESS(Status
))
1430 return RtlNtStatusToDosError(Status
);
1433 Ret
= GetNamedSecurityInfoW(ObjectName
.Buffer
,
1440 ppSecurityDescriptor
);
1442 RtlFreeUnicodeString(&ObjectName
);
1448 /**********************************************************************
1449 * SetNamedSecurityInfoW EXPORTED
1454 SetNamedSecurityInfoW(LPWSTR pObjectName
,
1455 SE_OBJECT_TYPE ObjectType
,
1456 SECURITY_INFORMATION SecurityInfo
,
1464 if (pObjectName
!= NULL
)
1466 ErrorCode
= CheckNtMartaPresent();
1467 if (ErrorCode
== ERROR_SUCCESS
)
1469 SECURITY_DESCRIPTOR SecurityDescriptor
;
1471 ErrorCode
= pSetSecurityInfoCheck(&SecurityDescriptor
,
1478 if (ErrorCode
== ERROR_SUCCESS
)
1480 /* call the MARTA provider */
1481 ErrorCode
= AccRewriteSetNamedRights(pObjectName
,
1484 &SecurityDescriptor
);
1489 ErrorCode
= ERROR_INVALID_PARAMETER
;
1495 /**********************************************************************
1496 * SetNamedSecurityInfoA EXPORTED
1501 SetNamedSecurityInfoA(LPSTR pObjectName
,
1502 SE_OBJECT_TYPE ObjectType
,
1503 SECURITY_INFORMATION SecurityInfo
,
1509 UNICODE_STRING ObjectName
;
1513 Status
= RtlCreateUnicodeStringFromAsciiz(&ObjectName
,
1515 if (!NT_SUCCESS(Status
))
1517 return RtlNtStatusToDosError(Status
);
1520 Ret
= SetNamedSecurityInfoW(ObjectName
.Buffer
,
1528 RtlFreeUnicodeString(&ObjectName
);
1534 /**********************************************************************
1535 * GetSecurityInfo EXPORTED
1540 GetSecurityInfo(HANDLE handle
,
1541 SE_OBJECT_TYPE ObjectType
,
1542 SECURITY_INFORMATION SecurityInfo
,
1547 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
1553 ErrorCode
= CheckNtMartaPresent();
1554 if (ErrorCode
== ERROR_SUCCESS
)
1556 ErrorCode
= pGetSecurityInfoCheck(SecurityInfo
,
1561 ppSecurityDescriptor
);
1563 if (ErrorCode
== ERROR_SUCCESS
)
1565 /* call the MARTA provider */
1566 ErrorCode
= AccRewriteGetHandleRights(handle
,
1573 ppSecurityDescriptor
);
1578 ErrorCode
= ERROR_INVALID_HANDLE
;
1584 /**********************************************************************
1585 * SetSecurityInfo EXPORTED
1591 SetSecurityInfo(HANDLE handle
,
1592 SE_OBJECT_TYPE ObjectType
,
1593 SECURITY_INFORMATION SecurityInfo
,
1603 ErrorCode
= CheckNtMartaPresent();
1604 if (ErrorCode
== ERROR_SUCCESS
)
1606 SECURITY_DESCRIPTOR SecurityDescriptor
;
1608 ErrorCode
= pSetSecurityInfoCheck(&SecurityDescriptor
,
1615 if (ErrorCode
== ERROR_SUCCESS
)
1617 /* call the MARTA provider */
1618 ErrorCode
= AccRewriteSetHandleRights(handle
,
1621 &SecurityDescriptor
);
1626 ErrorCode
= ERROR_INVALID_HANDLE
;
1632 /******************************************************************************
1633 * GetSecurityInfoExW EXPORTED
1635 DWORD WINAPI
GetSecurityInfoExA(
1637 SE_OBJECT_TYPE ObjectType
,
1638 SECURITY_INFORMATION SecurityInfo
,
1641 PACTRL_ACCESSA
*ppAccessList
,
1642 PACTRL_AUDITA
*ppAuditList
,
1647 DPRINT1("GetSecurityInfoExA stub!\n");
1648 return ERROR_BAD_PROVIDER
;
1652 /******************************************************************************
1653 * GetSecurityInfoExW EXPORTED
1655 DWORD WINAPI
GetSecurityInfoExW(
1657 SE_OBJECT_TYPE ObjectType
,
1658 SECURITY_INFORMATION SecurityInfo
,
1661 PACTRL_ACCESSW
*ppAccessList
,
1662 PACTRL_AUDITW
*ppAuditList
,
1667 DPRINT1("GetSecurityInfoExW stub!\n");
1668 return ERROR_BAD_PROVIDER
;
1672 /**********************************************************************
1673 * ImpersonateNamedPipeClient EXPORTED
1678 ImpersonateNamedPipeClient(HANDLE hNamedPipe
)
1680 IO_STATUS_BLOCK StatusBlock
;
1683 DPRINT("ImpersonateNamedPipeClient() called\n");
1685 Status
= NtFsControlFile(hNamedPipe
,
1690 FSCTL_PIPE_IMPERSONATE
,
1695 if (!NT_SUCCESS(Status
))
1697 SetLastError(RtlNtStatusToDosError(Status
));
1709 CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor
,
1710 PSECURITY_DESCRIPTOR CreatorDescriptor
,
1711 PSECURITY_DESCRIPTOR
*NewDescriptor
,
1712 BOOL IsDirectoryObject
,
1714 PGENERIC_MAPPING GenericMapping
)
1718 Status
= RtlNewSecurityObject(ParentDescriptor
,
1724 if (!NT_SUCCESS(Status
))
1726 SetLastError(RtlNtStatusToDosError(Status
));
1738 CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor
,
1739 PSECURITY_DESCRIPTOR CreatorDescriptor
,
1740 PSECURITY_DESCRIPTOR
* NewDescriptor
,
1742 BOOL IsContainerObject
,
1743 ULONG AutoInheritFlags
,
1745 PGENERIC_MAPPING GenericMapping
)
1747 DPRINT1("%s() not implemented!\n", __FUNCTION__
);
1756 CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor
,
1757 PSECURITY_DESCRIPTOR CreatorDescriptor
,
1758 PSECURITY_DESCRIPTOR
* NewDescriptor
,
1761 BOOL IsContainerObject
,
1762 ULONG AutoInheritFlags
,
1764 PGENERIC_MAPPING GenericMapping
)
1766 DPRINT1("%s() not implemented!\n", __FUNCTION__
);
1775 DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR
*ObjectDescriptor
)
1779 Status
= RtlDeleteSecurityObject(ObjectDescriptor
);
1780 if (!NT_SUCCESS(Status
))
1782 SetLastError(RtlNtStatusToDosError(Status
));
1794 GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR ObjectDescriptor
,
1795 SECURITY_INFORMATION SecurityInformation
,
1796 PSECURITY_DESCRIPTOR ResultantDescriptor
,
1797 DWORD DescriptorLength
,
1798 PDWORD ReturnLength
)
1802 Status
= RtlQuerySecurityObject(ObjectDescriptor
,
1803 SecurityInformation
,
1804 ResultantDescriptor
,
1807 if (!NT_SUCCESS(Status
))
1809 SetLastError(RtlNtStatusToDosError(Status
));
1821 SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation
,
1822 PSECURITY_DESCRIPTOR ModificationDescriptor
,
1823 PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
1824 PGENERIC_MAPPING GenericMapping
,
1829 Status
= RtlSetSecurityObject(SecurityInformation
,
1830 ModificationDescriptor
,
1831 ObjectsSecurityDescriptor
,
1834 if (!NT_SUCCESS(Status
))
1836 SetLastError(RtlNtStatusToDosError(Status
));