Blame plugins/modules/ipauser.py

Packit Service ee01e6
#!/usr/bin/python
Packit Service 0a38ef
# -*- coding: utf-8 -*-
Packit Service 0a38ef
Packit Service 0a38ef
# Authors:
Packit Service 0a38ef
#   Thomas Woerner <twoerner@redhat.com>
Packit Service 0a38ef
#
Packit Service 0a38ef
# Copyright (C) 2019 Red Hat
Packit Service 0a38ef
# see file 'COPYING' for use and warranty information
Packit Service 0a38ef
#
Packit Service 0a38ef
# This program is free software; you can redistribute it and/or modify
Packit Service 0a38ef
# it under the terms of the GNU General Public License as published by
Packit Service 0a38ef
# the Free Software Foundation, either version 3 of the License, or
Packit Service 0a38ef
# (at your option) any later version.
Packit Service 0a38ef
#
Packit Service 0a38ef
# This program is distributed in the hope that it will be useful,
Packit Service 0a38ef
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 0a38ef
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 0a38ef
# GNU General Public License for more details.
Packit Service 0a38ef
#
Packit Service 0a38ef
# You should have received a copy of the GNU General Public License
Packit Service 0a38ef
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit Service 0a38ef
Packit Service 0a38ef
ANSIBLE_METADATA = {
Packit Service 0a38ef
    "metadata_version": "1.0",
Packit Service 0a38ef
    "supported_by": "community",
Packit Service 0a38ef
    "status": ["preview"],
Packit Service 0a38ef
}
Packit Service 0a38ef
Packit Service 0a38ef
DOCUMENTATION = """
Packit Service 0a38ef
---
Packit Service 0a38ef
module: ipauser
Packit Service 0a38ef
short description: Manage FreeIPA users
Packit Service 0a38ef
description: Manage FreeIPA users
Packit Service 0a38ef
options:
Packit Service 0a38ef
  ipaadmin_principal:
Packit Service 0a38ef
    description: The admin principal
Packit Service 0a38ef
    default: admin
Packit Service 0a38ef
  ipaadmin_password:
Packit Service 0a38ef
    description: The admin password
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  name:
Packit Service 0a38ef
    description: The list of users (internally uid).
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  users:
Packit Service 0a38ef
    description: The list of user dicts (internally uid).
Packit Service 0a38ef
    options:
Packit Service 0a38ef
      name:
Packit Service 0a38ef
        description: The user (internally uid).
Packit Service 0a38ef
        required: true
Packit Service 0a38ef
      first:
Packit Service 0a38ef
        description: The first name
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
        aliases: ["givenname"]
Packit Service 0a38ef
      last:
Packit Service 0a38ef
        description: The last name
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
        aliases: ["sn"]
Packit Service 0a38ef
      fullname:
Packit Service 0a38ef
        description: The full name
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
        aliases: ["cn"]
Packit Service 0a38ef
      displayname:
Packit Service 0a38ef
        description: The display name
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      initials:
Packit Service 0a38ef
        description: Initials
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      homedir:
Packit Service 0a38ef
        description: The home directory
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      shell:
Packit Service 0a38ef
        description: The login shell
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
        aliases: ["loginshell"]
Packit Service 0a38ef
      email:
Packit Service 0a38ef
        description: List of email addresses
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      principal:
Packit Service 0a38ef
        description: The kerberos principal
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
        aliases: ["principalname", "krbprincipalname"]
Packit Service 0a38ef
      principalexpiration:
Packit Service a166ed
        description: |
Packit Service a166ed
          The kerberos principal expiration date
Packit Service a166ed
          (possible formats: YYYYMMddHHmmssZ, YYYY-MM-ddTHH:mm:ssZ,
Packit Service a166ed
          YYYY-MM-ddTHH:mmZ, YYYY-MM-ddZ, YYYY-MM-dd HH:mm:ssZ,
Packit Service a166ed
          YYYY-MM-dd HH:mmZ) The trailing 'Z' can be skipped.
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
        aliases: ["krbprincipalexpiration"]
Packit Service 0a38ef
      passwordexpiration:
Packit Service a166ed
        description: |
Packit Service a166ed
          The kerberos password expiration date (FreeIPA-4.7+)
Packit Service a166ed
          (possible formats: YYYYMMddHHmmssZ, YYYY-MM-ddTHH:mm:ssZ,
Packit Service a166ed
          YYYY-MM-ddTHH:mmZ, YYYY-MM-ddZ, YYYY-MM-dd HH:mm:ssZ,
Packit Service a166ed
          YYYY-MM-dd HH:mmZ) The trailing 'Z' can be skipped.
Packit Service a166ed
          Only usable with IPA versions 4.7 and up.
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
        aliases: ["krbpasswordexpiration"]
Packit Service 0a38ef
      password:
Packit Service 0a38ef
        description: The user password
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      random:
Packit Service 0a38ef
        description: Generate a random user password
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
        type: bool
Packit Service 0a38ef
      uid:
Packit Service 0a38ef
        description: The UID
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
        aliases: ["uidnumber"]
Packit Service 0a38ef
      gid:
Packit Service 0a38ef
        description: The GID
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
        aliases: ["gidnumber"]
Packit Service 0a38ef
      city:
Packit Service 0a38ef
        description: City
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      userstate:
Packit Service 0a38ef
        description: State/Province
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
        aliases: ["st"]
Packit Service 0a38ef
      postalcode:
Packit Service 0a38ef
        description: Postalcode/ZIP
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
        aliases: ["zip"]
Packit Service 0a38ef
      phone:
Packit Service 0a38ef
        description: List of telephone numbers
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
        aliases: ["telephonenumber"]
Packit Service 0a38ef
      mobile:
Packit Service 0a38ef
        description: List of mobile telephone numbers
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      pager:
Packit Service 0a38ef
        description: List of pager numbers
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      fax:
Packit Service 0a38ef
        description: List of fax numbers
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
        aliases: ["facsimiletelephonenumber"]
Packit Service 0a38ef
      orgunit:
Packit Service 0a38ef
        description: Org. Unit
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      title:
Packit Service 0a38ef
        description: The job title
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      manager:
Packit Service 0a38ef
        description: List of managers
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      carlicense:
Packit Service 0a38ef
        description: List of car licenses
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      sshpubkey:
Packit Service 0a38ef
        description: List of SSH public keys
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
        aliases: ["ipasshpubkey"]
Packit Service 0a38ef
      userauthtype:
Packit Service 0a38ef
        description:
Packit Service 0a38ef
          List of supported user authentication types
Packit Service 0a38ef
          Use empty string to reset userauthtype to the initial value.
Packit Service a166ed
        choices: ['password', 'radius', 'otp', '']
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
        aliases: ["ipauserauthtype"]
Packit Service 0a38ef
      userclass:
Packit Service 0a38ef
        description:
Packit Service 0a38ef
        - User category
Packit Service 0a38ef
        - (semantics placed on this attribute are for local interpretation)
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      radius:
Packit Service 0a38ef
        description: RADIUS proxy configuration
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      radiususer:
Packit Service 0a38ef
        description: RADIUS proxy username
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      departmentnumber:
Packit Service 0a38ef
        description: Department Number
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      employeenumber:
Packit Service 0a38ef
        description: Employee Number
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      employeetype:
Packit Service 0a38ef
        description: Employee Type
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      preferredlanguage:
Packit Service 0a38ef
        description: Preferred Language
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      certificate:
Packit Service 0a38ef
        description: List of base-64 encoded user certificates
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      certmapdata:
Packit Service 0a38ef
        description:
Packit Service 0a38ef
        - List of certificate mappings
Packit Service 0a38ef
        - Only usable with IPA versions 4.5 and up.
Packit Service 0a38ef
        options:
Packit Service 0a38ef
          certificate:
Packit Service 0a38ef
            description: Base-64 encoded user certificate
Packit Service 0a38ef
            required: false
Packit Service 0a38ef
          issuer:
Packit Service 0a38ef
            description: Issuer of the certificate
Packit Service 0a38ef
            required: false
Packit Service 0a38ef
          subject:
Packit Service 0a38ef
            description: Subject of the certificate
Packit Service 0a38ef
            required: false
Packit Service 0a38ef
          data:
Packit Service 0a38ef
            description: Certmap data
Packit Service 0a38ef
            required: false
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      noprivate:
Packit Service 0a38ef
        description: Don't create user private group
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
        type: bool
Packit Service 0a38ef
      nomembers:
Packit Service 0a38ef
        description: Suppress processing of membership attributes
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
        type: bool
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  first:
Packit Service 0a38ef
    description: The first name
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    aliases: ["givenname"]
Packit Service 0a38ef
  last:
Packit Service 0a38ef
    description: The last name
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    aliases: ["sn"]
Packit Service 0a38ef
  fullname:
Packit Service 0a38ef
    description: The full name
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    aliases: ["cn"]
Packit Service 0a38ef
  displayname:
Packit Service 0a38ef
    description: The display name
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  initials:
Packit Service 0a38ef
    description: Initials
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  homedir:
Packit Service 0a38ef
    description: The home directory
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  shell:
Packit Service 0a38ef
    description: The login shell
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    aliases: ["loginshell"]
Packit Service 0a38ef
  email:
Packit Service 0a38ef
    description: List of email addresses
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  principal:
Packit Service 0a38ef
    description: The kerberos principal
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    aliases: ["principalname", "krbprincipalname"]
Packit Service 0a38ef
  principalexpiration:
Packit Service a166ed
    description: |
Packit Service a166ed
      The kerberos principal expiration date
Packit Service a166ed
      (possible formats: YYYYMMddHHmmssZ, YYYY-MM-ddTHH:mm:ssZ,
Packit Service a166ed
      YYYY-MM-ddTHH:mmZ, YYYY-MM-ddZ, YYYY-MM-dd HH:mm:ssZ,
Packit Service a166ed
      YYYY-MM-dd HH:mmZ) The trailing 'Z' can be skipped.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    aliases: ["krbprincipalexpiration"]
Packit Service 0a38ef
  passwordexpiration:
Packit Service a166ed
    description: |
Packit Service a166ed
      The kerberos password expiration date (FreeIPA-4.7+)
Packit Service a166ed
      (possible formats: YYYYMMddHHmmssZ, YYYY-MM-ddTHH:mm:ssZ,
Packit Service a166ed
      YYYY-MM-ddTHH:mmZ, YYYY-MM-ddZ, YYYY-MM-dd HH:mm:ssZ,
Packit Service a166ed
      YYYY-MM-dd HH:mmZ) The trailing 'Z' can be skipped.
Packit Service a166ed
      Only usable with IPA versions 4.7 and up.
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    aliases: ["krbpasswordexpiration"]
Packit Service 0a38ef
  password:
Packit Service 0a38ef
    description: The user password
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  random:
Packit Service 0a38ef
    description: Generate a random user password
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: bool
Packit Service 0a38ef
  uid:
Packit Service 0a38ef
    description: The UID
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    aliases: ["uidnumber"]
Packit Service 0a38ef
  gid:
Packit Service 0a38ef
    description: The GID
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    aliases: ["gidnumber"]
Packit Service 0a38ef
  city:
Packit Service 0a38ef
    description: City
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  userstate:
Packit Service 0a38ef
    description: State/Province
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    aliases: ["st"]
Packit Service 0a38ef
  postalcode:
Packit Service 0a38ef
    description: ZIP
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    aliases: ["zip"]
Packit Service 0a38ef
  phone:
Packit Service 0a38ef
    description: List of telephone numbers
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    aliases: ["telephonenumber"]
Packit Service 0a38ef
  mobile:
Packit Service 0a38ef
    description: List of mobile telephone numbers
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  pager:
Packit Service 0a38ef
    description: List of pager numbers
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  fax:
Packit Service 0a38ef
    description: List of fax numbers
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    aliases: ["facsimiletelephonenumber"]
Packit Service 0a38ef
  orgunit:
Packit Service 0a38ef
    description: Org. Unit
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  title:
Packit Service 0a38ef
    description: The job title
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  manager:
Packit Service 0a38ef
    description: List of managers
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  carlicense:
Packit Service 0a38ef
    description: List of car licenses
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  sshpubkey:
Packit Service 0a38ef
    description: List of SSH public keys
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    aliases: ["ipasshpubkey"]
Packit Service 0a38ef
  userauthtype:
Packit Service 0a38ef
    description:
Packit Service 0a38ef
      List of supported user authentication types
Packit Service 0a38ef
      Use empty string to reset userauthtype to the initial value.
Packit Service a166ed
    choices: ['password', 'radius', 'otp', '']
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    aliases: ["ipauserauthtype"]
Packit Service 0a38ef
  userclass:
Packit Service 0a38ef
    description:
Packit Service 0a38ef
    - User category
Packit Service 0a38ef
    - (semantics placed on this attribute are for local interpretation)
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  radius:
Packit Service 0a38ef
    description: RADIUS proxy configuration
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  radiususer:
Packit Service 0a38ef
    description: RADIUS proxy username
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  departmentnumber:
Packit Service 0a38ef
    description: Department Number
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  employeenumber:
Packit Service 0a38ef
    description: Employee Number
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  employeetype:
Packit Service 0a38ef
    description: Employee Type
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  preferredlanguage:
Packit Service 0a38ef
    description: Preferred Language
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  certificate:
Packit Service 0a38ef
    description: List of base-64 encoded user certificates
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  certmapdata:
Packit Service 0a38ef
    description:
Packit Service 0a38ef
    - List of certificate mappings
Packit Service 0a38ef
    - Only usable with IPA versions 4.5 and up.
Packit Service 0a38ef
    options:
Packit Service 0a38ef
      certificate:
Packit Service 0a38ef
        description: Base-64 encoded user certificate
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      issuer:
Packit Service 0a38ef
        description: Issuer of the certificate
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      subject:
Packit Service 0a38ef
        description: Subject of the certificate
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
      data:
Packit Service 0a38ef
        description: Certmap data
Packit Service 0a38ef
        required: false
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  noprivate:
Packit Service 0a38ef
    description: Don't create user private group
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: bool
Packit Service 0a38ef
  nomembers:
Packit Service 0a38ef
    description: Suppress processing of membership attributes
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
    type: bool
Packit Service 0a38ef
  preserve:
Packit Service 0a38ef
    description: Delete a user, keeping the entry available for future use
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  update_password:
Packit Service 0a38ef
    description:
Packit Service 0a38ef
      Set password for a user in present state only on creation or always
Packit Service 0a38ef
    default: "always"
Packit Service 0a38ef
    choices: ["always", "on_create"]
Packit Service 0a38ef
    required: false
Packit Service 0a38ef
  action:
Packit Service 0a38ef
    description: Work on user or member level
Packit Service 0a38ef
    default: "user"
Packit Service 0a38ef
    choices: ["member", "user"]
Packit Service 0a38ef
  state:
Packit Service 0a38ef
    description: State to ensure
Packit Service 0a38ef
    default: present
Packit Service 0a38ef
    choices: ["present", "absent",
Packit Service 0a38ef
              "enabled", "disabled",
Packit Service 0a38ef
              "unlocked", "undeleted"]
Packit Service 0a38ef
author:
Packit Service 0a38ef
    - Thomas Woerner
Packit Service 0a38ef
"""
Packit Service 0a38ef
Packit Service 0a38ef
EXAMPLES = """
Packit Service 0a38ef
# Create user pinky
Packit Service 0a38ef
- ipauser:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: pinky
Packit Service 0a38ef
    first: pinky
Packit Service 0a38ef
    last: Acme
Packit Service 0a38ef
    uid: 10001
Packit Service 0a38ef
    gid: 100
Packit Service 0a38ef
    phone: "+555123457"
Packit Service 0a38ef
    email: pinky@acme.com
Packit Service 0a38ef
    passwordexpiration: "2023-01-19 23:59:59"
Packit Service 0a38ef
    password: "no-brain"
Packit Service 0a38ef
    update_password: on_create
Packit Service 0a38ef
Packit Service 0a38ef
# Create user brain
Packit Service 0a38ef
- ipauser:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: brain
Packit Service 0a38ef
    first: brain
Packit Service 0a38ef
    last: Acme
Packit Service 0a38ef
Packit Service 0a38ef
# Delete user pinky, but preserved
Packit Service 0a38ef
- ipauser:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: pinky
Packit Service 0a38ef
    preserve: yes
Packit Service 0a38ef
    state: absent
Packit Service 0a38ef
Packit Service 0a38ef
# Undelete user pinky
Packit Service 0a38ef
- ipauser:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: pinky
Packit Service 0a38ef
    state: undeleted
Packit Service 0a38ef
Packit Service 0a38ef
# Disable user pinky
Packit Service 0a38ef
- ipauser:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: pinky,brain
Packit Service 0a38ef
    state: disabled
Packit Service 0a38ef
Packit Service 0a38ef
# Enable user pinky and brain
Packit Service 0a38ef
- ipauser:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: pinky,brain
Packit Service 0a38ef
    state: enabled
Packit Service 0a38ef
Packit Service 0a38ef
# Remove user pinky and brain
Packit Service 0a38ef
- ipauser:
Packit Service 0a38ef
    ipaadmin_password: SomeADMINpassword
Packit Service 0a38ef
    name: pinky,brain
Packit Service 0a38ef
    state: disabled
Packit Service 0a38ef
"""
Packit Service 0a38ef
Packit Service 0a38ef
RETURN = """
Packit Service 0a38ef
user:
Packit Service 0a38ef
  description: User dict with random password
Packit Service 0a38ef
  returned: If random is yes and user did not exist or update_password is yes
Packit Service 0a38ef
  type: dict
Packit Service 0a38ef
  options:
Packit Service 0a38ef
    randompassword:
Packit Service 0a38ef
      description: The generated random password
Packit Service 0a38ef
      returned: If only one user is handled by the module
Packit Service 0a38ef
    name:
Packit Service 0a38ef
      description: The user name of the user that got a new random password
Packit Service 0a38ef
      returned: If several users are handled by the module
Packit Service 0a38ef
      type: dict
Packit Service 0a38ef
      options:
Packit Service 0a38ef
        randompassword:
Packit Service 0a38ef
          description: The generated random password
Packit Service 0a38ef
          returned: always
Packit Service 0a38ef
"""
Packit Service 0a38ef
Packit Service 0a38ef
from ansible.module_utils.basic import AnsibleModule
Packit Service 0a38ef
from ansible.module_utils._text import to_text
Packit Service 0a38ef
from ansible.module_utils.ansible_freeipa_module import temp_kinit, \
Packit Service 0a38ef
    temp_kdestroy, valid_creds, api_connect, api_command, date_format, \
