3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/advapi32/sec/ac.c
6 * PURPOSE: ACL/ACE functions
23 LPVOID pAclInformation
,
24 DWORD nAclInformationLength
,
25 ACL_INFORMATION_CLASS dwAclInformationClass
30 Status
= RtlQueryInformationAcl (pAcl
,
32 nAclInformationLength
,
33 dwAclInformationClass
);
34 if (!NT_SUCCESS(Status
))
36 SetLastError (RtlNtStatusToDosError (Status
));
57 Status
= RtlCreateAcl (pAcl
,
60 if (!NT_SUCCESS(Status
))
62 SetLastError (RtlNtStatusToDosError (Status
));
79 return RtlValidAcl (pAcl
);
90 LPVOID pAclInformation
,
91 DWORD nAclInformationLength
,
92 ACL_INFORMATION_CLASS dwAclInformationClass
97 Status
= RtlSetInformationAcl (pAcl
,
99 nAclInformationLength
,
100 dwAclInformationClass
);
101 if (!NT_SUCCESS(Status
))
103 SetLastError (RtlNtStatusToDosError (Status
));
118 AddAccessAllowedAce (
127 Status
= RtlAddAccessAllowedAce (pAcl
,
131 if (!NT_SUCCESS(Status
))
133 SetLastError (RtlNtStatusToDosError (Status
));
145 AddAccessAllowedAceEx(PACL pAcl
,
153 Status
= RtlAddAccessAllowedAceEx(pAcl
,
158 if (!NT_SUCCESS(Status
))
160 SetLastError(RtlNtStatusToDosError(Status
));
173 AddAccessAllowedObjectAce(
178 GUID
* ObjectTypeGuid
,
179 GUID
* InheritedObjectTypeGuid
,
184 Status
= RtlAddAccessAllowedObjectAce(pAcl
,
189 InheritedObjectTypeGuid
,
191 if (!NT_SUCCESS(Status
))
193 SetLastError(RtlNtStatusToDosError(Status
));
215 Status
= RtlAddAccessDeniedAce (pAcl
,
219 if (!NT_SUCCESS(Status
))
221 SetLastError (RtlNtStatusToDosError (Status
));
233 AddAccessDeniedAceEx(PACL pAcl
,
241 Status
= RtlAddAccessDeniedAceEx(pAcl
,
246 if (!NT_SUCCESS(Status
))
248 SetLastError(RtlNtStatusToDosError(Status
));
261 AddAccessDeniedObjectAce(
266 GUID
* ObjectTypeGuid
,
267 GUID
* InheritedObjectTypeGuid
,
272 Status
= RtlAddAccessDeniedObjectAce(pAcl
,
277 InheritedObjectTypeGuid
,
279 if (!NT_SUCCESS(Status
))
281 SetLastError(RtlNtStatusToDosError(Status
));
297 DWORD dwStartingAceIndex
,
304 Status
= RtlAddAce (pAcl
,
309 if (!NT_SUCCESS(Status
))
311 SetLastError (RtlNtStatusToDosError (Status
));
335 Status
= RtlAddAuditAccessAce (pAcl
,
341 if (!NT_SUCCESS(Status
))
343 SetLastError (RtlNtStatusToDosError (Status
));
355 AddAuditAccessAceEx(PACL pAcl
,
365 Status
= RtlAddAuditAccessAceEx(pAcl
,
372 if (!NT_SUCCESS(Status
))
374 SetLastError(RtlNtStatusToDosError(Status
));
387 AddAuditAccessObjectAce(
392 GUID
* ObjectTypeGuid
,
393 GUID
* InheritedObjectTypeGuid
,
400 Status
= RtlAddAuditAccessObjectAce(pAcl
,
405 InheritedObjectTypeGuid
,
409 if (!NT_SUCCESS(Status
))
411 SetLastError(RtlNtStatusToDosError(Status
));
431 Status
= RtlDeleteAce (pAcl
,
433 if (!NT_SUCCESS(Status
))
435 SetLastError (RtlNtStatusToDosError (Status
));
453 return RtlFirstFreeAce (pAcl
,
471 Status
= RtlGetAce (pAcl
,
474 if (!NT_SUCCESS(Status
))
476 SetLastError (RtlNtStatusToDosError (Status
));
489 GetInheritanceSourceW (
491 SE_OBJECT_TYPE ObjectType
,
492 SECURITY_INFORMATION SecurityInfo
,
494 GUID
** pObjectClassGuids OPTIONAL
,
497 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL
,
498 PGENERIC_MAPPING pGenericMapping
,
499 PINHERITED_FROMW pInheritArray
504 ErrorCode
= CheckNtMartaPresent();
505 if (ErrorCode
== ERROR_SUCCESS
)
507 /* call the MARTA provider */
508 ErrorCode
= AccGetInheritanceSource(pObjectName
,
529 GetInheritanceSourceA (
531 SE_OBJECT_TYPE ObjectType
,
532 SECURITY_INFORMATION SecurityInfo
,
534 GUID
** pObjectClassGuids OPTIONAL
,
537 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL
,
538 PGENERIC_MAPPING pGenericMapping
,
539 PINHERITED_FROM pInheritArray
542 /* That's all this function does, at least up to w2k3... Even MS was too
543 lazy to implement it... */
544 return ERROR_CALL_NOT_IMPLEMENTED
;
553 FreeInheritedFromArray (
554 PINHERITED_FROMW pInheritArray
,
556 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL
561 ErrorCode
= CheckNtMartaPresent();
562 if (ErrorCode
== ERROR_SUCCESS
)
564 /* call the MARTA provider */
565 ErrorCode
= AccFreeIndexArray(pInheritArray
,
580 ULONG cCountOfExplicitEntries
,
581 PEXPLICIT_ACCESS_W pListOfExplicitEntries
,
587 ErrorCode
= CheckNtMartaPresent();
588 if (ErrorCode
== ERROR_SUCCESS
)
590 /* call the MARTA provider */
591 ErrorCode
= AccRewriteSetEntriesInAcl(cCountOfExplicitEntries
,
592 pListOfExplicitEntries
,
602 InternalTrusteeAToW(IN PTRUSTEE_A pTrusteeA
,
603 OUT PTRUSTEE_W
*pTrusteeW
)
605 TRUSTEE_FORM TrusteeForm
;
608 DWORD ErrorCode
= ERROR_SUCCESS
;
610 ASSERT(sizeof(TRUSTEE_W
) == sizeof(TRUSTEE_A
));
612 TrusteeForm
= GetTrusteeForm(pTrusteeA
);
615 case TRUSTEE_IS_NAME
:
617 /* directly copy the array, this works as the size of the EXPLICIT_ACCESS_A
618 structure matches the size of the EXPLICIT_ACCESS_W version */
619 lpStr
= GetTrusteeName(pTrusteeA
);
621 BufferSize
= strlen(lpStr
) + 1;
623 *pTrusteeW
= RtlAllocateHeap(RtlGetProcessHeap(),
625 sizeof(TRUSTEE_W
) + (BufferSize
* sizeof(WCHAR
)));
626 if (*pTrusteeW
!= NULL
)
628 RtlCopyMemory(*pTrusteeW
,
630 FIELD_OFFSET(TRUSTEE_A
,
635 (*pTrusteeW
)->ptstrName
= (PWSTR
)((*pTrusteeW
) + 1);
637 /* convert the trustee's name */
638 if (MultiByteToWideChar(CP_ACP
,
642 (*pTrusteeW
)->ptstrName
,
650 RtlFreeHeap(RtlGetProcessHeap(),
653 goto NothingToConvert
;
657 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
661 case TRUSTEE_IS_OBJECTS_AND_NAME
:
663 POBJECTS_AND_NAME_A oanA
= (POBJECTS_AND_NAME_A
)GetTrusteeNameA(pTrusteeA
);
664 POBJECTS_AND_NAME_W oan
;
667 /* calculate the size needed */
668 if ((oanA
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
) &&
669 oanA
->InheritedObjectTypeName
!= NULL
)
671 BufferSize
= strlen(oanA
->InheritedObjectTypeName
) + 1;
673 if (oanA
->ptstrName
!= NULL
)
675 BufferSize
+= strlen(oanA
->ptstrName
) + 1;
678 *pTrusteeW
= RtlAllocateHeap(RtlGetProcessHeap(),
680 sizeof(TRUSTEE_W
) + sizeof(OBJECTS_AND_NAME_W
) +
681 (BufferSize
* sizeof(WCHAR
)));
683 if (*pTrusteeW
!= NULL
)
685 oan
= (POBJECTS_AND_NAME_W
)((*pTrusteeW
) + 1);
686 StrBuf
= (PWSTR
)(oan
+ 1);
688 /* copy over the parts of the TRUSTEE structure that don't need
690 RtlCopyMemory(*pTrusteeW
,
692 FIELD_OFFSET(TRUSTEE_A
,
695 (*pTrusteeW
)->ptstrName
= (LPWSTR
)oan
;
697 /* convert the OBJECTS_AND_NAME_A structure */
698 oan
->ObjectsPresent
= oanA
->ObjectsPresent
;
699 oan
->ObjectType
= oanA
->ObjectType
;
701 if ((oanA
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
) &&
702 oanA
->InheritedObjectTypeName
!= NULL
)
704 /* convert inherited object type name */
705 BufferSize
= strlen(oanA
->InheritedObjectTypeName
) + 1;
707 if (MultiByteToWideChar(CP_ACP
,
709 oanA
->InheritedObjectTypeName
,
716 oan
->InheritedObjectTypeName
= StrBuf
;
718 StrBuf
+= BufferSize
;
721 oan
->InheritedObjectTypeName
= NULL
;
723 if (oanA
->ptstrName
!= NULL
)
725 /* convert the trustee name */
726 BufferSize
= strlen(oanA
->ptstrName
) + 1;
728 if (MultiByteToWideChar(CP_ACP
,
736 ErrorCode
= GetLastError();
739 RtlFreeHeap(RtlGetProcessHeap(),
745 oan
->ptstrName
= StrBuf
;
748 oan
->ptstrName
= NULL
;
751 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
758 /* no need to convert anything to unicode */
759 *pTrusteeW
= (PTRUSTEE_W
)pTrusteeA
;
769 InternalFreeConvertedTrustee(IN PTRUSTEE_W pTrusteeW
,
770 IN PTRUSTEE_A pTrusteeA
)
772 if ((PVOID
)pTrusteeW
!= (PVOID
)pTrusteeA
)
774 RtlFreeHeap(RtlGetProcessHeap(),
782 InternalExplicitAccessAToW(IN ULONG cCountOfExplicitEntries
,
783 IN PEXPLICIT_ACCESS_A pListOfExplicitEntriesA
,
784 OUT PEXPLICIT_ACCESS_W
*pListOfExplicitEntriesW
)
786 TRUSTEE_FORM TrusteeForm
;
789 ULONG ObjectsAndNameCount
= 0;
790 PEXPLICIT_ACCESS_W peaw
= NULL
;
791 DWORD ErrorCode
= ERROR_SUCCESS
;
794 /* NOTE: This code assumes that the size of the TRUSTEE_A and TRUSTEE_W structure matches! */
795 ASSERT(sizeof(TRUSTEE_A
) == sizeof(TRUSTEE_W
));
797 if (cCountOfExplicitEntries
!= 0)
799 /* calculate the size needed */
800 Size
= cCountOfExplicitEntries
* sizeof(EXPLICIT_ACCESS_W
);
801 for (i
= 0; i
!= cCountOfExplicitEntries
; i
++)
803 TrusteeForm
= GetTrusteeForm(&pListOfExplicitEntriesA
[i
].Trustee
);
807 case TRUSTEE_IS_NAME
:
809 lpStr
= GetTrusteeNameA(&pListOfExplicitEntriesA
[i
].Trustee
);
811 Size
+= (strlen(lpStr
) + 1) * sizeof(WCHAR
);
815 case TRUSTEE_IS_OBJECTS_AND_NAME
:
817 POBJECTS_AND_NAME_A oan
= (POBJECTS_AND_NAME_A
)GetTrusteeNameA(&pListOfExplicitEntriesA
[i
].Trustee
);
819 if ((oan
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
) &&
820 oan
->InheritedObjectTypeName
!= NULL
)
822 Size
+= (strlen(oan
->InheritedObjectTypeName
) + 1) * sizeof(WCHAR
);
825 if (oan
->ptstrName
!= NULL
)
826 Size
+= (strlen(oan
->ptstrName
) + 1) * sizeof(WCHAR
);
828 ObjectsAndNameCount
++;
837 /* allocate the array */
838 peaw
= RtlAllocateHeap(RtlGetProcessHeap(),
844 POBJECTS_AND_NAME_W oan
= (POBJECTS_AND_NAME_W
)(peaw
+ cCountOfExplicitEntries
);
845 LPWSTR StrBuf
= (LPWSTR
)(oan
+ ObjectsAndNameCount
);
847 /* convert the array to unicode */
848 for (i
= 0; i
!= cCountOfExplicitEntries
; i
++)
850 peaw
[i
].grfAccessPermissions
= pListOfExplicitEntriesA
[i
].grfAccessPermissions
;
851 peaw
[i
].grfAccessMode
= pListOfExplicitEntriesA
[i
].grfAccessMode
;
852 peaw
[i
].grfInheritance
= pListOfExplicitEntriesA
[i
].grfInheritance
;
854 /* convert or copy the TRUSTEE structure */
855 TrusteeForm
= GetTrusteeForm(&pListOfExplicitEntriesA
[i
].Trustee
);
858 case TRUSTEE_IS_NAME
:
860 lpStr
= GetTrusteeNameA(&pListOfExplicitEntriesA
[i
].Trustee
);
863 /* convert the trustee name */
864 BufferSize
= strlen(lpStr
) + 1;
866 if (MultiByteToWideChar(CP_ACP
,
875 peaw
[i
].Trustee
.ptstrName
= StrBuf
;
877 StrBuf
+= BufferSize
;
885 case TRUSTEE_IS_OBJECTS_AND_NAME
:
887 POBJECTS_AND_NAME_A oanA
= (POBJECTS_AND_NAME_A
)GetTrusteeNameA(&pListOfExplicitEntriesA
[i
].Trustee
);
889 /* copy over the parts of the TRUSTEE structure that don't need
891 RtlCopyMemory(&peaw
[i
].Trustee
,
892 &pListOfExplicitEntriesA
[i
].Trustee
,
893 FIELD_OFFSET(TRUSTEE_A
,
896 peaw
[i
].Trustee
.ptstrName
= (LPWSTR
)oan
;
898 /* convert the OBJECTS_AND_NAME_A structure */
899 oan
->ObjectsPresent
= oanA
->ObjectsPresent
;
900 oan
->ObjectType
= oanA
->ObjectType
;
902 if ((oanA
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
) &&
903 oanA
->InheritedObjectTypeName
!= NULL
)
905 /* convert inherited object type name */
906 BufferSize
= strlen(oanA
->InheritedObjectTypeName
) + 1;
908 if (MultiByteToWideChar(CP_ACP
,
910 oanA
->InheritedObjectTypeName
,
917 oan
->InheritedObjectTypeName
= StrBuf
;
919 StrBuf
+= BufferSize
;
922 oan
->InheritedObjectTypeName
= NULL
;
924 if (oanA
->ptstrName
!= NULL
)
926 /* convert the trustee name */
927 BufferSize
= strlen(oanA
->ptstrName
) + 1;
929 if (MultiByteToWideChar(CP_ACP
,
937 ErrorCode
= GetLastError();
940 RtlFreeHeap(RtlGetProcessHeap(),
946 oan
->ptstrName
= StrBuf
;
948 StrBuf
+= BufferSize
;
951 oan
->ptstrName
= NULL
;
953 /* move on to the next OBJECTS_AND_NAME_A structure */
961 /* just copy over the TRUSTEE structure, they don't contain any
962 ansi/unicode specific data */
963 RtlCopyMemory(&peaw
[i
].Trustee
,
964 &pListOfExplicitEntriesA
[i
].Trustee
,
971 ASSERT(ErrorCode
== ERROR_SUCCESS
);
972 *pListOfExplicitEntriesW
= peaw
;
975 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
988 ULONG cCountOfExplicitEntries
,
989 PEXPLICIT_ACCESS_A pListOfExplicitEntries
,
993 PEXPLICIT_ACCESS_W ListOfExplicitEntriesW
= NULL
;
996 ErrorCode
= InternalExplicitAccessAToW(cCountOfExplicitEntries
,
997 pListOfExplicitEntries
,
998 &ListOfExplicitEntriesW
);
1000 if (ErrorCode
== ERROR_SUCCESS
)
1002 ErrorCode
= SetEntriesInAclW(cCountOfExplicitEntries
,
1003 ListOfExplicitEntriesW
,
1007 /* free the allocated array */
1008 RtlFreeHeap(RtlGetProcessHeap(),
1010 ListOfExplicitEntriesW
);
1022 GetExplicitEntriesFromAclW(
1024 PULONG pcCountOfExplicitEntries
,
1025 PEXPLICIT_ACCESS_W
* pListOfExplicitEntries
1030 ErrorCode
= CheckNtMartaPresent();
1031 if (ErrorCode
== ERROR_SUCCESS
)
1033 /* call the MARTA provider */
1034 ErrorCode
= AccRewriteGetExplicitEntriesFromAcl(pacl
,
1035 pcCountOfExplicitEntries
,
1036 pListOfExplicitEntries
);
1048 GetEffectiveRightsFromAclW(IN PACL pacl
,
1049 IN PTRUSTEE_W pTrustee
,
1050 OUT PACCESS_MASK pAccessRights
)
1052 DPRINT1("%s() not implemented!\n", __FUNCTION__
);
1053 return ERROR_CALL_NOT_IMPLEMENTED
;
1062 GetEffectiveRightsFromAclA(IN PACL pacl
,
1063 IN PTRUSTEE_A pTrustee
,
1064 OUT PACCESS_MASK pAccessRights
)
1066 PTRUSTEE_W pTrusteeW
= NULL
;
1069 ErrorCode
= InternalTrusteeAToW(pTrustee
,
1071 if (ErrorCode
== ERROR_SUCCESS
)
1073 ErrorCode
= GetEffectiveRightsFromAclW(pacl
,
1077 InternalFreeConvertedTrustee(pTrusteeW
,
1081 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
1092 GetAuditedPermissionsFromAclW(IN PACL pacl
,
1093 IN PTRUSTEE_W pTrustee
,
1094 OUT PACCESS_MASK pSuccessfulAuditedRights
,
1095 OUT PACCESS_MASK pFailedAuditRights
)
1097 DPRINT1("%s() not implemented!\n", __FUNCTION__
);
1098 return ERROR_CALL_NOT_IMPLEMENTED
;
1107 GetAuditedPermissionsFromAclA(IN PACL pacl
,
1108 IN PTRUSTEE_A pTrustee
,
1109 OUT PACCESS_MASK pSuccessfulAuditedRights
,
1110 OUT PACCESS_MASK pFailedAuditRights
)
1112 PTRUSTEE_W pTrusteeW
= NULL
;
1115 ErrorCode
= InternalTrusteeAToW(pTrustee
,
1117 if (ErrorCode
== ERROR_SUCCESS
)
1119 ErrorCode
= GetAuditedPermissionsFromAclW(pacl
,
1121 pSuccessfulAuditedRights
,
1122 pFailedAuditRights
);
1124 InternalFreeConvertedTrustee(pTrusteeW
,
1128 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;