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
13 /* Interface to ntmarta.dll ***************************************************/
15 NTMARTA NtMartaStatic
= { 0 };
16 static PNTMARTA NtMarta
= NULL
;
18 #define FindNtMartaProc(Name) \
19 NtMartaStatic.Name = (PVOID)GetProcAddress(NtMartaStatic.hDllInstance, \
21 if (NtMartaStatic.Name == NULL) \
23 return GetLastError(); \
27 LoadAndInitializeNtMarta(VOID
)
29 /* this code may be executed simultaneously by multiple threads in case they're
30 trying to initialize the interface at the same time, but that's no problem
31 because the pointers returned by GetProcAddress will be the same. However,
32 only one of the threads will change the NtMarta pointer to the NtMartaStatic
33 structure, the others threads will detect that there were other threads
34 initializing the structure faster and will release the reference to the
37 NtMartaStatic
.hDllInstance
= LoadLibraryW(L
"ntmarta.dll");
38 if (NtMartaStatic
.hDllInstance
== NULL
)
40 return GetLastError();
44 FindNtMartaProc(LookupAccountTrustee
);
45 FindNtMartaProc(LookupAccountName
);
46 FindNtMartaProc(LookupAccountSid
);
47 FindNtMartaProc(SetEntriesInAList
);
48 FindNtMartaProc(ConvertAccessToSecurityDescriptor
);
49 FindNtMartaProc(ConvertSDToAccess
);
50 FindNtMartaProc(ConvertAclToAccess
);
51 FindNtMartaProc(GetAccessForTrustee
);
52 FindNtMartaProc(GetExplicitEntries
);
54 FindNtMartaProc(RewriteGetNamedRights
);
55 FindNtMartaProc(RewriteSetNamedRights
);
56 FindNtMartaProc(RewriteGetHandleRights
);
57 FindNtMartaProc(RewriteSetHandleRights
);
58 FindNtMartaProc(RewriteSetEntriesInAcl
);
59 FindNtMartaProc(RewriteGetExplicitEntriesFromAcl
);
60 FindNtMartaProc(TreeResetNamedSecurityInfo
);
61 FindNtMartaProc(GetInheritanceSource
);
62 FindNtMartaProc(FreeIndexArray
);
68 CheckNtMartaPresent(VOID
)
74 /* we're the first one trying to use ntmarta, initialize it and change
75 the pointer after initialization */
76 ErrorCode
= LoadAndInitializeNtMarta();
78 if (ErrorCode
== ERROR_SUCCESS
)
80 /* try change the NtMarta pointer */
81 if (InterlockedCompareExchangePointer(&NtMarta
,
85 /* another thread initialized ntmarta in the meanwhile, release
86 the reference of the dll loaded. */
87 FreeLibrary(NtMartaStatic
.hDllInstance
);
93 DPRINT1("Failed to initialize ntmarta.dll! Error: 0x%x", ErrorCode
);
99 /* ntmarta was already initialized */
100 ErrorCode
= ERROR_SUCCESS
;
106 VOID
UnloadNtMarta(VOID
)
108 if (InterlockedExchangePointer(&NtMarta
,
111 FreeLibrary(NtMartaStatic
.hDllInstance
);
115 /******************************************************************************/
121 AreAllAccessesGranted(DWORD GrantedAccess
,
124 return((BOOL
)RtlAreAllAccessesGranted(GrantedAccess
,
133 AreAnyAccessesGranted(DWORD GrantedAccess
,
136 return((BOOL
)RtlAreAnyAccessesGranted(GrantedAccess
,
141 /******************************************************************************
142 * GetFileSecurityA [ADVAPI32.@]
144 * Obtains Specified information about the security of a file or directory.
147 * lpFileName [I] Name of the file to get info for
148 * RequestedInformation [I] SE_ flags from "winnt.h"
149 * pSecurityDescriptor [O] Destination for security information
150 * nLength [I] Length of pSecurityDescriptor
151 * lpnLengthNeeded [O] Destination for length of returned security information
154 * Success: TRUE. pSecurityDescriptor contains the requested information.
155 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
158 * The information returned is constrained by the callers access rights and
164 GetFileSecurityA(LPCSTR lpFileName
,
165 SECURITY_INFORMATION RequestedInformation
,
166 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
168 LPDWORD lpnLengthNeeded
)
170 UNICODE_STRING FileName
;
174 Status
= RtlCreateUnicodeStringFromAsciiz(&FileName
,
176 if (!NT_SUCCESS(Status
))
178 SetLastError(RtlNtStatusToDosError(Status
));
182 bResult
= GetFileSecurityW(FileName
.Buffer
,
183 RequestedInformation
,
188 RtlFreeUnicodeString(&FileName
);
198 GetFileSecurityW(LPCWSTR lpFileName
,
199 SECURITY_INFORMATION RequestedInformation
,
200 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
202 LPDWORD lpnLengthNeeded
)
204 OBJECT_ATTRIBUTES ObjectAttributes
;
205 IO_STATUS_BLOCK StatusBlock
;
206 UNICODE_STRING FileName
;
207 ULONG AccessMask
= 0;
211 DPRINT("GetFileSecurityW() called\n");
213 if (RequestedInformation
&
214 (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION
))
216 AccessMask
|= STANDARD_RIGHTS_READ
;
219 if (RequestedInformation
& SACL_SECURITY_INFORMATION
)
221 AccessMask
|= ACCESS_SYSTEM_SECURITY
;
224 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
229 DPRINT("Invalid path\n");
230 SetLastError(ERROR_INVALID_NAME
);
234 InitializeObjectAttributes(&ObjectAttributes
,
236 OBJ_CASE_INSENSITIVE
,
240 Status
= NtOpenFile(&FileHandle
,
244 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
246 if (!NT_SUCCESS(Status
))
248 DPRINT("NtOpenFile() failed (Status %lx)\n", Status
);
249 SetLastError(RtlNtStatusToDosError(Status
));
253 RtlFreeUnicodeString(&FileName
);
255 Status
= NtQuerySecurityObject(FileHandle
,
256 RequestedInformation
,
262 if (!NT_SUCCESS(Status
))
264 DPRINT("NtQuerySecurityObject() failed (Status %lx)\n", Status
);
265 SetLastError(RtlNtStatusToDosError(Status
));
277 GetKernelObjectSecurity(HANDLE Handle
,
278 SECURITY_INFORMATION RequestedInformation
,
279 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
281 LPDWORD lpnLengthNeeded
)
285 Status
= NtQuerySecurityObject(Handle
,
286 RequestedInformation
,
290 if (!NT_SUCCESS(Status
))
292 SetLastError(RtlNtStatusToDosError(Status
));
299 /******************************************************************************
300 * SetFileSecurityA [ADVAPI32.@]
301 * Sets the security of a file or directory
306 SetFileSecurityA (LPCSTR lpFileName
,
307 SECURITY_INFORMATION SecurityInformation
,
308 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
310 UNICODE_STRING FileName
;
314 Status
= RtlCreateUnicodeStringFromAsciiz(&FileName
,
316 if (!NT_SUCCESS(Status
))
318 SetLastError(RtlNtStatusToDosError(Status
));
322 bResult
= SetFileSecurityW(FileName
.Buffer
,
324 pSecurityDescriptor
);
326 RtlFreeUnicodeString(&FileName
);
332 /******************************************************************************
333 * SetFileSecurityW [ADVAPI32.@]
334 * Sets the security of a file or directory
339 SetFileSecurityW (LPCWSTR lpFileName
,
340 SECURITY_INFORMATION SecurityInformation
,
341 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
343 OBJECT_ATTRIBUTES ObjectAttributes
;
344 IO_STATUS_BLOCK StatusBlock
;
345 UNICODE_STRING FileName
;
346 ULONG AccessMask
= 0;
350 DPRINT("SetFileSecurityW() called\n");
352 if (SecurityInformation
&
353 (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
))
355 AccessMask
|= WRITE_OWNER
;
358 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
360 AccessMask
|= WRITE_DAC
;
363 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
365 AccessMask
|= ACCESS_SYSTEM_SECURITY
;
368 if (!RtlDosPathNameToNtPathName_U(lpFileName
,
373 DPRINT("Invalid path\n");
374 SetLastError(ERROR_INVALID_NAME
);
378 InitializeObjectAttributes(&ObjectAttributes
,
380 OBJ_CASE_INSENSITIVE
,
384 Status
= NtOpenFile(&FileHandle
,
388 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
390 if (!NT_SUCCESS(Status
))
392 DPRINT("NtOpenFile() failed (Status %lx)\n", Status
);
393 SetLastError(RtlNtStatusToDosError(Status
));
397 RtlFreeUnicodeString(&FileName
);
399 Status
= NtSetSecurityObject(FileHandle
,
401 pSecurityDescriptor
);
404 if (!NT_SUCCESS(Status
))
406 DPRINT("NtSetSecurityObject() failed (Status %lx)\n", Status
);
407 SetLastError(RtlNtStatusToDosError(Status
));
419 SetKernelObjectSecurity(HANDLE Handle
,
420 SECURITY_INFORMATION SecurityInformation
,
421 PSECURITY_DESCRIPTOR SecurityDescriptor
)
425 Status
= NtSetSecurityObject(Handle
,
428 if (!NT_SUCCESS(Status
))
430 SetLastError(RtlNtStatusToDosError(Status
));
441 ImpersonateLoggedOnUser(HANDLE hToken
)
443 SECURITY_QUALITY_OF_SERVICE Qos
;
444 OBJECT_ATTRIBUTES ObjectAttributes
;
451 /* Get the token type */
452 Status
= NtQueryInformationToken (hToken
,
457 if (!NT_SUCCESS(Status
))
459 SetLastError (RtlNtStatusToDosError (Status
));
463 if (Type
== TokenPrimary
)
465 /* Create a duplicate impersonation token */
466 Qos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
467 Qos
.ImpersonationLevel
= SecurityImpersonation
;
468 Qos
.ContextTrackingMode
= SECURITY_DYNAMIC_TRACKING
;
469 Qos
.EffectiveOnly
= FALSE
;
471 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
472 ObjectAttributes
.RootDirectory
= NULL
;
473 ObjectAttributes
.ObjectName
= NULL
;
474 ObjectAttributes
.Attributes
= 0;
475 ObjectAttributes
.SecurityDescriptor
= NULL
;
476 ObjectAttributes
.SecurityQualityOfService
= &Qos
;
478 Status
= NtDuplicateToken (hToken
,
479 TOKEN_IMPERSONATE
| TOKEN_QUERY
,
484 if (!NT_SUCCESS(Status
))
486 SetLastError (RtlNtStatusToDosError (Status
));
494 /* User the original impersonation token */
499 /* Impersonate the the current thread */
500 Status
= NtSetInformationThread (NtCurrentThread (),
501 ThreadImpersonationToken
,
505 if (Duplicated
== TRUE
)
510 if (!NT_SUCCESS(Status
))
512 SetLastError (RtlNtStatusToDosError (Status
));
524 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
528 Status
= RtlImpersonateSelf(ImpersonationLevel
);
529 if (!NT_SUCCESS(Status
))
531 SetLastError(RtlNtStatusToDosError(Status
));
547 Status
= NtSetInformationThread(NtCurrentThread(),
548 ThreadImpersonationToken
,
551 if (!NT_SUCCESS(Status
))
553 SetLastError(RtlNtStatusToDosError(Status
));
560 /******************************************************************************
561 * GetUserNameA [ADVAPI32.@]
563 * Get the current user name.
566 * lpszName [O] Destination for the user name.
567 * lpSize [I/O] Size of lpszName.
573 GetUserNameA( LPSTR lpszName
, LPDWORD lpSize
)
575 UNICODE_STRING NameW
;
579 /* apparently Win doesn't check whether lpSize is valid at all! */
582 NameW
.MaximumLength
= (*lpSize
) * sizeof(WCHAR
);
583 NameW
.Buffer
= LocalAlloc(LMEM_FIXED
, NameW
.MaximumLength
);
584 if(NameW
.Buffer
== NULL
)
586 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
591 NameA
.MaximumLength
= ((*lpSize
) < 0xFFFF ? (USHORT
)(*lpSize
) : 0xFFFF);
592 NameA
.Buffer
= lpszName
;
594 Ret
= GetUserNameW(NameW
.Buffer
,
598 RtlUnicodeStringToAnsiString(&NameA
, &NameW
, FALSE
);
599 NameA
.Buffer
[NameA
.Length
] = '\0';
601 *lpSize
= NameA
.Length
+ 1;
604 LocalFree(NameW
.Buffer
);
609 /******************************************************************************
610 * GetUserNameW [ADVAPI32.@]
617 GetUserNameW ( LPWSTR lpszName
, LPDWORD lpSize
)
619 HANDLE hToken
= INVALID_HANDLE_VALUE
;
622 TOKEN_USER
* token_user
= NULL
;
624 SID_NAME_USE snu
= SidTypeUser
;
625 WCHAR
* domain_name
= NULL
;
628 if ( !OpenThreadToken ( GetCurrentThread(), TOKEN_QUERY
, FALSE
, &hToken
) )
630 DWORD dwLastError
= GetLastError();
631 if ( dwLastError
!= ERROR_NO_TOKEN
632 && dwLastError
!= ERROR_NO_IMPERSONATION_TOKEN
)
634 /* don't call SetLastError(),
635 as OpenThreadToken() ought to have set one */
638 if ( !OpenProcessToken ( GetCurrentProcess(), TOKEN_QUERY
, &hToken
) )
640 /* don't call SetLastError(),
641 as OpenProcessToken() ought to have set one */
645 tu_buf
= LocalAlloc ( LMEM_FIXED
, 36 );
648 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
651 if ( !GetTokenInformation ( hToken
, TokenUser
, tu_buf
, 36, &tu_len
) || tu_len
> 36 )
653 LocalFree ( tu_buf
);
654 tu_buf
= LocalAlloc ( LMEM_FIXED
, tu_len
);
657 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
660 if ( !GetTokenInformation ( hToken
, TokenUser
, tu_buf
, tu_len
, &tu_len
) )
662 /* don't call SetLastError(),
663 as GetTokenInformation() ought to have set one */
664 LocalFree ( tu_buf
);
665 CloseHandle ( hToken
);
669 token_user
= (TOKEN_USER
*)tu_buf
;
673 domain_name
= LocalAlloc ( LMEM_FIXED
, dn_len
* sizeof(WCHAR
) );
676 LocalFree ( tu_buf
);
677 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
680 if ( !LookupAccountSidW ( NULL
, token_user
->User
.Sid
, lpszName
, &an_len
, domain_name
, &dn_len
, &snu
)
685 LocalFree ( domain_name
);
686 domain_name
= LocalAlloc ( LMEM_FIXED
, dn_len
* sizeof(WCHAR
) );
689 LocalFree ( tu_buf
);
690 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
694 if ( !LookupAccountSidW ( NULL
, token_user
->User
.Sid
, lpszName
, &an_len
, domain_name
, &dn_len
, &snu
) )
696 /* don't call SetLastError(),
697 as LookupAccountSid() ought to have set one */
698 LocalFree ( domain_name
);
699 CloseHandle ( hToken
);
704 LocalFree ( domain_name
);
705 LocalFree ( tu_buf
);
706 CloseHandle ( hToken
);
708 if ( an_len
> *lpSize
)
711 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
719 /******************************************************************************
720 * LookupAccountSidA [ADVAPI32.@]
725 LookupAccountSidA (LPCSTR lpSystemName
,
729 LPSTR lpReferencedDomainName
,
730 LPDWORD cchReferencedDomainName
,
733 UNICODE_STRING NameW
, ReferencedDomainNameW
, SystemNameW
;
734 DWORD szName
, szReferencedDomainName
;
738 * save the buffer sizes the caller passed to us, as they may get modified and
739 * we require the original values when converting back to ansi
742 szReferencedDomainName
= *cchReferencedDomainName
;
745 * allocate buffers for the unicode strings to receive
751 NameW
.MaximumLength
= szName
* sizeof(WCHAR
);
752 NameW
.Buffer
= (PWSTR
)LocalAlloc(LMEM_FIXED
, NameW
.MaximumLength
);
753 if(NameW
.Buffer
== NULL
)
755 SetLastError(ERROR_OUTOFMEMORY
);
762 if(szReferencedDomainName
> 0)
764 ReferencedDomainNameW
.Length
= 0;
765 ReferencedDomainNameW
.MaximumLength
= szReferencedDomainName
* sizeof(WCHAR
);
766 ReferencedDomainNameW
.Buffer
= (PWSTR
)LocalAlloc(LMEM_FIXED
, ReferencedDomainNameW
.MaximumLength
);
767 if(ReferencedDomainNameW
.Buffer
== NULL
)
771 LocalFree(NameW
.Buffer
);
773 SetLastError(ERROR_OUTOFMEMORY
);
778 ReferencedDomainNameW
.Buffer
= NULL
;
781 * convert the system name to unicode - if present
784 if(lpSystemName
!= NULL
)
786 ANSI_STRING SystemNameA
;
788 RtlInitAnsiString(&SystemNameA
, lpSystemName
);
789 RtlAnsiStringToUnicodeString(&SystemNameW
, &SystemNameA
, TRUE
);
792 SystemNameW
.Buffer
= NULL
;
795 * it's time to call the unicode version
798 Ret
= LookupAccountSidW(SystemNameW
.Buffer
,
802 ReferencedDomainNameW
.Buffer
,
803 cchReferencedDomainName
,
808 * convert unicode strings back to ansi, don't forget that we can't convert
809 * more than 0xFFFF (USHORT) characters! Also don't forget to explicitly
810 * terminate the converted string, the Rtl functions don't do that!
817 NameA
.MaximumLength
= ((szName
<= 0xFFFF) ? (USHORT
)szName
: 0xFFFF);
818 NameA
.Buffer
= lpName
;
820 RtlUnicodeStringToAnsiString(&NameA
, &NameW
, FALSE
);
821 NameA
.Buffer
[NameA
.Length
] = '\0';
824 if(lpReferencedDomainName
!= NULL
)
826 ANSI_STRING ReferencedDomainNameA
;
828 ReferencedDomainNameA
.Length
= 0;
829 ReferencedDomainNameA
.MaximumLength
= ((szReferencedDomainName
<= 0xFFFF) ?
830 (USHORT
)szReferencedDomainName
: 0xFFFF);
831 ReferencedDomainNameA
.Buffer
= lpReferencedDomainName
;
833 RtlUnicodeStringToAnsiString(&ReferencedDomainNameA
, &ReferencedDomainNameW
, FALSE
);
834 ReferencedDomainNameA
.Buffer
[ReferencedDomainNameA
.Length
] = '\0';
839 * free previously allocated buffers
842 if(SystemNameW
.Buffer
!= NULL
)
844 RtlFreeUnicodeString(&SystemNameW
);
846 if(NameW
.Buffer
!= NULL
)
848 LocalFree(NameW
.Buffer
);
850 if(ReferencedDomainNameW
.Buffer
!= NULL
)
852 LocalFree(ReferencedDomainNameW
.Buffer
);
859 /******************************************************************************
860 * LookupAccountSidW [ADVAPI32.@]
869 LPDWORD pdwAccountName
,
871 LPDWORD pdwDomainName
,
872 PSID_NAME_USE peUse
)
874 LSA_UNICODE_STRING SystemName
;
875 LSA_OBJECT_ATTRIBUTES ObjectAttributes
;
876 LSA_HANDLE PolicyHandle
= INVALID_HANDLE_VALUE
;
878 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain
= NULL
;
879 PLSA_TRANSLATED_NAME TranslatedName
= NULL
;
882 RtlInitUnicodeString ( &SystemName
, pSystemName
);
883 ZeroMemory(&ObjectAttributes
, sizeof(ObjectAttributes
));
884 Status
= LsaOpenPolicy ( &SystemName
, &ObjectAttributes
, POLICY_LOOKUP_NAMES
, &PolicyHandle
);
885 if ( !NT_SUCCESS(Status
) )
887 SetLastError ( LsaNtStatusToWinError(Status
) );
890 Status
= LsaLookupSids ( PolicyHandle
, 1, &pSid
, &ReferencedDomain
, &TranslatedName
);
892 LsaClose ( PolicyHandle
);
894 if ( !NT_SUCCESS(Status
) || Status
== STATUS_SOME_NOT_MAPPED
)
896 SetLastError ( LsaNtStatusToWinError(Status
) );
902 if ( TranslatedName
)
904 DWORD dwSrcLen
= TranslatedName
->Name
.Length
/ sizeof(WCHAR
);
905 if ( *pdwAccountName
<= dwSrcLen
)
907 *pdwAccountName
= dwSrcLen
+ 1;
912 *pdwAccountName
= dwSrcLen
;
913 wcscpy ( pAccountName
, TranslatedName
->Name
.Buffer
);
916 *peUse
= TranslatedName
->Use
;
919 if ( ReferencedDomain
)
921 if ( ReferencedDomain
->Entries
> 0 )
923 DWORD dwSrcLen
= ReferencedDomain
->Domains
[0].Name
.Length
/ sizeof(WCHAR
);
924 if ( *pdwDomainName
<= dwSrcLen
)
926 *pdwDomainName
= dwSrcLen
+ 1;
931 *pdwDomainName
= dwSrcLen
;
932 wcscpy ( pDomainName
, ReferencedDomain
->Domains
[0].Name
.Buffer
);
938 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
941 if ( ReferencedDomain
)
942 LsaFreeMemory ( ReferencedDomain
);
943 if ( TranslatedName
)
944 LsaFreeMemory ( TranslatedName
);
951 /******************************************************************************
952 * LookupAccountNameA [ADVAPI32.@]
957 LookupAccountNameA (LPCSTR SystemName
,
961 LPSTR ReferencedDomainName
,
962 LPDWORD hReferencedDomainNameLength
,
963 PSID_NAME_USE SidNameUse
)
965 DPRINT1("LookupAccountNameA is unimplemented\n");
966 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
971 /******************************************************************************
972 * LookupAccountNameW [ADVAPI32.@]
977 LookupAccountNameW (LPCWSTR SystemName
,
981 LPWSTR ReferencedDomainName
,
982 LPDWORD hReferencedDomainNameLength
,
983 PSID_NAME_USE SidNameUse
)
985 DPRINT1("LookupAccountNameW is unimplemented\n");
986 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
991 /**********************************************************************
992 * LookupPrivilegeValueA EXPORTED
997 LookupPrivilegeValueA (LPCSTR lpSystemName
,
1001 UNICODE_STRING SystemName
;
1002 UNICODE_STRING Name
;
1005 /* Remote system? */
1006 if (lpSystemName
!= NULL
)
1008 RtlCreateUnicodeStringFromAsciiz (&SystemName
,
1009 (LPSTR
)lpSystemName
);
1012 /* Check the privilege name is not NULL */
1015 SetLastError (ERROR_INVALID_PARAMETER
);
1019 RtlCreateUnicodeStringFromAsciiz (&Name
,
1022 Result
= LookupPrivilegeValueW ((lpSystemName
!= NULL
) ? SystemName
.Buffer
: NULL
,
1026 RtlFreeUnicodeString (&Name
);
1028 /* Remote system? */
1029 if (lpSystemName
!= NULL
)
1031 RtlFreeUnicodeString (&SystemName
);
1038 /**********************************************************************
1039 * LookupPrivilegeValueW EXPORTED
1044 LookupPrivilegeValueW (LPCWSTR SystemName
,
1048 static const WCHAR
* const DefaultPrivNames
[] =
1050 L
"SeCreateTokenPrivilege",
1051 L
"SeAssignPrimaryTokenPrivilege",
1052 L
"SeLockMemoryPrivilege",
1053 L
"SeIncreaseQuotaPrivilege",
1054 L
"SeUnsolicitedInputPrivilege",
1055 L
"SeMachineAccountPrivilege",
1057 L
"SeSecurityPrivilege",
1058 L
"SeTakeOwnershipPrivilege",
1059 L
"SeLoadDriverPrivilege",
1060 L
"SeSystemProfilePrivilege",
1061 L
"SeSystemtimePrivilege",
1062 L
"SeProfileSingleProcessPrivilege",
1063 L
"SeIncreaseBasePriorityPrivilege",
1064 L
"SeCreatePagefilePrivilege",
1065 L
"SeCreatePermanentPrivilege",
1066 L
"SeBackupPrivilege",
1067 L
"SeRestorePrivilege",
1068 L
"SeShutdownPrivilege",
1069 L
"SeDebugPrivilege",
1070 L
"SeAuditPrivilege",
1071 L
"SeSystemEnvironmentPrivilege",
1072 L
"SeChangeNotifyPrivilege",
1073 L
"SeRemoteShutdownPrivilege",
1074 L
"SeUndockPrivilege",
1075 L
"SeSyncAgentPrivilege",
1076 L
"SeEnableDelegationPrivilege",
1077 L
"SeManageVolumePrivilege",
1078 L
"SeImpersonatePrivilege",
1079 L
"SeCreateGlobalPrivilege"
1083 if (NULL
!= SystemName
&& L
'\0' != *SystemName
)
1085 DPRINT1("LookupPrivilegeValueW: not implemented for remote system\n");
1086 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1090 for (Priv
= 0; Priv
< sizeof(DefaultPrivNames
) / sizeof(DefaultPrivNames
[0]); Priv
++)
1092 if (0 == wcscmp(PrivName
, DefaultPrivNames
[Priv
]))
1094 Luid
->LowPart
= Priv
+ 1;
1100 DPRINT1("LookupPrivilegeValueW: no such privilege %S\n", PrivName
);
1101 SetLastError(ERROR_NO_SUCH_PRIVILEGE
);
1106 /**********************************************************************
1107 * LookupPrivilegeDisplayNameA EXPORTED
1112 LookupPrivilegeDisplayNameA (LPCSTR lpSystemName
,
1114 LPSTR lpDisplayName
,
1115 LPDWORD cbDisplayName
,
1116 LPDWORD lpLanguageId
)
1118 DPRINT1("LookupPrivilegeDisplayNameA: stub\n");
1119 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1124 /**********************************************************************
1125 * LookupPrivilegeDisplayNameW EXPORTED
1130 LookupPrivilegeDisplayNameW (LPCWSTR lpSystemName
,
1132 LPWSTR lpDisplayName
,
1133 LPDWORD cbDisplayName
,
1134 LPDWORD lpLanguageId
)
1136 DPRINT1("LookupPrivilegeDisplayNameW: stub\n");
1137 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1142 /**********************************************************************
1143 * LookupPrivilegeNameA EXPORTED
1148 LookupPrivilegeNameA (LPCSTR lpSystemName
,
1153 DPRINT1("LookupPrivilegeNameA: stub\n");
1154 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1159 /**********************************************************************
1160 * LookupPrivilegeNameW EXPORTED
1165 LookupPrivilegeNameW (LPCWSTR lpSystemName
,
1170 DPRINT1("LookupPrivilegeNameW: stub\n");
1171 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1177 pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo
,
1182 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
1184 if ((SecurityInfo
& (OWNER_SECURITY_INFORMATION
|
1185 GROUP_SECURITY_INFORMATION
|
1186 DACL_SECURITY_INFORMATION
|
1187 SACL_SECURITY_INFORMATION
)) &&
1188 ppSecurityDescriptor
== NULL
)
1190 /* if one of the SIDs or ACLs are present, the security descriptor
1192 return ERROR_INVALID_PARAMETER
;
1196 /* reset the pointers unless they're ignored */
1197 if ((SecurityInfo
& OWNER_SECURITY_INFORMATION
) &&
1202 if ((SecurityInfo
& GROUP_SECURITY_INFORMATION
) &&
1207 if ((SecurityInfo
& DACL_SECURITY_INFORMATION
) &&
1212 if ((SecurityInfo
& SACL_SECURITY_INFORMATION
) &&
1218 if (SecurityInfo
& (OWNER_SECURITY_INFORMATION
|
1219 GROUP_SECURITY_INFORMATION
|
1220 DACL_SECURITY_INFORMATION
|
1221 SACL_SECURITY_INFORMATION
))
1223 *ppSecurityDescriptor
= NULL
;
1226 return ERROR_SUCCESS
;
1232 pSetSecurityInfoCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1233 SECURITY_INFORMATION SecurityInfo
,
1239 /* initialize a security descriptor on the stack */
1240 if (!InitializeSecurityDescriptor(pSecurityDescriptor
,
1241 SECURITY_DESCRIPTOR_REVISION
))
1243 return GetLastError();
1246 if (SecurityInfo
& OWNER_SECURITY_INFORMATION
)
1248 if (RtlValidSid(psidOwner
))
1250 if (!SetSecurityDescriptorOwner(pSecurityDescriptor
,
1254 return GetLastError();
1259 return ERROR_INVALID_PARAMETER
;
1263 if (SecurityInfo
& GROUP_SECURITY_INFORMATION
)
1265 if (RtlValidSid(psidGroup
))
1267 if (!SetSecurityDescriptorGroup(pSecurityDescriptor
,
1271 return GetLastError();
1276 return ERROR_INVALID_PARAMETER
;
1280 if (SecurityInfo
& DACL_SECURITY_INFORMATION
)
1284 if (SetSecurityDescriptorDacl(pSecurityDescriptor
,
1289 /* check if the DACL needs to be protected from being
1290 modified by inheritable ACEs */
1291 if (SecurityInfo
& PROTECTED_DACL_SECURITY_INFORMATION
)
1298 return GetLastError();
1304 /* protect the DACL from being modified by inheritable ACEs */
1305 if (!SetSecurityDescriptorControl(pSecurityDescriptor
,
1309 return GetLastError();
1314 if (SecurityInfo
& SACL_SECURITY_INFORMATION
)
1318 if (SetSecurityDescriptorSacl(pSecurityDescriptor
,
1323 /* check if the SACL needs to be protected from being
1324 modified by inheritable ACEs */
1325 if (SecurityInfo
& PROTECTED_SACL_SECURITY_INFORMATION
)
1332 return GetLastError();
1338 /* protect the SACL from being modified by inheritable ACEs */
1339 if (!SetSecurityDescriptorControl(pSecurityDescriptor
,
1343 return GetLastError();
1348 return ERROR_SUCCESS
;
1352 /**********************************************************************
1353 * GetNamedSecurityInfoW EXPORTED
1358 GetNamedSecurityInfoW(LPWSTR pObjectName
,
1359 SE_OBJECT_TYPE ObjectType
,
1360 SECURITY_INFORMATION SecurityInfo
,
1365 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1369 if (pObjectName
!= NULL
)
1371 ErrorCode
= CheckNtMartaPresent();
1372 if (ErrorCode
== ERROR_SUCCESS
)
1374 ErrorCode
= pGetSecurityInfoCheck(SecurityInfo
,
1379 ppSecurityDescriptor
);
1381 if (ErrorCode
== ERROR_SUCCESS
)
1383 /* call the MARTA provider */
1384 ErrorCode
= AccRewriteGetNamedRights(pObjectName
,
1391 ppSecurityDescriptor
);
1396 ErrorCode
= ERROR_INVALID_PARAMETER
;
1402 /**********************************************************************
1403 * GetNamedSecurityInfoA EXPORTED
1408 GetNamedSecurityInfoA(LPSTR pObjectName
,
1409 SE_OBJECT_TYPE ObjectType
,
1410 SECURITY_INFORMATION SecurityInfo
,
1415 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1417 UNICODE_STRING ObjectName
;
1421 Status
= RtlCreateUnicodeStringFromAsciiz(&ObjectName
,
1423 if (!NT_SUCCESS(Status
))
1425 return RtlNtStatusToDosError(Status
);
1428 Ret
= GetNamedSecurityInfoW(ObjectName
.Buffer
,
1435 ppSecurityDescriptor
);
1437 RtlFreeUnicodeString(&ObjectName
);
1443 /**********************************************************************
1444 * SetNamedSecurityInfoW EXPORTED
1449 SetNamedSecurityInfoW(LPWSTR pObjectName
,
1450 SE_OBJECT_TYPE ObjectType
,
1451 SECURITY_INFORMATION SecurityInfo
,
1459 if (pObjectName
!= NULL
)
1461 ErrorCode
= CheckNtMartaPresent();
1462 if (ErrorCode
== ERROR_SUCCESS
)
1464 SECURITY_DESCRIPTOR SecurityDescriptor
;
1466 ErrorCode
= pSetSecurityInfoCheck(&SecurityDescriptor
,
1473 if (ErrorCode
== ERROR_SUCCESS
)
1475 /* call the MARTA provider */
1476 ErrorCode
= AccRewriteSetNamedRights(pObjectName
,
1479 &SecurityDescriptor
);
1484 ErrorCode
= ERROR_INVALID_PARAMETER
;
1490 /**********************************************************************
1491 * SetNamedSecurityInfoA EXPORTED
1496 SetNamedSecurityInfoA(LPSTR pObjectName
,
1497 SE_OBJECT_TYPE ObjectType
,
1498 SECURITY_INFORMATION SecurityInfo
,
1504 UNICODE_STRING ObjectName
;
1508 Status
= RtlCreateUnicodeStringFromAsciiz(&ObjectName
,
1510 if (!NT_SUCCESS(Status
))
1512 return RtlNtStatusToDosError(Status
);
1515 Ret
= SetNamedSecurityInfoW(ObjectName
.Buffer
,
1523 RtlFreeUnicodeString(&ObjectName
);
1529 /**********************************************************************
1530 * GetSecurityInfo EXPORTED
1535 GetSecurityInfo(HANDLE handle
,
1536 SE_OBJECT_TYPE ObjectType
,
1537 SECURITY_INFORMATION SecurityInfo
,
1542 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
1548 ErrorCode
= CheckNtMartaPresent();
1549 if (ErrorCode
== ERROR_SUCCESS
)
1551 ErrorCode
= pGetSecurityInfoCheck(SecurityInfo
,
1556 ppSecurityDescriptor
);
1558 if (ErrorCode
== ERROR_SUCCESS
)
1560 /* call the MARTA provider */
1561 ErrorCode
= AccRewriteGetHandleRights(handle
,
1568 ppSecurityDescriptor
);
1573 ErrorCode
= ERROR_INVALID_HANDLE
;
1579 /**********************************************************************
1580 * SetSecurityInfo EXPORTED
1586 SetSecurityInfo(HANDLE handle
,
1587 SE_OBJECT_TYPE ObjectType
,
1588 SECURITY_INFORMATION SecurityInfo
,
1598 ErrorCode
= CheckNtMartaPresent();
1599 if (ErrorCode
== ERROR_SUCCESS
)
1601 SECURITY_DESCRIPTOR SecurityDescriptor
;
1603 ErrorCode
= pSetSecurityInfoCheck(&SecurityDescriptor
,
1610 if (ErrorCode
== ERROR_SUCCESS
)
1612 /* call the MARTA provider */
1613 ErrorCode
= AccRewriteSetHandleRights(handle
,
1616 &SecurityDescriptor
);
1621 ErrorCode
= ERROR_INVALID_HANDLE
;
1627 /******************************************************************************
1628 * GetSecurityInfoExW EXPORTED
1630 DWORD WINAPI
GetSecurityInfoExA(
1632 SE_OBJECT_TYPE ObjectType
,
1633 SECURITY_INFORMATION SecurityInfo
,
1636 PACTRL_ACCESSA
*ppAccessList
,
1637 PACTRL_AUDITA
*ppAuditList
,
1642 DPRINT1("GetSecurityInfoExA stub!\n");
1643 return ERROR_BAD_PROVIDER
;
1647 /******************************************************************************
1648 * GetSecurityInfoExW EXPORTED
1650 DWORD WINAPI
GetSecurityInfoExW(
1652 SE_OBJECT_TYPE ObjectType
,
1653 SECURITY_INFORMATION SecurityInfo
,
1656 PACTRL_ACCESSW
*ppAccessList
,
1657 PACTRL_AUDITW
*ppAuditList
,
1662 DPRINT1("GetSecurityInfoExW stub!\n");
1663 return ERROR_BAD_PROVIDER
;
1667 /**********************************************************************
1668 * ImpersonateNamedPipeClient EXPORTED
1673 ImpersonateNamedPipeClient(HANDLE hNamedPipe
)
1675 IO_STATUS_BLOCK StatusBlock
;
1678 DPRINT("ImpersonateNamedPipeClient() called\n");
1680 Status
= NtFsControlFile(hNamedPipe
,
1685 FSCTL_PIPE_IMPERSONATE
,
1690 if (!NT_SUCCESS(Status
))
1692 SetLastError(RtlNtStatusToDosError(Status
));
1704 CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor
,
1705 PSECURITY_DESCRIPTOR CreatorDescriptor
,
1706 PSECURITY_DESCRIPTOR
*NewDescriptor
,
1707 BOOL IsDirectoryObject
,
1709 PGENERIC_MAPPING GenericMapping
)
1713 Status
= RtlNewSecurityObject(ParentDescriptor
,
1719 if (!NT_SUCCESS(Status
))
1721 SetLastError(RtlNtStatusToDosError(Status
));
1733 CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor
,
1734 PSECURITY_DESCRIPTOR CreatorDescriptor
,
1735 PSECURITY_DESCRIPTOR
* NewDescriptor
,
1737 BOOL IsContainerObject
,
1738 ULONG AutoInheritFlags
,
1740 PGENERIC_MAPPING GenericMapping
)
1742 DPRINT1("%s() not implemented!\n", __FUNCTION__
);
1751 CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor
,
1752 PSECURITY_DESCRIPTOR CreatorDescriptor
,
1753 PSECURITY_DESCRIPTOR
* NewDescriptor
,
1756 BOOL IsContainerObject
,
1757 ULONG AutoInheritFlags
,
1759 PGENERIC_MAPPING GenericMapping
)
1761 DPRINT1("%s() not implemented!\n", __FUNCTION__
);
1770 DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR
*ObjectDescriptor
)
1774 Status
= RtlDeleteSecurityObject(ObjectDescriptor
);
1775 if (!NT_SUCCESS(Status
))
1777 SetLastError(RtlNtStatusToDosError(Status
));
1789 GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR ObjectDescriptor
,
1790 SECURITY_INFORMATION SecurityInformation
,
1791 PSECURITY_DESCRIPTOR ResultantDescriptor
,
1792 DWORD DescriptorLength
,
1793 PDWORD ReturnLength
)
1797 Status
= RtlQuerySecurityObject(ObjectDescriptor
,
1798 SecurityInformation
,
1799 ResultantDescriptor
,
1802 if (!NT_SUCCESS(Status
))
1804 SetLastError(RtlNtStatusToDosError(Status
));
1816 SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation
,
1817 PSECURITY_DESCRIPTOR ModificationDescriptor
,
1818 PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
1819 PGENERIC_MAPPING GenericMapping
,
1824 Status
= RtlSetSecurityObject(SecurityInformation
,
1825 ModificationDescriptor
,
1826 ObjectsSecurityDescriptor
,
1829 if (!NT_SUCCESS(Status
))
1831 SetLastError(RtlNtStatusToDosError(Status
));
1843 TreeResetNamedSecurityInfoW(LPWSTR pObjectName
,
1844 SE_OBJECT_TYPE ObjectType
,
1845 SECURITY_INFORMATION SecurityInfo
,
1851 FN_PROGRESSW fnProgress
,
1852 PROG_INVOKE_SETTING ProgressInvokeSetting
,
1857 if (pObjectName
!= NULL
)
1859 ErrorCode
= CheckNtMartaPresent();
1860 if (ErrorCode
== ERROR_SUCCESS
)
1864 case SE_FILE_OBJECT
:
1865 case SE_REGISTRY_KEY
:
1867 /* check the SecurityInfo flags for sanity (both, the protected
1868 and unprotected dacl/sacl flag must not be passed together) */
1869 if (((SecurityInfo
& DACL_SECURITY_INFORMATION
) &&
1870 (SecurityInfo
& (PROTECTED_DACL_SECURITY_INFORMATION
| UNPROTECTED_DACL_SECURITY_INFORMATION
)) ==
1871 (PROTECTED_DACL_SECURITY_INFORMATION
| UNPROTECTED_DACL_SECURITY_INFORMATION
))
1875 ((SecurityInfo
& SACL_SECURITY_INFORMATION
) &&
1876 (SecurityInfo
& (PROTECTED_SACL_SECURITY_INFORMATION
| UNPROTECTED_SACL_SECURITY_INFORMATION
)) ==
1877 (PROTECTED_SACL_SECURITY_INFORMATION
| UNPROTECTED_SACL_SECURITY_INFORMATION
)))
1879 ErrorCode
= ERROR_INVALID_PARAMETER
;
1883 /* call the MARTA provider */
1884 ErrorCode
= AccTreeResetNamedSecurityInfo(pObjectName
,
1893 ProgressInvokeSetting
,
1899 /* object type not supported */
1900 ErrorCode
= ERROR_INVALID_PARAMETER
;
1906 ErrorCode
= ERROR_INVALID_PARAMETER
;
1916 TreeResetNamedSecurityInfoA(LPSTR pObjectName
,
1917 SE_OBJECT_TYPE ObjectType
,
1918 SECURITY_INFORMATION SecurityInfo
,
1924 FN_PROGRESSA fnProgress
,
1925 PROG_INVOKE_SETTING ProgressInvokeSetting
,
1928 /* That's all this function does, at least up to w2k3... Even MS was too
1929 lazy to implement it... */
1930 return ERROR_CALL_NOT_IMPLEMENTED
;