Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manage AD Object Permissions #39

Open
jiuka opened this issue May 26, 2023 · 4 comments
Open

Manage AD Object Permissions #39

jiuka opened this issue May 26, 2023 · 4 comments

Comments

@jiuka
Copy link

jiuka commented May 26, 2023

SUMMARY

We need to set/modify permissions on OUs and sometimes Groups. It would be nice to do this with ansible too. This includes enabling and disabling permission inheritance as well as add/set/remove of permisions. I am not sure if this should be a new module microsoft.ad.acl or should be integrated into ADObject.

ISSUE TYPE
  • Feature Idea
COMPONENT NAME

microsoft.ad.ou, microsoft.ad.group, microsoft.ad.user, microsoft.ad.object, microsoft.ad.computer

ADDITIONAL INFORMATION
- name: Ensure OU is protected
  microsoft.ad.acl:
    path: OU=AnsibleFest,DC=ansible,DC=local
    permissions:
      set:
        - group: Everyone
          rights: DeleteChild, DeleteTree, Delete
          type: deny
        - group: NT AUTHORITY\SYSTEM
          rights: GenericAll
        - group: NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERS
          rights: GenericRead
        - group: ANSIBLE\Domänen-Admins
          rights: GenericAll
        - group: ANSIBLE\AnsibleFestAdmins
          rights: CreateChild, DeleteChild
          object_type: bf967aba-0de6-11d0-a285-00aa003049e2
        - group: ANSIBLE\AnsibleFestAdmins
          rights: GenericAll
          inherited_object_type: bf967aba-0de6-11d0-a285-00aa003049e2
          inheritance: Descendents
- name: Ensure OU is present & protected
  microsoft.ad.ou:
    name: AnsibleFest
    permissions:
      set:
        - group: Everyone
          rights: DeleteChild, DeleteTree, Delete
          type: deny
        - group: NT AUTHORITY\SYSTEM
          rights: GenericAll
        - group: NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERS
          rights: GenericRead
        - group: ANSIBLE\Domänen-Admins
          rights: GenericAll
        - group: ANSIBLE\AnsibleFestAdmins
          rights: CreateChild, DeleteChild
          object_type: bf967aba-0de6-11d0-a285-00aa003049e2
        - group: ANSIBLE\AnsibleFestAdmins
          rights: GenericAll
          inherited_object_type: bf967aba-0de6-11d0-a285-00aa003049e2
          inheritance: Descendents
@jborean93
Copy link
Collaborator

This is something that I was interesting in adding and while it might be nice to have it part of each module using a common set of rules it might potentially overload an already overloaded set of options. The other complications come from how to deal with the object type guids and inherited object type rules. It is certainly doable but it might take some time to come up with a sane solution here.

@guyomog78
Copy link

guyomog78 commented Dec 4, 2023

I have done that with powershell previously

New-PSDrive -Name ADNEW -PSProvider ActiveDirectory -Root "" -Server $server

#Chargement Extended Rights
$global:erights = Invoke-Command -ScriptBlock {
	$rootDSE = Get-ADRootDSE
	$context = $rootDSE.ConfigurationNamingContext
	$container = "CN=Extended-Rights"
	New-PSDrive -Name ROOT -PSProvider ActiveDirectory -Root $context -Server $server | Out-Null
	$path = Join-Path -Path "ROOT:" -ChildPath $container
	Get-ChildItem -Path $path -Properties Displayname, RightsGUID, AppliesTo |
	Select-Object Name, RightsGUID
}