Packit Service 0a38ef
    compare_args_ipa, module_params_get, api_check_param, api_get_realm, \
Packit Service 0a38ef
    api_command_no_name, gen_add_del_lists, encode_certificate, \
Packit Service 0a38ef
    load_cert_from_str, DN_x500_text, api_check_command
Packit Service 0a38ef
import six
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service 0a38ef
if six.PY3:
Packit Service 0a38ef
    unicode = str
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service 0a38ef
def find_user(module, name, preserved=False):
Packit Service 0a38ef
    _args = {
Packit Service 0a38ef
        "all": True,
Packit Service 0a38ef
        "uid": name,
Packit Service 0a38ef
    }
Packit Service 0a38ef
    if preserved:
Packit Service 0a38ef
        _args["preserved"] = preserved
Packit Service 0a38ef
Packit Service 0a38ef
    _result = api_command(module, "user_find", name, _args)
Packit Service 0a38ef
Packit Service 0a38ef
    if len(_result["result"]) > 1:
Packit Service 0a38ef
        module.fail_json(
Packit Service 0a38ef
            msg="There is more than one user '%s'" % (name))
Packit Service 0a38ef
    elif len(_result["result"]) == 1:
Packit Service 0a38ef
        # Transform each principal to a string
Packit Service 0a38ef
        _result = _result["result"][0]
