2 * COPYRIGHT: See COPYING in the top level directory
4 * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
5 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
6 * Copyright 2006 Robert Reif
8 * PROJECT: ReactOS system libraries
9 * FILE: dll/win32/advapi32/sec/misc.c
10 * PURPOSE: Miscellaneous security functions (some ported from Wine)
15 WINE_DEFAULT_DEBUG_CHANNEL(advapi
);
17 /* Interface to ntmarta.dll ***************************************************/
19 NTMARTA NtMartaStatic
= { 0 };
20 static PNTMARTA NtMarta
= NULL
;
22 #define FindNtMartaProc(Name) \
23 NtMartaStatic.Name = (PVOID)GetProcAddress(NtMartaStatic.hDllInstance, \
25 if (NtMartaStatic.Name == NULL) \
27 return GetLastError(); \
32 LoadAndInitializeNtMarta(VOID
)
34 /* this code may be executed simultaneously by multiple threads in case they're
35 trying to initialize the interface at the same time, but that's no problem
36 because the pointers returned by GetProcAddress will be the same. However,
37 only one of the threads will change the NtMarta pointer to the NtMartaStatic
38 structure, the others threads will detect that there were other threads
39 initializing the structure faster and will release the reference to the
42 NtMartaStatic
.hDllInstance
= LoadLibraryW(L
"ntmarta.dll");
43 if (NtMartaStatic
.hDllInstance
== NULL
)
45 return GetLastError();
49 FindNtMartaProc(LookupAccountTrustee
);
50 FindNtMartaProc(LookupAccountName
);
51 FindNtMartaProc(LookupAccountSid
);
52 FindNtMartaProc(SetEntriesInAList
);
53 FindNtMartaProc(ConvertAccessToSecurityDescriptor
);
54 FindNtMartaProc(ConvertSDToAccess
);
55 FindNtMartaProc(ConvertAclToAccess
);
56 FindNtMartaProc(GetAccessForTrustee
);
57 FindNtMartaProc(GetExplicitEntries
);
59 FindNtMartaProc(RewriteGetNamedRights
);
60 FindNtMartaProc(RewriteSetNamedRights
);
61 FindNtMartaProc(RewriteGetHandleRights
);
62 FindNtMartaProc(RewriteSetHandleRights
);
63 FindNtMartaProc(RewriteSetEntriesInAcl
);
64 FindNtMartaProc(RewriteGetExplicitEntriesFromAcl
);
65 FindNtMartaProc(TreeResetNamedSecurityInfo
);
66 FindNtMartaProc(GetInheritanceSource
);
67 FindNtMartaProc(FreeIndexArray
);
74 CheckNtMartaPresent(VOID
)
78 if (InterlockedCompareExchangePointer((PVOID
)&NtMarta
,
82 /* we're the first one trying to use ntmarta, initialize it and change
83 the pointer after initialization */
84 ErrorCode
= LoadAndInitializeNtMarta();
86 if (ErrorCode
== ERROR_SUCCESS
)
88 /* try change the NtMarta pointer */
89 if (InterlockedCompareExchangePointer((PVOID
)&NtMarta
,
93 /* another thread initialized ntmarta in the meanwhile, release
94 the reference of the dll loaded. */
95 FreeLibrary(NtMartaStatic
.hDllInstance
);
101 ERR("Failed to initialize ntmarta.dll! Error: 0x%x", ErrorCode
);
107 /* ntmarta was already initialized */
108 ErrorCode
= ERROR_SUCCESS
;
118 if (InterlockedExchangePointer((PVOID
)&NtMarta
,
121 FreeLibrary(NtMartaStatic
.hDllInstance
);
126 /******************************************************************************/
133 ImpersonateAnonymousToken(IN HANDLE ThreadHandle
)
137 Status
= NtImpersonateAnonymousToken(ThreadHandle
);
138 if (!NT_SUCCESS(Status
))
140 SetLastError(RtlNtStatusToDosError(Status
));
152 ImpersonateLoggedOnUser(HANDLE hToken
)
154 SECURITY_QUALITY_OF_SERVICE Qos
;
155 OBJECT_ATTRIBUTES ObjectAttributes
;
162 /* Get the token type */
163 Status
= NtQueryInformationToken(hToken
,
168 if (!NT_SUCCESS(Status
))
170 SetLastError(RtlNtStatusToDosError(Status
));
174 if (Type
== TokenPrimary
)
176 /* Create a duplicate impersonation token */
177 Qos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
178 Qos
.ImpersonationLevel
= SecurityImpersonation
;
179 Qos
.ContextTrackingMode
= SECURITY_DYNAMIC_TRACKING
;
180 Qos
.EffectiveOnly
= FALSE
;
182 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
183 ObjectAttributes
.RootDirectory
= NULL
;
184 ObjectAttributes
.ObjectName
= NULL
;
185 ObjectAttributes
.Attributes
= 0;
186 ObjectAttributes
.SecurityDescriptor
= NULL
;
187 ObjectAttributes
.SecurityQualityOfService
= &Qos
;
189 Status
= NtDuplicateToken(hToken
,
190 TOKEN_IMPERSONATE
| TOKEN_QUERY
,
195 if (!NT_SUCCESS(Status
))
197 ERR("NtDuplicateToken failed: Status %08x\n", Status
);
198 SetLastError(RtlNtStatusToDosError(Status
));
206 /* User the original impersonation token */
211 /* Impersonate the the current thread */
212 Status
= NtSetInformationThread(NtCurrentThread(),
213 ThreadImpersonationToken
,
217 if (Duplicated
== TRUE
)
222 if (!NT_SUCCESS(Status
))
224 ERR("NtSetInformationThread failed: Status %08x\n", Status
);
225 SetLastError(RtlNtStatusToDosError(Status
));
232 /******************************************************************************
233 * GetUserNameA [ADVAPI32.@]
235 * Get the current user name.
238 * lpszName [O] Destination for the user name.
239 * lpSize [I/O] Size of lpszName.
246 GetUserNameA(LPSTR lpszName
,
249 UNICODE_STRING NameW
;
253 /* apparently Win doesn't check whether lpSize is valid at all! */
255 NameW
.MaximumLength
= (*lpSize
) * sizeof(WCHAR
);
256 NameW
.Buffer
= LocalAlloc(LMEM_FIXED
, NameW
.MaximumLength
);
257 if(NameW
.Buffer
== NULL
)
259 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
264 NameA
.MaximumLength
= ((*lpSize
) < 0xFFFF ? (USHORT
)(*lpSize
) : 0xFFFF);
265 NameA
.Buffer
= lpszName
;
267 Ret
= GetUserNameW(NameW
.Buffer
,
271 NameW
.Length
= (*lpSize
- 1) * sizeof(WCHAR
);
272 RtlUnicodeStringToAnsiString(&NameA
, &NameW
, FALSE
);
274 *lpSize
= NameA
.Length
+ 1;
277 LocalFree(NameW
.Buffer
);
282 /******************************************************************************
283 * GetUserNameW [ADVAPI32.@]
291 GetUserNameW(LPWSTR lpszName
,
294 HANDLE hToken
= INVALID_HANDLE_VALUE
;
297 TOKEN_USER
* token_user
= NULL
;
299 SID_NAME_USE snu
= SidTypeUser
;
300 WCHAR
* domain_name
= NULL
;
303 if (!OpenThreadToken (GetCurrentThread(), TOKEN_QUERY
, FALSE
, &hToken
))
305 DWORD dwLastError
= GetLastError();
306 if (dwLastError
!= ERROR_NO_TOKEN
307 && dwLastError
!= ERROR_NO_IMPERSONATION_TOKEN
)
309 /* don't call SetLastError(),
310 as OpenThreadToken() ought to have set one */
314 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
, &hToken
))
316 /* don't call SetLastError(),
317 as OpenProcessToken() ought to have set one */
322 tu_buf
= LocalAlloc(LMEM_FIXED
, 36);
325 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
330 if (!GetTokenInformation(hToken
, TokenUser
, tu_buf
, 36, &tu_len
) || tu_len
> 36)
333 tu_buf
= LocalAlloc(LMEM_FIXED
, tu_len
);
336 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
341 if (!GetTokenInformation(hToken
, TokenUser
, tu_buf
, tu_len
, &tu_len
))
343 /* don't call SetLastError(),
344 as GetTokenInformation() ought to have set one */
352 token_user
= (TOKEN_USER
*)tu_buf
;
356 domain_name
= LocalAlloc(LMEM_FIXED
, dn_len
* sizeof(WCHAR
));
360 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
364 if (!LookupAccountSidW(NULL
, token_user
->User
.Sid
, lpszName
, &an_len
, domain_name
, &dn_len
, &snu
)
369 LocalFree(domain_name
);
370 domain_name
= LocalAlloc(LMEM_FIXED
, dn_len
* sizeof(WCHAR
));
374 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
380 if (!LookupAccountSidW(NULL
, token_user
->User
.Sid
, lpszName
, &an_len
, domain_name
, &dn_len
, &snu
))
382 /* don't call SetLastError(),
383 as LookupAccountSid() ought to have set one */
384 LocalFree(domain_name
);
391 LocalFree(domain_name
);
393 *lpSize
= an_len
+ 1;
398 /******************************************************************************
399 * LookupAccountSidA [ADVAPI32.@]
405 LookupAccountSidA(LPCSTR lpSystemName
,
409 LPSTR lpReferencedDomainName
,
410 LPDWORD cchReferencedDomainName
,
413 UNICODE_STRING NameW
, ReferencedDomainNameW
, SystemNameW
;
414 LPWSTR NameBuffer
= NULL
;
415 LPWSTR ReferencedDomainNameBuffer
= NULL
;
416 DWORD dwName
, dwReferencedDomainName
;
420 * save the buffer sizes the caller passed to us, as they may get modified and
421 * we require the original values when converting back to ansi
424 dwReferencedDomainName
= *cchReferencedDomainName
;
426 /* allocate buffers for the unicode strings to receive */
429 NameBuffer
= LocalAlloc(LMEM_FIXED
, dwName
* sizeof(WCHAR
));
430 if (NameBuffer
== NULL
)
432 SetLastError(ERROR_OUTOFMEMORY
);
439 if (dwReferencedDomainName
> 0)
441 ReferencedDomainNameBuffer
= LocalAlloc(LMEM_FIXED
, dwReferencedDomainName
* sizeof(WCHAR
));
442 if (ReferencedDomainNameBuffer
== NULL
)
446 LocalFree(NameBuffer
);
449 SetLastError(ERROR_OUTOFMEMORY
);
454 ReferencedDomainNameBuffer
= NULL
;
457 /* convert the system name to unicode - if present */
458 if (lpSystemName
!= NULL
)
460 ANSI_STRING SystemNameA
;
462 RtlInitAnsiString(&SystemNameA
, lpSystemName
);
463 RtlAnsiStringToUnicodeString(&SystemNameW
, &SystemNameA
, TRUE
);
466 SystemNameW
.Buffer
= NULL
;
468 /* it's time to call the unicode version */
469 Ret
= LookupAccountSidW(SystemNameW
.Buffer
,
473 ReferencedDomainNameBuffer
,
474 cchReferencedDomainName
,
479 * convert unicode strings back to ansi, don't forget that we can't convert
480 * more than 0xFFFF (USHORT) characters! Also don't forget to explicitly
481 * terminate the converted string, the Rtl functions don't do that!
488 NameA
.MaximumLength
= ((dwName
<= 0xFFFF) ? (USHORT
)dwName
: 0xFFFF);
489 NameA
.Buffer
= lpName
;
491 RtlInitUnicodeString(&NameW
, NameBuffer
);
492 RtlUnicodeStringToAnsiString(&NameA
, &NameW
, FALSE
);
493 NameA
.Buffer
[NameA
.Length
] = '\0';
496 if (lpReferencedDomainName
!= NULL
)
498 ANSI_STRING ReferencedDomainNameA
;
500 ReferencedDomainNameA
.Length
= 0;
501 ReferencedDomainNameA
.MaximumLength
= ((dwReferencedDomainName
<= 0xFFFF) ?
502 (USHORT
)dwReferencedDomainName
: 0xFFFF);
503 ReferencedDomainNameA
.Buffer
= lpReferencedDomainName
;
505 RtlInitUnicodeString(&ReferencedDomainNameW
, ReferencedDomainNameBuffer
);
506 RtlUnicodeStringToAnsiString(&ReferencedDomainNameA
, &ReferencedDomainNameW
, FALSE
);
507 ReferencedDomainNameA
.Buffer
[ReferencedDomainNameA
.Length
] = '\0';
511 /* free previously allocated buffers */
512 if (SystemNameW
.Buffer
!= NULL
)
514 RtlFreeUnicodeString(&SystemNameW
);
517 if (NameBuffer
!= NULL
)
519 LocalFree(NameBuffer
);
522 if (ReferencedDomainNameBuffer
!= NULL
)
524 LocalFree(ReferencedDomainNameBuffer
);
531 /******************************************************************************
532 * LookupAccountSidW [ADVAPI32.@]
537 LookupAccountSidW(LPCWSTR pSystemName
,
540 LPDWORD pdwAccountName
,
542 LPDWORD pdwDomainName
,
545 LSA_UNICODE_STRING SystemName
;
546 LSA_OBJECT_ATTRIBUTES ObjectAttributes
= {0};
547 LSA_HANDLE PolicyHandle
= NULL
;
549 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain
= NULL
;
550 PLSA_TRANSLATED_NAME TranslatedName
= NULL
;
552 DWORD dwAccountName
, dwDomainName
;
554 RtlInitUnicodeString(&SystemName
, pSystemName
);
555 Status
= LsaOpenPolicy(&SystemName
, &ObjectAttributes
, POLICY_LOOKUP_NAMES
, &PolicyHandle
);
556 if (!NT_SUCCESS(Status
))
558 SetLastError(LsaNtStatusToWinError(Status
));
562 Status
= LsaLookupSids(PolicyHandle
, 1, &pSid
, &ReferencedDomain
, &TranslatedName
);
564 LsaClose(PolicyHandle
);
566 if (!NT_SUCCESS(Status
) || Status
== STATUS_SOME_NOT_MAPPED
)
568 SetLastError(LsaNtStatusToWinError(Status
));
575 dwAccountName
= TranslatedName
->Name
.Length
/ sizeof(WCHAR
);
576 if (ReferencedDomain
&& ReferencedDomain
->Entries
> 0)
577 dwDomainName
= ReferencedDomain
->Domains
[0].Name
.Length
/ sizeof(WCHAR
);
581 if (*pdwAccountName
<= dwAccountName
|| *pdwDomainName
<= dwDomainName
)
583 /* One or two buffers are insufficient, add up a char for NULL termination */
584 *pdwAccountName
= dwAccountName
+ 1;
585 *pdwDomainName
= dwDomainName
+ 1;
590 /* Lengths are sufficient, copy the data */
592 RtlCopyMemory(pAccountName
, TranslatedName
->Name
.Buffer
, dwAccountName
* sizeof(WCHAR
));
593 pAccountName
[dwAccountName
] = L
'\0';
596 RtlCopyMemory(pDomainName
, ReferencedDomain
->Domains
[0].Name
.Buffer
, dwDomainName
* sizeof(WCHAR
));
597 pDomainName
[dwDomainName
] = L
'\0';
599 *pdwAccountName
= dwAccountName
;
600 *pdwDomainName
= dwDomainName
;
603 *peUse
= TranslatedName
->Use
;
607 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
610 if (ReferencedDomain
)
611 LsaFreeMemory(ReferencedDomain
);
614 LsaFreeMemory(TranslatedName
);
619 /******************************************************************************
620 * LookupAccountNameW [ADVAPI32.@]
626 LookupAccountNameW(LPCWSTR lpSystemName
,
627 LPCWSTR lpAccountName
,
630 LPWSTR ReferencedDomainName
,
631 LPDWORD cchReferencedDomainName
,
634 OBJECT_ATTRIBUTES ObjectAttributes
= {0};
635 UNICODE_STRING SystemName
;
636 UNICODE_STRING AccountName
;
637 LSA_HANDLE PolicyHandle
= NULL
;
638 PLSA_REFERENCED_DOMAIN_LIST ReferencedDomains
= NULL
;
639 PLSA_TRANSLATED_SID TranslatedSid
= NULL
;
641 DWORD dwDomainNameLength
;
643 UCHAR nSubAuthorities
;
647 TRACE("%s %s %p %p %p %p %p\n", lpSystemName
, lpAccountName
,
648 Sid
, cbSid
, ReferencedDomainName
, cchReferencedDomainName
, peUse
);
650 RtlInitUnicodeString(&SystemName
,
653 Status
= LsaOpenPolicy(lpSystemName
? &SystemName
: NULL
,
657 if (!NT_SUCCESS(Status
))
659 SetLastError(LsaNtStatusToWinError(Status
));
663 RtlInitUnicodeString(&AccountName
,
666 Status
= LsaLookupNames(PolicyHandle
,
672 LsaClose(PolicyHandle
);
674 if (!NT_SUCCESS(Status
) || Status
== STATUS_SOME_NOT_MAPPED
)
676 SetLastError(LsaNtStatusToWinError(Status
));
681 pDomainSid
= ReferencedDomains
->Domains
[TranslatedSid
->DomainIndex
].Sid
;
682 nSubAuthorities
= *GetSidSubAuthorityCount(pDomainSid
);
683 dwSidLength
= GetSidLengthRequired(nSubAuthorities
+ 1);
685 dwDomainNameLength
= ReferencedDomains
->Domains
->Name
.Length
/ sizeof(WCHAR
);
687 if (*cbSid
< dwSidLength
||
688 *cchReferencedDomainName
< dwDomainNameLength
+ 1)
690 *cbSid
= dwSidLength
;
691 *cchReferencedDomainName
= dwDomainNameLength
+ 1;
697 CopySid(*cbSid
, Sid
, pDomainSid
);
698 *GetSidSubAuthorityCount(Sid
) = nSubAuthorities
+ 1;
699 *GetSidSubAuthority(Sid
, (DWORD
)nSubAuthorities
) = TranslatedSid
->RelativeId
;
701 RtlCopyMemory(ReferencedDomainName
, ReferencedDomains
->Domains
->Name
.Buffer
, dwDomainNameLength
* sizeof(WCHAR
));
702 ReferencedDomainName
[dwDomainNameLength
] = L
'\0';
704 *cchReferencedDomainName
= dwDomainNameLength
;
706 *peUse
= TranslatedSid
->Use
;
711 if (bResult
== FALSE
)
712 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
715 if (ReferencedDomains
!= NULL
)
716 LsaFreeMemory(ReferencedDomains
);
718 if (TranslatedSid
!= NULL
)
719 LsaFreeMemory(TranslatedSid
);
725 /**********************************************************************
726 * LookupPrivilegeValueA EXPORTED
732 LookupPrivilegeValueA(LPCSTR lpSystemName
,
736 UNICODE_STRING SystemName
;
741 if (lpSystemName
!= NULL
)
743 RtlCreateUnicodeStringFromAsciiz(&SystemName
,
744 (LPSTR
)lpSystemName
);
747 SystemName
.Buffer
= NULL
;
749 /* Check the privilege name is not NULL */
752 SetLastError(ERROR_NO_SUCH_PRIVILEGE
);
756 RtlCreateUnicodeStringFromAsciiz(&Name
,
759 Result
= LookupPrivilegeValueW(SystemName
.Buffer
,
763 RtlFreeUnicodeString(&Name
);
766 if (SystemName
.Buffer
!= NULL
)
768 RtlFreeUnicodeString(&SystemName
);
775 /**********************************************************************
776 * LookupPrivilegeValueW
782 LookupPrivilegeValueW(LPCWSTR lpSystemName
,
783 LPCWSTR lpPrivilegeName
,
786 OBJECT_ATTRIBUTES ObjectAttributes
= {0};
787 UNICODE_STRING SystemName
;
788 UNICODE_STRING PrivilegeName
;
789 LSA_HANDLE PolicyHandle
= NULL
;
792 TRACE("%S,%S,%p\n", lpSystemName
, lpPrivilegeName
, lpLuid
);
794 RtlInitUnicodeString(&SystemName
,
797 Status
= LsaOpenPolicy(lpSystemName
? &SystemName
: NULL
,
801 if (!NT_SUCCESS(Status
))
803 SetLastError(LsaNtStatusToWinError(Status
));
807 RtlInitUnicodeString(&PrivilegeName
,
810 Status
= LsaLookupPrivilegeValue(PolicyHandle
,
814 LsaClose(PolicyHandle
);
816 if (!NT_SUCCESS(Status
))
818 SetLastError(LsaNtStatusToWinError(Status
));
825 /**********************************************************************
826 * LookupPrivilegeNameW EXPORTED
832 LookupPrivilegeNameW(LPCWSTR lpSystemName
,
837 OBJECT_ATTRIBUTES ObjectAttributes
= {0};
838 UNICODE_STRING SystemName
;
839 PUNICODE_STRING PrivilegeName
= NULL
;
840 LSA_HANDLE PolicyHandle
= NULL
;
843 TRACE("%S,%p,%p,%p\n", lpSystemName
, lpLuid
, lpName
, cchName
);
845 RtlInitUnicodeString(&SystemName
,
848 Status
= LsaOpenPolicy(lpSystemName
? &SystemName
: NULL
,
852 if (!NT_SUCCESS(Status
))
854 SetLastError(LsaNtStatusToWinError(Status
));
858 Status
= LsaLookupPrivilegeName(PolicyHandle
,
861 if (NT_SUCCESS(Status
))
863 if (PrivilegeName
->Length
+ sizeof(WCHAR
) > *cchName
* sizeof(WCHAR
))
865 Status
= STATUS_BUFFER_TOO_SMALL
;
867 *cchName
= (PrivilegeName
->Length
+ sizeof(WCHAR
)) / sizeof(WCHAR
);
871 RtlMoveMemory(lpName
,
872 PrivilegeName
->Buffer
,
873 PrivilegeName
->Length
);
874 lpName
[PrivilegeName
->Length
/ sizeof(WCHAR
)] = 0;
876 *cchName
= PrivilegeName
->Length
/ sizeof(WCHAR
);
879 LsaFreeMemory(PrivilegeName
->Buffer
);
880 LsaFreeMemory(PrivilegeName
);
883 LsaClose(PolicyHandle
);
885 if (!NT_SUCCESS(Status
))
887 SetLastError(LsaNtStatusToWinError(Status
));
896 pGetSecurityInfoCheck(SECURITY_INFORMATION SecurityInfo
,
901 PSECURITY_DESCRIPTOR
* ppSecurityDescriptor
)
903 if ((SecurityInfo
& (OWNER_SECURITY_INFORMATION
|
904 GROUP_SECURITY_INFORMATION
|
905 DACL_SECURITY_INFORMATION
|
906 SACL_SECURITY_INFORMATION
)) &&
907 ppSecurityDescriptor
== NULL
)
909 /* if one of the SIDs or ACLs are present, the security descriptor
911 return ERROR_INVALID_PARAMETER
;
915 /* reset the pointers unless they're ignored */
916 if ((SecurityInfo
& OWNER_SECURITY_INFORMATION
) &&
921 if ((SecurityInfo
& GROUP_SECURITY_INFORMATION
) &&
926 if ((SecurityInfo
& DACL_SECURITY_INFORMATION
) &&
931 if ((SecurityInfo
& SACL_SECURITY_INFORMATION
) &&
937 if (SecurityInfo
& (OWNER_SECURITY_INFORMATION
|
938 GROUP_SECURITY_INFORMATION
|
939 DACL_SECURITY_INFORMATION
|
940 SACL_SECURITY_INFORMATION
))
942 *ppSecurityDescriptor
= NULL
;
945 return ERROR_SUCCESS
;
951 pSetSecurityInfoCheck(PSECURITY_DESCRIPTOR pSecurityDescriptor
,
952 SECURITY_INFORMATION SecurityInfo
,
958 /* initialize a security descriptor on the stack */
959 if (!InitializeSecurityDescriptor(pSecurityDescriptor
,
960 SECURITY_DESCRIPTOR_REVISION
))
962 return GetLastError();
965 if (SecurityInfo
& OWNER_SECURITY_INFORMATION
)
967 if (RtlValidSid(psidOwner
))
969 if (!SetSecurityDescriptorOwner(pSecurityDescriptor
,
973 return GetLastError();
978 return ERROR_INVALID_PARAMETER
;
982 if (SecurityInfo
& GROUP_SECURITY_INFORMATION
)
984 if (RtlValidSid(psidGroup
))
986 if (!SetSecurityDescriptorGroup(pSecurityDescriptor
,
990 return GetLastError();
995 return ERROR_INVALID_PARAMETER
;
999 if (SecurityInfo
& DACL_SECURITY_INFORMATION
)
1003 if (SetSecurityDescriptorDacl(pSecurityDescriptor
,
1008 /* check if the DACL needs to be protected from being
1009 modified by inheritable ACEs */
1010 if (SecurityInfo
& PROTECTED_DACL_SECURITY_INFORMATION
)
1017 return GetLastError();
1023 /* protect the DACL from being modified by inheritable ACEs */
1024 if (!SetSecurityDescriptorControl(pSecurityDescriptor
,
1028 return GetLastError();
1033 if (SecurityInfo
& SACL_SECURITY_INFORMATION
)
1037 if (SetSecurityDescriptorSacl(pSecurityDescriptor
,
1042 /* check if the SACL needs to be protected from being
1043 modified by inheritable ACEs */
1044 if (SecurityInfo
& PROTECTED_SACL_SECURITY_INFORMATION
)
1051 return GetLastError();
1057 /* protect the SACL from being modified by inheritable ACEs */
1058 if (!SetSecurityDescriptorControl(pSecurityDescriptor
,
1062 return GetLastError();
1067 return ERROR_SUCCESS
;
1071 /**********************************************************************
1072 * GetNamedSecurityInfoW EXPORTED
1078 GetNamedSecurityInfoW(LPWSTR pObjectName
,
1079 SE_OBJECT_TYPE ObjectType
,
1080 SECURITY_INFORMATION SecurityInfo
,
1085 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1089 if (pObjectName
!= NULL
)
1091 ErrorCode
= CheckNtMartaPresent();
1092 if (ErrorCode
== ERROR_SUCCESS
)
1094 ErrorCode
= pGetSecurityInfoCheck(SecurityInfo
,
1099 ppSecurityDescriptor
);
1101 if (ErrorCode
== ERROR_SUCCESS
)
1103 /* call the MARTA provider */
1104 ErrorCode
= AccRewriteGetNamedRights(pObjectName
,
1111 ppSecurityDescriptor
);
1116 ErrorCode
= ERROR_INVALID_PARAMETER
;
1121 /**********************************************************************
1122 * SetNamedSecurityInfoW EXPORTED
1128 SetNamedSecurityInfoW(LPWSTR pObjectName
,
1129 SE_OBJECT_TYPE ObjectType
,
1130 SECURITY_INFORMATION SecurityInfo
,
1138 if (pObjectName
!= NULL
)
1140 ErrorCode
= CheckNtMartaPresent();
1141 if (ErrorCode
== ERROR_SUCCESS
)
1143 SECURITY_DESCRIPTOR SecurityDescriptor
;
1145 ErrorCode
= pSetSecurityInfoCheck(&SecurityDescriptor
,
1152 if (ErrorCode
== ERROR_SUCCESS
)
1154 /* call the MARTA provider */
1155 ErrorCode
= AccRewriteSetNamedRights(pObjectName
,
1158 &SecurityDescriptor
);
1163 ErrorCode
= ERROR_INVALID_PARAMETER
;
1168 /**********************************************************************
1169 * GetSecurityInfo EXPORTED
1175 GetSecurityInfo(HANDLE handle
,
1176 SE_OBJECT_TYPE ObjectType
,
1177 SECURITY_INFORMATION SecurityInfo
,
1182 PSECURITY_DESCRIPTOR
*ppSecurityDescriptor
)
1188 ErrorCode
= CheckNtMartaPresent();
1189 if (ErrorCode
== ERROR_SUCCESS
)
1191 ErrorCode
= pGetSecurityInfoCheck(SecurityInfo
,
1196 ppSecurityDescriptor
);
1198 if (ErrorCode
== ERROR_SUCCESS
)
1200 /* call the MARTA provider */
1201 ErrorCode
= AccRewriteGetHandleRights(handle
,
1208 ppSecurityDescriptor
);
1213 ErrorCode
= ERROR_INVALID_HANDLE
;
1219 /**********************************************************************
1220 * SetSecurityInfo EXPORTED
1226 SetSecurityInfo(HANDLE handle
,
1227 SE_OBJECT_TYPE ObjectType
,
1228 SECURITY_INFORMATION SecurityInfo
,
1238 ErrorCode
= CheckNtMartaPresent();
1239 if (ErrorCode
== ERROR_SUCCESS
)
1241 SECURITY_DESCRIPTOR SecurityDescriptor
;
1243 ErrorCode
= pSetSecurityInfoCheck(&SecurityDescriptor
,
1250 if (ErrorCode
== ERROR_SUCCESS
)
1252 /* call the MARTA provider */
1253 ErrorCode
= AccRewriteSetHandleRights(handle
,
1256 &SecurityDescriptor
);
1261 ErrorCode
= ERROR_INVALID_HANDLE
;
1271 CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR ParentDescriptor
,
1272 PSECURITY_DESCRIPTOR CreatorDescriptor
,
1273 PSECURITY_DESCRIPTOR
*NewDescriptor
,
1274 BOOL IsDirectoryObject
,
1276 PGENERIC_MAPPING GenericMapping
)
1280 Status
= RtlNewSecurityObject(ParentDescriptor
,
1286 if (!NT_SUCCESS(Status
))
1288 SetLastError(RtlNtStatusToDosError(Status
));
1301 CreatePrivateObjectSecurityEx(PSECURITY_DESCRIPTOR ParentDescriptor
,
1302 PSECURITY_DESCRIPTOR CreatorDescriptor
,
1303 PSECURITY_DESCRIPTOR
* NewDescriptor
,
1305 BOOL IsContainerObject
,
1306 ULONG AutoInheritFlags
,
1308 PGENERIC_MAPPING GenericMapping
)
1310 FIXME("%s() not implemented!\n", __FUNCTION__
);
1320 CreatePrivateObjectSecurityWithMultipleInheritance(PSECURITY_DESCRIPTOR ParentDescriptor
,
1321 PSECURITY_DESCRIPTOR CreatorDescriptor
,
1322 PSECURITY_DESCRIPTOR
* NewDescriptor
,
1325 BOOL IsContainerObject
,
1326 ULONG AutoInheritFlags
,
1328 PGENERIC_MAPPING GenericMapping
)
1330 FIXME("%s() not implemented!\n", __FUNCTION__
);
1340 DestroyPrivateObjectSecurity(PSECURITY_DESCRIPTOR
*ObjectDescriptor
)
1344 Status
= RtlDeleteSecurityObject(ObjectDescriptor
);
1345 if (!NT_SUCCESS(Status
))
1347 SetLastError(RtlNtStatusToDosError(Status
));
1360 GetPrivateObjectSecurity(IN PSECURITY_DESCRIPTOR ObjectDescriptor
,
1361 IN SECURITY_INFORMATION SecurityInformation
,
1362 OUT PSECURITY_DESCRIPTOR ResultantDescriptor OPTIONAL
,
1363 IN DWORD DescriptorLength
,
1364 OUT PDWORD ReturnLength
)
1369 Status
= RtlQuerySecurityObject(ObjectDescriptor
,
1370 SecurityInformation
,
1371 ResultantDescriptor
,
1374 if (!NT_SUCCESS(Status
))
1377 SetLastError(RtlNtStatusToDosError(Status
));
1391 SetPrivateObjectSecurity(SECURITY_INFORMATION SecurityInformation
,
1392 PSECURITY_DESCRIPTOR ModificationDescriptor
,
1393 PSECURITY_DESCRIPTOR
*ObjectsSecurityDescriptor
,
1394 PGENERIC_MAPPING GenericMapping
,
1399 Status
= RtlSetSecurityObject(SecurityInformation
,
1400 ModificationDescriptor
,
1401 ObjectsSecurityDescriptor
,
1404 if (!NT_SUCCESS(Status
))
1406 SetLastError(RtlNtStatusToDosError(Status
));
1419 TreeResetNamedSecurityInfoW(LPWSTR pObjectName
,
1420 SE_OBJECT_TYPE ObjectType
,
1421 SECURITY_INFORMATION SecurityInfo
,
1427 FN_PROGRESSW fnProgress
,
1428 PROG_INVOKE_SETTING ProgressInvokeSetting
,
1433 if (pObjectName
!= NULL
)
1435 ErrorCode
= CheckNtMartaPresent();
1436 if (ErrorCode
== ERROR_SUCCESS
)
1440 case SE_FILE_OBJECT
:
1441 case SE_REGISTRY_KEY
:
1443 /* check the SecurityInfo flags for sanity (both, the protected
1444 and unprotected dacl/sacl flag must not be passed together) */
1445 if (((SecurityInfo
& DACL_SECURITY_INFORMATION
) &&
1446 (SecurityInfo
& (PROTECTED_DACL_SECURITY_INFORMATION
| UNPROTECTED_DACL_SECURITY_INFORMATION
)) ==
1447 (PROTECTED_DACL_SECURITY_INFORMATION
| UNPROTECTED_DACL_SECURITY_INFORMATION
))
1451 ((SecurityInfo
& SACL_SECURITY_INFORMATION
) &&
1452 (SecurityInfo
& (PROTECTED_SACL_SECURITY_INFORMATION
| UNPROTECTED_SACL_SECURITY_INFORMATION
)) ==
1453 (PROTECTED_SACL_SECURITY_INFORMATION
| UNPROTECTED_SACL_SECURITY_INFORMATION
)))
1455 ErrorCode
= ERROR_INVALID_PARAMETER
;
1459 /* call the MARTA provider */
1460 ErrorCode
= AccTreeResetNamedSecurityInfo(pObjectName
,
1469 ProgressInvokeSetting
,
1475 /* object type not supported */
1476 ErrorCode
= ERROR_INVALID_PARAMETER
;
1482 ErrorCode
= ERROR_INVALID_PARAMETER
;
1487 #ifdef HAS_FN_PROGRESSW
1489 typedef struct _INERNAL_FNPROGRESSW_DATA
1491 FN_PROGRESSA fnProgress
;
1493 } INERNAL_FNPROGRESSW_DATA
, *PINERNAL_FNPROGRESSW_DATA
;
1496 InternalfnProgressW(LPWSTR pObjectName
,
1498 PPROG_INVOKE_SETTING pInvokeSetting
,
1502 PINERNAL_FNPROGRESSW_DATA pifnProgressData
= (PINERNAL_FNPROGRESSW_DATA
)Args
;
1506 ObjectNameSize
= WideCharToMultiByte(CP_ACP
,
1515 if (ObjectNameSize
> 0)
1517 pObjectNameA
= RtlAllocateHeap(RtlGetProcessHeap(),
1520 if (pObjectNameA
!= NULL
)
1522 pObjectNameA
[0] = '\0';
1523 WideCharToMultiByte(CP_ACP
,
1532 pifnProgressData
->fnProgress((LPWSTR
)pObjectNameA
, /* FIXME: wrong cast!! */
1535 pifnProgressData
->Args
,
1538 RtlFreeHeap(RtlGetProcessHeap(),
1552 TreeResetNamedSecurityInfoA(LPSTR pObjectName
,
1553 SE_OBJECT_TYPE ObjectType
,
1554 SECURITY_INFORMATION SecurityInfo
,
1560 FN_PROGRESSA fnProgress
,
1561 PROG_INVOKE_SETTING ProgressInvokeSetting
,
1564 #ifndef HAS_FN_PROGRESSW
1565 /* That's all this function does, at least up to w2k3... Even MS was too
1566 lazy to implement it... */
1567 return ERROR_CALL_NOT_IMPLEMENTED
;
1569 INERNAL_FNPROGRESSW_DATA ifnProgressData
;
1570 UNICODE_STRING ObjectName
;
1573 if (!RtlCreateUnicodeStringFromAsciiz(&ObjectName
, pObjectName
))
1575 return ERROR_NOT_ENOUGH_MEMORY
;
1578 ifnProgressData
.fnProgress
= fnProgress
;
1579 ifnProgressData
.Args
= Args
;
1581 Ret
= TreeResetNamedSecurityInfoW(ObjectName
.Buffer
,
1589 (fnProgress
!= NULL
? InternalfnProgressW
: NULL
),
1590 ProgressInvokeSetting
,
1593 RtlFreeUnicodeString(&ObjectName
);