
    Vh-                         d dl mZmZmZ eZdZdZdZd dl	Z	d dl
mZmZ d dlmZmZmZ d dlmZmZmZ d dlZdZ	 d dlZd dlZd	Z G d de      Zd Zedk(  r e        yy# e$ r  e	j6                         Zd
ZY 6w xY w)    )absolute_importdivisionprint_functiona
  
module: ldap_attrs
short_description: Add or remove multiple LDAP attribute values
description:
  - Add or remove multiple LDAP attribute values.
notes:
  - This only deals with attributes on existing entries. To add or remove whole entries, see M(community.general.ldap_entry).
  - For O(state=present) and O(state=absent), all value comparisons are performed on the server for maximum accuracy. For
    O(state=exact), values have to be compared in Python, which obviously ignores LDAP matching rules. This should work out
    in most cases, but it is theoretically possible to see spurious changes when target and actual values are semantically
    identical but lexically distinct.
version_added: '0.2.0'
author:
  - Jiri Tyr (@jtyr)
  - Alexander Korinek (@noles)
  - Maciej Delmanowski (@drybjed)
requirements:
  - python-ldap
attributes:
  check_mode:
    support: full
  diff_mode:
    support: full
    version_added: 8.5.0
options:
  state:
    required: false
    type: str
    choices: [present, absent, exact]
    default: present
    description:
      - The state of the attribute values. If V(present), all given attribute values will be added if they are missing. If
        V(absent), all given attribute values will be removed if present. If V(exact), the set of attribute values will be
        forced to exactly those provided and no others. If O(state=exact) and the attribute value is empty, all values for
        this attribute will be removed.
  attributes:
    required: true
    type: dict
    description:
      - The attribute(s) and value(s) to add or remove.
      - Each attribute value can be a string for single-valued attributes or a list of strings for multi-valued attributes.
      - If you specify values for this option in YAML, please note that you can improve readability for long string values
        by using YAML block modifiers as seen in the examples for this module.
      - Note that when using values that YAML/ansible-core interprets as other types, like V(yes), V(no) (booleans), or V(2.10)
        (float), make sure to quote them if these are meant to be strings. Otherwise the wrong values may be sent to LDAP.
  ordered:
    required: false
    type: bool
    default: false
    description:
      - If V(true), prepend list values with X-ORDERED index numbers in all attributes specified in the current task. This
        is useful mostly with C(olcAccess) attribute to easily manage LDAP Access Control Lists.
extends_documentation_fragment:
  - community.general.ldap.documentation
  - community.general.attributes
a  
- name: Configure directory number 1 for example.com
  community.general.ldap_attrs:
    dn: olcDatabase={1}hdb,cn=config
    attributes:
      olcSuffix: dc=example,dc=com
    state: exact

# The complex argument format is required here to pass a list of ACL strings.
- name: Set up the ACL
  community.general.ldap_attrs:
    dn: olcDatabase={1}hdb,cn=config
    attributes:
      olcAccess:
        - >-
          {0}to attrs=userPassword,shadowLastChange
          by self write
          by anonymous auth
          by dn="cn=admin,dc=example,dc=com" write
          by * none'
        - >-
          {1}to dn.base="dc=example,dc=com"
          by dn="cn=admin,dc=example,dc=com" write
          by * read
    state: exact

# An alternative approach with automatic X-ORDERED numbering
- name: Set up the ACL
  community.general.ldap_attrs:
    dn: olcDatabase={1}hdb,cn=config
    attributes:
      olcAccess:
        - >-
          to attrs=userPassword,shadowLastChange
          by self write
          by anonymous auth
          by dn="cn=admin,dc=example,dc=com" write
          by * none'
        - >-
          to dn.base="dc=example,dc=com"
          by dn="cn=admin,dc=example,dc=com" write
          by * read
    ordered: true
    state: exact

- name: Declare some indexes
  community.general.ldap_attrs:
    dn: olcDatabase={1}hdb,cn=config
    attributes:
      olcDbIndex:
        - objectClass eq
        - uid eq