Packit Service 0a38ef
        if "krbprincipalname" in _result \
Packit Service 0a38ef
           and _result["krbprincipalname"] is not None:
Packit Service 0a38ef
            _list = []
Packit Service 0a38ef
            for x in _result["krbprincipalname"]:
Packit Service 0a38ef
                _list.append(str(x))
Packit Service 0a38ef
            _result["krbprincipalname"] = _list
Packit Service 0a38ef
        certs = _result.get("usercertificate")
Packit Service 0a38ef
        if certs is not None:
Packit Service 0a38ef
            _result["usercertificate"] = [encode_certificate(x)
Packit Service 0a38ef
                                          for x in certs]
Packit Service 0a38ef
Packit Service 0a38ef
        return _result
Packit Service 0a38ef
    else:
Packit Service 0a38ef
        return None
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service 0a38ef
def gen_args(first, last, fullname, displayname, initials, homedir, shell,
Packit Service 0a38ef
             email, principalexpiration, passwordexpiration, password,
Packit Service 0a38ef
             random, uid, gid, city, userstate, postalcode, phone, mobile,
Packit Service 0a38ef
             pager, fax, orgunit, title, carlicense, sshpubkey, userauthtype,
Packit Service 0a38ef
             userclass, radius, radiususer, departmentnumber, employeenumber,
Packit Service 0a38ef
             employeetype, preferredlanguage, noprivate, nomembers):
Packit Service 0a38ef
    # principal, manager, certificate and certmapdata are handled not in here
Packit Service 0a38ef
    _args = {}
Packit Service 0a38ef
    if first is not None:
Packit Service 0a38ef
        _args["givenname"] = first
Packit Service 0a38ef
    if last is not None:
Packit Service 0a38ef
        _args["sn"] = last
Packit Service 0a38ef
    if fullname is not None:
Packit Service 0a38ef
        _args["cn"] = fullname
Packit Service 0a38ef
    if displayname is not None:
Packit Service 0a38ef
        _args["displayname"] = displayname
Packit Service 0a38ef
    if initials is not None:
Packit Service 0a38ef
        _args["initials"] = initials
Packit Service 0a38ef
    if homedir is not None:
Packit Service 0a38ef
        _args["homedirectory"] = homedir
Packit Service 0a38ef
    if shell is not None:
Packit Service 0a38ef
        _args["loginshell"] = shell
Packit Service 0a38ef
    if email is not None and len(email) > 0:
Packit Service 0a38ef
        _args["mail"] = email
Packit Service 0a38ef
    if principalexpiration is not None:
Packit Service 0a38ef
        _args["krbprincipalexpiration"] = principalexpiration
Packit Service 0a38ef
    if passwordexpiration is not None:
Packit Service 0a38ef
        _args["krbpasswordexpiration"] = passwordexpiration
Packit Service 0a38ef
    if password is not None:
Packit Service 0a38ef
        _args["userpassword"] = password
Packit Service 0a38ef
    if random is not None:
Packit Service 0a38ef
        _args["random"] = random
Packit Service 0a38ef
    if uid is not None:
Packit Service 0a38ef
        _args["uidnumber"] = to_text(str(uid))
Packit Service 0a38ef
    if gid is not None:
Packit Service 0a38ef
        _args["gidnumber"] = to_text(str(gid))
Packit Service 0a38ef
    if city is not None:
Packit Service 0a38ef
        _args["l"] = city
Packit Service 0a38ef
    if userstate is not None:
Packit Service 0a38ef
        _args["st"] = userstate
Packit Service 0a38ef
    if postalcode is not None:
Packit Service 0a38ef
        _args["postalcode"] = postalcode
Packit Service 0a38ef
    if phone is not None and len(phone) > 0:
Packit Service 0a38ef
        _args["telephonenumber"] = phone
Packit Service 0a38ef
    if mobile is not None and len(mobile) > 0:
Packit Service 0a38ef
        _args["mobile"] = mobile
Packit Service 0a38ef
    if pager is not None and len(pager) > 0:
Packit Service 0a38ef
        _args["pager"] = pager
Packit Service 0a38ef
    if fax is not None and len(fax) > 0:
Packit Service 0a38ef
        _args["facsimiletelephonenumber"] = fax
Packit Service 0a38ef
    if orgunit is not None:
Packit Service 0a38ef
        _args["ou"] = orgunit
Packit Service 0a38ef
    if title is not None:
Packit Service 0a38ef
        _args["title"] = title
Packit Service 0a38ef
    if carlicense is not None and len(carlicense) > 0:
Packit Service 0a38ef
        _args["carlicense"] = carlicense
Packit Service 0a38ef
    if sshpubkey is not None and len(sshpubkey) > 0:
Packit Service 0a38ef
        _args["ipasshpubkey"] = sshpubkey
Packit Service 0a38ef
    if userauthtype is not None and len(userauthtype) > 0:
Packit Service 0a38ef
        _args["ipauserauthtype"] = userauthtype
Packit Service 0a38ef
    if userclass is not None:
Packit Service 0a38ef
        _args["userclass"] = userclass
Packit Service 0a38ef
    if radius is not None:
Packit Service 0a38ef
        _args["ipatokenradiusconfiglink"] = radius
Packit Service 0a38ef
    if radiususer is not None:
Packit Service 0a38ef
        _args["ipatokenradiususername"] = radiususer
Packit Service 0a38ef
    if departmentnumber is not None:
Packit Service 0a38ef
        _args["departmentnumber"] = departmentnumber
Packit Service 0a38ef
    if employeenumber is not None:
Packit Service 0a38ef
        _args["employeenumber"] = employeenumber
Packit Service 0a38ef
    if employeetype is not None:
Packit Service 0a38ef
        _args["employeetype"] = employeetype
Packit Service 0a38ef
    if preferredlanguage is not None:
Packit Service 0a38ef
        _args["preferredlanguage"] = preferredlanguage
Packit Service 0a38ef
    if noprivate is not None:
Packit Service 0a38ef
        _args["noprivate"] = noprivate
Packit Service 0a38ef
    if nomembers is not None:
Packit Service 0a38ef
        _args["no_members"] = nomembers
Packit Service 0a38ef
    return _args
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service 0a38ef
def check_parameters(module, state, action,
Packit Service 0a38ef
                     first, last, fullname, displayname, initials, homedir,
Packit Service 0a38ef
                     shell, email, principal, principalexpiration,
Packit Service 0a38ef
                     passwordexpiration, password, random, uid, gid, city,
Packit Service 0a38ef
                     phone, mobile, pager, fax, orgunit, title, manager,
Packit Service 0a38ef
                     carlicense, sshpubkey, userauthtype, userclass, radius,
Packit Service 0a38ef
                     radiususer, departmentnumber, employeenumber,
Packit Service 0a38ef
                     employeetype, preferredlanguage, certificate,
Packit Service 0a38ef
                     certmapdata, noprivate, nomembers, preserve,
Packit Service 0a38ef
                     update_password):
Packit Service 0a38ef
Packit Service 0a38ef
    if state == "present":
Packit Service 0a38ef
        if action == "member":
Packit Service 0a38ef
            invalid = ["first", "last", "fullname", "displayname", "initials",
Packit Service 0a38ef
                       "homedir", "shell", "email", "principalexpiration",
Packit Service 0a38ef
                       "passwordexpiration", "password", "random", "uid",
Packit Service 0a38ef
                       "gid", "city", "phone", "mobile", "pager", "fax",
Packit Service 0a38ef
                       "orgunit", "title", "carlicense", "sshpubkey",
Packit Service 0a38ef
                       "userauthtype", "userclass", "radius", "radiususer",
Packit Service 0a38ef
                       "departmentnumber", "employeenumber", "employeetype",
Packit Service 0a38ef
                       "preferredlanguage", "noprivate", "nomembers",
Packit Service 0a38ef
                       "preserve", "update_password"]
Packit Service 0a38ef
            for x in invalid:
Packit Service 0a38ef
                if vars()[x] is not None:
Packit Service 0a38ef
                    module.fail_json(
Packit Service 0a38ef
                        msg="Argument '%s' can not be used with action "
Packit Service 0a38ef
                        "'%s'" % (x, action))
Packit Service 0a38ef
Packit Service 0a38ef
    else:
Packit Service 0a38ef
        invalid = ["first", "last", "fullname", "displayname", "initials",
Packit Service 0a38ef
                   "homedir", "shell", "email", "principalexpiration",
Packit Service 0a38ef
                   "passwordexpiration", "password", "random", "uid",
Packit Service 0a38ef
                   "gid", "city", "phone", "mobile", "pager", "fax",
Packit Service 0a38ef
                   "orgunit", "title", "carlicense", "sshpubkey",
Packit Service 0a38ef
                   "userauthtype", "userclass", "radius", "radiususer",
Packit Service 0a38ef
                   "departmentnumber", "employeenumber", "employeetype",
Packit Service 0a38ef
                   "preferredlanguage", "noprivate", "nomembers",
Packit Service 0a38ef
                   "update_password"]
Packit Service 0a38ef
        if action == "user":
Packit Service 0a38ef
            invalid.extend(["principal", "manager",
Packit Service 0a38ef
                            "certificate", "certmapdata",
Packit Service 0a38ef
                            ])
Packit Service 0a38ef
        for x in invalid:
Packit Service 0a38ef
            if vars()[x] is not None:
