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 AddAccessAllowedObjectAce(PACL pAcl
,
23 GUID
*InheritedObjectTypeGuid
,
28 Status
= RtlAddAccessAllowedObjectAce(pAcl
,
33 InheritedObjectTypeGuid
,
35 if (!NT_SUCCESS(Status
))
37 SetLastError(RtlNtStatusToDosError(Status
));
49 AddAccessDeniedObjectAce(PACL pAcl
,
54 GUID
* InheritedObjectTypeGuid
,
59 Status
= RtlAddAccessDeniedObjectAce(pAcl
,
64 InheritedObjectTypeGuid
,
66 if (!NT_SUCCESS(Status
))
68 SetLastError(RtlNtStatusToDosError(Status
));
80 AddAuditAccessObjectAce(PACL pAcl
,
85 GUID
*InheritedObjectTypeGuid
,
92 Status
= RtlAddAuditAccessObjectAce(pAcl
,
97 InheritedObjectTypeGuid
,
101 if (!NT_SUCCESS(Status
))
103 SetLastError(RtlNtStatusToDosError(Status
));
115 GetInheritanceSourceW(LPWSTR pObjectName
,
116 SE_OBJECT_TYPE ObjectType
,
117 SECURITY_INFORMATION SecurityInfo
,
119 GUID
**pObjectClassGuids OPTIONAL
,
122 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL
,
123 PGENERIC_MAPPING pGenericMapping
,
124 PINHERITED_FROMW pInheritArray
)
128 ErrorCode
= CheckNtMartaPresent();
129 if (ErrorCode
== ERROR_SUCCESS
)
131 /* call the MARTA provider */
132 ErrorCode
= AccGetInheritanceSource(pObjectName
,
153 GetInheritanceSourceA(LPSTR pObjectName
,
154 SE_OBJECT_TYPE ObjectType
,
155 SECURITY_INFORMATION SecurityInfo
,
157 GUID
**pObjectClassGuids OPTIONAL
,
160 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL
,
161 PGENERIC_MAPPING pGenericMapping
,
162 PINHERITED_FROMA pInheritArray
)
164 /* That's all this function does, at least up to w2k3... Even MS was too
165 lazy to implement it... */
166 return ERROR_CALL_NOT_IMPLEMENTED
;
175 FreeInheritedFromArray(PINHERITED_FROMW pInheritArray
,
177 PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL
)
181 ErrorCode
= CheckNtMartaPresent();
182 if (ErrorCode
== ERROR_SUCCESS
)
184 /* call the MARTA provider */
185 ErrorCode
= AccFreeIndexArray(pInheritArray
,
199 SetEntriesInAclW(ULONG cCountOfExplicitEntries
,
200 PEXPLICIT_ACCESS_W pListOfExplicitEntries
,
208 return ERROR_INVALID_PARAMETER
;
211 ErrorCode
= CheckNtMartaPresent();
212 if (ErrorCode
== ERROR_SUCCESS
)
214 /* call the MARTA provider */
215 ErrorCode
= AccRewriteSetEntriesInAcl(cCountOfExplicitEntries
,
216 pListOfExplicitEntries
,
226 InternalTrusteeAToW(IN PTRUSTEE_A pTrusteeA
,
227 OUT PTRUSTEE_W
*pTrusteeW
)
229 TRUSTEE_FORM TrusteeForm
;
232 DWORD ErrorCode
= ERROR_SUCCESS
;
234 //ASSERT(sizeof(TRUSTEE_W) == sizeof(TRUSTEE_A));
236 TrusteeForm
= GetTrusteeFormA(pTrusteeA
);
239 case TRUSTEE_IS_NAME
:
241 /* directly copy the array, this works as the size of the EXPLICIT_ACCESS_A
242 structure matches the size of the EXPLICIT_ACCESS_W version */
243 lpStr
= GetTrusteeNameA(pTrusteeA
);
245 BufferSize
= strlen(lpStr
) + 1;
247 *pTrusteeW
= RtlAllocateHeap(RtlGetProcessHeap(),
249 sizeof(TRUSTEE_W
) + (BufferSize
* sizeof(WCHAR
)));
250 if (*pTrusteeW
!= NULL
)
252 RtlCopyMemory(*pTrusteeW
,
254 FIELD_OFFSET(TRUSTEE_A
,
259 (*pTrusteeW
)->ptstrName
= (PWSTR
)((*pTrusteeW
) + 1);
261 /* convert the trustee's name */
262 if (MultiByteToWideChar(CP_ACP
,
266 (*pTrusteeW
)->ptstrName
,
274 RtlFreeHeap(RtlGetProcessHeap(),
277 goto NothingToConvert
;
281 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
285 case TRUSTEE_IS_OBJECTS_AND_NAME
:
287 POBJECTS_AND_NAME_A oanA
= (POBJECTS_AND_NAME_A
)GetTrusteeNameA(pTrusteeA
);
288 POBJECTS_AND_NAME_W oan
;
291 /* calculate the size needed */
292 if ((oanA
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
) &&
293 oanA
->InheritedObjectTypeName
!= NULL
)
295 BufferSize
= strlen(oanA
->InheritedObjectTypeName
) + 1;
297 if (oanA
->ptstrName
!= NULL
)
299 BufferSize
+= strlen(oanA
->ptstrName
) + 1;
302 *pTrusteeW
= RtlAllocateHeap(RtlGetProcessHeap(),
304 sizeof(TRUSTEE_W
) + sizeof(OBJECTS_AND_NAME_W
) +
305 (BufferSize
* sizeof(WCHAR
)));
307 if (*pTrusteeW
!= NULL
)
309 oan
= (POBJECTS_AND_NAME_W
)((*pTrusteeW
) + 1);
310 StrBuf
= (PWSTR
)(oan
+ 1);
312 /* copy over the parts of the TRUSTEE structure that don't need
314 RtlCopyMemory(*pTrusteeW
,
316 FIELD_OFFSET(TRUSTEE_A
,
319 (*pTrusteeW
)->ptstrName
= (LPWSTR
)oan
;
321 /* convert the OBJECTS_AND_NAME_A structure */
322 oan
->ObjectsPresent
= oanA
->ObjectsPresent
;
323 oan
->ObjectType
= oanA
->ObjectType
;
325 if ((oanA
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
) &&
326 oanA
->InheritedObjectTypeName
!= NULL
)
328 /* convert inherited object type name */
329 BufferSize
= strlen(oanA
->InheritedObjectTypeName
) + 1;
331 if (MultiByteToWideChar(CP_ACP
,
333 oanA
->InheritedObjectTypeName
,
340 oan
->InheritedObjectTypeName
= StrBuf
;
342 StrBuf
+= BufferSize
;
345 oan
->InheritedObjectTypeName
= NULL
;
347 if (oanA
->ptstrName
!= NULL
)
349 /* convert the trustee name */
350 BufferSize
= strlen(oanA
->ptstrName
) + 1;
352 if (MultiByteToWideChar(CP_ACP
,
361 oan
->ptstrName
= StrBuf
;
364 oan
->ptstrName
= NULL
;
367 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
374 /* no need to convert anything to unicode */
375 *pTrusteeW
= (PTRUSTEE_W
)pTrusteeA
;
383 ErrorCode
= GetLastError();
386 RtlFreeHeap(RtlGetProcessHeap(),
395 InternalFreeConvertedTrustee(IN PTRUSTEE_W pTrusteeW
,
396 IN PTRUSTEE_A pTrusteeA
)
398 if ((PVOID
)pTrusteeW
!= (PVOID
)pTrusteeA
)
400 RtlFreeHeap(RtlGetProcessHeap(),
408 InternalExplicitAccessAToW(IN ULONG cCountOfExplicitEntries
,
409 IN PEXPLICIT_ACCESS_A pListOfExplicitEntriesA
,
410 OUT PEXPLICIT_ACCESS_W
*pListOfExplicitEntriesW
)
412 TRUSTEE_FORM TrusteeForm
;
415 ULONG ObjectsAndNameCount
= 0;
416 PEXPLICIT_ACCESS_W peaw
= NULL
;
417 DWORD ErrorCode
= ERROR_SUCCESS
;
420 /* NOTE: This code assumes that the size of the TRUSTEE_A and TRUSTEE_W structure matches! */
421 //ASSERT(sizeof(TRUSTEE_A) == sizeof(TRUSTEE_W));
423 if (cCountOfExplicitEntries
!= 0)
425 /* calculate the size needed */
426 Size
= cCountOfExplicitEntries
* sizeof(EXPLICIT_ACCESS_W
);
427 for (i
= 0; i
!= cCountOfExplicitEntries
; i
++)
429 TrusteeForm
= GetTrusteeFormA(&pListOfExplicitEntriesA
[i
].Trustee
);
433 case TRUSTEE_IS_NAME
:
435 lpStr
= GetTrusteeNameA(&pListOfExplicitEntriesA
[i
].Trustee
);
437 Size
+= (strlen(lpStr
) + 1) * sizeof(WCHAR
);
441 case TRUSTEE_IS_OBJECTS_AND_NAME
:
443 POBJECTS_AND_NAME_A oan
= (POBJECTS_AND_NAME_A
)GetTrusteeNameA(&pListOfExplicitEntriesA
[i
].Trustee
);
445 if ((oan
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
) &&
446 oan
->InheritedObjectTypeName
!= NULL
)
448 Size
+= (strlen(oan
->InheritedObjectTypeName
) + 1) * sizeof(WCHAR
);
451 if (oan
->ptstrName
!= NULL
)
452 Size
+= (strlen(oan
->ptstrName
) + 1) * sizeof(WCHAR
);
454 ObjectsAndNameCount
++;
463 /* allocate the array */
464 peaw
= RtlAllocateHeap(RtlGetProcessHeap(),
470 POBJECTS_AND_NAME_W oan
= (POBJECTS_AND_NAME_W
)(peaw
+ cCountOfExplicitEntries
);
471 LPWSTR StrBuf
= (LPWSTR
)(oan
+ ObjectsAndNameCount
);
473 /* convert the array to unicode */
474 for (i
= 0; i
!= cCountOfExplicitEntries
; i
++)
476 peaw
[i
].grfAccessPermissions
= pListOfExplicitEntriesA
[i
].grfAccessPermissions
;
477 peaw
[i
].grfAccessMode
= pListOfExplicitEntriesA
[i
].grfAccessMode
;
478 peaw
[i
].grfInheritance
= pListOfExplicitEntriesA
[i
].grfInheritance
;
480 /* convert or copy the TRUSTEE structure */
481 TrusteeForm
= GetTrusteeFormA(&pListOfExplicitEntriesA
[i
].Trustee
);
484 case TRUSTEE_IS_NAME
:
486 lpStr
= GetTrusteeNameA(&pListOfExplicitEntriesA
[i
].Trustee
);
489 /* convert the trustee name */
490 BufferSize
= strlen(lpStr
) + 1;
492 if (MultiByteToWideChar(CP_ACP
,
501 peaw
[i
].Trustee
.ptstrName
= StrBuf
;
503 StrBuf
+= BufferSize
;
511 case TRUSTEE_IS_OBJECTS_AND_NAME
:
513 POBJECTS_AND_NAME_A oanA
= (POBJECTS_AND_NAME_A
)GetTrusteeNameA(&pListOfExplicitEntriesA
[i
].Trustee
);
515 /* copy over the parts of the TRUSTEE structure that don't need
517 RtlCopyMemory(&peaw
[i
].Trustee
,
518 &pListOfExplicitEntriesA
[i
].Trustee
,
519 FIELD_OFFSET(TRUSTEE_A
,
522 peaw
[i
].Trustee
.ptstrName
= (LPWSTR
)oan
;
524 /* convert the OBJECTS_AND_NAME_A structure */
525 oan
->ObjectsPresent
= oanA
->ObjectsPresent
;
526 oan
->ObjectType
= oanA
->ObjectType
;
528 if ((oanA
->ObjectsPresent
& ACE_INHERITED_OBJECT_TYPE_PRESENT
) &&
529 oanA
->InheritedObjectTypeName
!= NULL
)
531 /* convert inherited object type name */
532 BufferSize
= strlen(oanA
->InheritedObjectTypeName
) + 1;
534 if (MultiByteToWideChar(CP_ACP
,
536 oanA
->InheritedObjectTypeName
,
543 oan
->InheritedObjectTypeName
= StrBuf
;
545 StrBuf
+= BufferSize
;
548 oan
->InheritedObjectTypeName
= NULL
;
550 if (oanA
->ptstrName
!= NULL
)
552 /* convert the trustee name */
553 BufferSize
= strlen(oanA
->ptstrName
) + 1;
555 if (MultiByteToWideChar(CP_ACP
,
564 oan
->ptstrName
= StrBuf
;
566 StrBuf
+= BufferSize
;
569 oan
->ptstrName
= NULL
;
571 /* move on to the next OBJECTS_AND_NAME_A structure */
579 /* just copy over the TRUSTEE structure, they don't contain any
580 ansi/unicode specific data */
581 RtlCopyMemory(&peaw
[i
].Trustee
,
582 &pListOfExplicitEntriesA
[i
].Trustee
,
589 ASSERT(ErrorCode
== ERROR_SUCCESS
);
590 *pListOfExplicitEntriesW
= peaw
;
593 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
599 ErrorCode
= GetLastError();
602 RtlFreeHeap(RtlGetProcessHeap(),
615 SetEntriesInAclA(ULONG cCountOfExplicitEntries
,
616 PEXPLICIT_ACCESS_A pListOfExplicitEntries
,
620 PEXPLICIT_ACCESS_W ListOfExplicitEntriesW
= NULL
;
623 ErrorCode
= InternalExplicitAccessAToW(cCountOfExplicitEntries
,
624 pListOfExplicitEntries
,
625 &ListOfExplicitEntriesW
);
626 if (ErrorCode
== ERROR_SUCCESS
)
628 ErrorCode
= SetEntriesInAclW(cCountOfExplicitEntries
,
629 ListOfExplicitEntriesW
,
633 /* free the allocated array */
634 RtlFreeHeap(RtlGetProcessHeap(),
636 ListOfExplicitEntriesW
);
648 GetExplicitEntriesFromAclW(PACL pacl
,
649 PULONG pcCountOfExplicitEntries
,
650 PEXPLICIT_ACCESS_W
*pListOfExplicitEntries
)
654 ErrorCode
= CheckNtMartaPresent();
655 if (ErrorCode
== ERROR_SUCCESS
)
657 /* call the MARTA provider */
658 ErrorCode
= AccRewriteGetExplicitEntriesFromAcl(pacl
,
659 pcCountOfExplicitEntries
,
660 pListOfExplicitEntries
);
672 GetEffectiveRightsFromAclW(IN PACL pacl
,
673 IN PTRUSTEE_W pTrustee
,
674 OUT PACCESS_MASK pAccessRights
)
676 FIXME("%p %p %p - stub\n", pacl
, pTrustee
, pAccessRights
);
678 *pAccessRights
= STANDARD_RIGHTS_ALL
| SPECIFIC_RIGHTS_ALL
;
679 return ERROR_SUCCESS
;
688 GetEffectiveRightsFromAclA(IN PACL pacl
,
689 IN PTRUSTEE_A pTrustee
,
690 OUT PACCESS_MASK pAccessRights
)
692 PTRUSTEE_W pTrusteeW
= NULL
;
695 ErrorCode
= InternalTrusteeAToW(pTrustee
,
697 if (ErrorCode
== ERROR_SUCCESS
)
699 ErrorCode
= GetEffectiveRightsFromAclW(pacl
,
703 InternalFreeConvertedTrustee(pTrusteeW
,
707 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
718 GetAuditedPermissionsFromAclW(IN PACL pacl
,
719 IN PTRUSTEE_W pTrustee
,
720 OUT PACCESS_MASK pSuccessfulAuditedRights
,
721 OUT PACCESS_MASK pFailedAuditRights
)
723 FIXME("%s() not implemented!\n", __FUNCTION__
);
724 return ERROR_CALL_NOT_IMPLEMENTED
;
733 GetAuditedPermissionsFromAclA(IN PACL pacl
,
734 IN PTRUSTEE_A pTrustee
,
735 OUT PACCESS_MASK pSuccessfulAuditedRights
,
736 OUT PACCESS_MASK pFailedAuditRights
)
738 PTRUSTEE_W pTrusteeW
= NULL
;
741 ErrorCode
= InternalTrusteeAToW(pTrustee
,
743 if (ErrorCode
== ERROR_SUCCESS
)
745 ErrorCode
= GetAuditedPermissionsFromAclW(pacl
,
747 pSuccessfulAuditedRights
,
750 InternalFreeConvertedTrustee(pTrusteeW
,
754 ErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;