2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/advapi32/sec/ac.c
5 * PURPOSE: ACL/ACE functions
9 WINE_DEFAULT_DEBUG_CHANNEL(advapi
);
18 GetAclInformation(PACL pAcl
,
19 LPVOID pAclInformation
,
20 DWORD nAclInformationLength
,
21 ACL_INFORMATION_CLASS dwAclInformationClass
)
25 Status
= RtlQueryInformationAcl(pAcl
,
27 nAclInformationLength
,
28 dwAclInformationClass
);
29 if (!NT_SUCCESS(Status
))
31 SetLastError(RtlNtStatusToDosError(Status
));
44 InitializeAcl(PACL pAcl
,
50 Status
= RtlCreateAcl(pAcl
,
53 if (!NT_SUCCESS(Status
))
55 SetLastError(RtlNtStatusToDosError(Status
));
70 return RtlValidAcl (pAcl
);
79 SetAclInformation(PACL pAcl
,
80 LPVOID pAclInformation
,
81 DWORD nAclInformationLength
,
82 ACL_INFORMATION_CLASS dwAclInformationClass
)
86 Status
= RtlSetInformationAcl(pAcl
,
88 nAclInformationLength
,
89 dwAclInformationClass
);
90 if (!NT_SUCCESS(Status
))
92 SetLastError(RtlNtStatusToDosError(Status
));
107 AddAccessAllowedAce(PACL pAcl
,
114 Status
= RtlAddAccessAllowedAce(pAcl
,
118 if (!NT_SUCCESS(Status
))
120 SetLastError(RtlNtStatusToDosError(Status
));
132 AddAccessAllowedAceEx(PACL pAcl
,
140 Status
= RtlAddAccessAllowedAceEx(pAcl
,
145 if (!NT_SUCCESS(Status
))
147 SetLastError(RtlNtStatusToDosError(Status
));
160 AddAccessAllowedObjectAce(PACL pAcl
,
164 GUID
*ObjectTypeGuid
,
165 GUID
*InheritedObjectTypeGuid
,
170 Status
= RtlAddAccessAllowedObjectAce(pAcl
,
175 InheritedObjectTypeGuid
,
177 if (!NT_SUCCESS(Status
))
179 SetLastError(RtlNtStatusToDosError(Status
));
192 AddAccessDeniedAce(PACL pAcl
,
199 Status
= RtlAddAccessDeniedAce(pAcl
,
203 if (!NT_SUCCESS(Status
))
205 SetLastError(RtlNtStatusToDosError(Status
));
217 AddAccessDeniedAceEx(PACL pAcl
,
225 Status
= RtlAddAccessDeniedAceEx(pAcl
,
230 if (!NT_SUCCESS(Status
))
232 SetLastError(RtlNtStatusToDosError(Status
));
245 AddAccessDeniedObjectAce(PACL pAcl
,
249 GUID
* ObjectTypeGuid
,
250 GUID
* InheritedObjectTypeGuid
,
255 Status
= RtlAddAccessDeniedObjectAce(pAcl
,
260 InheritedObjectTypeGuid
,
262 if (!NT_SUCCESS(Status
))
264 SetLastError(RtlNtStatusToDosError(Status
));
279 DWORD dwStartingAceIndex
,
281 DWORD nAceListLength
)
285 Status
= RtlAddAce(pAcl
,
290 if (!NT_SUCCESS(Status
))
292 SetLastError(RtlNtStatusToDosError(Status
));
305 AddAuditAccessAce(PACL pAcl
,
314 Status
= RtlAddAuditAccessAce(pAcl
,
320 if (!NT_SUCCESS(Status
))
322 SetLastError(RtlNtStatusToDosError(Status
));
334 AddAuditAccessAceEx(PACL pAcl
,
344 Status
= RtlAddAuditAccessAceEx(pAcl
,
351 if (!NT_SUCCESS(Status
))
353 SetLastError(RtlNtStatusToDosError(Status
));
366 AddAuditAccessObjectAce(PACL pAcl
,
370 GUID
*ObjectTypeGuid
,
371 GUID
*InheritedObjectTypeGuid
,
378 Status
= RtlAddAuditAccessObjectAce(pAcl
,
383 InheritedObjectTypeGuid
,
387 if (!NT_SUCCESS(Status
))
389 SetLastError(RtlNtStatusToDosError(Status
));
406 Status
= RtlDeleteAce(pAcl
,
408 if (!NT_SUCCESS(Status
))
410 SetLastError(RtlNtStatusToDosError(Status
));
423 FindFirstFreeAce(PACL pAcl
,
426 return RtlFirstFreeAce(pAcl
,
442 Status
= RtlGetAce(pAcl
,
445 if (!NT_SUCCESS(Status
))
447 SetLastError(RtlNtStatusToDosError(Status
));
460 GetInheritanceSourceW(LPWSTR pObjectName
,
461 SE_OBJECT_TYPE ObjectType
,
462 SECURITY_INFORMATION SecurityInfo
,
464 GUID
**pObjectClassGuids OPTIONAL
,
467 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL
,
468 PGENERIC_MAPPING pGenericMapping
,
469 PINHERITED_FROMW pInheritArray
)
473 ErrorCode
= CheckNtMartaPresent();
474 if (ErrorCode
== ERROR_SUCCESS
)
476 /* call the MARTA provider */
477 ErrorCode
= AccGetInheritanceSource(pObjectName
,
498 GetInheritanceSourceA(LPSTR pObjectName
,
499 SE_OBJECT_TYPE ObjectType
,
500 SECURITY_INFORMATION SecurityInfo
,
502 GUID
**pObjectClassGuids OPTIONAL
,
505 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL
,
506 PGENERIC_MAPPING pGenericMapping
,
507 PINHERITED_FROMA pInheritArray
)
509 /* That's all this function does, at least up to w2k3... Even MS was too
510 lazy to implement it... */
511 return ERROR_CALL_NOT_IMPLEMENTED
;
520 FreeInheritedFromArray(PINHERITED_FROMW pInheritArray
,
522 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL
)
526 ErrorCode
= CheckNtMartaPresent();
527 if (ErrorCode
== ERROR_SUCCESS
)
529 /* call the MARTA provider */
530 ErrorCode
= AccFreeIndexArray(pInheritArray
,
544 SetEntriesInAclW(ULONG cCountOfExplicitEntries
,
545 PEXPLICIT_ACCESS_W pListOfExplicitEntries
,
553 return ERROR_INVALID_PARAMETER
;
556 ErrorCode
= CheckNtMartaPresent();
557 if (ErrorCode
== ERROR_SUCCESS
)
559 /* call the MARTA provider */
560 ErrorCode
= AccRewriteSetEntriesInAcl(cCountOfExplicitEntries
,
561 pListOfExplicitEntries
,
571 InternalTrusteeAToW(IN PTRUSTEE_A pTrusteeA
,
572 OUT PTRUSTEE_W
*pTrusteeW
)
574 TRUSTEE_FORM TrusteeForm
;
577 DWORD ErrorCode
= ERROR_SUCCESS
;
579 //ASSERT(sizeof(TRUSTEE_W) == sizeof(TRUSTEE_A));
581 TrusteeForm
= GetTrusteeFormA(pTrusteeA
);
584 case TRUSTEE_IS_NAME
:
586 /* directly copy the array, this works as the size of the EXPLICIT_ACCESS_A
587 structure matches the size of the EXPLICIT_ACCESS_W version */
588 lpStr
= GetTrusteeNameA(pTrusteeA
);
590 BufferSize
= strlen(lpStr
) + 1;
592 *pTrusteeW
= RtlAllocateHeap(RtlGetProcessHeap(),
594 sizeof(TRUSTEE_W
) + (BufferSize
* sizeof(WCHAR
)));
595 if (*pTrusteeW
!= NULL
)
597 RtlCopyMemory(*pTrusteeW
,
599 FIELD_OFFSET(TRUSTEE_A
,
604 (*pTrusteeW
)->ptstrName
= (PWSTR
)((*pTrusteeW
) + 1);
606 /* convert the trustee's name */
607 if (MultiByteToWideChar(CP_ACP
,
611 (*pTrusteeW
)->ptstrName
,
619 RtlFreeHeap(RtlGetProcessHeap(),
622 goto NothingToConvert
;
626 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
630 case TRUSTEE_IS_OBJECTS_AND_NAME
:
632 POBJECTS_AND_NAME_A oanA
= (POBJECTS_AND_NAME_A
)GetTrusteeNameA(pTrusteeA
);
633 POBJECTS_AND_NAME_W oan
;
636 /* calculate the size needed */
637 if ((oanA
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
) &&
638 oanA
->InheritedObjectTypeName
!= NULL
)
640 BufferSize
= strlen(oanA
->InheritedObjectTypeName
) + 1;
642 if (oanA
->ptstrName
!= NULL
)
644 BufferSize
+= strlen(oanA
->ptstrName
) + 1;
647 *pTrusteeW
= RtlAllocateHeap(RtlGetProcessHeap(),
649 sizeof(TRUSTEE_W
) + sizeof(OBJECTS_AND_NAME_W
) +
650 (BufferSize
* sizeof(WCHAR
)));
652 if (*pTrusteeW
!= NULL
)
654 oan
= (POBJECTS_AND_NAME_W
)((*pTrusteeW
) + 1);
655 StrBuf
= (PWSTR
)(oan
+ 1);
657 /* copy over the parts of the TRUSTEE structure that don't need
659 RtlCopyMemory(*pTrusteeW
,
661 FIELD_OFFSET(TRUSTEE_A
,
664 (*pTrusteeW
)->ptstrName
= (LPWSTR
)oan
;
666 /* convert the OBJECTS_AND_NAME_A structure */
667 oan
->ObjectsPresent
= oanA
->ObjectsPresent
;
668 oan
->ObjectType
= oanA
->ObjectType
;
670 if ((oanA
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
) &&
671 oanA
->InheritedObjectTypeName
!= NULL
)
673 /* convert inherited object type name */
674 BufferSize
= strlen(oanA
->InheritedObjectTypeName
) + 1;
676 if (MultiByteToWideChar(CP_ACP
,
678 oanA
->InheritedObjectTypeName
,
685 oan
->InheritedObjectTypeName
= StrBuf
;
687 StrBuf
+= BufferSize
;
690 oan
->InheritedObjectTypeName
= NULL
;
692 if (oanA
->ptstrName
!= NULL
)
694 /* convert the trustee name */
695 BufferSize
= strlen(oanA
->ptstrName
) + 1;
697 if (MultiByteToWideChar(CP_ACP
,
706 oan
->ptstrName
= StrBuf
;
709 oan
->ptstrName
= NULL
;
712 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
719 /* no need to convert anything to unicode */
720 *pTrusteeW
= (PTRUSTEE_W
)pTrusteeA
;
728 ErrorCode
= GetLastError();
731 RtlFreeHeap(RtlGetProcessHeap(),
740 InternalFreeConvertedTrustee(IN PTRUSTEE_W pTrusteeW
,
741 IN PTRUSTEE_A pTrusteeA
)
743 if ((PVOID
)pTrusteeW
!= (PVOID
)pTrusteeA
)
745 RtlFreeHeap(RtlGetProcessHeap(),
753 InternalExplicitAccessAToW(IN ULONG cCountOfExplicitEntries
,
754 IN PEXPLICIT_ACCESS_A pListOfExplicitEntriesA
,
755 OUT PEXPLICIT_ACCESS_W
*pListOfExplicitEntriesW
)
757 TRUSTEE_FORM TrusteeForm
;
760 ULONG ObjectsAndNameCount
= 0;
761 PEXPLICIT_ACCESS_W peaw
= NULL
;
762 DWORD ErrorCode
= ERROR_SUCCESS
;
765 /* NOTE: This code assumes that the size of the TRUSTEE_A and TRUSTEE_W structure matches! */
766 //ASSERT(sizeof(TRUSTEE_A) == sizeof(TRUSTEE_W));
768 if (cCountOfExplicitEntries
!= 0)
770 /* calculate the size needed */
771 Size
= cCountOfExplicitEntries
* sizeof(EXPLICIT_ACCESS_W
);
772 for (i
= 0; i
!= cCountOfExplicitEntries
; i
++)
774 TrusteeForm
= GetTrusteeFormA(&pListOfExplicitEntriesA
[i
].Trustee
);
778 case TRUSTEE_IS_NAME
:
780 lpStr
= GetTrusteeNameA(&pListOfExplicitEntriesA
[i
].Trustee
);
782 Size
+= (strlen(lpStr
) + 1) * sizeof(WCHAR
);
786 case TRUSTEE_IS_OBJECTS_AND_NAME
:
788 POBJECTS_AND_NAME_A oan
= (POBJECTS_AND_NAME_A
)GetTrusteeNameA(&pListOfExplicitEntriesA
[i
].Trustee
);
790 if ((oan
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
) &&
791 oan
->InheritedObjectTypeName
!= NULL
)
793 Size
+= (strlen(oan
->InheritedObjectTypeName
) + 1) * sizeof(WCHAR
);
796 if (oan
->ptstrName
!= NULL
)
797 Size
+= (strlen(oan
->ptstrName
) + 1) * sizeof(WCHAR
);
799 ObjectsAndNameCount
++;
808 /* allocate the array */
809 peaw
= RtlAllocateHeap(RtlGetProcessHeap(),
815 POBJECTS_AND_NAME_W oan
= (POBJECTS_AND_NAME_W
)(peaw
+ cCountOfExplicitEntries
);
816 LPWSTR StrBuf
= (LPWSTR
)(oan
+ ObjectsAndNameCount
);
818 /* convert the array to unicode */
819 for (i
= 0; i
!= cCountOfExplicitEntries
; i
++)
821 peaw
[i
].grfAccessPermissions
= pListOfExplicitEntriesA
[i
].grfAccessPermissions
;
822 peaw
[i
].grfAccessMode
= pListOfExplicitEntriesA
[i
].grfAccessMode
;
823 peaw
[i
].grfInheritance
= pListOfExplicitEntriesA
[i
].grfInheritance
;
825 /* convert or copy the TRUSTEE structure */
826 TrusteeForm
= GetTrusteeFormA(&pListOfExplicitEntriesA
[i
].Trustee
);
829 case TRUSTEE_IS_NAME
:
831 lpStr
= GetTrusteeNameA(&pListOfExplicitEntriesA
[i
].Trustee
);
834 /* convert the trustee name */
835 BufferSize
= strlen(lpStr
) + 1;
837 if (MultiByteToWideChar(CP_ACP
,
846 peaw
[i
].Trustee
.ptstrName
= StrBuf
;
848 StrBuf
+= BufferSize
;
856 case TRUSTEE_IS_OBJECTS_AND_NAME
:
858 POBJECTS_AND_NAME_A oanA
= (POBJECTS_AND_NAME_A
)GetTrusteeNameA(&pListOfExplicitEntriesA
[i
].Trustee
);
860 /* copy over the parts of the TRUSTEE structure that don't need
862 RtlCopyMemory(&peaw
[i
].Trustee
,
863 &pListOfExplicitEntriesA
[i
].Trustee
,
864 FIELD_OFFSET(TRUSTEE_A
,
867 peaw
[i
].Trustee
.ptstrName
= (LPWSTR
)oan
;
869 /* convert the OBJECTS_AND_NAME_A structure */
870 oan
->ObjectsPresent
= oanA
->ObjectsPresent
;
871 oan
->ObjectType
= oanA
->ObjectType
;
873 if ((oanA
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
) &&
874 oanA
->InheritedObjectTypeName
!= NULL
)
876 /* convert inherited object type name */
877 BufferSize
= strlen(oanA
->InheritedObjectTypeName
) + 1;
879 if (MultiByteToWideChar(CP_ACP
,
881 oanA
->InheritedObjectTypeName
,
888 oan
->InheritedObjectTypeName
= StrBuf
;
890 StrBuf
+= BufferSize
;
893 oan
->InheritedObjectTypeName
= NULL
;
895 if (oanA
->ptstrName
!= NULL
)
897 /* convert the trustee name */
898 BufferSize
= strlen(oanA
->ptstrName
) + 1;
900 if (MultiByteToWideChar(CP_ACP
,
909 oan
->ptstrName
= StrBuf
;
911 StrBuf
+= BufferSize
;
914 oan
->ptstrName
= NULL
;
916 /* move on to the next OBJECTS_AND_NAME_A structure */
924 /* just copy over the TRUSTEE structure, they don't contain any
925 ansi/unicode specific data */
926 RtlCopyMemory(&peaw
[i
].Trustee
,
927 &pListOfExplicitEntriesA
[i
].Trustee
,
934 ASSERT(ErrorCode
== ERROR_SUCCESS
);
935 *pListOfExplicitEntriesW
= peaw
;
938 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
944 ErrorCode
= GetLastError();
947 RtlFreeHeap(RtlGetProcessHeap(),
960 SetEntriesInAclA(ULONG cCountOfExplicitEntries
,
961 PEXPLICIT_ACCESS_A pListOfExplicitEntries
,
965 PEXPLICIT_ACCESS_W ListOfExplicitEntriesW
= NULL
;
968 ErrorCode
= InternalExplicitAccessAToW(cCountOfExplicitEntries
,
969 pListOfExplicitEntries
,
970 &ListOfExplicitEntriesW
);
971 if (ErrorCode
== ERROR_SUCCESS
)
973 ErrorCode
= SetEntriesInAclW(cCountOfExplicitEntries
,
974 ListOfExplicitEntriesW
,
978 /* free the allocated array */
979 RtlFreeHeap(RtlGetProcessHeap(),
981 ListOfExplicitEntriesW
);
993 GetExplicitEntriesFromAclW(PACL pacl
,
994 PULONG pcCountOfExplicitEntries
,
995 PEXPLICIT_ACCESS_W
*pListOfExplicitEntries
)
999 ErrorCode
= CheckNtMartaPresent();
1000 if (ErrorCode
== ERROR_SUCCESS
)
1002 /* call the MARTA provider */
1003 ErrorCode
= AccRewriteGetExplicitEntriesFromAcl(pacl
,
1004 pcCountOfExplicitEntries
,
1005 pListOfExplicitEntries
);
1017 GetEffectiveRightsFromAclW(IN PACL pacl
,
1018 IN PTRUSTEE_W pTrustee
,
1019 OUT PACCESS_MASK pAccessRights
)
1021 FIXME("%p %p %p - stub\n", pacl
, pTrustee
, pAccessRights
);
1023 *pAccessRights
= STANDARD_RIGHTS_ALL
| SPECIFIC_RIGHTS_ALL
;
1024 return ERROR_SUCCESS
;
1033 GetEffectiveRightsFromAclA(IN PACL pacl
,
1034 IN PTRUSTEE_A pTrustee
,
1035 OUT PACCESS_MASK pAccessRights
)
1037 PTRUSTEE_W pTrusteeW
= NULL
;
1040 ErrorCode
= InternalTrusteeAToW(pTrustee
,
1042 if (ErrorCode
== ERROR_SUCCESS
)
1044 ErrorCode
= GetEffectiveRightsFromAclW(pacl
,
1048 InternalFreeConvertedTrustee(pTrusteeW
,
1052 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
1063 GetAuditedPermissionsFromAclW(IN PACL pacl
,
1064 IN PTRUSTEE_W pTrustee
,
1065 OUT PACCESS_MASK pSuccessfulAuditedRights
,
1066 OUT PACCESS_MASK pFailedAuditRights
)
1068 FIXME("%s() not implemented!\n", __FUNCTION__
);
1069 return ERROR_CALL_NOT_IMPLEMENTED
;
1078 GetAuditedPermissionsFromAclA(IN PACL pacl
,
1079 IN PTRUSTEE_A pTrustee
,
1080 OUT PACCESS_MASK pSuccessfulAuditedRights
,
1081 OUT PACCESS_MASK pFailedAuditRights
)
1083 PTRUSTEE_W pTrusteeW
= NULL
;
1086 ErrorCode
= InternalTrusteeAToW(pTrustee
,
1088 if (ErrorCode
== ERROR_SUCCESS
)
1090 ErrorCode
= GetAuditedPermissionsFromAclW(pacl
,
1092 pSuccessfulAuditedRights
,
1093 pFailedAuditRights
);
1095 InternalFreeConvertedTrustee(pTrusteeW
,
1099 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;