Packit Service 0a38ef
                module.fail_json(
Packit Service 0a38ef
                    msg="Argument '%s' can not be used with state '%s'" %
Packit Service 0a38ef
                    (x, state))
Packit Service 0a38ef
Packit Service 0a38ef
        if state != "absent" and preserve is not None:
Packit Service 0a38ef
            module.fail_json(
Packit Service 0a38ef
                msg="Preserve is only possible for state=absent")
Packit Service 0a38ef
Packit Service 0a38ef
    if certmapdata is not None:
Packit Service 0a38ef
        for x in certmapdata:
Packit Service 0a38ef
            certificate = x.get("certificate")
Packit Service 0a38ef
            issuer = x.get("issuer")
Packit Service 0a38ef
            subject = x.get("subject")
Packit Service 0a38ef
            data = x.get("data")
Packit Service 0a38ef
Packit Service 0a38ef
            if data is not None:
Packit Service 0a38ef
                if certificate is not None or issuer is not None or \
Packit Service 0a38ef
                   subject is not None:
Packit Service 0a38ef
                    module.fail_json(
Packit Service 0a38ef
                        msg="certmapdata: data can not be used with "
Packit Service 0a38ef
                        "certificate, issuer or subject")
Packit Service 0a38ef
                check_certmapdata(data)
Packit Service 0a38ef
            if certificate is not None \
Packit Service 0a38ef
               and (issuer is not None or subject is not None):
Packit Service 0a38ef
                module.fail_json(
Packit Service 0a38ef
                    msg="certmapdata: certificate can not be used with "
Packit Service 0a38ef
                    "issuer or subject")
Packit Service 0a38ef
            if data is None and certificate is None:
Packit Service 0a38ef
                if issuer is None:
Packit Service 0a38ef
                    module.fail_json(msg="certmapdata: issuer is missing")
Packit Service 0a38ef
                if subject is None:
Packit Service 0a38ef
                    module.fail_json(msg="certmapdata: subject is missing")
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service 0a38ef
def extend_emails(email, default_email_domain):
Packit Service 0a38ef
    if email is not None:
Packit Service 0a38ef
        return ["%s@%s" % (_email, default_email_domain)
Packit Service 0a38ef
                if "@" not in _email else _email
Packit Service 0a38ef
                for _email in email]
Packit Service 0a38ef
    return email
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service 0a38ef
def convert_certmapdata(certmapdata):
Packit Service 0a38ef
    if certmapdata is None:
Packit Service 0a38ef
        return None
Packit Service 0a38ef
Packit Service 0a38ef
    _result = []
Packit Service 0a38ef
    for x in certmapdata:
Packit Service 0a38ef
        certificate = x.get("certificate")
Packit Service 0a38ef
        issuer = x.get("issuer")
Packit Service 0a38ef
        subject = x.get("subject")
Packit Service 0a38ef
        data = x.get("data")
Packit Service 0a38ef
Packit Service 0a38ef
        if data is None:
Packit Service 0a38ef
            if issuer is None and subject is None:
Packit Service 0a38ef
                cert = load_cert_from_str(certificate)
Packit Service 0a38ef
                issuer = cert.issuer
Packit Service 0a38ef
                subject = cert.subject
Packit Service 0a38ef
Packit Service 0a38ef
            _result.append("X509:%s<S>%s" % (DN_x500_text(issuer),
Packit Service 0a38ef
                                                DN_x500_text(subject)))
Packit Service 0a38ef
        else:
Packit Service 0a38ef
            _result.append(data)
Packit Service 0a38ef
Packit Service 0a38ef
    return _result
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service 0a38ef
def check_certmapdata(data):
Packit Service 0a38ef
    if not data.startswith("X509:"):
Packit Service 0a38ef
        return False
Packit Service 0a38ef
Packit Service 0a38ef
    i = data.find("", 4)
Packit Service 0a38ef
    s = data.find("<S>", i)
Packit Service 0a38ef
    issuer = data[i+3:s]
Packit Service 0a38ef
    subject = data[s+3:]
Packit Service 0a38ef
Packit Service 0a38ef
    if i < 0 or s < 0 or "CN" not in issuer or "CN" not in subject:
Packit Service 0a38ef
        return False
Packit Service 0a38ef
Packit Service 0a38ef
    return True
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service 0a38ef
def gen_certmapdata_args(certmapdata):
Packit Service 0a38ef
    return {"ipacertmapdata": to_text(certmapdata)}
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service 0a38ef
def main():
Packit Service 0a38ef
    user_spec = dict(
Packit Service 0a38ef
        # present
Packit Service 0a38ef
        first=dict(type="str", aliases=["givenname"], default=None),
Packit Service 0a38ef
        last=dict(type="str", aliases=["sn"], default=None),
Packit Service 0a38ef
        fullname=dict(type="str", aliases=["cn"], default=None),
Packit Service 0a38ef
        displayname=dict(type="str", default=None),
Packit Service 0a38ef
        initials=dict(type="str", default=None),
Packit Service 0a38ef
        homedir=dict(type="str", default=None),
Packit Service 0a38ef
        shell=dict(type="str", aliases=["loginshell"], default=None),
Packit Service 0a38ef
        email=dict(type="list", default=None),
Packit Service 0a38ef
        principal=dict(type="list", aliases=["principalname",
Packit Service 0a38ef
                                             "krbprincipalname"],
Packit Service 0a38ef
                       default=None),
Packit Service 0a38ef
        principalexpiration=dict(type="str",
Packit Service 0a38ef
                                 aliases=["krbprincipalexpiration"],
Packit Service 0a38ef
                                 default=None),
Packit Service 0a38ef
        passwordexpiration=dict(type="str",
Packit Service 0a38ef
                                aliases=["krbpasswordexpiration"],
Packit Service 0a38ef
                                default=None),
Packit Service 0a38ef
        password=dict(type="str", default=None, no_log=True),
Packit Service 0a38ef
        random=dict(type='bool', default=None),
Packit Service 0a38ef
        uid=dict(type="int", aliases=["uidnumber"], default=None),
Packit Service 0a38ef
        gid=dict(type="int", aliases=["gidnumber"], default=None),
Packit Service 0a38ef
        city=dict(type="str", default=None),
Packit Service 0a38ef
        userstate=dict(type="str", aliases=["st"], default=None),
Packit Service 0a38ef
        postalcode=dict(type="str", aliases=["zip"], default=None),
Packit Service 0a38ef
        phone=dict(type="list", aliases=["telephonenumber"], default=None),
Packit Service 0a38ef
        mobile=dict(type="list", default=None),
Packit Service 0a38ef
        pager=dict(type="list", default=None),
Packit Service 0a38ef
        fax=dict(type="list", aliases=["facsimiletelephonenumber"],
Packit Service 0a38ef
                 default=None),
Packit Service 0a38ef
        orgunit=dict(type="str", aliases=["ou"], default=None),
Packit Service 0a38ef
        title=dict(type="str", default=None),
Packit Service 0a38ef
        manager=dict(type="list", default=None),
Packit Service 0a38ef
        carlicense=dict(type="list", default=None),
Packit Service 0a38ef
        sshpubkey=dict(type="list", aliases=["ipasshpubkey"],
Packit Service 0a38ef
                       default=None),
Packit Service 0a38ef
        userauthtype=dict(type='list', aliases=["ipauserauthtype"],
Packit Service 0a38ef
                          default=None,
Packit Service 0a38ef
                          choices=['password', 'radius', 'otp', '']),
Packit Service 0a38ef
        userclass=dict(type="list", aliases=["class"],
Packit Service 0a38ef
                       default=None),
Packit Service 0a38ef
        radius=dict(type="str", aliases=["ipatokenradiusconfiglink"],
Packit Service 0a38ef
                    default=None),
Packit Service 0a38ef
        radiususer=dict(type="str", aliases=["radiususername",
Packit Service 0a38ef
                                             "ipatokenradiususername"],
Packit Service 0a38ef
                        default=None),
Packit Service 0a38ef
        departmentnumber=dict(type="list", default=None),
Packit Service 0a38ef
        employeenumber=dict(type="str", default=None),
Packit Service 0a38ef
        employeetype=dict(type="str", default=None),
Packit Service 0a38ef
        preferredlanguage=dict(type="str", default=None),
Packit Service 0a38ef
        certificate=dict(type="list", aliases=["usercertificate"],
Packit Service 0a38ef
                         default=None),
Packit Service 0a38ef
        certmapdata=dict(type="list", default=None,
Packit Service 0a38ef
                         options=dict(
Packit Service 0a38ef
                             # Here certificate is a simple string
Packit Service 0a38ef
                             certificate=dict(type="str", default=None),
Packit Service 0a38ef
                             issuer=dict(type="str", default=None),
Packit Service 0a38ef
                             subject=dict(type="str", default=None),
Packit Service 0a38ef
                             data=dict(type="str", default=None)
Packit Service 0a38ef
                         ),
Packit Service 0a38ef
                         elements='dict', required=False),
Packit Service 0a38ef
        noprivate=dict(type='bool', default=None),
Packit Service 0a38ef
        nomembers=dict(type='bool', default=None),
Packit Service 0a38ef
    )
Packit Service 0a38ef
Packit Service 0a38ef
    ansible_module = AnsibleModule(
Packit Service 0a38ef
        argument_spec=dict(
Packit Service 0a38ef
            # general
Packit Service 0a38ef
            ipaadmin_principal=dict(type="str", default="admin"),
Packit Service 0a38ef
            ipaadmin_password=dict(type="str", required=False, no_log=True),
Packit Service 0a38ef
Packit Service 0a38ef
            name=dict(type="list", aliases=["login"], default=None,
Packit Service 0a38ef
                      required=False),
Packit Service 0a38ef
            users=dict(type="list", aliases=["login"], default=None,
Packit Service 0a38ef
                       options=dict(
Packit Service 0a38ef
                           # Here name is a simple string
Packit Service 0a38ef
                           name=dict(type="str", required=True),
Packit Service 0a38ef
                           # Add user specific parameters
Packit Service 0a38ef
                           **user_spec
Packit Service 0a38ef
                       ),
Packit Service 0a38ef
                       elements='dict', required=False),
Packit Service 0a38ef
Packit Service 0a38ef
            # deleted
Packit Service 0a38ef
            preserve=dict(required=False, type='bool', default=None),
Packit Service 0a38ef
Packit Service 0a38ef
            # mod
Packit Service 0a38ef
            update_password=dict(type='str', default=None, no_log=False,
Packit Service 0a38ef
                                 choices=['always', 'on_create']),
Packit Service 0a38ef
Packit Service 0a38ef
            # general
Packit Service 0a38ef
            action=dict(type="str", default="user",
Packit Service 0a38ef
                        choices=["member", "user"]),
Packit Service 0a38ef
            state=dict(type="str", default="present",
Packit Service 0a38ef
                       choices=["present", "absent", "enabled", "disabled",
Packit Service 0a38ef
                                "unlocked", "undeleted"]),
Packit Service 0a38ef
Packit Service 0a38ef
            # Add user specific parameters for simple use case
Packit Service 0a38ef
            **user_spec
Packit Service 0a38ef
        ),
Packit Service 0a38ef
        mutually_exclusive=[["name", "users"]],
Packit Service 0a38ef
        required_one_of=[["name", "users"]],
Packit Service 0a38ef
        supports_check_mode=True,
Packit Service 0a38ef
    )
Packit Service 0a38ef
Packit Service 0a38ef
    ansible_module._ansible_debug = True
Packit Service 0a38ef
Packit Service 0a38ef
    # Get parameters
Packit Service 0a38ef
Packit Service 0a38ef
    # general
Packit Service 0a38ef
    ipaadmin_principal = module_params_get(ansible_module,
Packit Service 0a38ef
                                           "ipaadmin_principal")
Packit Service 0a38ef
    ipaadmin_password = module_params_get(ansible_module, "ipaadmin_password")
Packit Service 0a38ef
    names = module_params_get(ansible_module, "name")
Packit Service 0a38ef
    users = module_params_get(ansible_module, "users")
Packit Service 0a38ef
Packit Service 0a38ef
    # present
Packit Service 0a38ef
    first = module_params_get(ansible_module, "first")
Packit Service 0a38ef
    last = module_params_get(ansible_module, "last")
Packit Service 0a38ef
    fullname = module_params_get(ansible_module, "fullname")
Packit Service 0a38ef
    displayname = module_params_get(ansible_module, "displayname")
Packit Service 0a38ef
    initials = module_params_get(ansible_module, "initials")
Packit Service 0a38ef
    homedir = module_params_get(ansible_module, "homedir")
Packit Service 0a38ef
    shell = module_params_get(ansible_module, "shell")
Packit Service 0a38ef
    email = module_params_get(ansible_module, "email")
Packit Service 0a38ef
    principal = module_params_get(ansible_module, "principal")
Packit Service 0a38ef
    principalexpiration = module_params_get(ansible_module,
Packit Service 0a38ef
                                            "principalexpiration")
Packit Service 0a38ef
    if principalexpiration is not None:
Packit Service 0a38ef
        if principalexpiration[:-1] != "Z":
Packit Service 0a38ef
            principalexpiration = principalexpiration + "Z"
Packit Service 0a38ef
        principalexpiration = date_format(principalexpiration)
Packit Service 0a38ef
    passwordexpiration = module_params_get(ansible_module,
Packit Service 0a38ef
                                           "passwordexpiration")
Packit Service 0a38ef
    if passwordexpiration is not None:
Packit Service 0a38ef
        if passwordexpiration[:-1] != "Z":
Packit Service 0a38ef
            passwordexpiration = passwordexpiration + "Z"
Packit Service 0a38ef
        passwordexpiration = date_format(passwordexpiration)
Packit Service 0a38ef
    password = module_params_get(ansible_module, "password")
Packit Service 0a38ef
    random = module_params_get(ansible_module, "random")
Packit Service 0a38ef
    uid = module_params_get(ansible_module, "uid")
Packit Service 0a38ef
    gid = module_params_get(ansible_module, "gid")
Packit Service 0a38ef
    city = module_params_get(ansible_module, "city")
Packit Service 0a38ef
    userstate = module_params_get(ansible_module, "userstate")
Packit Service 0a38ef
    postalcode = module_params_get(ansible_module, "postalcode")
Packit Service 0a38ef
    phone = module_params_get(ansible_module, "phone")
Packit Service 0a38ef
    mobile = module_params_get(ansible_module, "mobile")
Packit Service 0a38ef
    pager = module_params_get(ansible_module, "pager")
Packit Service 0a38ef
    fax = module_params_get(ansible_module, "fax")
Packit Service 0a38ef
    orgunit = module_params_get(ansible_module, "orgunit")
Packit Service 0a38ef
    title = module_params_get(ansible_module, "title")
Packit Service 0a38ef
    manager = module_params_get(ansible_module, "manager")
Packit Service 0a38ef
    carlicense = module_params_get(ansible_module, "carlicense")
Packit Service 0a38ef
    sshpubkey = module_params_get(ansible_module, "sshpubkey")
Packit Service 0a38ef
    userauthtype = module_params_get(ansible_module, "userauthtype")
Packit Service 0a38ef
    userclass = module_params_get(ansible_module, "userclass")
Packit Service 0a38ef
    radius = module_params_get(ansible_module, "radius")
Packit Service 0a38ef
    radiususer = module_params_get(ansible_module, "radiususer")
Packit Service 0a38ef
    departmentnumber = module_params_get(ansible_module, "departmentnumber")
Packit Service 0a38ef
    employeenumber = module_params_get(ansible_module, "employeenumber")
Packit Service 0a38ef
    employeetype = module_params_get(ansible_module, "employeetype")
Packit Service 0a38ef
    preferredlanguage = module_params_get(ansible_module, "preferredlanguage")
Packit Service 0a38ef
    certificate = module_params_get(ansible_module, "certificate")
Packit Service 0a38ef
    certmapdata = module_params_get(ansible_module, "certmapdata")
Packit Service 0a38ef
    noprivate = module_params_get(ansible_module, "noprivate")
Packit Service 0a38ef
    nomembers = module_params_get(ansible_module, "nomembers")
Packit Service 0a38ef
    # deleted
Packit Service 0a38ef
    preserve = module_params_get(ansible_module, "preserve")
Packit Service 0a38ef
    # mod
Packit Service 0a38ef
    update_password = module_params_get(ansible_module, "update_password")
Packit Service 0a38ef
    # general
Packit Service 0a38ef
    action = module_params_get(ansible_module, "action")
Packit Service 0a38ef
    state = module_params_get(ansible_module, "state")
Packit Service 0a38ef
Packit Service 0a38ef
    # Check parameters
Packit Service 0a38ef
Packit Service 0a38ef
    if (names is None or len(names) < 1) and \
Packit Service 0a38ef
       (users is None or len(users) < 1):
Packit Service 0a38ef
        ansible_module.fail_json(msg="One of name and users is required")
Packit Service 0a38ef
Packit Service 0a38ef
    if state == "present":
Packit Service 0a38ef
        if names is not None and len(names) != 1:
Packit Service 0a38ef
            ansible_module.fail_json(
Packit Service 0a38ef
                msg="Only one user can be added at a time using name.")
Packit Service 0a38ef
Packit Service 0a38ef
    check_parameters(
Packit Service 0a38ef
        ansible_module, state, action,
Packit Service 0a38ef
        first, last, fullname, displayname, initials, homedir, shell, email,
Packit Service 0a38ef
        principal, principalexpiration, passwordexpiration, password, random,
Packit Service 0a38ef
        uid, gid, city, phone, mobile, pager, fax, orgunit, title, manager,
Packit Service 0a38ef
        carlicense, sshpubkey, userauthtype, userclass, radius, radiususer,
Packit Service 0a38ef
        departmentnumber, employeenumber, employeetype, preferredlanguage,
Packit Service 0a38ef
        certificate, certmapdata, noprivate, nomembers, preserve,
Packit Service 0a38ef
        update_password)
Packit Service 0a38ef
    certmapdata = convert_certmapdata(certmapdata)
Packit Service 0a38ef
Packit Service 0a38ef
    # Use users if names is None
Packit Service 0a38ef
    if users is not None:
Packit Service 0a38ef
        names = users
Packit Service 0a38ef
Packit Service 0a38ef
    # Init
Packit Service 0a38ef
Packit Service 0a38ef
    changed = False
Packit Service 0a38ef
    exit_args = {}
Packit Service 0a38ef
    ccache_dir = None
Packit Service 0a38ef
    ccache_name = None
Packit Service 0a38ef
    try:
Packit Service 0a38ef
        if not valid_creds(ansible_module, ipaadmin_principal):
Packit Service 0a38ef
            ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
Packit Service 0a38ef
                                                 ipaadmin_password)
Packit Service 0a38ef
        api_connect()
Packit Service 0a38ef
Packit Service 0a38ef
        # Check version specific settings
Packit Service 0a38ef
Packit Service 0a38ef
        server_realm = api_get_realm()
Packit Service 0a38ef
Packit Service 0a38ef
        # Default email domain
Packit Service 0a38ef
Packit Service 0a38ef
        result = api_command_no_name(ansible_module, "config_show", {})
Packit Service 0a38ef
        default_email_domain = result["result"]["ipadefaultemaildomain"][0]
Packit Service 0a38ef
Packit Service 0a38ef
        # Extend email addresses
Packit Service 0a38ef
Packit Service 0a38ef
        email = extend_emails(email, default_email_domain)
Packit Service 0a38ef
Packit Service 0a38ef
        # commands
Packit Service 0a38ef
Packit Service 0a38ef
        commands = []
Packit Service a166ed
        user_set = set()
Packit Service 0a38ef
Packit Service 0a38ef
        for user in names:
Packit Service 0a38ef
            if isinstance(user, dict):
Packit Service 0a38ef
                name = user.get("name")
Packit Service a166ed
                if name in user_set:
Packit Service a166ed
                    ansible_module.fail_json(
Packit Service a166ed
                        msg="user '%s' is used more than once" % name)
Packit Service a166ed
                user_set.add(name)
Packit Service 0a38ef
                # present
Packit Service 0a38ef
                first = user.get("first")
Packit Service 0a38ef
                last = user.get("last")
Packit Service 0a38ef
                fullname = user.get("fullname")
Packit Service 0a38ef
                displayname = user.get("displayname")
Packit Service 0a38ef
                initials = user.get("initials")
Packit Service 0a38ef
                homedir = user.get("homedir")
Packit Service 0a38ef
                shell = user.get("shell")
Packit Service 0a38ef
                email = user.get("email")
Packit Service 0a38ef
                principal = user.get("principal")
Packit Service 0a38ef
                principalexpiration = user.get("principalexpiration")
Packit Service 0a38ef
                if principalexpiration is not None:
Packit Service 0a38ef
                    if principalexpiration[:-1] != "Z":
Packit Service 0a38ef
                        principalexpiration = principalexpiration + "Z"
Packit Service 0a38ef
                    principalexpiration = date_format(principalexpiration)
Packit Service 0a38ef
                passwordexpiration = user.get("passwordexpiration")
Packit Service 0a38ef
                if passwordexpiration is not None:
Packit Service 0a38ef
                    if passwordexpiration[:-1] != "Z":
Packit Service 0a38ef
                        passwordexpiration = passwordexpiration + "Z"
Packit Service 0a38ef
                    passwordexpiration = date_format(passwordexpiration)
Packit Service 0a38ef
                password = user.get("password")
Packit Service 0a38ef
                random = user.get("random")
Packit Service 0a38ef
                uid = user.get("uid")
Packit Service 0a38ef
                gid = user.get("gid")
Packit Service 0a38ef
                city = user.get("city")
Packit Service 0a38ef
                userstate = user.get("userstate")
Packit Service 0a38ef
                postalcode = user.get("postalcode")
Packit Service 0a38ef
                phone = user.get("phone")
Packit Service 0a38ef
                mobile = user.get("mobile")
Packit Service 0a38ef
                pager = user.get("pager")
Packit Service 0a38ef
                fax = user.get("fax")
Packit Service 0a38ef
                orgunit = user.get("orgunit")
Packit Service 0a38ef
                title = user.get("title")
Packit Service 0a38ef
                manager = user.get("manager")
Packit Service 0a38ef
                carlicense = user.get("carlicense")
Packit Service 0a38ef
                sshpubkey = user.get("sshpubkey")
Packit Service 0a38ef
                userauthtype = user.get("userauthtype")
Packit Service 0a38ef
                userclass = user.get("userclass")
Packit Service 0a38ef
                radius = user.get("radius")
Packit Service 0a38ef
                radiususer = user.get("radiususer")
Packit Service 0a38ef
                departmentnumber = user.get("departmentnumber")
Packit Service 0a38ef
                employeenumber = user.get("employeenumber")
Packit Service 0a38ef
                employeetype = user.get("employeetype")
Packit Service 0a38ef
                preferredlanguage = user.get("preferredlanguage")
Packit Service 0a38ef
                certificate = user.get("certificate")
Packit Service 0a38ef
                certmapdata = user.get("certmapdata")
Packit Service 0a38ef
                noprivate = user.get("noprivate")
Packit Service 0a38ef
                nomembers = user.get("nomembers")
Packit Service 0a38ef
Packit Service 0a38ef
                check_parameters(
Packit Service 0a38ef
                    ansible_module, state, action,
Packit Service 0a38ef
                    first, last, fullname, displayname, initials, homedir,
Packit Service 0a38ef
                    shell, email, principal, principalexpiration,
Packit Service 0a38ef
                    passwordexpiration, password, random, uid, gid, city,
Packit Service 0a38ef
                    phone, mobile, pager, fax, orgunit, title, manager,
Packit Service 0a38ef
                    carlicense, sshpubkey, userauthtype, userclass, radius,
Packit Service 0a38ef
                    radiususer, departmentnumber, employeenumber,
Packit Service 0a38ef
                    employeetype, preferredlanguage, certificate,
Packit Service 0a38ef
                    certmapdata, noprivate, nomembers, preserve,
Packit Service 0a38ef
                    update_password)
Packit Service 0a38ef
                certmapdata = convert_certmapdata(certmapdata)
Packit Service 0a38ef
Packit Service 0a38ef
                # Extend email addresses
Packit Service 0a38ef
Packit Service 0a38ef
                email = extend_emails(email, default_email_domain)
Packit Service 0a38ef
Packit Service 0a38ef
            elif isinstance(user, str) or isinstance(user, unicode):
Packit Service 0a38ef
                name = user
Packit Service 0a38ef
            else:
Packit Service 0a38ef
                ansible_module.fail_json(msg="User '%s' is not valid" %
Packit Service 0a38ef
                                         repr(user))
Packit Service 0a38ef
Packit Service 0a38ef
            # Fix principals: add realm if missing
Packit Service 0a38ef
            # We need the connected API for the realm, therefore it can not
Packit Service 0a38ef
            # be part of check_parameters as this is used also before the
Packit Service 0a38ef
            # connection to the API has been established.
Packit Service 0a38ef
            if principal is not None:
Packit Service 0a38ef
                principal = [x if "@" in x else x + "@" + server_realm
Packit Service 0a38ef
                             for x in principal]
Packit Service 0a38ef
Packit Service 0a38ef
            # Check passwordexpiration availability.
Packit Service 0a38ef
            # We need the connected API for this test, therefore it can not
Packit Service 0a38ef
            # be part of check_parameters as this is used also before the
Packit Service 0a38ef
            # connection to the API has been established.
Packit Service 0a38ef
            if passwordexpiration is not None and \
Packit Service 0a38ef
               not api_check_param("user_add", "krbpasswordexpiration"):
Packit Service 0a38ef
                ansible_module.fail_json(
Packit Service 0a38ef
                    msg="The use of passwordexpiration is not supported by "
Packit Service 0a38ef
                    "your IPA version")
Packit Service 0a38ef
Packit Service 0a38ef
            # Check certmapdata availability.
Packit Service 0a38ef
            # We need the connected API for this test, therefore it can not
Packit Service 0a38ef
            # be part of check_parameters as this is used also before the
Packit Service 0a38ef
            # connection to the API has been established.
Packit Service 0a38ef
            if certmapdata is not None and \
Packit Service 0a38ef
               not api_check_command("user_add_certmapdata"):
Packit Service 0a38ef
                ansible_module.fail_json(
Packit Service 0a38ef
                    msg="The use of certmapdata is not supported by "
Packit Service 0a38ef
                    "your IPA version")
Packit Service 0a38ef
Packit Service 0a38ef
            # Make sure user exists
Packit Service 0a38ef
            res_find = find_user(ansible_module, name)
Packit Service 0a38ef
            # Also search for preserved user if the user could not be found
Packit Service 0a38ef
            if res_find is None:
Packit Service 0a38ef
                res_find_preserved = find_user(ansible_module, name,
Packit Service 0a38ef
                                               preserved=True)
Packit Service 0a38ef
            else:
Packit Service 0a38ef
                res_find_preserved = None
Packit Service 0a38ef
Packit Service 0a38ef
            # Create command
Packit Service 0a38ef
            if state == "present":
Packit Service 0a38ef
                # Generate args
Packit Service 0a38ef
                args = gen_args(
Packit Service 0a38ef
                    first, last, fullname, displayname, initials, homedir,
Packit Service 0a38ef
                    shell, email, principalexpiration, passwordexpiration,
Packit Service 0a38ef
                    password, random, uid, gid, city, userstate, postalcode,
Packit Service 0a38ef
                    phone, mobile, pager, fax, orgunit, title, carlicense,
Packit Service 0a38ef
                    sshpubkey, userauthtype, userclass, radius, radiususer,
Packit Service 0a38ef
                    departmentnumber, employeenumber, employeetype,
Packit Service 0a38ef
                    preferredlanguage, noprivate, nomembers)
Packit Service 0a38ef
Packit Service 0a38ef
                # Also check preserved users
Packit Service 0a38ef
                if res_find is None and res_find_preserved is not None:
Packit Service 0a38ef
                    res_find = res_find_preserved
Packit Service 0a38ef
Packit Service 0a38ef
                if action == "user":
Packit Service 0a38ef
                    # Found the user
Packit Service 0a38ef
                    if res_find is not None:
Packit Service 0a38ef
                        # Ignore password and random with
Packit Service 0a38ef
                        # update_password == on_create
Packit Service 0a38ef
                        if update_password == "on_create":
Packit Service 0a38ef
                            if "userpassword" in args:
Packit Service 0a38ef
                                del args["userpassword"]
Packit Service 0a38ef
                            if "random" in args:
Packit Service 0a38ef
                                del args["random"]
Packit Service 0a38ef
                        if "noprivate" in args:
Packit Service 0a38ef
                            del args["noprivate"]
Packit Service 0a38ef
Packit Service 0a38ef
                        # Ignore userauthtype if it is empty (for resetting)
Packit Service 0a38ef
                        # and not set in for the user
Packit Service 0a38ef
                        if "ipauserauthtype" not in res_find and \
Packit Service 0a38ef
                           "ipauserauthtype" in args and \
