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
|= READ_CONTROL
;
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
,
247 RtlFreeHeap(RtlGetProcessHeap(),
251 if (!NT_SUCCESS(Status
))
253 DPRINT("NtOpenFile() failed (Status %lx)\n", Status
);
254 SetLastError(RtlNtStatusToDosError(Status
));
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(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
,
394 RtlFreeHeap(RtlGetProcessHeap(),
398 if (!NT_SUCCESS(Status
))
400 DPRINT("NtOpenFile() failed (Status %lx)\n", Status
);
401 SetLastError(RtlNtStatusToDosError(Status
));
405 Status
= NtSetSecurityObject(FileHandle
,
407 pSecurityDescriptor
);
410 if (!NT_SUCCESS(Status
))
412 DPRINT("NtSetSecurityObject() failed (Status %lx)\n", Status
);
413 SetLastError(RtlNtStatusToDosError(Status
));
425 SetKernelObjectSecurity(HANDLE Handle
,
426 SECURITY_INFORMATION SecurityInformation
,
427 PSECURITY_DESCRIPTOR SecurityDescriptor
)
431 Status
= NtSetSecurityObject(Handle
,
434 if (!NT_SUCCESS(Status
))
436 SetLastError(RtlNtStatusToDosError(Status
));
447 ImpersonateLoggedOnUser(HANDLE hToken
)
449 SECURITY_QUALITY_OF_SERVICE Qos
;
450 OBJECT_ATTRIBUTES ObjectAttributes
;
457 /* Get the token type */
458 Status
= NtQueryInformationToken (hToken
,
463 if (!NT_SUCCESS(Status
))
465 SetLastError (RtlNtStatusToDosError (Status
));
469 if (Type
== TokenPrimary
)
471 /* Create a duplicate impersonation token */
472 Qos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
473 Qos
.ImpersonationLevel
= SecurityImpersonation
;
474 Qos
.ContextTrackingMode
= SECURITY_DYNAMIC_TRACKING
;
475 Qos
.EffectiveOnly
= FALSE
;
477 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
478 ObjectAttributes
.RootDirectory
= NULL
;
479 ObjectAttributes
.ObjectName
= NULL
;
480 ObjectAttributes
.Attributes
= 0;
481 ObjectAttributes
.SecurityDescriptor
= NULL
;
482 ObjectAttributes
.SecurityQualityOfService
= &Qos
;
484 Status
= NtDuplicateToken (hToken
,
485 TOKEN_IMPERSONATE
| TOKEN_QUERY
,
490 if (!NT_SUCCESS(Status
))
492 SetLastError (RtlNtStatusToDosError (Status
));
500 /* User the original impersonation token */
505 /* Impersonate the the current thread */
506 Status
= NtSetInformationThread (NtCurrentThread (),
507 ThreadImpersonationToken
,
511 if (Duplicated
== TRUE
)
516 if (!NT_SUCCESS(Status
))
518 SetLastError (RtlNtStatusToDosError (Status
));
530 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
)
534 Status
= RtlImpersonateSelf(ImpersonationLevel
);
535 if (!NT_SUCCESS(Status
))
537 SetLastError(RtlNtStatusToDosError(Status
));
553 Status
= NtSetInformationThread(NtCurrentThread(),
554 ThreadImpersonationToken
,
557 if (!NT_SUCCESS(Status
))
559 SetLastError(RtlNtStatusToDosError(Status
));
566 /******************************************************************************
567 * GetUserNameA [ADVAPI32.@]
569 * Get the current user name.
572 * lpszName [O] Destination for the user name.
573 * lpSize [I/O] Size of lpszName.
579 GetUserNameA( LPSTR lpszName
, LPDWORD lpSize
)
581 UNICODE_STRING NameW
;
585 /* apparently Win doesn't check whether lpSize is valid at all! */
588 NameW
.MaximumLength
= (*lpSize
) * sizeof(WCHAR
);
589 NameW
.Buffer
= LocalAlloc(LMEM_FIXED
, NameW
.MaximumLength
);
590 if(NameW
.Buffer
== NULL
)
592 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
597 NameA
.MaximumLength
= ((*lpSize
) < 0xFFFF ? (USHORT
)(*lpSize
) : 0xFFFF);
598 NameA
.Buffer
= lpszName
;
600 Ret
= GetUserNameW(NameW
.Buffer
,
604 RtlUnicodeStringToAnsiString(&NameA
, &NameW
, FALSE
);
605 NameA
.Buffer
[NameA
.Length
] = '\0';
607 *lpSize
= NameA
.Length
+ 1;
610 LocalFree(NameW
.Buffer
);
615 /******************************************************************************
616 * GetUserNameW [ADVAPI32.@]
623 GetUserNameW ( LPWSTR lpszName
, LPDWORD lpSize
)
625 HANDLE hToken
= INVALID_HANDLE_VALUE
;
628 TOKEN_USER
* token_user
= NULL
;
630 SID_NAME_USE snu
= SidTypeUser
;
631 WCHAR
* domain_name
= NULL
;
634 if ( !OpenThreadToken ( GetCurrentThread(), TOKEN_QUERY
, FALSE
, &hToken
) )
636 DWORD dwLastError
= GetLastError();
637 if ( dwLastError
!= ERROR_NO_TOKEN
638 && dwLastError
!= ERROR_NO_IMPERSONATION_TOKEN
)
640 /* don't call SetLastError(),
641 as OpenThreadToken() ought to have set one */
644 if ( !OpenProcessToken ( GetCurrentProcess(), TOKEN_QUERY
, &hToken
) )
646 /* don't call SetLastError(),
647 as OpenProcessToken() ought to have set one */
651 tu_buf
= LocalAlloc ( LMEM_FIXED
, 36 );
654 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
657 if ( !GetTokenInformation ( hToken
, TokenUser
, tu_buf
, 36, &tu_len
) || tu_len
> 36 )
659 LocalFree ( tu_buf
);
660 tu_buf
= LocalAlloc ( LMEM_FIXED
, tu_len
);
663 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
666 if ( !GetTokenInformation ( hToken
, TokenUser
, tu_buf
, tu_len
, &tu_len
) )
668 /* don't call SetLastError(),
669 as GetTokenInformation() ought to have set one */
670 LocalFree ( tu_buf
);
671 CloseHandle ( hToken
);
675 token_user
= (TOKEN_USER
*)tu_buf
;
679 domain_name
= LocalAlloc ( LMEM_FIXED
, dn_len
* sizeof(WCHAR
) );
682 LocalFree ( tu_buf
);
683 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
686 if ( !LookupAccountSidW ( NULL
, token_user
->User
.Sid
, lpszName
, &an_len
, domain_name
, &dn_len
, &snu
)
691 LocalFree ( domain_name
);
692 domain_name
= LocalAlloc ( LMEM_FIXED
, dn_len
* sizeof(WCHAR
) );
695 LocalFree ( tu_buf
);
696 SetLastError ( ERROR_NOT_ENOUGH_MEMORY
);
700 if ( !LookupAccountSidW ( NULL
, token_user
->User
.Sid
, lpszName
, &an_len
, domain_name
, &dn_len
, &snu
) )
702 /* don't call SetLastError(),
703 as LookupAccountSid() ought to have set one */
704 LocalFree ( domain_name
);
705 CloseHandle ( hToken
);
710 LocalFree ( domain_name
);
711 LocalFree ( tu_buf
);
712 CloseHandle ( hToken
);
714 if ( an_len
> *lpSize
)
717 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
725 /******************************************************************************
726 * LookupAccountSidA [ADVAPI32.@]
731 LookupAccountSidA (LPCSTR lpSystemName
,
735 LPSTR lpReferencedDomainName
,
736 LPDWORD cchReferencedDomainName
,
739 UNICODE_STRING NameW
, ReferencedDomainNameW
, SystemNameW
;
740 DWORD szName
, szReferencedDomainName
;
744 * save the buffer sizes the caller passed to us, as they may get modified and
745 * we require the original values when converting back to ansi
748 szReferencedDomainName
= *cchReferencedDomainName
;
751 * allocate buffers for the unicode strings to receive
757 NameW
.MaximumLength
= szName
* sizeof(WCHAR
);
758 NameW
.Buffer
= (PWSTR
)LocalAlloc(LMEM_FIXED
, NameW
.MaximumLength
);
759 if(NameW
.Buffer
== NULL
)
761 SetLastError(ERROR_OUTOFMEMORY
);
768 if(szReferencedDomainName
> 0)
770 ReferencedDomainNameW
.Length
= 0;
771 ReferencedDomainNameW
.MaximumLength
= szReferencedDomainName
* sizeof(WCHAR
);
772 ReferencedDomainNameW
.Buffer
= (PWSTR
)LocalAlloc(LMEM_FIXED
, ReferencedDomainNameW
.MaximumLength
);
773 if(ReferencedDomainNameW
.Buffer
== NULL
)
777 LocalFree(NameW
.Buffer
);
779 SetLastError(ERROR_OUTOFMEMORY
);
784 ReferencedDomainNameW
.Buffer
= NULL
;
787 * convert the system name to unicode - if present
790 if(lpSystemName
!= NULL
)
792 ANSI_STRING SystemNameA
;
794 RtlInitAnsiString(&SystemNameA
, lpSystemName
);
795 RtlAnsiStringToUnicodeString(&SystemNameW
, &SystemNameA
, TRUE
);
798 SystemNameW
.Buffer
= NULL
;
801 * it's time to call the unicode version
804 Ret
= LookupAccountSidW(SystemNameW
.Buffer
,
808 ReferencedDomainNameW
.Buffer
,
809 cchReferencedDomainName
,
814 * convert unicode strings back to ansi, don't forget that we can't convert
815 * more than 0xFFFF (USHORT) characters! Also don't forget to explicitly
816 * terminate the converted string, the Rtl functions don't do that!
823 NameA
.MaximumLength
= ((szName
<= 0xFFFF) ? (USHORT
)szName
: 0xFFFF);
824 NameA
.Buffer
= lpName
;
826 RtlUnicodeStringToAnsiString(&NameA
, &NameW
, FALSE
);
827 NameA
.Buffer
[NameA
.Length
] = '\0';
830 if(lpReferencedDomainName
!= NULL
)
832 ANSI_STRING ReferencedDomainNameA
;
834 ReferencedDomainNameA
.Length
= 0;
835 ReferencedDomainNameA
.MaximumLength
= ((szReferencedDomainName
<= 0xFFFF) ?
836 (USHORT
)szReferencedDomainName
: 0xFFFF);
837 ReferencedDomainNameA
.Buffer
= lpReferencedDomainName
;
839 RtlUnicodeStringToAnsiString(&ReferencedDomainNameA
, &ReferencedDomainNameW
, FALSE
);
840 ReferencedDomainNameA
.Buffer
[ReferencedDomainNameA
.Length
] = '\0';
845 * free previously allocated buffers
848 if(SystemNameW
.Buffer
!= NULL
)
850 RtlFreeUnicodeString(&SystemNameW
);
852 if(NameW
.Buffer
!= NULL
)
854 LocalFree(NameW
.Buffer
);
856 if(ReferencedDomainNameW
.Buffer
!= NULL
)
858 LocalFree(ReferencedDomainNameW
.Buffer
);
865 /******************************************************************************
866 * LookupAccountSidW [ADVAPI32.@]
875 LPDWORD pdwAccountName
,
877 LPDWORD pdwDomainName
,
878 PSID_NAME_USE peUse
)
880 LSA_UNICODE_STRING SystemName
;
881 LSA_OBJECT_ATTRIBUTES ObjectAttributes
= {0};
882 LSA_HANDLE PolicyHandle
= NULL
;
884 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain
= NULL
;
885 PLSA_TRANSLATED_NAME TranslatedName
= NULL
;
888 RtlInitUnicodeString ( &SystemName
, pSystemName
);
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 RtlCopyMemory ( pAccountName
, TranslatedName
->Name
.Buffer
, TranslatedName
->Name
.Length
);
919 pAccountName
[TranslatedName
->Name
.Length
/ sizeof(WCHAR
)] = L
'\0';
922 *peUse
= TranslatedName
->Use
;
925 if ( ReferencedDomain
)
927 if ( ReferencedDomain
->Entries
> 0 )
929 DWORD dwSrcLen
= ReferencedDomain
->Domains
[0].Name
.Length
/ sizeof(WCHAR
);
930 if ( *pdwDomainName
<= dwSrcLen
)
932 *pdwDomainName
= dwSrcLen
+ 1;
937 *pdwDomainName
= dwSrcLen
;
938 RtlCopyMemory ( pDomainName
, ReferencedDomain
->Domains
[0].Name
.Buffer
, ReferencedDomain
->Domains
[0].Name
.Length
);
939 pDomainName
[ReferencedDomain
->Domains
[0].Name
.Length
/ sizeof(WCHAR
)] = L
'\0';
945 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
948 if ( ReferencedDomain
)
949 LsaFreeMemory ( ReferencedDomain
);
950 if ( TranslatedName
)
951 LsaFreeMemory ( TranslatedName
);
958 /******************************************************************************
959 * LookupAccountNameA [ADVAPI32.@]
964 LookupAccountNameA (LPCSTR SystemName
,
968 LPSTR ReferencedDomainName
,
969 LPDWORD hReferencedDomainNameLength
,
970 PSID_NAME_USE SidNameUse
)
972 DPRINT1("LookupAccountNameA is unimplemented\n");
973 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
978 /******************************************************************************
979 * LookupAccountNameW [ADVAPI32.@]
984 LookupAccountNameW (LPCWSTR SystemName
,
988 LPWSTR ReferencedDomainName
,
989 LPDWORD hReferencedDomainNameLength
,
990 PSID_NAME_USE SidNameUse
)
992 DPRINT1("LookupAccountNameW is unimplemented\n");
993 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
998 /**********************************************************************
999 * LookupPrivilegeValueA EXPORTED
1004 LookupPrivilegeValueA (LPCSTR lpSystemName
,
1008 UNICODE_STRING SystemName
;
1009 UNICODE_STRING Name
;
1012 /* Remote system? */
1013 if (lpSystemName
!= NULL
)
1015 RtlCreateUnicodeStringFromAsciiz (&SystemName
,
1016 (LPSTR
)lpSystemName
);
1019 /* Check the privilege name is not NULL */
1022 SetLastError (ERROR_INVALID_PARAMETER
);
1026 RtlCreateUnicodeStringFromAsciiz (&Name
,
1029 Result
= LookupPrivilegeValueW ((lpSystemName
!= NULL
) ? SystemName
.Buffer
: NULL
,
1033 RtlFreeUnicodeString (&Name
);
1035 /* Remote system? */
1036 if (lpSystemName
!= NULL
)
1038 RtlFreeUnicodeString (&SystemName
);
1045 /**********************************************************************
1046 * LookupPrivilegeValueW EXPORTED
1051 LookupPrivilegeValueW (LPCWSTR SystemName
,
1055 static const WCHAR
* const DefaultPrivNames
[] =
1057 L
"SeCreateTokenPrivilege",
1058 L
"SeAssignPrimaryTokenPrivilege",
1059 L
"SeLockMemoryPrivilege",
1060 L
"SeIncreaseQuotaPrivilege",
1061 L
"SeUnsolicitedInputPrivilege",
1062 L
"SeMachineAccountPrivilege",
1064 L
"SeSecurityPrivilege",
1065 L
"SeTakeOwnershipPrivilege",
1066 L
"SeLoadDriverPrivilege",
1067 L
"SeSystemProfilePrivilege",
1068 L
"SeSystemtimePrivilege",
1069 L
"SeProfileSingleProcessPrivilege",
1070 L
"SeIncreaseBasePriorityPrivilege",
1071 L
"SeCreatePagefilePrivilege",
1072 L
"SeCreatePermanentPrivilege",
1073 L
"SeBackupPrivilege",
1074 L
"SeRestorePrivilege",
1075 L
"SeShutdownPrivilege",
1076 L
"SeDebugPrivilege",
1077 L
"SeAuditPrivilege",
1078 L
"SeSystemEnvironmentPrivilege",
1079 L
"SeChangeNotifyPrivilege",
1080 L
"SeRemoteShutdownPrivilege",
1081 L
"SeUndockPrivilege",
1082 L
"SeSyncAgentPrivilege",
1083 L
"SeEnableDelegationPrivilege",
1084 L
"SeManageVolumePrivilege",
1085 L
"SeImpersonatePrivilege",
1086 L
"SeCreateGlobalPrivilege"
1090 if (NULL
!= SystemName
&& L
'\0' != *SystemName
)
1092 DPRINT1("LookupPrivilegeValueW: not implemented for remote system\n");
1093 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1097 for (Priv
= 0; Priv
< sizeof(DefaultPrivNames
) / sizeof(DefaultPrivNames
[0]); Priv
++)
1099 if (0 == wcscmp(PrivName
, DefaultPrivNames
[Priv
]))
1101 Luid
->LowPart
= Priv
+ 1;
1107 DPRINT1("LookupPrivilegeValueW: no such privilege %S\n", PrivName
);
1108 SetLastError(ERROR_NO_SUCH_PRIVILEGE
);
1113 /**********************************************************************
1114 * LookupPrivilegeDisplayNameA EXPORTED
1119 LookupPrivilegeDisplayNameA (LPCSTR lpSystemName
,
1121 LPSTR lpDisplayName
,
1122 LPDWORD cbDisplayName
,
1123 LPDWORD lpLanguageId
)
1125 DPRINT1("LookupPrivilegeDisplayNameA: stub\n");
1126 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1131 /**********************************************************************
1132 * LookupPrivilegeDisplayNameW EXPORTED
1137 LookupPrivilegeDisplayNameW (LPCWSTR lpSystemName
,
1139 LPWSTR lpDisplayName
,
1140 LPDWORD cbDisplayName
,
1141 LPDWORD lpLanguageId
)
1143 DPRINT1("LookupPrivilegeDisplayNameW: stub\n");
1144 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1149 /**********************************************************************
1150 * LookupPrivilegeNameA EXPORTED
1155 LookupPrivilegeNameA (LPCSTR lpSystemName
,
1160 DPRINT1("LookupPrivilegeNameA: stub\n");
1161 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1166 /**********************************************************************
1167 * LookupPrivilegeNameW EXPORTED
1172 LookupPrivilegeNameW (LPCWSTR lpSystemName
,
1177 DPRINT1("LookupPrivilegeNameW: stub\n");
1178 SetLastError (ERROR_CALL_NOT_IMPLEMENTED
);
1184 pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo
,
1189 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
1191 if ((SecurityInfo
& (OWNER_SECURITY_INFORMATION
|
1192 GROUP_SECURITY_INFORMATION
|
1193 DACL_SECURITY_INFORMATION
|
1194 SACL_SECURITY_INFORMATION
)) &&
1195 ppSecurityDescriptor
== NULL
)
1197 /* if one of the SIDs or ACLs are present, the security descriptor
1199 return ERROR_INVALID_PARAMETER
;
1203 /* reset the pointers unless they're ignored */
1204 if ((SecurityInfo
& OWNER_SECURITY_INFORMATION
) &&
1209 if ((SecurityInfo
& GROUP_SECURITY_INFORMATION
) &&
1214 if ((SecurityInfo
& DACL_SECURITY_INFORMATION
) &&
1219 if ((SecurityInfo
& SACL_SECURITY_INFORMATION
) &&
1225 if (SecurityInfo
& (OWNER_SECURITY_INFORMATION
|
1226 GROUP_SECURITY_INFORMATION
|
1227 DACL_SECURITY_INFORMATION
|
1228 SACL_SECURITY_INFORMATION
))
1230 *ppSecurityDescriptor
= NULL
;
1233 return ERROR_SUCCESS
;
1239 pSetSecurityInfoCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor
,
1240 SECURITY_INFORMATION SecurityInfo
,
1246 /* initialize a security descriptor on the stack */
1247 if (!InitializeSecurityDescriptor(pSecurityDescriptor
,
1248 SECURITY_DESCRIPTOR_REVISION
))
1250 return GetLastError();
1253 if (SecurityInfo
& OWNER_SECURITY_INFORMATION
)
1255 if (RtlValidSid(psidOwner
))
1257 if (!SetSecurityDescriptorOwner(pSecurityDescriptor
,
1261 return GetLastError();
1266 return ERROR_INVALID_PARAMETER
;
1270 if (SecurityInfo
& GROUP_SECURITY_INFORMATION
)
1272 if (RtlValidSid(psidGroup
))
1274 if (!SetSecurityDescriptorGroup(pSecurityDescriptor
,
1278 return GetLastError();
1283 return ERROR_INVALID_PARAMETER
;
1287 if (SecurityInfo
& DACL_SECURITY_INFORMATION
)
1291 if (SetSecurityDescriptorDacl(pSecurityDescriptor
,
1296 /* check if the DACL needs to be protected from being
1297 modified by inheritable ACEs */
1298 if (SecurityInfo
& PROTECTED_DACL_SECURITY_INFORMATION
)
1305 return GetLastError();
1311 /* protect the DACL from being modified by inheritable ACEs */
1312 if (!SetSecurityDescriptorControl(pSecurityDescriptor
,
1316 return GetLastError();
1321 if (SecurityInfo
& SACL_SECURITY_INFORMATION
)
1325 if (SetSecurityDescriptorSacl(pSecurityDescriptor
,
1330 /* check if the SACL needs to be protected from being
1331 modified by inheritable ACEs */
1332 if (SecurityInfo
& PROTECTED_SACL_SECURITY_INFORMATION
)
1339 return GetLastError();
1345 /* protect the SACL from being modified by inheritable ACEs */
1346 if (!SetSecurityDescriptorControl(pSecurityDescriptor
,
1350 return GetLastError();
1355 return ERROR_SUCCESS
;
1359 /**********************************************************************
1360 * GetNamedSecurityInfoW EXPORTED
1365 GetNamedSecurityInfoW(LPWSTR pObjectName
,
1366 SE_OBJECT_TYPE ObjectType
,
1367 SECURITY_INFORMATION SecurityInfo
,
1372 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1376 if (pObjectName
!= NULL
)
1378 ErrorCode
= CheckNtMartaPresent();
1379 if (ErrorCode
== ERROR_SUCCESS
)
1381 ErrorCode
= pGetSecurityInfoCheck(SecurityInfo
,
1386 ppSecurityDescriptor
);
1388 if (ErrorCode
== ERROR_SUCCESS
)
1390 /* call the MARTA provider */
1391 ErrorCode
= AccRewriteGetNamedRights(pObjectName
,
1398 ppSecurityDescriptor
);
1403 ErrorCode
= ERROR_INVALID_PARAMETER
;
1409 /**********************************************************************
1410 * GetNamedSecurityInfoA EXPORTED
1415 GetNamedSecurityInfoA(LPSTR pObjectName
,
1416 SE_OBJECT_TYPE ObjectType
,
1417 SECURITY_INFORMATION SecurityInfo
,
1422 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1424 UNICODE_STRING ObjectName
;
1428 Status
= RtlCreateUnicodeStringFromAsciiz(&ObjectName
,
1430 if (!NT_SUCCESS(Status
))
1432 return RtlNtStatusToDosError(Status
);
1435 Ret
= GetNamedSecurityInfoW(ObjectName
.Buffer
,
1442 ppSecurityDescriptor
);
1444 RtlFreeUnicodeString(&ObjectName
);
1450 /**********************************************************************
1451 * SetNamedSecurityInfoW EXPORTED
1456 SetNamedSecurityInfoW(LPWSTR pObjectName
,
1457 SE_OBJECT_TYPE ObjectType
,
1458 SECURITY_INFORMATION SecurityInfo
,
1466 if (pObjectName
!= NULL
)
1468 ErrorCode
= CheckNtMartaPresent();
1469 if (ErrorCode
== ERROR_SUCCESS
)
1471 SECURITY_DESCRIPTOR SecurityDescriptor
;
1473 ErrorCode
= pSetSecurityInfoCheck(&SecurityDescriptor
,
1480 if (ErrorCode
== ERROR_SUCCESS
)
1482 /* call the MARTA provider */
1483 ErrorCode
= AccRewriteSetNamedRights(pObjectName
,
1486 &SecurityDescriptor
);
1491 ErrorCode
= ERROR_INVALID_PARAMETER
;
1497 /**********************************************************************
1498 * SetNamedSecurityInfoA EXPORTED
1503 SetNamedSecurityInfoA(LPSTR pObjectName
,
1504 SE_OBJECT_TYPE ObjectType
,
1505 SECURITY_INFORMATION SecurityInfo
,
1511 UNICODE_STRING ObjectName
;
1515 Status
= RtlCreateUnicodeStringFromAsciiz(&ObjectName
,
1517 if (!NT_SUCCESS(Status
))
1519 return RtlNtStatusToDosError(Status
);
1522 Ret
= SetNamedSecurityInfoW(ObjectName
.Buffer
,
1530 RtlFreeUnicodeString(&ObjectName
);
1536 /**********************************************************************
1537 * GetSecurityInfo EXPORTED
1542 GetSecurityInfo(HANDLE handle
,
1543 SE_OBJECT_TYPE ObjectType
,
1544 SECURITY_INFORMATION SecurityInfo
,
1549 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
1555 ErrorCode
= CheckNtMartaPresent();
1556 if (ErrorCode
== ERROR_SUCCESS
)
1558 ErrorCode
= pGetSecurityInfoCheck(SecurityInfo
,
1563 ppSecurityDescriptor
);
1565 if (ErrorCode
== ERROR_SUCCESS
)
1567 /* call the MARTA provider */
1568 ErrorCode
= AccRewriteGetHandleRights(handle
,
1575 ppSecurityDescriptor
);
1580 ErrorCode
= ERROR_INVALID_HANDLE
;
1586 /**********************************************************************
1587 * SetSecurityInfo EXPORTED
1593 SetSecurityInfo(HANDLE handle
,
1594 SE_OBJECT_TYPE ObjectType
,
1595 SECURITY_INFORMATION SecurityInfo
,
1605 ErrorCode
= CheckNtMartaPresent();
1606 if (ErrorCode
== ERROR_SUCCESS
)
1608 SECURITY_DESCRIPTOR SecurityDescriptor
;
1610 ErrorCode
= pSetSecurityInfoCheck(&SecurityDescriptor
,
1617 if (ErrorCode
== ERROR_SUCCESS
)
1619 /* call the MARTA provider */
1620 ErrorCode
= AccRewriteSetHandleRights(handle
,
1623 &SecurityDescriptor
);
1628 ErrorCode
= ERROR_INVALID_HANDLE
;
1634 /******************************************************************************
1635 * GetSecurityInfoExW EXPORTED
1637 DWORD WINAPI
GetSecurityInfoExA(
1639 SE_OBJECT_TYPE ObjectType
,
1640 SECURITY_INFORMATION SecurityInfo
,
1643 PACTRL_ACCESSA
*ppAccessList
,
1644 PACTRL_AUDITA
*ppAuditList
,
1649 DPRINT1("GetSecurityInfoExA stub!\n");
1650 return ERROR_BAD_PROVIDER
;
1654 /******************************************************************************
1655 * GetSecurityInfoExW EXPORTED
1657 DWORD WINAPI
GetSecurityInfoExW(
1659 SE_OBJECT_TYPE ObjectType
,
1660 SECURITY_INFORMATION SecurityInfo
,
1663 PACTRL_ACCESSW
*ppAccessList
,
1664 PACTRL_AUDITW
*ppAuditList
,
1669 DPRINT1("GetSecurityInfoExW stub!\n");
1670 return ERROR_BAD_PROVIDER
;
1674 /**********************************************************************
1675 * ImpersonateNamedPipeClient EXPORTED
1680 ImpersonateNamedPipeClient(HANDLE hNamedPipe
)
1682 IO_STATUS_BLOCK StatusBlock
;
1685 DPRINT("ImpersonateNamedPipeClient() called\n");
1687 Status
= NtFsControlFile(hNamedPipe
,
1692 FSCTL_PIPE_IMPERSONATE
,
1697 if (!NT_SUCCESS(Status
))
1699 SetLastError(RtlNtStatusToDosError(Status
));
1711 CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor
,
1712 PSECURITY_DESCRIPTOR CreatorDescriptor
,
1713 PSECURITY_DESCRIPTOR
*NewDescriptor
,
1714 BOOL IsDirectoryObject
,
1716 PGENERIC_MAPPING GenericMapping
)
1720 Status
= RtlNewSecurityObject(ParentDescriptor
,
1726 if (!NT_SUCCESS(Status
))
1728 SetLastError(RtlNtStatusToDosError(Status
));
1740 CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor
,
1741 PSECURITY_DESCRIPTOR CreatorDescriptor
,
1742 PSECURITY_DESCRIPTOR
* NewDescriptor
,
1744 BOOL IsContainerObject
,
1745 ULONG AutoInheritFlags
,
1747 PGENERIC_MAPPING GenericMapping
)
1749 DPRINT1("%s() not implemented!\n", __FUNCTION__
);
1758 CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor
,
1759 PSECURITY_DESCRIPTOR CreatorDescriptor
,
1760 PSECURITY_DESCRIPTOR
* NewDescriptor
,
1763 BOOL IsContainerObject
,
1764 ULONG AutoInheritFlags
,
1766 PGENERIC_MAPPING GenericMapping
)
1768 DPRINT1("%s() not implemented!\n", __FUNCTION__
);
1777 DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR
*ObjectDescriptor
)
1781 Status
= RtlDeleteSecurityObject(ObjectDescriptor
);
1782 if (!NT_SUCCESS(Status
))
1784 SetLastError(RtlNtStatusToDosError(Status
));
1796 GetPrivateObjectSecurity(PSECURITY_DESCRIPTOR ObjectDescriptor
,
1797 SECURITY_INFORMATION SecurityInformation
,
1798 PSECURITY_DESCRIPTOR ResultantDescriptor
,
1799 DWORD DescriptorLength
,
1800 PDWORD ReturnLength
)
1804 Status
= RtlQuerySecurityObject(ObjectDescriptor
,
1805 SecurityInformation
,
1806 ResultantDescriptor
,
1809 if (!NT_SUCCESS(Status
))
1811 SetLastError(RtlNtStatusToDosError(Status
));
1823 SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation
,
1824 PSECURITY_DESCRIPTOR ModificationDescriptor
,
1825 PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
1826 PGENERIC_MAPPING GenericMapping
,
1831 Status
= RtlSetSecurityObject(SecurityInformation
,
1832 ModificationDescriptor
,
1833 ObjectsSecurityDescriptor
,
1836 if (!NT_SUCCESS(Status
))
1838 SetLastError(RtlNtStatusToDosError(Status
));
1850 TreeResetNamedSecurityInfoW(LPWSTR pObjectName
,
1851 SE_OBJECT_TYPE ObjectType
,
1852 SECURITY_INFORMATION SecurityInfo
,
1858 FN_PROGRESSW fnProgress
,
1859 PROG_INVOKE_SETTING ProgressInvokeSetting
,
1864 if (pObjectName
!= NULL
)
1866 ErrorCode
= CheckNtMartaPresent();
1867 if (ErrorCode
== ERROR_SUCCESS
)
1871 case SE_FILE_OBJECT
:
1872 case SE_REGISTRY_KEY
:
1874 /* check the SecurityInfo flags for sanity (both, the protected
1875 and unprotected dacl/sacl flag must not be passed together) */
1876 if (((SecurityInfo
& DACL_SECURITY_INFORMATION
) &&
1877 (SecurityInfo
& (PROTECTED_DACL_SECURITY_INFORMATION
| UNPROTECTED_DACL_SECURITY_INFORMATION
)) ==
1878 (PROTECTED_DACL_SECURITY_INFORMATION
| UNPROTECTED_DACL_SECURITY_INFORMATION
))
1882 ((SecurityInfo
& SACL_SECURITY_INFORMATION
) &&
1883 (SecurityInfo
& (PROTECTED_SACL_SECURITY_INFORMATION
| UNPROTECTED_SACL_SECURITY_INFORMATION
)) ==
1884 (PROTECTED_SACL_SECURITY_INFORMATION
| UNPROTECTED_SACL_SECURITY_INFORMATION
)))
1886 ErrorCode
= ERROR_INVALID_PARAMETER
;
1890 /* call the MARTA provider */
1891 ErrorCode
= AccTreeResetNamedSecurityInfo(pObjectName
,
1900 ProgressInvokeSetting
,
1906 /* object type not supported */
1907 ErrorCode
= ERROR_INVALID_PARAMETER
;
1913 ErrorCode
= ERROR_INVALID_PARAMETER
;
1923 TreeResetNamedSecurityInfoA(LPSTR pObjectName
,
1924 SE_OBJECT_TYPE ObjectType
,
1925 SECURITY_INFORMATION SecurityInfo
,
1931 FN_PROGRESSA fnProgress
,
1932 PROG_INVOKE_SETTING ProgressInvokeSetting
,
1935 /* That's all this function does, at least up to w2k3... Even MS was too
1936 lazy to implement it... */
1937 return ERROR_CALL_NOT_IMPLEMENTED
;