- name: Set up a root user, which we can use later to bootstrap the directory
  community.general.ldap_attrs:
    dn: olcDatabase={1}hdb,cn=config
    attributes:
      olcRootDN: cn=root,dc=example,dc=com
      olcRootPW: "{SSHA}tabyipcHzhwESzRaGA7oQ/SDoBZQOGND"
    state: exact

- name: Remove an attribute with a specific value
  community.general.ldap_attrs:
    dn: uid=jdoe,ou=people,dc=example,dc=com
    attributes:
      description: "An example user account"
    state: absent
    server_uri: ldap://localhost/
    bind_dn: cn=admin,dc=example,dc=com
    bind_pw: password

- name: Remove specified attribute(s) from an entry
  community.general.ldap_attrs:
    dn: uid=jdoe,ou=people,dc=example,dc=com
    attributes:
      description: []
    state: exact
    server_uri: ldap://localhost/
    bind_dn: cn=admin,dc=example,dc=com
    bind_pw: password
z
modlist:
  description: List of modified parameters.
  returned: success
  type: list
  sample:
    - [2, "olcRootDN", ["cn=root,dc=example,dc=com"]]
N)AnsibleModulemissing_required_lib)	to_nativeto_bytesto_text)LdapGeneric	gen_specsldap_required_togetherTFc                   <    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
y	)
	LdapAttrsc                     t        j                  | |       | j                  j                  d   | _        | j                  j                  d   | _        | j                  j                  d   | _        y )N
attributesstateordered)r   __init__moduleparamsattrsr   r   )selfr   s     p/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/general/plugins/modules/ldap_attrs.pyr   zLdapAttrs.__init__   sV    T6* [[''5
[[''0
{{)))4    c                     g }t        |t              rMt        |      D ]?  \  }}t        j                  dd|      }|j                  dt        |      z   dz   |z          A |S )z8 Prepend X-ORDERED index numbers to attribute's values. z^\{\d+\} {})
isinstancelist	enumerateresubappendstr)r   valuesordered_valuesindexvaluecleaned_values         r   _order_valueszLdapAttrs._order_values   sf    fd# )& 1 Nu "{B >%%cCJ&6&<}&LMN r   c                 $   g }t        |t              rh| j                  rAt        t        t        | j                  t        t        t        |                              }|S t        t        t        |            }|S t	        t        |            g}|S )z Normalize attribute's values. )r   r    r   mapr	   r+   r%   )r   r&   norm_valuess      r   _normalize_valueszLdapAttrs._normalize_values   s    fd#||"3x#'#5#5d3s?E<G 7H $I$J K 	 #3x#89  $CK01Kr   c                 B   g }i }| j                   j                  d   j                         D ]m  \  }}| j                  |      }g }|D ]H  }| j	                  ||      s|j                  t        j                  ||f       |j                  |       J |si|||<   o |i |fS Nr   )r   r   itemsr/   _is_value_absentr$   ldapMOD_ADD)r   modlist	new_attrsnamer&   r.   added_valuesr)   s           r   addzLdapAttrs.add   s    	 KK..|<BBD 	.LD&008KL$ /((u5NNDLL$#>? ''./ "-	$	. I%%r   c                    g }i }i }| j                   j                  d   j                         D ]  \  }}| j                  |      }g }|D ]H  }| j	                  ||      s|j                  |       |j                  t        j                  ||f       J |si|||<   |D cg c]	  }||vs| c}||<    |||fS c c}w r1   )r   r   r2   r/   _is_value_presentr$   r4   
MOD_DELETE)	r   r6   	old_attrsr7   r8   r&   r.   removed_valuesr)   s	            r   deletezLdapAttrs.delete   s    		 KK..|<BBD 		bLD&008KN$ C))$6"))%0NNDOOT5#ABC "-	$6A"aUUR`E`5"a	$		b 	9,, #bs    	B;*B;c                 T   g }i }i }| j                   j                  d   j                         D ]=  \  }}| j                  |      }	 | j                  j                  | j                  t        j                  |g      }d   d   j                  |g       }	t        |      t        |	      k7  st        |	      dk(  r#|j                  t        j                  ||f       nSt        |      dk(  r#|j                  t        j                   |d f       n"|j                  t        j"                  ||f       |	||<   |||<   t        |	      dk(  st        |      dk(  s.|	d   ||<   |d   ||<   @ |||fS # t        j                  $ r }| j                  d|z  |       Y d }~$d }~ww xY w)Nr   )attrlistzCannot search for attribute %sr      )r   r   r2   r/   
connectionsearch_sdnr4   
SCOPE_BASE	LDAPErrorfailget	frozensetlenr$   r5   r=   MOD_REPLACE)
r   r6   r>   r7   r8   r&   r.   resultsecurrents
             r   exactzLdapAttrs.exact   s   		 KK..|<BBD 	5LD&008KF//22GGT__v 3 ?
 ajm''b1G%7);;w<1$NNDLL$#DE%*NNDOOT4#@ANND$4$4dK#HI")	$"-	$w<1$[)9Q)>&-ajIdO&1!nIdO+	5. 	9,,% >> F		:TA1EEFs   7E44F'F""F'c                 (   	 t         j                  j                  t        |            }d|d|d}| j                  j                  | j                  t         j                  |      }t        |      dk(  }|S # t         j                  $ r d}Y |S w xY w)z3 True if the target attribute has the given value. (=)rC   F)
r4   filterescape_filter_charsr
   rD   rE   rF   rG   rL   NO_SUCH_OBJECT)r   r8   r)   escaped_value	filterstrdns
is_presents          r   r<   zLdapAttrs._is_value_present  s    	 KK;;GENKM%)=9I//**477DOOYOCSQJ  "" 	J	s   A4A8 8BBc                 (    | j                  ||       S )z< True if the target attribute doesn't have the given value. )r<   )r   r8   r)   s      r   r3   zLdapAttrs._is_value_absent#  s    ))$666r   N)__name__
__module____qualname__r   r+   r/   r:   r@   rQ   r<   r3    r   r   r   r      s*    5	 &- -:
7r   r   c                     t        t        t        dd      t        ddd      t        ddg d	
            dt                     } t        s | j                  t        d      t               t        |       }d }d }| j                  d   }|dk(  r |j                         \  }}}n5|dk(  r |j                         \  }}}n|dk(  r |j                         \  }}}d}t              dkD  r5d}| j                  s'	 |j                  j!                  |j"                  |       | j)                  ||||d       y # t$        $ r&}| j                  dt'        |             Y d }~Bd }~ww xY w)NdictT)typerequiredboolF)rd   defaultre   r%   present)absentrQ   rh   )rd   rg   choices)r   r   r   )argument_specsupports_check_moderequired_togetherzpython-ldap)msg	exceptionr   ri   rQ   r   zAttribute action failed.)rn   details)beforeafter)changedr6   diff)r   r   rc   r   HAS_LDAP	fail_jsonr   LDAP_IMP_ERRr   r   r:   r@   rQ   rL   
check_moderD   modify_srF   	Exceptionr   	exit_json)r   r4   r>   r7   r   r6   rs   rO   s           r   mainr|   (  si   $7feeDE9>\]

 !02F 1-@#/ 	 	1 VDIIMM'"E 	(0
%I	(	(3%I	'	(2

%IG
7|a  W((': Wgy[d<ef  W  %?ST VVWs   ;&D9 9	E(E##E(__main__)
__future__r   r   r   rd   __metaclass__DOCUMENTATIONEXAMPLESRETURN	tracebackansible.module_utils.basicr   r   +ansible.module_utils.common.text.convertersr   r	   r
   ?ansible_collections.community.general.plugins.module_utils.ldapr   r   r   r"   rw   r4   ldap.filterru   ImportError
format_excr   r|   r^   ra   r   r   <module>r      s    A @7tPf
  J T T z z 	Hm7 m7`)gX zF C  '9'')LHs   
A   A;:A;