$global:dicNameToSchemaIDGUIDs = @{"user"="BF967ABA-0DE6-11D0-A285-00AA003049E2";`
"computer" = "BF967A86-0DE6-11D0-A285-00AA003049E2";`
"group" = "BF967A9C-0DE6-11D0-A285-00AA003049E2";`
"volume" = "BF967ABB-0DE6-11D0-A285-00AA003049E2";`
"gPLink" = "F30E3BBE-9FF0-11D1-B603-0000F80367C1";`
"gPOptions" = "F30E3BBF-9FF0-11D1-B603-0000F80367C1";`
"printQueue" = "BF967AA8-0DE6-11D0-A285-00AA003049E2";`
"inetOrgPerson" = "4828CC14-1437-45BC-9B07-AD6F015E5F28";`
"contact" = "5CB41ED0-0E4C-11D0-A286-00AA003049E2";`
"organizationalUnit" = "BF967AA5-0DE6-11D0-A285-00AA003049E2";`
"Null" = "00000000-0000-0000-0000-000000000000";`
"pwdLastSet" = "BF967A0A-0DE6-11D0-A285-00AA003049E2"}


$erights |%{$dicNameToSchemaIDGUIDs.add($_.Name,$_.RightsGUID)}

and another part of the script:

foreach ($Delegation in $Delegations) {
	#récupération des ACL
	$OURightPath = $Delegation.ObjectToApply + $domainDN
	$OUPath=join-path -Path "ADNEW:\" -ChildPath $OURightPath
	$acl = Get-ACL -Path $OUPath
	#Loop pour toutes les délegations à injecter
	foreach	($DelegatedRight in $Delegation.DelegatedRights){
		$RightSID = get-SID $DelegatedRight.IdentityReference
		$ActiveDirectoryRights = $DelegatedRight.ActiveDirectoryRights
		$AccessControlType = $DelegatedRight.AccessControlType
		$objectType = $dicNameToSchemaIDGUIDs[$DelegatedRight.ObjectType]
		[System.DirectoryServices.ActiveDirectorySecurityInheritance]$InheritanceType = $DelegatedRight.InheritanceType
		$InheritedObjectType = $dicNameToSchemaIDGUIDs[$DelegatedRight.InheritedObjectType]

        try{
		    $acl.AddAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule `
		    $RightSID,$ActiveDirectoryRights,$AccessControlType,$objectType,$InheritanceType,$InheritedObjectType))
        }
        catch{
        Write-Host "Unable to apply $($DelegatedRight.OuterXml)`n$_"
        }
	}
	
	Set-Acl -AclObject $acl -Path $OUPath
}

It was not reviewed from years, so I guess it's possible to improve this code that permit to discover all GUID for rights and then loop on acl list to set them.

here is example for how passed information

{
  "DelegatedRights": {
    "ActiveDirectoryRights": "ExtendedRight",
    "InheritanceType": "All",
    "ObjectType": "DS-Replication-Get-Changes",
    "InheritedObjectType": "Null",
    "AccessControlType": "Allow",
    "IdentityReference": "[email protected]"
  }
}

Also, I suggest to do a module for rights, because all rights are managed with the path first. I have no time for now to help, but maybe next year!

@guyomog78
Copy link

Well I just seen the #72 that in a good progress!

@abelal83
Copy link

abelal83 commented Nov 5, 2024

Until there's a proper solution, I've come up with this as a temporary solution.

    - name: Modify AD OU Permission # noqa: run-once[task]
      run_once: true
      ansible.windows.win_powershell:
        script: |
          param (
            [PSCredential] $Credential,
            [string] $OU,
            [string] $UserOrGroup,
            [string] $Permission,
            [string] $State
          )

          $ErrorActionPreference = 'Stop'

            # Get the security descriptor of the OU
          $OUObject = Get-ADOrganizationalUnit -Identity $OU -Properties nTSecurityDescriptor -Credential $Credential
          $SecurityDescriptor = $OUObject.nTSecurityDescriptor

          # Create a new access control entry (ACE)
          $accessControlEntry = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
              (New-Object System.Security.Principal.NTAccount($UserOrGroup)),
              [System.DirectoryServices.ActiveDirectoryRights]::$Permission,
              [System.Security.AccessControl.AccessControlType]::Allow
          )

          switch ($State.ToLower()) {
            'present' { $SecurityDescriptor.AddAccessRule($accessControlEntry) }
            'absent' { $SecurityDescriptor.RemoveAccessRule($accessControlEntry) }
            default { throw "unknown state given for state parameter: $State" }
          }

          # Apply the updated security descriptor to the OU
          Set-ADOrganizationalUnit -Identity $OU -Replace @{nTSecurityDescriptor = $SecurityDescriptor} -Credential $Credential

          switch ($State.ToLower()) {
            'present' { Write-Host "$Permission permissions have been applied to $UserOrGroup on $OU" }
            'absent' { Write-Host "$Permission permissions have been removed for $UserOrGroup on $OU" }
            default { throw "unknown state given for state parameter: $State" }
          }
        parameters:
          OU: "{{ item.ou }}"
          UserOrGroup: "{{ item.member }}"
          Permission: "{{ item.permission }}"
          State: "{{ item.state }}"
        sensitive_parameters:
          - name: Credential
            username: "{{ domain_username }}"
            password: "{{ domain_password }}"
      loop:
        "{{ ad_ou_permissions }}"

and vars look like

ad_ou_permissions:
  - ou: "ou=Groups,{{ active_directory_root_path }}"
    member: MYDOMAIN\abelal
    permission: GenericAll
    state: absent

It's by no means ideal but it adds and removes permissions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants