Hello,
Actually, the solution with copy/paste group memberships using Custom Commands already takes advantage of Adaxes Role-Based Access control. The thing is that the script for pasting group memberships uses the $Context.BindToObjectEx method to bind to the group that the user needs to be added to / removed from. When using this method in scripts and setting the second parameter in parentheses to $True, binding to objects is always performed with the credentials of the operation initiator, that is, the user who launched the Custom Command. Thus, since the script binds to the groups with the credentials of the operation initiator, if the initiator does not have the permission to write the Member property of a group, Adaxes access control will not allow the script to add the target user to that group.
The only thing that was missing in the original solution is that the "Paste Membership' script was missing some error handling for the situation when the user does not have the permissions to to write the Member property of a group. Find below a slightly modified version of the script that fixes this issue.
Also, the scripts from the original solution not only add the target user to the groups that the original user is a member of, but also remove the target user from the groups that the original user is not member of. If you do not need this functionality and want the resulting group memberships to be membership in the copied groups plus membership in the groups that the user was a member of before the operation, we can modify the script.
Here's the modified version of the script for 'pasting' group memberships. As for the script for 'copying' group memberships, you can use it from the original solution we provided above.
# Get an array of group GUIDs
try
{
$sourceGroupGuids = $Context.Initiator.UserAdsObject.Get("adm-CustomAttributeBinary1")
}
catch
{
$Context.Cancel("Failed to get group GUIDs.")
}
# Calculate the number of GUIDs
$totalBytes = $sourceGroupGuids.Length
# Make sure that the total number of bytes is a divisible of 16
$remainder = 0
[System.Math]::DivRem($totalBytes, 16, [ref] $remainder)
if ($remainder -ne 0)
{
$Context.Cancel("Unexpected data length!")
}
$groupsToAdd = New-Object "System.Collections.Generic.HashSet[System.Guid]"
for ($i = 0; $i -lt ($totalBytes / 16); $i++)
{
$bytes = [System.Guid]::Empty.ToByteArray()
[System.Array]::Copy($sourceGroupGuids, $i * 16, $bytes, 0, 16)
$guid = New-Object "System.Guid" (,$bytes)
$groupsToAdd.Add($guid)
}
# Get GUIDs of the groups the user is a member of
$targetGroupGuids = $Context.TargetObject.GetEx("adm-DirectMemberOfGuid")
# Adjust the list of groups to add the user to, and the list of groups to remove the user from
$groupsToRemove = New-Object "System.Collections.Generic.HashSet[System.Guid]"
foreach($targetGroupGuidBytes in $targetGroupGuids)
{
$guid = New-Object "System.Guid" (,$targetGroupGuidBytes)
if ($groupsToAdd.Contains($guid))
{
$groupsToAdd.Remove($guid) # already a member of the group
}
else
{
$groupsToRemove.Add($guid)
}
}
# Remove from groups that are not in the list of copied groups
$unsuccessfullyRemoved = ""
$successfullyRemoved = ""
foreach($groupGuid in $groupsToRemove)
{
$groupGuid = $groupGuid.ToString("B")
$groupPath = "Adaxes://<GUID=$groupGuid>"
try
{
$group = $Context.BindToObjectEx($groupPath, $True)
$group.Remove($Context.TargetObject.AdsPath)
}
catch
{
$group = $Context.BindToObject($groupPath)
$unsuccessfullyRemoved += $group.Get("Name") + "; "
continue
}
$successfullyRemoved += $group.Get("Name") + "; "
}
# Add to groups
$unsuccessfullyAdded = ""
$successfullyAdded = ""
foreach($groupGuid in $groupsToAdd)
{
$groupGuid = $groupGuid.ToString("B")
$groupPath = "Adaxes://<GUID=$groupGuid>"
try
{
$group = $Context.BindToObjectEx($groupPath, $True)
$group.Add($Context.TargetObject.AdsPath)
}
catch
{
$group = $Context.BindToObject($groupPath)
$unsuccessfullyAdded += $group.Get("Name") + "; "
continue
}
$successfullyAdded += $group.Get("Name") + "; "
}
if ($successfullyAdded.Length -ne 0)
{
$Context.LogMessage("The user was added to the following groups: $successfullyAdded", "Information") # TODO: modify me
}
if ($unsuccessfullyAdded.Length -ne 0)
{
$Context.LogMessage("The user was not added to the following groups because you do not have sufficient permissions: $unsuccessfullyAdded", "Information") # TODO: modify me
}
if ($successfullyRemoved.Length -ne 0)
{
$Context.LogMessage("The user was removed from the following groups: $successfullyRemoved", "Information") # TODO: modify me
}
if ($unsuccessfullyRemoved.Length -ne 0)
{
$Context.LogMessage("The user was not removed from the following groups because you do not have sufficient permissions: $unsuccessfullyRemoved", "Information") # TODO: modify me
}