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
10 WINE_DEFAULT_DEBUG_CHANNEL(advapi
);
19 GetAclInformation(PACL pAcl
,
20 LPVOID pAclInformation
,
21 DWORD nAclInformationLength
,
22 ACL_INFORMATION_CLASS dwAclInformationClass
)
26 Status
= RtlQueryInformationAcl(pAcl
,
28 nAclInformationLength
,
29 dwAclInformationClass
);
30 if (!NT_SUCCESS(Status
))
32 SetLastError(RtlNtStatusToDosError(Status
));
45 InitializeAcl(PACL pAcl
,
51 Status
= RtlCreateAcl(pAcl
,
54 if (!NT_SUCCESS(Status
))
56 SetLastError(RtlNtStatusToDosError(Status
));
71 return RtlValidAcl (pAcl
);
80 SetAclInformation(PACL pAcl
,
81 LPVOID pAclInformation
,
82 DWORD nAclInformationLength
,
83 ACL_INFORMATION_CLASS dwAclInformationClass
)
87 Status
= RtlSetInformationAcl(pAcl
,
89 nAclInformationLength
,
90 dwAclInformationClass
);
91 if (!NT_SUCCESS(Status
))
93 SetLastError(RtlNtStatusToDosError(Status
));
108 AddAccessAllowedAce(PACL pAcl
,
115 Status
= RtlAddAccessAllowedAce(pAcl
,
119 if (!NT_SUCCESS(Status
))
121 SetLastError(RtlNtStatusToDosError(Status
));
133 AddAccessAllowedAceEx(PACL pAcl
,
141 Status
= RtlAddAccessAllowedAceEx(pAcl
,
146 if (!NT_SUCCESS(Status
))
148 SetLastError(RtlNtStatusToDosError(Status
));
161 AddAccessAllowedObjectAce(PACL pAcl
,
165 GUID
*ObjectTypeGuid
,
166 GUID
*InheritedObjectTypeGuid
,
171 Status
= RtlAddAccessAllowedObjectAce(pAcl
,
176 InheritedObjectTypeGuid
,
178 if (!NT_SUCCESS(Status
))
180 SetLastError(RtlNtStatusToDosError(Status
));
193 AddAccessDeniedAce(PACL pAcl
,
200 Status
= RtlAddAccessDeniedAce(pAcl
,
204 if (!NT_SUCCESS(Status
))
206 SetLastError(RtlNtStatusToDosError(Status
));
218 AddAccessDeniedAceEx(PACL pAcl
,
226 Status
= RtlAddAccessDeniedAceEx(pAcl
,
231 if (!NT_SUCCESS(Status
))
233 SetLastError(RtlNtStatusToDosError(Status
));
246 AddAccessDeniedObjectAce(PACL pAcl
,
250 GUID
* ObjectTypeGuid
,
251 GUID
* InheritedObjectTypeGuid
,
256 Status
= RtlAddAccessDeniedObjectAce(pAcl
,
261 InheritedObjectTypeGuid
,
263 if (!NT_SUCCESS(Status
))
265 SetLastError(RtlNtStatusToDosError(Status
));
280 DWORD dwStartingAceIndex
,
282 DWORD nAceListLength
)
286 Status
= RtlAddAce(pAcl
,
291 if (!NT_SUCCESS(Status
))
293 SetLastError(RtlNtStatusToDosError(Status
));
306 AddAuditAccessAce(PACL pAcl
,
315 Status
= RtlAddAuditAccessAce(pAcl
,
321 if (!NT_SUCCESS(Status
))
323 SetLastError(RtlNtStatusToDosError(Status
));
335 AddAuditAccessAceEx(PACL pAcl
,
345 Status
= RtlAddAuditAccessAceEx(pAcl
,
352 if (!NT_SUCCESS(Status
))
354 SetLastError(RtlNtStatusToDosError(Status
));
367 AddAuditAccessObjectAce(PACL pAcl
,
371 GUID
*ObjectTypeGuid
,
372 GUID
*InheritedObjectTypeGuid
,
379 Status
= RtlAddAuditAccessObjectAce(pAcl
,
384 InheritedObjectTypeGuid
,
388 if (!NT_SUCCESS(Status
))
390 SetLastError(RtlNtStatusToDosError(Status
));
407 Status
= RtlDeleteAce(pAcl
,
409 if (!NT_SUCCESS(Status
))
411 SetLastError(RtlNtStatusToDosError(Status
));
424 FindFirstFreeAce(PACL pAcl
,
427 return RtlFirstFreeAce(pAcl
,
443 Status
= RtlGetAce(pAcl
,
446 if (!NT_SUCCESS(Status
))
448 SetLastError(RtlNtStatusToDosError(Status
));
461 GetInheritanceSourceW(LPWSTR pObjectName
,
462 SE_OBJECT_TYPE ObjectType
,
463 SECURITY_INFORMATION SecurityInfo
,
465 GUID
**pObjectClassGuids OPTIONAL
,
468 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL
,
469 PGENERIC_MAPPING pGenericMapping
,
470 PINHERITED_FROMW pInheritArray
)
474 ErrorCode
= CheckNtMartaPresent();
475 if (ErrorCode
== ERROR_SUCCESS
)
477 /* call the MARTA provider */
478 ErrorCode
= AccGetInheritanceSource(pObjectName
,
499 GetInheritanceSourceA(LPSTR pObjectName
,
500 SE_OBJECT_TYPE ObjectType
,
501 SECURITY_INFORMATION SecurityInfo
,
503 GUID
**pObjectClassGuids OPTIONAL
,
506 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL
,
507 PGENERIC_MAPPING pGenericMapping
,
508 PINHERITED_FROMA pInheritArray
)
510 /* That's all this function does, at least up to w2k3... Even MS was too
511 lazy to implement it... */
512 return ERROR_CALL_NOT_IMPLEMENTED
;
521 FreeInheritedFromArray(PINHERITED_FROMW pInheritArray
,
523 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL
)
527 ErrorCode
= CheckNtMartaPresent();
528 if (ErrorCode
== ERROR_SUCCESS
)
530 /* call the MARTA provider */
531 ErrorCode
= AccFreeIndexArray(pInheritArray
,
545 SetEntriesInAclW(ULONG cCountOfExplicitEntries
,
546 PEXPLICIT_ACCESS_W pListOfExplicitEntries
,
554 return ERROR_INVALID_PARAMETER
;
557 ErrorCode
= CheckNtMartaPresent();
558 if (ErrorCode
== ERROR_SUCCESS
)
560 /* call the MARTA provider */
561 ErrorCode
= AccRewriteSetEntriesInAcl(cCountOfExplicitEntries
,
562 pListOfExplicitEntries
,
572 InternalTrusteeAToW(IN PTRUSTEE_A pTrusteeA
,
573 OUT PTRUSTEE_W
*pTrusteeW
)
575 TRUSTEE_FORM TrusteeForm
;
578 DWORD ErrorCode
= ERROR_SUCCESS
;
580 //ASSERT(sizeof(TRUSTEE_W) == sizeof(TRUSTEE_A));
582 TrusteeForm
= GetTrusteeFormA(pTrusteeA
);
585 case TRUSTEE_IS_NAME
:
587 /* directly copy the array, this works as the size of the EXPLICIT_ACCESS_A
588 structure matches the size of the EXPLICIT_ACCESS_W version */
589 lpStr
= GetTrusteeNameA(pTrusteeA
);
591 BufferSize
= strlen(lpStr
) + 1;
593 *pTrusteeW
= RtlAllocateHeap(RtlGetProcessHeap(),
595 sizeof(TRUSTEE_W
) + (BufferSize
* sizeof(WCHAR
)));
596 if (*pTrusteeW
!= NULL
)
598 RtlCopyMemory(*pTrusteeW
,
600 FIELD_OFFSET(TRUSTEE_A
,
605 (*pTrusteeW
)->ptstrName
= (PWSTR
)((*pTrusteeW
) + 1);
607 /* convert the trustee's name */
608 if (MultiByteToWideChar(CP_ACP
,
612 (*pTrusteeW
)->ptstrName
,
620 RtlFreeHeap(RtlGetProcessHeap(),
623 goto NothingToConvert
;
627 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
631 case TRUSTEE_IS_OBJECTS_AND_NAME
:
633 POBJECTS_AND_NAME_A oanA
= (POBJECTS_AND_NAME_A
)GetTrusteeNameA(pTrusteeA
);
634 POBJECTS_AND_NAME_W oan
;
637 /* calculate the size needed */
638 if ((oanA
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
) &&
639 oanA
->InheritedObjectTypeName
!= NULL
)
641 BufferSize
= strlen(oanA
->InheritedObjectTypeName
) + 1;
643 if (oanA
->ptstrName
!= NULL
)
645 BufferSize
+= strlen(oanA
->ptstrName
) + 1;
648 *pTrusteeW
= RtlAllocateHeap(RtlGetProcessHeap(),
650 sizeof(TRUSTEE_W
) + sizeof(OBJECTS_AND_NAME_W
) +
651 (BufferSize
* sizeof(WCHAR
)));
653 if (*pTrusteeW
!= NULL
)
655 oan
= (POBJECTS_AND_NAME_W
)((*pTrusteeW
) + 1);
656 StrBuf
= (PWSTR
)(oan
+ 1);
658 /* copy over the parts of the TRUSTEE structure that don't need
660 RtlCopyMemory(*pTrusteeW
,
662 FIELD_OFFSET(TRUSTEE_A
,
665 (*pTrusteeW
)->ptstrName
= (LPWSTR
)oan
;
667 /* convert the OBJECTS_AND_NAME_A structure */
668 oan
->ObjectsPresent
= oanA
->ObjectsPresent
;
669 oan
->ObjectType
= oanA
->ObjectType
;
671 if ((oanA
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
) &&
672 oanA
->InheritedObjectTypeName
!= NULL
)
674 /* convert inherited object type name */
675 BufferSize
= strlen(oanA
->InheritedObjectTypeName
) + 1;
677 if (MultiByteToWideChar(CP_ACP
,
679 oanA
->InheritedObjectTypeName
,
686 oan
->InheritedObjectTypeName
= StrBuf
;
688 StrBuf
+= BufferSize
;
691 oan
->InheritedObjectTypeName
= NULL
;
693 if (oanA
->ptstrName
!= NULL
)
695 /* convert the trustee name */
696 BufferSize
= strlen(oanA
->ptstrName
) + 1;
698 if (MultiByteToWideChar(CP_ACP
,
707 oan
->ptstrName
= StrBuf
;
710 oan
->ptstrName
= NULL
;
713 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
720 /* no need to convert anything to unicode */
721 *pTrusteeW
= (PTRUSTEE_W
)pTrusteeA
;
729 ErrorCode
= GetLastError();
732 RtlFreeHeap(RtlGetProcessHeap(),
741 InternalFreeConvertedTrustee(IN PTRUSTEE_W pTrusteeW
,
742 IN PTRUSTEE_A pTrusteeA
)
744 if ((PVOID
)pTrusteeW
!= (PVOID
)pTrusteeA
)
746 RtlFreeHeap(RtlGetProcessHeap(),
754 InternalExplicitAccessAToW(IN ULONG cCountOfExplicitEntries
,
755 IN PEXPLICIT_ACCESS_A pListOfExplicitEntriesA
,
756 OUT PEXPLICIT_ACCESS_W
*pListOfExplicitEntriesW
)
758 TRUSTEE_FORM TrusteeForm
;
761 ULONG ObjectsAndNameCount
= 0;
762 PEXPLICIT_ACCESS_W peaw
= NULL
;
763 DWORD ErrorCode
= ERROR_SUCCESS
;
766 /* NOTE: This code assumes that the size of the TRUSTEE_A and TRUSTEE_W structure matches! */
767 //ASSERT(sizeof(TRUSTEE_A) == sizeof(TRUSTEE_W));
769 if (cCountOfExplicitEntries
!= 0)
771 /* calculate the size needed */
772 Size
= cCountOfExplicitEntries
* sizeof(EXPLICIT_ACCESS_W
);
773 for (i
= 0; i
!= cCountOfExplicitEntries
; i
++)
775 TrusteeForm
= GetTrusteeFormA(&pListOfExplicitEntriesA
[i
].Trustee
);
779 case TRUSTEE_IS_NAME
:
781 lpStr
= GetTrusteeNameA(&pListOfExplicitEntriesA
[i
].Trustee
);
783 Size
+= (strlen(lpStr
) + 1) * sizeof(WCHAR
);
787 case TRUSTEE_IS_OBJECTS_AND_NAME
:
789 POBJECTS_AND_NAME_A oan
= (POBJECTS_AND_NAME_A
)GetTrusteeNameA(&pListOfExplicitEntriesA
[i
].Trustee
);
791 if ((oan
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
) &&
792 oan
->InheritedObjectTypeName
!= NULL
)
794 Size
+= (strlen(oan
->InheritedObjectTypeName
) + 1) * sizeof(WCHAR
);
797 if (oan
->ptstrName
!= NULL
)
798 Size
+= (strlen(oan
->ptstrName
) + 1) * sizeof(WCHAR
);
800 ObjectsAndNameCount
++;
809 /* allocate the array */
810 peaw
= RtlAllocateHeap(RtlGetProcessHeap(),
816 POBJECTS_AND_NAME_W oan
= (POBJECTS_AND_NAME_W
)(peaw
+ cCountOfExplicitEntries
);
817 LPWSTR StrBuf
= (LPWSTR
)(oan
+ ObjectsAndNameCount
);
819 /* convert the array to unicode */
820 for (i
= 0; i
!= cCountOfExplicitEntries
; i
++)
822 peaw
[i
].grfAccessPermissions
= pListOfExplicitEntriesA
[i
].grfAccessPermissions
;
823 peaw
[i
].grfAccessMode
= pListOfExplicitEntriesA
[i
].grfAccessMode
;
824 peaw
[i
].grfInheritance
= pListOfExplicitEntriesA
[i
].grfInheritance
;
826 /* convert or copy the TRUSTEE structure */
827 TrusteeForm
= GetTrusteeFormA(&pListOfExplicitEntriesA
[i
].Trustee
);
830 case TRUSTEE_IS_NAME
:
832 lpStr
= GetTrusteeNameA(&pListOfExplicitEntriesA
[i
].Trustee
);
835 /* convert the trustee name */
836 BufferSize
= strlen(lpStr
) + 1;
838 if (MultiByteToWideChar(CP_ACP
,
847 peaw
[i
].Trustee
.ptstrName
= StrBuf
;
849 StrBuf
+= BufferSize
;
857 case TRUSTEE_IS_OBJECTS_AND_NAME
:
859 POBJECTS_AND_NAME_A oanA
= (POBJECTS_AND_NAME_A
)GetTrusteeNameA(&pListOfExplicitEntriesA
[i
].Trustee
);
861 /* copy over the parts of the TRUSTEE structure that don't need
863 RtlCopyMemory(&peaw
[i
].Trustee
,
864 &pListOfExplicitEntriesA
[i
].Trustee
,
865 FIELD_OFFSET(TRUSTEE_A
,
868 peaw
[i
].Trustee
.ptstrName
= (LPWSTR
)oan
;
870 /* convert the OBJECTS_AND_NAME_A structure */
871 oan
->ObjectsPresent
= oanA
->ObjectsPresent
;
872 oan
->ObjectType
= oanA
->ObjectType
;
874 if ((oanA
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
) &&
875 oanA
->InheritedObjectTypeName
!= NULL
)
877 /* convert inherited object type name */
878 BufferSize
= strlen(oanA
->InheritedObjectTypeName
) + 1;
880 if (MultiByteToWideChar(CP_ACP
,
882 oanA
->InheritedObjectTypeName
,
889 oan
->InheritedObjectTypeName
= StrBuf
;
891 StrBuf
+= BufferSize
;
894 oan
->InheritedObjectTypeName
= NULL
;
896 if (oanA
->ptstrName
!= NULL
)
898 /* convert the trustee name */
899 BufferSize
= strlen(oanA
->ptstrName
) + 1;
901 if (MultiByteToWideChar(CP_ACP
,
910 oan
->ptstrName
= StrBuf
;
912 StrBuf
+= BufferSize
;
915 oan
->ptstrName
= NULL
;
917 /* move on to the next OBJECTS_AND_NAME_A structure */
925 /* just copy over the TRUSTEE structure, they don't contain any
926 ansi/unicode specific data */
927 RtlCopyMemory(&peaw
[i
].Trustee
,
928 &pListOfExplicitEntriesA
[i
].Trustee
,
935 ASSERT(ErrorCode
== ERROR_SUCCESS
);
936 *pListOfExplicitEntriesW
= peaw
;
939 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
945 ErrorCode
= GetLastError();
948 RtlFreeHeap(RtlGetProcessHeap(),
961 SetEntriesInAclA(ULONG cCountOfExplicitEntries
,
962 PEXPLICIT_ACCESS_A pListOfExplicitEntries
,
966 PEXPLICIT_ACCESS_W ListOfExplicitEntriesW
= NULL
;
969 ErrorCode
= InternalExplicitAccessAToW(cCountOfExplicitEntries
,
970 pListOfExplicitEntries
,
971 &ListOfExplicitEntriesW
);
972 if (ErrorCode
== ERROR_SUCCESS
)
974 ErrorCode
= SetEntriesInAclW(cCountOfExplicitEntries
,
975 ListOfExplicitEntriesW
,
979 /* free the allocated array */
980 RtlFreeHeap(RtlGetProcessHeap(),
982 ListOfExplicitEntriesW
);
994 GetExplicitEntriesFromAclW(PACL pacl
,
995 PULONG pcCountOfExplicitEntries
,
996 PEXPLICIT_ACCESS_W
*pListOfExplicitEntries
)
1000 ErrorCode
= CheckNtMartaPresent();
1001 if (ErrorCode
== ERROR_SUCCESS
)
1003 /* call the MARTA provider */
1004 ErrorCode
= AccRewriteGetExplicitEntriesFromAcl(pacl
,
1005 pcCountOfExplicitEntries
,
1006 pListOfExplicitEntries
);
1018 GetEffectiveRightsFromAclW(IN PACL pacl
,
1019 IN PTRUSTEE_W pTrustee
,
1020 OUT PACCESS_MASK pAccessRights
)
1022 FIXME("%p %p %p - stub\n", pacl
, pTrustee
, pAccessRights
);
1024 *pAccessRights
= STANDARD_RIGHTS_ALL
| SPECIFIC_RIGHTS_ALL
;
1025 return ERROR_SUCCESS
;
1034 GetEffectiveRightsFromAclA(IN PACL pacl
,
1035 IN PTRUSTEE_A pTrustee
,
1036 OUT PACCESS_MASK pAccessRights
)
1038 PTRUSTEE_W pTrusteeW
= NULL
;
1041 ErrorCode
= InternalTrusteeAToW(pTrustee
,
1043 if (ErrorCode
== ERROR_SUCCESS
)
1045 ErrorCode
= GetEffectiveRightsFromAclW(pacl
,
1049 InternalFreeConvertedTrustee(pTrusteeW
,
1053 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
1064 GetAuditedPermissionsFromAclW(IN PACL pacl
,
1065 IN PTRUSTEE_W pTrustee
,
1066 OUT PACCESS_MASK pSuccessfulAuditedRights
,
1067 OUT PACCESS_MASK pFailedAuditRights
)
1069 FIXME("%s() not implemented!\n", __FUNCTION__
);
1070 return ERROR_CALL_NOT_IMPLEMENTED
;
1079 GetAuditedPermissionsFromAclA(IN PACL pacl
,
1080 IN PTRUSTEE_A pTrustee
,
1081 OUT PACCESS_MASK pSuccessfulAuditedRights
,
1082 OUT PACCESS_MASK pFailedAuditRights
)
1084 PTRUSTEE_W pTrusteeW
= NULL
;
1087 ErrorCode
= InternalTrusteeAToW(pTrustee
,
1089 if (ErrorCode
== ERROR_SUCCESS
)
1091 ErrorCode
= GetAuditedPermissionsFromAclW(pacl
,
1093 pSuccessfulAuditedRights
,
1094 pFailedAuditRights
);
1096 InternalFreeConvertedTrustee(pTrusteeW
,
1100 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;