Packit Service 0a38ef
                           args["ipauserauthtype"] == ['']:
Packit Service 0a38ef
                            del args["ipauserauthtype"]
Packit Service 0a38ef
Packit Service 0a38ef
                        # For all settings is args, check if there are
Packit Service 0a38ef
                        # different settings in the find result.
Packit Service 0a38ef
                        # If yes: modify
Packit Service 0a38ef
                        if not compare_args_ipa(ansible_module, args,
Packit Service 0a38ef
                                                res_find):
Packit Service 0a38ef
                            commands.append([name, "user_mod", args])
Packit Service 0a38ef
Packit Service 0a38ef
                    else:
Packit Service 0a38ef
                        # Make sure we have a first and last name
Packit Service 0a38ef
                        if first is None:
Packit Service 0a38ef
                            ansible_module.fail_json(
Packit Service 0a38ef
                                msg="First name is needed")
Packit Service 0a38ef
                        if last is None:
Packit Service 0a38ef
                            ansible_module.fail_json(
Packit Service 0a38ef
                                msg="Last name is needed")
Packit Service 0a38ef
Packit Service 0a38ef
                        commands.append([name, "user_add", args])
Packit Service 0a38ef
Packit Service 0a38ef
                    # Handle members: principal, manager, certificate and
Packit Service 0a38ef
                    # certmapdata
Packit Service 0a38ef
                    if res_find is not None:
Packit Service 0a38ef
                        # Generate addition and removal lists
Packit Service 0a38ef
                        manager_add, manager_del = gen_add_del_lists(
Packit Service 0a38ef
                            manager, res_find.get("manager"))
Packit Service 0a38ef
Packit Service 0a38ef
                        principal_add, principal_del = gen_add_del_lists(
Packit Service 0a38ef
                            principal, res_find.get("krbprincipalname"))
Packit Service 0a38ef
                        # Principals are not returned as utf8 for IPA using
Packit Service 0a38ef
                        # python2 using user_find, therefore we need to
Packit Service 0a38ef
                        # convert the principals that we should remove.
Packit Service 0a38ef
                        principal_del = [to_text(x) for x in principal_del]
Packit Service 0a38ef
Packit Service 0a38ef
                        certificate_add, certificate_del = gen_add_del_lists(
Packit Service 0a38ef
                            certificate, res_find.get("usercertificate"))
Packit Service 0a38ef
Packit Service 0a38ef
                        certmapdata_add, certmapdata_del = gen_add_del_lists(
Packit Service 0a38ef
                            certmapdata, res_find.get("ipacertmapdata"))
Packit Service 0a38ef
Packit Service 0a38ef
                    else:
Packit Service 0a38ef
                        # Use given managers and principals
Packit Service 0a38ef
                        manager_add = manager or []
Packit Service 0a38ef
                        manager_del = []
Packit Service 0a38ef
                        principal_add = principal or []
Packit Service 0a38ef
                        principal_del = []
Packit Service 0a38ef
                        certificate_add = certificate or []
Packit Service 0a38ef
                        certificate_del = []
Packit Service 0a38ef
                        certmapdata_add = certmapdata or []
Packit Service 0a38ef
                        certmapdata_del = []
Packit Service 0a38ef
Packit Service 0a38ef
                    # Remove canonical principal from principal_del
Packit Service 0a38ef
                    canonical_principal = name + "@" + server_realm
Packit Service 0a38ef
                    if canonical_principal in principal_del:
Packit Service 0a38ef
                        principal_del.remove(canonical_principal)
Packit Service 0a38ef
Packit Service 0a38ef
                    # Add managers
Packit Service 0a38ef
                    if len(manager_add) > 0:
Packit Service 0a38ef
                        commands.append([name, "user_add_manager",
Packit Service 0a38ef
                                         {
Packit Service 0a38ef
                                             "user": manager_add,
Packit Service 0a38ef
                                         }])
Packit Service 0a38ef
                    # Remove managers
Packit Service 0a38ef
                    if len(manager_del) > 0:
Packit Service 0a38ef
                        commands.append([name, "user_remove_manager",
Packit Service 0a38ef
                                         {
Packit Service 0a38ef
                                             "user": manager_del,
Packit Service 0a38ef
                                         }])
Packit Service 0a38ef
Packit Service 0a38ef
                    # Principals need to be added and removed one by one,
Packit Service 0a38ef
                    # because if entry already exists, the processing of
Packit Service 0a38ef
                    # the remaining enries is stopped. The same applies to
Packit Service 0a38ef
                    # the removal of non-existing entries.
Packit Service 0a38ef
Packit Service 0a38ef
                    # Add principals
Packit Service 0a38ef
                    if len(principal_add) > 0:
Packit Service 0a38ef
                        for _principal in principal_add:
Packit Service 0a38ef
                            commands.append([name, "user_add_principal",
Packit Service 0a38ef
                                             {
Packit Service 0a38ef
                                                 "krbprincipalname":
Packit Service 0a38ef
                                                 _principal,
Packit Service 0a38ef
                                             }])
Packit Service 0a38ef
                    # Remove principals
Packit Service 0a38ef
                    if len(principal_del) > 0:
Packit Service 0a38ef
                        for _principal in principal_del:
Packit Service 0a38ef
                            commands.append([name, "user_remove_principal",
Packit Service 0a38ef
                                             {
Packit Service 0a38ef
                                                 "krbprincipalname":
Packit Service 0a38ef
                                                 _principal,
Packit Service 0a38ef
                                             }])
Packit Service 0a38ef
Packit Service 0a38ef
                    # Certificates need to be added and removed one by one,
Packit Service 0a38ef
                    # because if entry already exists, the processing of
Packit Service 0a38ef
                    # the remaining enries is stopped. The same applies to
Packit Service 0a38ef
                    # the removal of non-existing entries.
Packit Service 0a38ef
Packit Service 0a38ef
                    # Add certificates
Packit Service 0a38ef
                    if len(certificate_add) > 0:
Packit Service 0a38ef
                        for _certificate in certificate_add:
Packit Service 0a38ef
                            commands.append([name, "user_add_cert",
Packit Service 0a38ef
                                             {
Packit Service 0a38ef
                                                 "usercertificate":
Packit Service 0a38ef
                                                 _certificate,
Packit Service 0a38ef
                                             }])
Packit Service 0a38ef
                    # Remove certificates
Packit Service 0a38ef
                    if len(certificate_del) > 0:
Packit Service 0a38ef
                        for _certificate in certificate_del:
Packit Service 0a38ef
                            commands.append([name, "user_remove_cert",
Packit Service 0a38ef
                                             {
Packit Service 0a38ef
                                                 "usercertificate":
Packit Service 0a38ef
                                                 _certificate,
Packit Service 0a38ef
                                             }])
Packit Service 0a38ef
Packit Service 0a38ef
                    # certmapdata need to be added and removed one by one,
Packit Service 0a38ef
                    # because issuer and subject can only be done one by
Packit Service 0a38ef
                    # one reliably (https://pagure.io/freeipa/issue/8097)
Packit Service 0a38ef
Packit Service 0a38ef
                    # Add certmapdata
Packit Service 0a38ef
                    if len(certmapdata_add) > 0:
Packit Service 0a38ef
                        for _data in certmapdata_add:
Packit Service 0a38ef
                            commands.append([name, "user_add_certmapdata",
Packit Service 0a38ef
                                             gen_certmapdata_args(_data)])
Packit Service 0a38ef
                    # Remove certmapdata
Packit Service 0a38ef
                    if len(certmapdata_del) > 0:
Packit Service 0a38ef
                        for _data in certmapdata_del:
Packit Service 0a38ef
                            commands.append([name, "user_remove_certmapdata",
Packit Service 0a38ef
                                             gen_certmapdata_args(_data)])
Packit Service 0a38ef
Packit Service 0a38ef
                elif action == "member":
Packit Service 0a38ef
                    if res_find is None:
Packit Service 0a38ef
                        ansible_module.fail_json(
Packit Service 0a38ef
                            msg="No user '%s'" % name)
Packit Service 0a38ef
Packit Service 0a38ef
                    # Ensure managers are present
Packit Service 0a38ef
                    if manager is not None and len(manager) > 0:
Packit Service 0a38ef
                        commands.append([name, "user_add_manager",
Packit Service 0a38ef
                                         {
Packit Service 0a38ef
                                             "user": manager,
Packit Service 0a38ef
                                         }])
Packit Service 0a38ef
Packit Service 0a38ef
                    # Principals need to be added and removed one by one,
Packit Service 0a38ef
                    # because if entry already exists, the processing of
Packit Service 0a38ef
                    # the remaining enries is stopped. The same applies to
Packit Service 0a38ef
                    # the removal of non-existing entries.
Packit Service 0a38ef
Packit Service 0a38ef
                    # Ensure principals are present
Packit Service 0a38ef
                    if principal is not None and len(principal) > 0:
Packit Service 0a38ef
                        for _principal in principal:
Packit Service 0a38ef
                            commands.append([name, "user_add_principal",
Packit Service 0a38ef
                                             {
Packit Service 0a38ef
                                                 "krbprincipalname":
Packit Service 0a38ef
                                                 _principal,
Packit Service 0a38ef
                                             }])
Packit Service 0a38ef
Packit Service 0a38ef
                    # Certificates need to be added and removed one by one,
Packit Service 0a38ef
                    # because if entry already exists, the processing of
Packit Service 0a38ef
                    # the remaining enries is stopped. The same applies to
Packit Service 0a38ef
                    # the removal of non-existing entries.
Packit Service 0a38ef
Packit Service 0a38ef
                    # Ensure certificates are present
Packit Service 0a38ef
                    if certificate is not None and len(certificate) > 0:
Packit Service 0a38ef
                        for _certificate in certificate:
Packit Service 0a38ef
                            commands.append([name, "user_add_cert",
Packit Service 0a38ef
                                             {
Packit Service 0a38ef
                                                 "usercertificate":
Packit Service 0a38ef
                                                 _certificate,
Packit Service 0a38ef
                                             }])
Packit Service 0a38ef
Packit Service 0a38ef
                    # certmapdata need to be added and removed one by one,
Packit Service 0a38ef
                    # because issuer and subject can only be done one by
Packit Service 0a38ef
                    # one reliably (https://pagure.io/freeipa/issue/8097)
Packit Service 0a38ef
Packit Service 0a38ef
                    # Ensure certmapdata are present
Packit Service 0a38ef
                    if certmapdata is not None and len(certmapdata) > 0:
Packit Service 0a38ef
                        for _data in certmapdata:
Packit Service 0a38ef
                            commands.append([name, "user_add_certmapdata",
Packit Service 0a38ef
                                             gen_certmapdata_args(_data)])
Packit Service 0a38ef
Packit Service 0a38ef
            elif state == "absent":
Packit Service 0a38ef
                # Also check preserved users
Packit Service 0a38ef
                if res_find is None and res_find_preserved is not None:
Packit Service 0a38ef
                    res_find = res_find_preserved
Packit Service 0a38ef
Packit Service 0a38ef
                if action == "user":
Packit Service 0a38ef
                    if res_find is not None:
Packit Service 0a38ef
                        args = {}
Packit Service 0a38ef
                        if preserve is not None:
Packit Service 0a38ef
                            args["preserve"] = preserve
Packit Service 0a38ef
                        commands.append([name, "user_del", args])
Packit Service 0a38ef
                elif action == "member":
Packit Service 0a38ef
                    if res_find is None:
Packit Service 0a38ef
                        ansible_module.fail_json(
Packit Service 0a38ef
                            msg="No user '%s'" % name)
Packit Service 0a38ef
Packit Service 0a38ef
                    # Ensure managers are absent
Packit Service 0a38ef
                    if manager is not None and len(manager) > 0:
Packit Service 0a38ef
                        commands.append([name, "user_remove_manager",
Packit Service 0a38ef
                                         {
Packit Service 0a38ef
                                             "user": manager,
Packit Service 0a38ef
                                         }])
Packit Service 0a38ef
Packit Service 0a38ef
                    # Principals need to be added and removed one by one,
Packit Service 0a38ef
                    # because if entry already exists, the processing of
Packit Service 0a38ef
                    # the remaining enries is stopped. The same applies to
Packit Service 0a38ef
                    # the removal of non-existing entries.
Packit Service 0a38ef
Packit Service 0a38ef
                    # Ensure principals are absent
Packit Service 0a38ef
                    if principal is not None and len(principal) > 0:
Packit Service 0a38ef
                        commands.append([name, "user_remove_principal",
Packit Service 0a38ef
                                         {
Packit Service 0a38ef
                                             "krbprincipalname": principal,
Packit Service 0a38ef
                                         }])
Packit Service 0a38ef
Packit Service 0a38ef
                    # Certificates need to be added and removed one by one,
Packit Service 0a38ef
                    # because if entry already exists, the processing of
Packit Service 0a38ef
                    # the remaining enries is stopped. The same applies to
Packit Service 0a38ef
                    # the removal of non-existing entries.
Packit Service 0a38ef
Packit Service 0a38ef
                    # Ensure certificates are absent
Packit Service 0a38ef
                    if certificate is not None and len(certificate) > 0:
Packit Service 0a38ef
                        for _certificate in certificate:
Packit Service 0a38ef
                            commands.append([name, "user_remove_cert",
Packit Service 0a38ef
                                             {
Packit Service 0a38ef
                                                 "usercertificate":
Packit Service 0a38ef
                                                 _certificate,
Packit Service 0a38ef
                                             }])
Packit Service 0a38ef
Packit Service 0a38ef
                    # certmapdata need to be added and removed one by one,
Packit Service 0a38ef
                    # because issuer and subject can only be done one by
Packit Service 0a38ef
                    # one reliably (https://pagure.io/freeipa/issue/8097)
Packit Service 0a38ef
Packit Service 0a38ef
                    # Ensure certmapdata are absent
Packit Service 0a38ef
                    if certmapdata is not None and len(certmapdata) > 0:
Packit Service 0a38ef
                        # Using issuer and subject can only be done one by
Packit Service 0a38ef
                        # one reliably (https://pagure.io/freeipa/issue/8097)
Packit Service 0a38ef
                        for _data in certmapdata:
Packit Service 0a38ef
                            commands.append([name, "user_remove_certmapdata",
Packit Service 0a38ef
                                             gen_certmapdata_args(_data)])
Packit Service 0a38ef
            elif state == "undeleted":
Packit Service 0a38ef
                if res_find_preserved is not None:
Packit Service 0a38ef
                    commands.append([name, "user_undel", {}])
Packit Service 0a38ef
                else:
Packit Service 0a38ef
                    raise ValueError("No preserved user '%s'" % name)
Packit Service 0a38ef
Packit Service 0a38ef
            elif state == "enabled":
Packit Service 0a38ef
                if res_find is not None:
Packit Service 0a38ef
                    if res_find["nsaccountlock"]:
Packit Service 0a38ef
                        commands.append([name, "user_enable", {}])
Packit Service 0a38ef
                else:
Packit Service 0a38ef
                    raise ValueError("No disabled user '%s'" % name)
Packit Service 0a38ef
Packit Service 0a38ef
            elif state == "disabled":
Packit Service 0a38ef
                if res_find is not None:
Packit Service 0a38ef
                    if not res_find["nsaccountlock"]:
Packit Service 0a38ef
                        commands.append([name, "user_disable", {}])
Packit Service 0a38ef
                else:
Packit Service 0a38ef
                    raise ValueError("No user '%s'" % name)
Packit Service 0a38ef
Packit Service 0a38ef
            elif state == "unlocked":
Packit Service 0a38ef
                if res_find is not None:
Packit Service 0a38ef
                    commands.append([name, "user_unlock", {}])
Packit Service 0a38ef
Packit Service 0a38ef
            else:
Packit Service 0a38ef
                ansible_module.fail_json(msg="Unkown state '%s'" % state)
Packit Service 0a38ef
Packit Service a166ed
        del user_set
Packit Service a166ed
Packit Service 0a38ef
        # Execute commands
Packit Service 0a38ef
Packit Service 0a38ef
        errors = []
Packit Service 0a38ef
        for name, command, args in commands:
Packit Service 0a38ef
            try:
Packit Service 0a38ef
                result = api_command(ansible_module, command, name,
Packit Service 0a38ef
                                     args)
Packit Service 0a38ef
                if "completed" in result:
Packit Service 0a38ef
                    if result["completed"] > 0:
Packit Service 0a38ef
                        changed = True
Packit Service 0a38ef
                else:
Packit Service 0a38ef
                    changed = True
Packit Service 0a38ef
Packit Service 0a38ef
                if "random" in args and command in ["user_add", "user_mod"] \
Packit Service 0a38ef
                   and "randompassword" in result["result"]:
Packit Service 0a38ef
                    if len(names) == 1:
Packit Service 0a38ef
                        exit_args["randompassword"] = \
Packit Service 0a38ef
                            result["result"]["randompassword"]
Packit Service 0a38ef
                    else:
Packit Service 0a38ef
                        exit_args.setdefault(name, {})["randompassword"] = \
Packit Service 0a38ef
                            result["result"]["randompassword"]
Packit Service 0a38ef
Packit Service 0a38ef
            except Exception as e:
Packit Service 0a38ef
                msg = str(e)
Packit Service 0a38ef
                if "already contains" in msg \
Packit Service 0a38ef
                   or "does not contain" in msg:
Packit Service 0a38ef
                    continue
Packit Service 0a38ef
                #  The canonical principal name may not be removed
Packit Service 0a38ef
                if "equal to the canonical principal name must" in msg:
Packit Service 0a38ef
                    continue
Packit Service 0a38ef
                ansible_module.fail_json(msg="%s: %s: %s" % (command, name,
Packit Service 0a38ef
                                                             msg))
Packit Service 0a38ef
Packit Service 0a38ef
            # Get all errors
Packit Service 0a38ef
            # All "already a member" and "not a member" failures in the
Packit Service 0a38ef
            # result are ignored. All others are reported.
Packit Service 0a38ef
            if "failed" in result and len(result["failed"]) > 0:
Packit Service 0a38ef
                for item in result["failed"]:
Packit Service 0a38ef
                    failed_item = result["failed"][item]
Packit Service 0a38ef
                    for member_type in failed_item:
Packit Service 0a38ef
                        for member, failure in failed_item[member_type]:
Packit Service 0a38ef
                            if "already a member" in failure \
Packit Service 0a38ef
                               or "not a member" in failure:
Packit Service 0a38ef
                                continue
Packit Service 0a38ef
                            errors.append("%s: %s %s: %s" % (
Packit Service 0a38ef
                                command, member_type, member, failure))
Packit Service 0a38ef
Packit Service 0a38ef
        if len(errors) > 0:
Packit Service 0a38ef
            ansible_module.fail_json(msg=", ".join(errors))
Packit Service 0a38ef
Packit Service 0a38ef
    except Exception as e:
Packit Service 0a38ef
        ansible_module.fail_json(msg=str(e))
Packit Service 0a38ef
Packit Service 0a38ef
    finally:
Packit Service 0a38ef
        temp_kdestroy(ccache_dir, ccache_name)
Packit Service 0a38ef
Packit Service 0a38ef
    # Done
Packit Service 0a38ef
    ansible_module.exit_json(changed=changed, user=exit_args)
Packit Service 0a38ef
Packit Service 0a38ef
Packit Service 0a38ef
if __name__ == "__main__":
Packit Service 0a38ef
    main()