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
);
62 FindNtMartaProc(RewriteGetExplicitEntriesFromAcl
);
63 FindNtMartaProc(TreeResetNamedSecurityInfo
);
64 FindNtMartaProc(GetInheritanceSource
);
65 FindNtMartaProc(FreeIndexArray
);
71 CheckNtMartaPresent(VOID
)
77 /* we're the first one trying to use ntmarta, initialize it and change
78 the pointer after initialization */
79 ErrorCode
= LoadAndInitializeNtMarta();
81 if (ErrorCode
== ERROR_SUCCESS
)
83 /* try change the NtMarta pointer */
84 if (InterlockedCompareExchangePointer(&NtMarta
,
88 /* another thread initialized ntmarta in the meanwhile, release
89 the reference of the dll loaded. */
90 FreeLibrary(NtMartaStatic
.hDllInstance
);
96 DPRINT1("Failed to initialize ntmarta.dll! Error: 0x%x", ErrorCode
);
102 /* ntmarta was already initialized */
103 ErrorCode
= ERROR_SUCCESS
;
109 VOID
UnloadNtMarta(VOID
)
111 if (InterlockedExchangePointer(&NtMarta
,
114 FreeLibrary(NtMartaStatic
.hDllInstance
);
118 /******************************************************************************/
124 AreAllAccessesGranted(DWORD GrantedAccess
,
127 return((BOOL
)RtlAreAllAccessesGranted(GrantedAccess
,
136 AreAnyAccessesGranted(DWORD GrantedAccess
,
139 return((BOOL
)RtlAreAnyAccessesGranted(GrantedAccess
,
144 /******************************************************************************
145 * GetFileSecurityA [ADVAPI32.@]
147 * Obtains Specified information about the security of a file or directory.
150 * lpFileName [I] Name of the file to get info for
151 * RequestedInformation [I] SE_ flags from "winnt.h"
152 * pSecurityDescriptor [O] Destination for security information
153 * nLength [I] Length of pSecurityDescriptor
154 * lpnLengthNeeded [O] Destination for length of returned security information
157 * Success: TRUE. pSecurityDescriptor contains the requested information.
158 * Failure: FALSE. lpnLengthNeeded contains the required space to return the info.
161 * The information returned is constrained by the callers access rights and
167 GetFileSecurityA(LPCSTR lpFileName
,
168 SECURITY_INFORMATION RequestedInformation
,
169 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
171 LPDWORD lpnLengthNeeded
)
173 UNICODE_STRING FileName
;
177 Status
= RtlCreateUnicodeStringFromAsciiz(&FileName
,
179 if (!NT_SUCCESS(Status
))
181 SetLastError(RtlNtStatusToDosError(Status
));
185 bResult
= GetFileSecurityW(FileName
.Buffer
,
186 RequestedInformation
,
191 RtlFreeUnicodeString(&FileName
);
201 GetFileSecurityW(LPCWSTR lpFileName
,
202 SECURITY_INFORMATION RequestedInformation
,
203 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
205 LPDWORD lpnLengthNeeded
)
207 OBJECT_ATTRIBUTES ObjectAttributes
;
208 IO_STATUS_BLOCK StatusBlock
;
209 UNICODE_STRING FileName
;
210 ULONG AccessMask
= 0;
214 DPRINT("GetFileSecurityW() called\n");
216 if (RequestedInformation
&
217 (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION
))
219 AccessMask
|= STANDARD_RIGHTS_READ
;
222 if (RequestedInformation
& SACL_SECURITY_INFORMATION
)
224 AccessMask
|= ACCESS_SYSTEM_SECURITY
;
227 if (!RtlDosPathNameToNtPathName_U((LPWSTR
)lpFileName
,
232 DPRINT("Invalid path\n");
233 SetLastError(ERROR_INVALID_NAME
);
237 InitializeObjectAttributes(&ObjectAttributes
,
239 OBJ_CASE_INSENSITIVE
,
243 Status
= NtOpenFile(&FileHandle
,
247 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
249 if (!NT_SUCCESS(Status
))
251 DPRINT("NtOpenFile() failed (Status %lx)\n", Status
);
252 SetLastError(RtlNtStatusToDosError(Status
));
256 RtlFreeUnicodeString(&FileName
);
258 Status
= NtQuerySecurityObject(FileHandle
,
259 RequestedInformation
,
265 if (!NT_SUCCESS(Status
))
267 DPRINT("NtQuerySecurityObject() failed (Status %lx)\n", Status
);
268 SetLastError(RtlNtStatusToDosError(Status
));
280 GetKernelObjectSecurity(HANDLE Handle
,
281 SECURITY_INFORMATION RequestedInformation
,
282 PSECURITY_DESCRIPTOR pSecurityDescriptor
,
284 LPDWORD lpnLengthNeeded
)
288 Status
= NtQuerySecurityObject(Handle
,
289 RequestedInformation
,
293 if (!NT_SUCCESS(Status
))
295 SetLastError(RtlNtStatusToDosError(Status
));
302 /******************************************************************************
303 * SetFileSecurityA [ADVAPI32.@]
304 * Sets the security of a file or directory
309 SetFileSecurityA (LPCSTR lpFileName
,
310 SECURITY_INFORMATION SecurityInformation
,
311 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
313 UNICODE_STRING FileName
;
317 Status
= RtlCreateUnicodeStringFromAsciiz(&FileName
,
319 if (!NT_SUCCESS(Status
))
321 SetLastError(RtlNtStatusToDosError(Status
));
325 bResult
= SetFileSecurityW(FileName
.Buffer
,
327 pSecurityDescriptor
);
329 RtlFreeUnicodeString(&FileName
);
335 /******************************************************************************
336 * SetFileSecurityW [ADVAPI32.@]
337 * Sets the security of a file or directory
342 SetFileSecurityW (LPCWSTR lpFileName
,
343 SECURITY_INFORMATION SecurityInformation
,
344 PSECURITY_DESCRIPTOR pSecurityDescriptor
)
346 OBJECT_ATTRIBUTES ObjectAttributes
;
347 IO_STATUS_BLOCK StatusBlock
;
348 UNICODE_STRING FileName
;
349 ULONG AccessMask
= 0;
353 DPRINT("SetFileSecurityW() called\n");
355 if (SecurityInformation
&
356 (OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION
))
358 AccessMask
|= WRITE_OWNER
;
361 if (SecurityInformation
& DACL_SECURITY_INFORMATION
)
363 AccessMask
|= WRITE_DAC
;
366 if (SecurityInformation
& SACL_SECURITY_INFORMATION
)
368 AccessMask
|= ACCESS_SYSTEM_SECURITY
;
371 if (!RtlDosPathNameToNtPathName_U((LPWSTR
)lpFileName
,
376 DPRINT("Invalid path\n");
377 SetLastError(ERROR_INVALID_NAME
);
381 InitializeObjectAttributes(&ObjectAttributes
,
383 OBJ_CASE_INSENSITIVE
,
387 Status
= NtOpenFile(&FileHandle
,
391 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
393 if (!NT_SUCCESS(Status
))
395 DPRINT("NtOpenFile() failed (Status %lx)\n", Status
);
396 SetLastError(RtlNtStatusToDosError(Status
));
400 RtlFreeUnicodeString(&FileName
);
402 Status
= NtSetSecurityObject(FileHandle
,
404 pSecurityDescriptor
);
407 if (!NT_SUCCESS(Status
))
409 DPRINT("NtSetSecurityObject() failed (Status %lx)\n", Status
);
410 SetLastError(RtlNtStatusToDosError(Status
));
422 SetKernelObjectSecurity(HANDLE Handle
,
423 SECURITY_INFORMATION SecurityInformation
,
424 PSECURITY_DESCRIPTOR SecurityDescriptor
)
428 Status
= NtSetSecurityObject(Handle
,
431 if (!NT_SUCCESS(Status
))
433 SetLastError(RtlNtStatusToDosError(Status
));
444 ImpersonateLoggedOnUser(HANDLE hToken
)
446 SECURITY_QUALITY_OF_SERVICE Qos
;
447 OBJECT_ATTRIBUTES ObjectAttributes
;
454 /* Get the token type */
455 Status
= NtQueryInformationToken (hToken
,
460 if (!NT_SUCCESS(Status
))
462 SetLastError (RtlNtStatusToDosError (Status
));
466 if (Type
== TokenPrimary
)
468 /* Create a duplicate impersonation token */
469 Qos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
470 Qos
.ImpersonationLevel
= SecurityImpersonation
;
471 Qos
.ContextTrackingMode
= SECURITY_DYNAMIC_TRACKING
;
472 Qos
.EffectiveOnly
= FALSE
;
474 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
475 ObjectAttributes
.RootDirectory
= NULL
;
476 ObjectAttributes
.ObjectName
= NULL
;
477 ObjectAttributes
.Attributes
= 0;
478 ObjectAttributes
.SecurityDescriptor
= NULL
;
479 ObjectAttributes
.SecurityQualityOfService
= &Qos
;
481 Status
= NtDuplicateToken (hToken
,
482 TOKEN_IMPERSONATE
| TOKEN_QUERY
,
487 if (!NT_SUCCESS(Status
))
489 SetLastError (RtlNtStatusToDosError (Status
));
497 /* User the original impersonation token */
502 /* Impersonate the the current thread */
503 Status
= NtSetInformationThread (NtCurrentThread (),
504 ThreadImpersonationToken
,
508 if (Duplicated
== TRUE
)
513 if (!NT_SUCCESS(Status
))
515 SetLastError (RtlNtStatusToDosError (Status
));
527 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
531 Status
= RtlImpersonateSelf(ImpersonationLevel
);
532 if (!NT_SUCCESS(Status
))
534 SetLastError(RtlNtStatusToDosError(Status
));
550 Status
= NtSetInformationThread(NtCurrentThread(),
551 ThreadImpersonationToken
,
554 if (!NT_SUCCESS(Status
))
556 SetLastError(RtlNtStatusToDosError(Status
));
563 /******************************************************************************
564 * GetUserNameA [ADVAPI32.@]
566 * Get the current user name.
569 * lpszName [O] Destination for the user name.
570 * lpSize [I/O] Size of lpszName.
576 GetUserNameA( LPSTR lpszName
, LPDWORD lpSize
)
578 UNICODE_STRING NameW
;
582 /* apparently Win doesn't check whether lpSize is valid at all! */
585 NameW
.MaximumLength
= (*lpSize
) * sizeof(WCHAR
);
586 NameW
.Buffer
= LocalAlloc(LMEM_FIXED
, NameW
.MaximumLength
);
587 if(NameW
.Buffer
== NULL
)
589 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
594 NameA
.MaximumLength
= ((*lpSize
) < 0xFFFF ? (USHORT
)(*lpSize
) : 0xFFFF);
595 NameA
.Buffer
= lpszName
;
597 Ret
= GetUserNameW(NameW
.Buffer
,
601 RtlUnicodeStringToAnsiString(&NameA
, &NameW
, FALSE
);
602 NameA
.Buffer
[NameA
.Length
] = '\0';
604 *lpSize
= NameA
.Length
+ 1;
607 LocalFree(NameW
.Buffer
);
612 /******************************************************************************
613 * GetUserNameW [ADVAPI32.@]
620 GetUserNameW ( LPWSTR lpszName
, LPDWORD lpSize
)
622 HANDLE hToken
= INVALID_HANDLE_VALUE
;
625 TOKEN_USER
* token_user
= NULL
;
627 SID_NAME_USE snu
= SidTypeUser
;
628 WCHAR
* domain_name
= NULL
;
631 if ( !OpenThreadToken ( GetCurrentThread(), TOKEN_QUERY
, FALSE
, &hToken
) )
633 DWORD dwLastError
= GetLastError();
634 if ( dwLastError
!= ERROR_NO_TOKEN
635 && dwLastError
!= ERROR_NO_IMPERSONATION_TOKEN
)
637 /* don't call SetLastError(),
638 as OpenThreadToken() ought to have set one */
641 if ( !OpenProcessToken ( GetCurrentProcess(), TOKEN_QUERY
, &hToken
) )
643 /* don't call SetLastError(),
644 as OpenProcessToken() ought to have set one */
648 tu_buf
= LocalAlloc ( LMEM_FIXED
, 36 );
651 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
654 if ( !GetTokenInformation ( hToken
, TokenUser
, tu_buf
, 36, &tu_len
) || tu_len
> 36 )
656 LocalFree ( tu_buf
);
657 tu_buf
= LocalAlloc ( LMEM_FIXED
, tu_len
);
660 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
663 if ( !GetTokenInformation ( hToken
, TokenUser
, tu_buf
, tu_len
, &tu_len
) )
665 /* don't call SetLastError(),
666 as GetTokenInformation() ought to have set one */
667 LocalFree ( tu_buf
);
668 CloseHandle ( hToken
);
672 token_user
= (TOKEN_USER
*)tu_buf
;
676 domain_name
= LocalAlloc ( LMEM_FIXED
, dn_len
* sizeof(WCHAR
) );
679 LocalFree ( tu_buf
);
680 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
683 if ( !LookupAccountSidW ( NULL
, token_user
->User
.Sid
, lpszName
, &an_len
, domain_name
, &dn_len
, &snu
)
688 LocalFree ( domain_name
);
689 domain_name
= LocalAlloc ( LMEM_FIXED
, dn_len
* sizeof(WCHAR
) );
692 LocalFree ( tu_buf
);
693 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
697 if ( !LookupAccountSidW ( NULL
, token_user
->User
.Sid
, lpszName
, &an_len
, domain_name
, &dn_len
, &snu
) )
699 /* don't call SetLastError(),
700 as LookupAccountSid() ought to have set one */
701 LocalFree ( domain_name
);
702 CloseHandle ( hToken
);
707 LocalFree ( domain_name
);
708 LocalFree ( tu_buf
);
709 CloseHandle ( hToken
);
711 if ( an_len
> *lpSize
)
714 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
722 /******************************************************************************
723 * LookupAccountSidA [ADVAPI32.@]
728 LookupAccountSidA (LPCSTR lpSystemName
,
732 LPSTR lpReferencedDomainName
,
733 LPDWORD cchReferencedDomainName
,
736 UNICODE_STRING NameW
, ReferencedDomainNameW
, SystemNameW
;
737 DWORD szName
, szReferencedDomainName
;
741 * save the buffer sizes the caller passed to us, as they may get modified and
742 * we require the original values when converting back to ansi
745 szReferencedDomainName
= *cchReferencedDomainName
;
748 * allocate buffers for the unicode strings to receive
754 NameW
.MaximumLength
= szName
* sizeof(WCHAR
);
755 NameW
.Buffer
= (PWSTR
)LocalAlloc(LMEM_FIXED
, NameW
.MaximumLength
);
756 if(NameW
.Buffer
== NULL
)
758 SetLastError(ERROR_OUTOFMEMORY
);
765 if(szReferencedDomainName
> 0)
767 ReferencedDomainNameW
.Length
= 0;
768 ReferencedDomainNameW
.MaximumLength
= szReferencedDomainName
* sizeof(WCHAR
);
769 ReferencedDomainNameW
.Buffer
= (PWSTR
)LocalAlloc(LMEM_FIXED
, ReferencedDomainNameW
.MaximumLength
);
770 if(ReferencedDomainNameW
.Buffer
== NULL
)
774 LocalFree(NameW
.Buffer
);
776 SetLastError(ERROR_OUTOFMEMORY
);
781 ReferencedDomainNameW
.Buffer
= NULL
;
784 * convert the system name to unicode - if present
787 if(lpSystemName
!= NULL
)
789 ANSI_STRING SystemNameA
;
791 RtlInitAnsiString(&SystemNameA
, lpSystemName
);
792 RtlAnsiStringToUnicodeString(&SystemNameW
, &SystemNameA
, TRUE
);
795 SystemNameW
.Buffer
= NULL
;
798 * it's time to call the unicode version
801 Ret
= LookupAccountSidW(SystemNameW
.Buffer
,
805 ReferencedDomainNameW
.Buffer
,
806 cchReferencedDomainName
,
811 * convert unicode strings back to ansi, don't forget that we can't convert
812 * more than 0xFFFF (USHORT) characters! Also don't forget to explicitly
813 * terminate the converted string, the Rtl functions don't do that!
820 NameA
.MaximumLength
= ((szName
<= 0xFFFF) ? (USHORT
)szName
: 0xFFFF);
821 NameA
.Buffer
= lpName
;
823 RtlUnicodeStringToAnsiString(&NameA
, &NameW
, FALSE
);
824 NameA
.Buffer
[NameA
.Length
] = '\0';
827 if(lpReferencedDomainName
!= NULL
)
829 ANSI_STRING ReferencedDomainNameA
;
831 ReferencedDomainNameA
.Length
= 0;
832 ReferencedDomainNameA
.MaximumLength
= ((szReferencedDomainName
<= 0xFFFF) ?
833 (USHORT
)szReferencedDomainName
: 0xFFFF);
834 ReferencedDomainNameA
.Buffer
= lpReferencedDomainName
;
836 RtlUnicodeStringToAnsiString(&ReferencedDomainNameA
, &ReferencedDomainNameW
, FALSE
);
837 ReferencedDomainNameA
.Buffer
[ReferencedDomainNameA
.Length
] = '\0';
842 * free previously allocated buffers
845 if(SystemNameW
.Buffer
!= NULL
)
847 RtlFreeUnicodeString(&SystemNameW
);
849 if(NameW
.Buffer
!= NULL
)
851 LocalFree(NameW
.Buffer
);
853 if(ReferencedDomainNameW
.Buffer
!= NULL
)
855 LocalFree(ReferencedDomainNameW
.Buffer
);
862 /******************************************************************************
863 * LookupAccountSidW [ADVAPI32.@]
872 LPDWORD pdwAccountName
,
874 LPDWORD pdwDomainName
,
875 PSID_NAME_USE peUse
)
877 LSA_UNICODE_STRING SystemName
;
878 LSA_OBJECT_ATTRIBUTES ObjectAttributes
;
879 LSA_HANDLE PolicyHandle
= INVALID_HANDLE_VALUE
;
881 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain
= NULL
;
882 PLSA_TRANSLATED_NAME TranslatedName
= NULL
;
885 RtlInitUnicodeString ( &SystemName
, pSystemName
);
886 ZeroMemory(&ObjectAttributes
, sizeof(ObjectAttributes
));
887 Status
= LsaOpenPolicy ( &SystemName
, &ObjectAttributes
, POLICY_LOOKUP_NAMES
, &PolicyHandle
);
888 if ( !NT_SUCCESS(Status
) )
890 SetLastError ( LsaNtStatusToWinError(Status
) );
893 Status
= LsaLookupSids ( PolicyHandle
, 1, &pSid
, &ReferencedDomain
, &TranslatedName
);
895 LsaClose ( PolicyHandle
);
897 if ( !NT_SUCCESS(Status
) || Status
== STATUS_SOME_NOT_MAPPED
)
899 SetLastError ( LsaNtStatusToWinError(Status
) );
905 if ( TranslatedName
)
907 DWORD dwSrcLen
= TranslatedName
->Name
.Length
/ sizeof(WCHAR
);
908 if ( *pdwAccountName
<= dwSrcLen
)
910 *pdwAccountName
= dwSrcLen
+ 1;
915 *pdwAccountName
= dwSrcLen
;
916 wcscpy ( pAccountName
, TranslatedName
->Name
.Buffer
);
919 *peUse
= TranslatedName
->Use
;
922 if ( ReferencedDomain
)
924 if ( ReferencedDomain
->Entries
> 0 )
926 DWORD dwSrcLen
= ReferencedDomain
->Domains
[0].Name
.Length
/ sizeof(WCHAR
);
927 if ( *pdwDomainName
<= dwSrcLen
)
929 *pdwDomainName
= dwSrcLen
+ 1;
934 *pdwDomainName
= dwSrcLen
;
935 wcscpy ( pDomainName
, ReferencedDomain
->Domains
[0].Name
.Buffer
);
941 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
944 if ( ReferencedDomain
)
945 LsaFreeMemory ( ReferencedDomain
);
946 if ( TranslatedName
)
947 LsaFreeMemory ( TranslatedName
);
954 /******************************************************************************
955 * LookupAccountNameA [ADVAPI32.@]
960 LookupAccountNameA (LPCSTR SystemName
,
964 LPSTR ReferencedDomainName
,
965 LPDWORD hReferencedDomainNameLength
,
966 PSID_NAME_USE SidNameUse
)
968 DPRINT1("LookupAccountNameA is unimplemented\n");
969 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
974 /******************************************************************************
975 * LookupAccountNameW [ADVAPI32.@]
980 LookupAccountNameW (LPCWSTR SystemName
,
984 LPWSTR ReferencedDomainName
,
985 LPDWORD hReferencedDomainNameLength
,
986 PSID_NAME_USE SidNameUse
)
988 DPRINT1("LookupAccountNameW is unimplemented\n");
989 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
994 /**********************************************************************
995 * LookupPrivilegeValueA EXPORTED
1000 LookupPrivilegeValueA (LPCSTR lpSystemName
,
1004 UNICODE_STRING SystemName
;
1005 UNICODE_STRING Name
;
1008 /* Remote system? */
1009 if (lpSystemName
!= NULL
)
1011 RtlCreateUnicodeStringFromAsciiz (&SystemName
,
1012 (LPSTR
)lpSystemName
);
1015 /* Check the privilege name is not NULL */
1018 SetLastError (ERROR_INVALID_PARAMETER
);
1022 RtlCreateUnicodeStringFromAsciiz (&Name
,
1025 Result
= LookupPrivilegeValueW ((lpSystemName
!= NULL
) ? SystemName
.Buffer
: NULL
,
1029 RtlFreeUnicodeString (&Name
);
1031 /* Remote system? */
1032 if (lpSystemName
!= NULL
)
1034 RtlFreeUnicodeString (&SystemName
);
1041 /**********************************************************************
1042 * LookupPrivilegeValueW EXPORTED
1047 LookupPrivilegeValueW (LPCWSTR SystemName
,
1051 static const WCHAR
* const DefaultPrivNames
[] =
1053 L
"SeCreateTokenPrivilege",
1054 L
"SeAssignPrimaryTokenPrivilege",
1055 L
"SeLockMemoryPrivilege",
1056 L
"SeIncreaseQuotaPrivilege",
1057 L
"SeUnsolicitedInputPrivilege",
1058 L
"SeMachineAccountPrivilege",
1060 L
"SeSecurityPrivilege",
1061 L
"SeTakeOwnershipPrivilege",
1062 L
"SeLoadDriverPrivilege",
1063 L
"SeSystemProfilePrivilege",
1064 L
"SeSystemtimePrivilege",
1065 L
"SeProfileSingleProcessPrivilege",
1066 L
"SeIncreaseBasePriorityPrivilege",
1067 L
"SeCreatePagefilePrivilege",
1068 L
"SeCreatePermanentPrivilege",
1069 L
"SeBackupPrivilege",
1070 L
"SeRestorePrivilege",
1071 L
"SeShutdownPrivilege",
1072 L
"SeDebugPrivilege",
1073 L
"SeAuditPrivilege",
1074 L
"SeSystemEnvironmentPrivilege",
1075 L
"SeChangeNotifyPrivilege",
1076 L
"SeRemoteShutdownPrivilege",
1077 L
"SeUndockPrivilege",
1078 L
"SeSyncAgentPrivilege",
1079 L
"SeEnableDelegationPrivilege",
1080 L
"SeManageVolumePrivilege",
1081 L
"SeImpersonatePrivilege",
1082 L
"SeCreateGlobalPrivilege"
1086 if (NULL
!= SystemName
&& L
'\0' != *SystemName
)
1088 DPRINT1("LookupPrivilegeValueW: not implemented for remote system\n");
1089 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1093 for (Priv
= 0; Priv
< sizeof(DefaultPrivNames
) / sizeof(DefaultPrivNames
[0]); Priv
++)
1095 if (0 == wcscmp(PrivName
, DefaultPrivNames
[Priv
]))
1097 Luid
->LowPart
= Priv
+ 1;
1103 DPRINT1("LookupPrivilegeValueW: no such privilege %S\n", PrivName
);
1104 SetLastError(ERROR_NO_SUCH_PRIVILEGE
);
1109 /**********************************************************************
1110 * LookupPrivilegeDisplayNameA EXPORTED
1115 LookupPrivilegeDisplayNameA (LPCSTR lpSystemName
,
1117 LPSTR lpDisplayName
,
1118 LPDWORD cbDisplayName
,
1119 LPDWORD lpLanguageId
)
1121 DPRINT1("LookupPrivilegeDisplayNameA: stub\n");
1122 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1127 /**********************************************************************
1128 * LookupPrivilegeDisplayNameW EXPORTED
1133 LookupPrivilegeDisplayNameW (LPCWSTR lpSystemName
,
1135 LPWSTR lpDisplayName
,
1136 LPDWORD cbDisplayName
,
1137 LPDWORD lpLanguageId
)
1139 DPRINT1("LookupPrivilegeDisplayNameW: stub\n");
1140 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1145 /**********************************************************************
1146 * LookupPrivilegeNameA EXPORTED
1151 LookupPrivilegeNameA (LPCSTR lpSystemName
,
1156 DPRINT1("LookupPrivilegeNameA: stub\n");
1157 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1162 /**********************************************************************
1163 * LookupPrivilegeNameW EXPORTED
1168 LookupPrivilegeNameW (LPCWSTR lpSystemName
,
1173 DPRINT1("LookupPrivilegeNameW: stub\n");
1174 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1180 pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo
,
1185 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
1187 if ((SecurityInfo
& (OWNER_SECURITY_INFORMATION
|
1188 GROUP_SECURITY_INFORMATION
|
1189 DACL_SECURITY_INFORMATION
|
1190 SACL_SECURITY_INFORMATION
)) &&
1191 ppSecurityDescriptor
== NULL
)
1193 /* if one of the SIDs or ACLs are present, the security descriptor
1195 return ERROR_INVALID_PARAMETER
;
1199 /* reset the pointers unless they're ignored */
1200 if ((SecurityInfo
& OWNER_SECURITY_INFORMATION
) &&
1205 if ((SecurityInfo
& GROUP_SECURITY_INFORMATION
) &&
1206 *ppsidGroup
!= NULL
)
1210 if ((SecurityInfo
& DACL_SECURITY_INFORMATION
) &&
1215 if ((SecurityInfo
& SACL_SECURITY_INFORMATION
) &&
1221 if (SecurityInfo
& (OWNER_SECURITY_INFORMATION
|
1222 GROUP_SECURITY_INFORMATION
|
1223 DACL_SECURITY_INFORMATION
|
1224 SACL_SECURITY_INFORMATION
))
1226 *ppSecurityDescriptor
= NULL
;
1229 return ERROR_SUCCESS
;
1235 pSetSecurityInfoCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1236 SECURITY_INFORMATION SecurityInfo
,
1242 /* initialize a security descriptor on the stack */
1243 if (!InitializeSecurityDescriptor(pSecurityDescriptor
,
1244 SECURITY_DESCRIPTOR_REVISION
))
1246 return GetLastError();
1249 if (SecurityInfo
& OWNER_SECURITY_INFORMATION
)
1251 if (RtlValidSid(psidOwner
))
1253 if (!SetSecurityDescriptorOwner(pSecurityDescriptor
,
1257 return GetLastError();
1262 return ERROR_INVALID_PARAMETER
;
1266 if (SecurityInfo
& GROUP_SECURITY_INFORMATION
)
1268 if (RtlValidSid(psidGroup
))
1270 if (!SetSecurityDescriptorGroup(pSecurityDescriptor
,
1274 return GetLastError();
1279 return ERROR_INVALID_PARAMETER
;
1283 if (SecurityInfo
& DACL_SECURITY_INFORMATION
)
1287 if (SetSecurityDescriptorDacl(pSecurityDescriptor
,
1292 /* check if the DACL needs to be protected from being
1293 modified by inheritable ACEs */
1294 if (SecurityInfo
& PROTECTED_DACL_SECURITY_INFORMATION
)
1301 return GetLastError();
1307 /* protect the DACL from being modified by inheritable ACEs */
1308 if (!SetSecurityDescriptorControl(pSecurityDescriptor
,
1312 return GetLastError();
1317 if (SecurityInfo
& SACL_SECURITY_INFORMATION
)
1321 if (SetSecurityDescriptorSacl(pSecurityDescriptor
,
1326 /* check if the SACL needs to be protected from being
1327 modified by inheritable ACEs */
1328 if (SecurityInfo
& PROTECTED_SACL_SECURITY_INFORMATION
)
1335 return GetLastError();
1341 /* protect the SACL from being modified by inheritable ACEs */
1342 if (!SetSecurityDescriptorControl(pSecurityDescriptor
,
1346 return GetLastError();
1351 return ERROR_SUCCESS
;
1355 /**********************************************************************
1356 * GetNamedSecurityInfoW EXPORTED
1361 GetNamedSecurityInfoW(LPWSTR pObjectName
,
1362 SE_OBJECT_TYPE ObjectType
,
1363 SECURITY_INFORMATION SecurityInfo
,
1368 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1372 if (pObjectName
!= NULL
)
1374 ErrorCode
= CheckNtMartaPresent();
1375 if (ErrorCode
== ERROR_SUCCESS
)
1377 ErrorCode
= pGetSecurityInfoCheck(SecurityInfo
,
1382 ppSecurityDescriptor
);
1384 if (ErrorCode
== ERROR_SUCCESS
)
1386 /* call the MARTA provider */
1387 ErrorCode
= AccRewriteGetNamedRights(pObjectName
,
1394 ppSecurityDescriptor
);
1399 ErrorCode
= ERROR_INVALID_PARAMETER
;
1405 /**********************************************************************
1406 * GetNamedSecurityInfoA EXPORTED
1411 GetNamedSecurityInfoA(LPSTR pObjectName
,
1412 SE_OBJECT_TYPE ObjectType
,
1413 SECURITY_INFORMATION SecurityInfo
,
1418 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1420 UNICODE_STRING ObjectName
;
1424 Status
= RtlCreateUnicodeStringFromAsciiz(&ObjectName
,
1426 if (!NT_SUCCESS(Status
))
1428 return RtlNtStatusToDosError(Status
);
1431 Ret
= GetNamedSecurityInfoW(ObjectName
.Buffer
,
1438 ppSecurityDescriptor
);
1440 RtlFreeUnicodeString(&ObjectName
);
1446 /**********************************************************************
1447 * SetNamedSecurityInfoW EXPORTED
1452 SetNamedSecurityInfoW(LPWSTR pObjectName
,
1453 SE_OBJECT_TYPE ObjectType
,
1454 SECURITY_INFORMATION SecurityInfo
,
1462 if (pObjectName
!= NULL
)
1464 ErrorCode
= CheckNtMartaPresent();
1465 if (ErrorCode
== ERROR_SUCCESS
)
1467 SECURITY_DESCRIPTOR SecurityDescriptor
;
1469 ErrorCode
= pSetSecurityInfoCheck(&SecurityDescriptor
,
1476 if (ErrorCode
== ERROR_SUCCESS
)
1478 /* call the MARTA provider */
1479 ErrorCode
= AccRewriteSetNamedRights(pObjectName
,
1482 &SecurityDescriptor
);
1487 ErrorCode
= ERROR_INVALID_PARAMETER
;
1493 /**********************************************************************
1494 * SetNamedSecurityInfoA EXPORTED
1499 SetNamedSecurityInfoA(LPSTR pObjectName
,
1500 SE_OBJECT_TYPE ObjectType
,
1501 SECURITY_INFORMATION SecurityInfo
,
1507 UNICODE_STRING ObjectName
;
1511 Status
= RtlCreateUnicodeStringFromAsciiz(&ObjectName
,
1513 if (!NT_SUCCESS(Status
))
1515 return RtlNtStatusToDosError(Status
);
1518 Ret
= SetNamedSecurityInfoW(ObjectName
.Buffer
,
1526 RtlFreeUnicodeString(&ObjectName
);
1532 /**********************************************************************
1533 * GetSecurityInfo EXPORTED
1538 GetSecurityInfo(HANDLE handle
,
1539 SE_OBJECT_TYPE ObjectType
,
1540 SECURITY_INFORMATION SecurityInfo
,
1545 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
1551 ErrorCode
= CheckNtMartaPresent();
1552 if (ErrorCode
== ERROR_SUCCESS
)
1554 ErrorCode
= pGetSecurityInfoCheck(SecurityInfo
,
1559 ppSecurityDescriptor
);
1561 if (ErrorCode
== ERROR_SUCCESS
)
1563 /* call the MARTA provider */
1564 ErrorCode
= AccRewriteGetHandleRights(handle
,
1571 ppSecurityDescriptor
);
1576 ErrorCode
= ERROR_INVALID_HANDLE
;
1582 /**********************************************************************
1583 * SetSecurityInfo EXPORTED
1589 SetSecurityInfo(HANDLE handle
,
1590 SE_OBJECT_TYPE ObjectType
,
1591 SECURITY_INFORMATION SecurityInfo
,
1601 ErrorCode
= CheckNtMartaPresent();
1602 if (ErrorCode
== ERROR_SUCCESS
)
1604 SECURITY_DESCRIPTOR SecurityDescriptor
;
1606 ErrorCode
= pSetSecurityInfoCheck(&SecurityDescriptor
,
1613 if (ErrorCode
== ERROR_SUCCESS
)
1615 /* call the MARTA provider */
1616 ErrorCode
= AccRewriteSetHandleRights(handle
,
1619 &SecurityDescriptor
);
1624 ErrorCode
= ERROR_INVALID_HANDLE
;
1630 /******************************************************************************
1631 * GetSecurityInfoExW EXPORTED
1633 DWORD WINAPI
GetSecurityInfoExA(
1635 SE_OBJECT_TYPE ObjectType
,
1636 SECURITY_INFORMATION SecurityInfo
,
1639 PACTRL_ACCESSA
*ppAccessList
,
1640 PACTRL_AUDITA
*ppAuditList
,
1645 DPRINT1("GetSecurityInfoExA stub!\n");
1646 return ERROR_BAD_PROVIDER
;
1650 /******************************************************************************
1651 * GetSecurityInfoExW EXPORTED
1653 DWORD WINAPI
GetSecurityInfoExW(
1655 SE_OBJECT_TYPE ObjectType
,
1656 SECURITY_INFORMATION SecurityInfo
,
1659 PACTRL_ACCESSW
*ppAccessList
,
1660 PACTRL_AUDITW
*ppAuditList
,
1665 DPRINT1("GetSecurityInfoExW stub!\n");
1666 return ERROR_BAD_PROVIDER
;
1670 /**********************************************************************
1671 * ImpersonateNamedPipeClient EXPORTED
1676 ImpersonateNamedPipeClient(HANDLE hNamedPipe
)
1678 IO_STATUS_BLOCK StatusBlock
;
1681 DPRINT("ImpersonateNamedPipeClient() called\n");
1683 Status
= NtFsControlFile(hNamedPipe
,
1688 FSCTL_PIPE_IMPERSONATE
,
1693 if (!NT_SUCCESS(Status
))
1695 SetLastError(RtlNtStatusToDosError(Status
));
1707 CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor
,
1708 PSECURITY_DESCRIPTOR CreatorDescriptor
,
1709 PSECURITY_DESCRIPTOR
*NewDescriptor
,
1710 BOOL IsDirectoryObject
,
1712 PGENERIC_MAPPING GenericMapping
)
1716 Status
= RtlNewSecurityObject(ParentDescriptor
,
1722 if (!NT_SUCCESS(Status
))
1724 SetLastError(RtlNtStatusToDosError(Status
));
1736 CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor
,
1737 PSECURITY_DESCRIPTOR CreatorDescriptor
,
1738 PSECURITY_DESCRIPTOR
* NewDescriptor
,
1740 BOOL IsContainerObject
,
1741 ULONG AutoInheritFlags
,
1743 PGENERIC_MAPPING GenericMapping
)
1745 DPRINT1("%s() not implemented!\n", __FUNCTION__
);
1754 CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor
,
1755 PSECURITY_DESCRIPTOR CreatorDescriptor
,
1756 PSECURITY_DESCRIPTOR
* NewDescriptor
,
1759 BOOL IsContainerObject
,
1760 ULONG AutoInheritFlags
,
1762 PGENERIC_MAPPING GenericMapping
)
1764 DPRINT1("%s() not implemented!\n", __FUNCTION__
);
1773 DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR
*ObjectDescriptor
)
1777 Status
= RtlDeleteSecurityObject(ObjectDescriptor
);
1778 if (!NT_SUCCESS(Status
))
1780 SetLastError(RtlNtStatusToDosError(Status
));
1792 GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR ObjectDescriptor
,
1793 SECURITY_INFORMATION SecurityInformation
,
1794 PSECURITY_DESCRIPTOR ResultantDescriptor
,
1795 DWORD DescriptorLength
,
1796 PDWORD ReturnLength
)
1800 Status
= RtlQuerySecurityObject(ObjectDescriptor
,
1801 SecurityInformation
,
1802 ResultantDescriptor
,
1805 if (!NT_SUCCESS(Status
))
1807 SetLastError(RtlNtStatusToDosError(Status
));
1819 SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation
,
1820 PSECURITY_DESCRIPTOR ModificationDescriptor
,
1821 PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
1822 PGENERIC_MAPPING GenericMapping
,
1827 Status
= RtlSetSecurityObject(SecurityInformation
,
1828 ModificationDescriptor
,
1829 ObjectsSecurityDescriptor
,
1832 if (!NT_SUCCESS(Status
))
1834 SetLastError(RtlNtStatusToDosError(Status
));
1846 TreeResetNamedSecurityInfoW(LPWSTR pObjectName
,
1847 SE_OBJECT_TYPE ObjectType
,
1848 SECURITY_INFORMATION SecurityInfo
,
1854 FN_PROGRESSW fnProgress
,
1855 PROG_INVOKE_SETTING ProgressInvokeSetting
,
1860 if (pObjectName
!= NULL
)
1862 ErrorCode
= CheckNtMartaPresent();
1863 if (ErrorCode
== ERROR_SUCCESS
)
1867 case SE_FILE_OBJECT
:
1868 case SE_REGISTRY_KEY
:
1870 /* check the SecurityInfo flags for sanity (both, the protected
1871 and unprotected dacl/sacl flag must not be passed together) */
1872 if (((SecurityInfo
& DACL_SECURITY_INFORMATION
) &&
1873 (SecurityInfo
& (PROTECTED_DACL_SECURITY_INFORMATION
| UNPROTECTED_DACL_SECURITY_INFORMATION
)) ==
1874 (PROTECTED_DACL_SECURITY_INFORMATION
| UNPROTECTED_DACL_SECURITY_INFORMATION
))
1878 ((SecurityInfo
& SACL_SECURITY_INFORMATION
) &&
1879 (SecurityInfo
& (PROTECTED_SACL_SECURITY_INFORMATION
| UNPROTECTED_SACL_SECURITY_INFORMATION
)) ==
1880 (PROTECTED_SACL_SECURITY_INFORMATION
| UNPROTECTED_SACL_SECURITY_INFORMATION
)))
1882 ErrorCode
= ERROR_INVALID_PARAMETER
;
1886 /* call the MARTA provider */
1887 ErrorCode
= AccTreeResetNamedSecurityInfo(pObjectName
,
1896 ProgressInvokeSetting
,
1902 /* object type not supported */
1903 ErrorCode
= ERROR_INVALID_PARAMETER
;
1909 ErrorCode
= ERROR_INVALID_PARAMETER
;
1919 TreeResetNamedSecurityInfoA(LPSTR pObjectName
,
1920 SE_OBJECT_TYPE ObjectType
,
1921 SECURITY_INFORMATION SecurityInfo
,
1927 FN_PROGRESSA fnProgress
,
1928 PROG_INVOKE_SETTING ProgressInvokeSetting
,
1931 /* That's all this function does, at least up to w2k3... Even MS was too
1932 lazy to implement it... */
1933 return ERROR_CALL_NOT_IMPLEMENTED
;