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 lpStr
= GetTrusteeName(pTrusteeA
);
619 BufferSize
= strlen(lpStr
) + 1;
621 *pTrusteeW
= RtlAllocateHeap(RtlGetProcessHeap(),
623 sizeof(TRUSTEE_W
) + (BufferSize
* sizeof(WCHAR
)));
624 if (*pTrusteeW
!= NULL
)
626 RtlCopyMemory(*pTrusteeW
,
628 FIELD_OFFSET(TRUSTEE_A
,
633 (*pTrusteeW
)->ptstrName
= (PWSTR
)((*pTrusteeW
) + 1);
635 /* convert the trustee's name */
636 if (MultiByteToWideChar(CP_ACP
,
640 (*pTrusteeW
)->ptstrName
,
648 RtlFreeHeap(RtlGetProcessHeap(),
651 goto NothingToConvert
;
655 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
659 case TRUSTEE_IS_OBJECTS_AND_NAME
:
661 POBJECTS_AND_NAME_A oanA
= (POBJECTS_AND_NAME_A
)GetTrusteeNameA(pTrusteeA
);
662 POBJECTS_AND_NAME_W oan
;
665 /* calculate the size needed */
666 if ((oanA
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
) &&
667 oanA
->InheritedObjectTypeName
!= NULL
)
669 BufferSize
= strlen(oanA
->InheritedObjectTypeName
) + 1;
671 if (oanA
->ptstrName
!= NULL
)
673 BufferSize
+= strlen(oanA
->ptstrName
) + 1;
676 *pTrusteeW
= RtlAllocateHeap(RtlGetProcessHeap(),
678 sizeof(TRUSTEE_W
) + sizeof(OBJECTS_AND_NAME_W
) +
679 (BufferSize
* sizeof(WCHAR
)));
681 if (*pTrusteeW
!= NULL
)
683 oan
= (POBJECTS_AND_NAME_W
)((*pTrusteeW
) + 1);
684 StrBuf
= (PWSTR
)(oan
+ 1);
686 /* copy over the parts of the TRUSTEE structure that don't need
688 RtlCopyMemory(*pTrusteeW
,
690 FIELD_OFFSET(TRUSTEE_A
,
693 (*pTrusteeW
)->ptstrName
= (LPWSTR
)oan
;
695 /* convert the OBJECTS_AND_NAME_A structure */
696 oan
->ObjectsPresent
= oanA
->ObjectsPresent
;
697 oan
->ObjectType
= oanA
->ObjectType
;
699 if ((oanA
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
) &&
700 oanA
->InheritedObjectTypeName
!= NULL
)
702 /* convert inherited object type name */
703 BufferSize
= strlen(oanA
->InheritedObjectTypeName
) + 1;
705 if (MultiByteToWideChar(CP_ACP
,
707 oanA
->InheritedObjectTypeName
,
714 oan
->InheritedObjectTypeName
= StrBuf
;
716 StrBuf
+= BufferSize
;
719 oan
->InheritedObjectTypeName
= NULL
;
721 if (oanA
->ptstrName
!= NULL
)
723 /* convert the trustee name */
724 BufferSize
= strlen(oanA
->ptstrName
) + 1;
726 if (MultiByteToWideChar(CP_ACP
,
734 ErrorCode
= GetLastError();
737 RtlFreeHeap(RtlGetProcessHeap(),
743 oan
->ptstrName
= StrBuf
;
746 oan
->ptstrName
= NULL
;
749 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
756 /* no need to convert anything to unicode */
757 *pTrusteeW
= (PTRUSTEE_W
)pTrusteeA
;
767 InternalFreeConvertedTrustee(IN PTRUSTEE_W pTrusteeW
,
768 IN PTRUSTEE_A pTrusteeA
)
770 if ((PVOID
)pTrusteeW
!= (PVOID
)pTrusteeA
)
772 RtlFreeHeap(RtlGetProcessHeap(),
780 InternalExplicitAccessAToW(IN ULONG cCountOfExplicitEntries
,
781 IN PEXPLICIT_ACCESS_A pListOfExplicitEntriesA
,
782 OUT PEXPLICIT_ACCESS_W
*pListOfExplicitEntriesW
)
784 TRUSTEE_FORM TrusteeForm
;
787 ULONG ObjectsAndNameCount
= 0;
788 PEXPLICIT_ACCESS_W peaw
= NULL
;
789 DWORD ErrorCode
= ERROR_SUCCESS
;
792 /* NOTE: This code assumes that the size of the TRUSTEE_A and TRUSTEE_W structure matches! */
793 ASSERT(sizeof(TRUSTEE_A
) == sizeof(TRUSTEE_W
));
795 if (cCountOfExplicitEntries
!= 0)
797 /* calculate the size needed */
798 Size
= cCountOfExplicitEntries
* sizeof(EXPLICIT_ACCESS_W
);
799 for (i
= 0; i
!= cCountOfExplicitEntries
; i
++)
801 TrusteeForm
= GetTrusteeForm(&pListOfExplicitEntriesA
[i
].Trustee
);
805 case TRUSTEE_IS_NAME
:
807 lpStr
= GetTrusteeNameA(&pListOfExplicitEntriesA
[i
].Trustee
);
809 Size
+= (strlen(lpStr
) + 1) * sizeof(WCHAR
);
813 case TRUSTEE_IS_OBJECTS_AND_NAME
:
815 POBJECTS_AND_NAME_A oan
= (POBJECTS_AND_NAME_A
)GetTrusteeNameA(&pListOfExplicitEntriesA
[i
].Trustee
);
817 if ((oan
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
) &&
818 oan
->InheritedObjectTypeName
!= NULL
)
820 Size
+= (strlen(oan
->InheritedObjectTypeName
) + 1) * sizeof(WCHAR
);
823 if (oan
->ptstrName
!= NULL
)
824 Size
+= (strlen(oan
->ptstrName
) + 1) * sizeof(WCHAR
);
826 ObjectsAndNameCount
++;
835 /* allocate the array */
836 peaw
= RtlAllocateHeap(RtlGetProcessHeap(),
842 POBJECTS_AND_NAME_W oan
= (POBJECTS_AND_NAME_W
)(peaw
+ cCountOfExplicitEntries
);
843 LPWSTR StrBuf
= (LPWSTR
)(oan
+ ObjectsAndNameCount
);
845 /* convert the array to unicode */
846 for (i
= 0; i
!= cCountOfExplicitEntries
; i
++)
848 peaw
[i
].grfAccessPermissions
= pListOfExplicitEntriesA
[i
].grfAccessPermissions
;
849 peaw
[i
].grfAccessMode
= pListOfExplicitEntriesA
[i
].grfAccessMode
;
850 peaw
[i
].grfInheritance
= pListOfExplicitEntriesA
[i
].grfInheritance
;
852 /* convert or copy the TRUSTEE structure */
853 TrusteeForm
= GetTrusteeForm(&pListOfExplicitEntriesA
[i
].Trustee
);
856 case TRUSTEE_IS_NAME
:
858 lpStr
= GetTrusteeNameA(&pListOfExplicitEntriesA
[i
].Trustee
);
861 /* convert the trustee name */
862 BufferSize
= strlen(lpStr
) + 1;
864 if (MultiByteToWideChar(CP_ACP
,
873 peaw
[i
].Trustee
.ptstrName
= StrBuf
;
875 StrBuf
+= BufferSize
;
883 case TRUSTEE_IS_OBJECTS_AND_NAME
:
885 POBJECTS_AND_NAME_A oanA
= (POBJECTS_AND_NAME_A
)GetTrusteeNameA(&pListOfExplicitEntriesA
[i
].Trustee
);
887 /* copy over the parts of the TRUSTEE structure that don't need
889 RtlCopyMemory(&peaw
[i
].Trustee
,
890 &pListOfExplicitEntriesA
[i
].Trustee
,
891 FIELD_OFFSET(TRUSTEE_A
,
894 peaw
[i
].Trustee
.ptstrName
= (LPWSTR
)oan
;
896 /* convert the OBJECTS_AND_NAME_A structure */
897 oan
->ObjectsPresent
= oanA
->ObjectsPresent
;
898 oan
->ObjectType
= oanA
->ObjectType
;
900 if ((oanA
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
) &&
901 oanA
->InheritedObjectTypeName
!= NULL
)
903 /* convert inherited object type name */
904 BufferSize
= strlen(oanA
->InheritedObjectTypeName
) + 1;
906 if (MultiByteToWideChar(CP_ACP
,
908 oanA
->InheritedObjectTypeName
,
915 oan
->InheritedObjectTypeName
= StrBuf
;
917 StrBuf
+= BufferSize
;
920 oan
->InheritedObjectTypeName
= NULL
;
922 if (oanA
->ptstrName
!= NULL
)
924 /* convert the trustee name */
925 BufferSize
= strlen(oanA
->ptstrName
) + 1;
927 if (MultiByteToWideChar(CP_ACP
,
935 ErrorCode
= GetLastError();
938 RtlFreeHeap(RtlGetProcessHeap(),
944 oan
->ptstrName
= StrBuf
;
946 StrBuf
+= BufferSize
;
949 oan
->ptstrName
= NULL
;
951 /* move on to the next OBJECTS_AND_NAME_A structure */
959 /* just copy over the TRUSTEE structure, they don't contain any
960 ansi/unicode specific data */
961 RtlCopyMemory(&peaw
[i
].Trustee
,
962 &pListOfExplicitEntriesA
[i
].Trustee
,
969 ASSERT(ErrorCode
== ERROR_SUCCESS
);
970 *pListOfExplicitEntriesW
= peaw
;
973 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
986 ULONG cCountOfExplicitEntries
,
987 PEXPLICIT_ACCESS_A pListOfExplicitEntries
,
991 PEXPLICIT_ACCESS_W ListOfExplicitEntriesW
= NULL
;
994 ErrorCode
= InternalExplicitAccessAToW(cCountOfExplicitEntries
,
995 pListOfExplicitEntries
,
996 &ListOfExplicitEntriesW
);
998 if (ErrorCode
== ERROR_SUCCESS
)
1000 ErrorCode
= SetEntriesInAclW(cCountOfExplicitEntries
,
1001 ListOfExplicitEntriesW
,
1005 /* free the allocated array */
1006 RtlFreeHeap(RtlGetProcessHeap(),
1008 ListOfExplicitEntriesW
);
1020 GetExplicitEntriesFromAclW(
1022 PULONG pcCountOfExplicitEntries
,
1023 PEXPLICIT_ACCESS_W
* pListOfExplicitEntries
1028 ErrorCode
= CheckNtMartaPresent();
1029 if (ErrorCode
== ERROR_SUCCESS
)
1031 /* call the MARTA provider */
1032 ErrorCode
= AccRewriteGetExplicitEntriesFromAcl(pacl
,
1033 pcCountOfExplicitEntries
,
1034 pListOfExplicitEntries
);
1046 GetEffectiveRightsFromAclW(IN PACL pacl
,
1047 IN PTRUSTEE_W pTrustee
,
1048 OUT PACCESS_MASK pAccessRights
)
1050 DPRINT1("%s() not implemented!\n", __FUNCTION__
);
1051 return ERROR_CALL_NOT_IMPLEMENTED
;
1060 GetEffectiveRightsFromAclA(IN PACL pacl
,
1061 IN PTRUSTEE_A pTrustee
,
1062 OUT PACCESS_MASK pAccessRights
)
1064 PTRUSTEE_W pTrusteeW
= NULL
;
1067 ErrorCode
= InternalTrusteeAToW(pTrustee
,
1069 if (ErrorCode
== ERROR_SUCCESS
)
1071 ErrorCode
= GetEffectiveRightsFromAclW(pacl
,
1075 InternalFreeConvertedTrustee(pTrusteeW
,
1079 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
1090 GetAuditedPermissionsFromAclW(IN PACL pacl
,
1091 IN PTRUSTEE_W pTrustee
,
1092 OUT PACCESS_MASK pSuccessfulAuditedRights
,
1093 OUT PACCESS_MASK pFailedAuditRights
)
1095 DPRINT1("%s() not implemented!\n", __FUNCTION__
);
1096 return ERROR_CALL_NOT_IMPLEMENTED
;
1105 GetAuditedPermissionsFromAclA(IN PACL pacl
,
1106 IN PTRUSTEE_A pTrustee
,
1107 OUT PACCESS_MASK pSuccessfulAuditedRights
,
1108 OUT PACCESS_MASK pFailedAuditRights
)
1110 PTRUSTEE_W pTrusteeW
= NULL
;
1113 ErrorCode
= InternalTrusteeAToW(pTrustee
,
1115 if (ErrorCode
== ERROR_SUCCESS
)
1117 ErrorCode
= GetAuditedPermissionsFromAclW(pacl
,
1119 pSuccessfulAuditedRights
,
1120 pFailedAuditRights
);
1122 InternalFreeConvertedTrustee(pTrusteeW
,
1126 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;