
    Vhd                     :   d dl mZmZmZ eZdZdZdZd dl	Z	d dl
Z
d dlmZmZ d dlmZ d dlmZ 	 d dlZd	ZdZ	 d dlZeseZd	ZdZ G d de      Zd Zedk(  r e        yy# e$ r d
Z e
j*                         ZY Cw xY w# e$ r d
Z e
j*                         ZY Tw xY w)    )absolute_importdivisionprint_functionaL  
module: homectl
author:
  - "James Livulpi (@jameslivulpi)"
short_description: Manage user accounts with systemd-homed
version_added: 4.4.0
description:
  - Manages a user's home directory managed by systemd-homed.
notes:
  - This module requires the deprecated L(crypt Python module, https://docs.python.org/3.12/library/crypt.html) library which
    was removed from Python 3.13. For Python 3.13 or newer, you need to install L(legacycrypt, https://pypi.org/project/legacycrypt/).
requirements:
  - legacycrypt (on Python 3.13 or newer)
extends_documentation_fragment:
  - community.general.attributes
attributes:
  check_mode:
    support: full
  diff_mode:
    support: none
options:
  name:
    description:
      - The user name to create, remove, or update.
    required: true
    aliases: ['user', 'username']
    type: str
  password:
    description:
      - Set the user's password to this.
      - Homed requires this value to be in cleartext on user creation and updating a user.
      - The module takes the password and generates a password hash in SHA-512 with 10000 rounds of salt generation using
        crypt.
      - See U(https://systemd.io/USER_RECORD/).
      - This is required for O(state=present). When an existing user is updated this is checked against the stored hash in
        homed.
    type: str
  state:
    description:
      - The operation to take on the user.
    choices: ['absent', 'present']
    default: present
    type: str
  storage:
    description:
      - Indicates the storage mechanism for the user's home directory.
      - If the storage type is not specified, C(homed.conf(5\)) defines which default storage to use.
      - Only used when a user is first created.
    choices: ['classic', 'luks', 'directory', 'subvolume', 'fscrypt', 'cifs']
    type: str
  disksize:
    description:
      - The intended home directory disk space.
      - Human readable value such as V(10G), V(10M), or V(10B).
    type: str
  resize:
    description:
      - When used with O(disksize) this will attempt to resize the home directory immediately.
    default: false
    type: bool
  realname:
    description:
      - The user's real ('human') name.
      - This can also be used to add a comment to maintain compatibility with C(useradd).
    aliases: ['comment']
    type: str
  realm:
    description:
      - The 'realm' a user is defined in.
    type: str
  email:
    description:
      - The email address of the user.
    type: str
  location:
    description:
      - A free-form location string describing the location of the user.
    type: str
  iconname:
    description:
      - The name of an icon picked by the user, for example for the purpose of an avatar.
      - Should follow the semantics defined in the Icon Naming Specification.
      - See U(https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html) for specifics.
    type: str
  homedir:
    description:
      - Path to use as home directory for the user.
      - This is the directory the user's home directory is mounted to while the user is logged in.
      - This is not where the user's data is actually stored, see O(imagepath) for that.
      - Only used when a user is first created.
    type: path
  imagepath:
    description:
      - Path to place the user's home directory.
      - See U(https://www.freedesktop.org/software/systemd/man/homectl.html#--image-path=PATH) for more information.
      - Only used when a user is first created.
    type: path
  uid:
    description:
      - Sets the UID of the user.
      - If using O(gid) homed requires the value to be the same.
      - Only used when a user is first created.
    type: int
  gid:
    description:
      - Sets the gid of the user.
      - If using O(uid) homed requires the value to be the same.
      - Only used when a user is first created.
    type: int
  mountopts:
    description:
      - String separated by comma each indicating mount options for a users home directory.
      - Valid options are V(nosuid), V(nodev) or V(noexec).
      - Homed by default uses V(nodev) and V(nosuid) while V(noexec) is off.
    type: str
  umask:
    description:
      - Sets the umask for the user's login sessions.
      - Value from V(0000) to V(0777).
    type: int
  memberof:
    description:
      - String separated by comma each indicating a UNIX group this user shall be a member of.
      - Groups the user should be a member of should be supplied as comma separated list.
    aliases: ['groups']
    type: str
  skeleton:
    description:
      - The absolute path to the skeleton directory to populate a new home directory from.
      - This is only used when a home directory is first created.
      - If not specified homed by default uses V(/etc/skel).
    aliases: ['skel']
    type: path
  shell:
    description:
      - Shell binary to use for terminal logins of given user.
      - If not specified homed by default uses V(/bin/bash).
    type: str
  environment:
    description:
      - String separated by comma each containing an environment variable and its value to set for the user's login session,
        in a format compatible with C(putenv(\)).
      - Any environment variable listed here is automatically set by pam_systemd for all login sessions of the user.
    aliases: ['setenv']
    type: str
  timezone:
    description:
      - Preferred timezone to use for the user.
      - Should be a tzdata compatible location string such as V(America/New_York).
    type: str
  locked:
    description:
      - Whether the user account should be locked or not.
    type: bool
  language:
    description:
      - The preferred language/locale for the user.
      - This should be in a format compatible with the E(LANG) environment variable.
    type: str
  passwordhint:
    description:
      - Password hint for the given user.
    type: str
  sshkeys:
    description:
      - String separated by comma each listing a SSH public key that is authorized to access the account.
      - The keys should follow the same format as the lines in a traditional C(~/.ssh/authorized_key) file.
    type: str
  notbefore:
    description:
      - A time since the UNIX epoch before which the record should be considered invalid for the purpose of logging in.
    type: int
  notafter:
    description:
      - A time since the UNIX epoch after which the record should be considered invalid for the purpose of logging in.
    type: int
a  
- name: Add the user 'james'
  community.general.homectl:
    name: johnd
    password: myreallysecurepassword1!
    state: present

- name: Add the user 'alice' with a zsh shell, uid of 1000, and gid of 2000
  community.general.homectl:
    name: alice
    password: myreallysecurepassword1!
    state: present
    shell: /bin/zsh
    uid: 1000
    gid: 1000

- name: Modify an existing user 'frank' to have 10G of diskspace and resize usage now
  community.general.homectl:
    name: frank
    password: myreallysecurepassword1!
    state: present
    disksize: 10G
    resize: true

- name: Remove an existing user 'janet'
  community.general.homectl:
    name: janet
    state: absent
a  
data:
  description: Dictionary returned from C(homectl inspect -j).
  returned: success
  type: dict
  sample:
    {
      "data": {
        "binding": {
          "e9ed2a5b0033427286b228e97c1e8343": {
            "fileSystemType": "btrfs",
            "fileSystemUuid": "7bd59491-2812-4642-a492-220c3f0c6c0b",
            "gid": 60268,
            "imagePath": "/home/james.home",
            "luksCipher": "aes",
            "luksCipherMode": "xts-plain64",
            "luksUuid": "7f05825a-2c38-47b4-90e1-f21540a35a81",
            "luksVolumeKeySize": 32,
            "partitionUuid": "5a906126-d3c8-4234-b230-8f6e9b427b2f",
            "storage": "luks",
            "uid": 60268
          }
        },
        "diskSize": 3221225472,
        "disposition": "regular",
        "lastChangeUSec": 1641941238208691,
        "lastPasswordChangeUSec": 1641941238208691,
        "privileged": {
          "hashedPassword": [
            "$6$ov9AKni.trf76inT$tTtfSyHgbPTdUsG0CvSSQZXGqFGdHKQ9Pb6e0BTZhDmlgrL/vA5BxrXduBi8u/PCBiYUffGLIkGhApjKMK3bV."
          ]
        },
        "signature": [
          {
            "data": "o6zVFbymcmk4YTVaY6KPQK23YCp+VkXdGEeniZeV1pzIbFzoaZBvVLPkNKMoPAQbodY5BYfBtuy41prNL78qAg==",
            "key": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAbs7ELeiEYBxkUQhxZ+5NGyu6J7gTtZtZ5vmIw3jowcY=\n-----END PUBLIC KEY-----\n"
          }
        ],
        "status": {
          "e9ed2a5b0033427286b228e97c1e8343": {
            "diskCeiling": 21845405696,
            "diskFloor": 268435456,
            "diskSize": 3221225472,
            "service": "io.systemd.Home",
            "signedLocally": true,
            "state": "inactive"
          }
        },
        "userName": "james"
      }
    }
N)AnsibleModulemissing_required_lib)jsonify)human_to_bytesTFc                   N    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 ZddZy)Homectlz#TODO DOC STRINGSc                    || _         |j                  d   | _        |j                  d   | _        |j                  d   | _        |j                  d   | _        |j                  d   | _        |j                  d   | _        |j                  d   | _        |j                  d   | _	        |j                  d	   | _
        |j                  d
   | _        |j                  d   | _        |j                  d   | _        |j                  d   | _        |j                  d   | _        |j                  d   | _        |j                  d   | _        |j                  d   | _        |j                  d   | _        |j                  d   | _        |j                  d   | _        |j                  d   | _        |j                  d   | _        |j                  d   | _        |j                  d   | _        |j                  d   | _        |j                  d   | _        |j                  d   | _        |j                  d   | _        i | _        y )Nstatenamepasswordstoragedisksizeresizerealnamerealmemaillocationiconnamehomedir	imagepathuidgidumaskmemberofskeletonshellenvironmenttimezonelockedpasswordhintsshkeyslanguage	notbeforenotafter	mountopts)moduleparamsr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   result)selfr)   s     m/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/general/plugins/modules/homectl.py__init__zHomectl.__init__.  s   ]]7+
MM&)	j1}}Y/j1mmH-j1]]7+
]]7+
j1j1}}Y/{3=='==']]7+
j1j1]]7+
!==7j1mmH-"MM.9}}Y/j1{3j1{3    c                     d}g d}| j                   j                  |      \  }}}|dk(  r)|j                  d      d   }|j                         dk7  rd}|S )NT)	systemctlshowzsystemd-homed.servicez-pActiveStater   =   activeF)r)   run_commandrsplitstrip)r,   	is_activecmdrcshow_service_stdoutstderrr   s          r-   homed_service_activezHomectl.homed_service_activeP  s]    	Q*.++*A*A#*F'7'..s3A6E{{}(!	r/   c                     d}d}| j                         \  }}}|dk(  rBd}| j                  dk7  r1t        j                  |      d   d   d   }| j	                  |      rd}||fS )NFr   Tabsent
privilegedhashedPassword)get_user_metadatar   jsonloads_check_password)r,   existsvalid_pwr<   stdoutr>   stored_pwhashs          r-   user_existszHomectl.user_existsZ  sv    !335FF7FzzX% $

6 2< @AQ RST U''6#Hxr/   c                     | j                  d      }| j                  j                  dd      g}|j                  d       |j                  d       | j                  j	                  ||      S )NT)createhomectlrN   --identity=-data)create_json_recordr)   get_bin_pathappendr7   r,   recordr;   s      r-   create_userzHomectl.create_userh  s`    (((5{{''	489

8

>"{{&&s&88r/   c                     t         j                  }t        j                  |d      }t        j                   ||      }|S )Ni'  )rounds)cryptMETHOD_SHA512mksalt)r,   r   methodsaltpw_hashs        r-   _hash_passwordzHomectl._hash_passwordo  s2    $$||F51++h-r/   c                 L    t        j                   | j                  |      }||k(  S )N)r[   r   )r,   pwhashhashs      r-   rG   zHomectl._check_passwordu  s     {{4==&1~r/   c                     | j                   j                  dd      g}|j                  d       |j                  | j                         | j                   j	                  |      S )NrO   Tremover)   rT   rU   r   r7   )r,   r;   s     r-   remove_userzHomectl.remove_usery  sL    {{''	489

8

499{{&&s++r/   c                 p   | j                         }| j                  j                  dd      g}|j                  d       |j                  | j                         |j                  d       | j
                  r=| j                  r1|j                  d       |j                  d       d| j                  d<   ||fS )NrO   TupdaterP   z--and-resizetruechanged)rS   r)   rT   rU   r   r   r   r+   rV   s      r-   prepare_modify_user_commandz#Homectl.prepare_modify_user_command  s    ((*{{''	489

8

499

>" ==T[[JJ~&JJv%)DKK	"F{r/   c                     | j                   j                  dd      g}|j                  d       |j                  | j                         |j                  d       |j                  d       | j                   j	                  |      \  }}}|||fS )NrO   Tinspectz-jz
--no-pagerrg   )r,   r;   r<   rJ   r>   s        r-   rD   zHomectl.get_user_metadata  sw    {{''	489

9

499

4

< ![[44S9FF66!!r/   c                    i }i }d| j                   d<   |ss| j                         \  }}}t        j                  |      }|j	                  dd        |j	                  dd        |j	                  dd        |j	                  dd        |}| j
                  |d<   d| j                  gi|d	<   |r2| j                  | j                        }d
|gi|d<   d| j                   d<   | j                  r;| j                  r/|r-| j                  |d<   | j                  |d<   d| j                   d<   | j                  rNt        | j                  j                  d            }||j                  dd g      k7  r||d<   d| j                   d<   | j                  r<| j                  |j                  d      k7  r| j                  |d<   d| j                   d<   | j                  r |r| j                  |d<   d| j                   d<   | j                   r |r| j                   |d<   d| j                   d<   | j"                  r |r| j"                  |d<   d| j                   d<   | j$                  rE| j$                  |j                  d      k7  r't'        | j$                        |d<   d| j                   d<   | j(                  r<| j(                  |j                  d      k7  r| j(                  |d<   d| j                   d<   | j*                  r<| j*                  |j                  d      k7  r| j*                  |d<   d| j                   d<   | j,                  r<| j,                  |j                  d      k7  r| j,                  |d<   d| j                   d<   | j.                  r<| j.                  |j                  d      k7  r| j.                  |d<   d| j                   d<   | j0                  r<| j0                  |j                  d      k7  r| j0                  |d<   d| j                   d<   | j2                  r<| j2                  |j                  d      k7  r| j2                  |d<   d| j                   d<   | j4                  r<| j4                  |j                  d      k7  r| j4                  |d<   d| j                   d<   | j6                  rV| j6                  |j                  dd g      k7  r6t        | j6                  j                  d            |d<   d| j                   d<   | j8                  r<| j8                  |j                  d      k7  r| j8                  |d<   d| j                   d<   | j:                  r<| j:                  |j                  d      k7  r| j:                  |d<   d| j                   d<   | j<                  rO| j<                  |j                  di       j                  d       k7  r!| j<                  |d   d <   d| j                   d<   | j>                  rg| j>                  |j                  di       j                  d!      k7  r9t        | j>                  j                  d            |d   d!<   d| j                   d<   | j@                  r<| j:                  |j                  d"      k7  r| j@                  |d"<   d| j                   d<   | jB                  r<| j:                  |j                  d#      k7  r| jB                  |d#<   d| j                   d<   | jD                  r<| j:                  |j                  d$      k7  r| jD                  |d$<   d| j                   d<   | jF                  r't        | jF                  j                  d            }d%|v r(|j                  d&      dur<d|d&<   d| j                   d<   n'|j                  d&      durd|d&<   d| j                   d<   d'|v r(|j                  d(      dur<d|d(<   d| j                   d<   n'|j                  d(      durd|d(<   d| j                   d<   d)|v r2|j                  d*      durFd|d*<   d| j                   d<   tI        |      S |j                  d*      durd|d*<   d| j                   d<   tI        |      S )+NFrl   	signaturebindingstatuslastChangeUSecuserNamer   secretrC   rB   Tr   r   ,memberOfrealNamer   homeDirectory	imagePathdiskSizer   emailAddressr   iconNameskeletonDirectoryr   r   r    timeZoner"   passwordHintsshAuthorizedKeyspreferredLanguagenotBeforeUSecnotAfterUSecnosuidmountNoSuidnodevmountNoDevicesnoexecmountNoExecute)%r+   rD   rE   rF   popr   r   ra   r   r   r   listsplitgetr   r   r   r   r   r	   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r   )	r,   rN   rW   user_metadatar<   r>   password_hashmember_listoptss	            r-   rS   zHomectl.create_json_record  s<   !&I(,(>(>(@%Bv JJ}5M k40i.h-.5"F!YYz&8x //>M$4}o#FF< %)DKK	"88V HHF5M HHF5M%)DKK	"==t}}22378KfjjdV<<%0z")-I&==}}

: 66%)]]z")-I& <<F $F9%)DKK	" <<F&*llF?#%)DKK	" >>f"&..F;%)DKK	"==}}

: 66%3DMM%Bz")-I&::zzVZZ00"&**w)-I&::zzVZZ77)-~&)-I&==}}

: 66%)]]z")-I&==}}

: 66%)]]z")-I&==}}

+> ??.2mm*+)-I&::zzVZZ00"&**w)-I&::zzVZZ00"&**w)-I&6::mdV#DD(,T-=-=-C-CC-H(I}%)-I&==}}

: 66%)]]z")-I&;;{{fjj22#';;x )-I&  FJJ|R$@$D$D^$TT7;7H7H|$^4)-I&<<||vzz,;??@STT<@ASASTWAX<Y|$%89)-I&=={{fjj)<==.2mm*+)-I&>>{{fjj99*...')-I&=={{fjj88)-~&)-I&>>,,S12D4::m,D8,0F=)-1DKK	*::m,E9,1F=)-1DKK	*$::./t;/3F+,-1DKK	*::./u</4F+,-1DKK	*4::./t;/3F+,-1DKK	* v	 ::./u</4F+,-1DKK	*vr/   N)F)__name__
__module____qualname____doc__r.   r?   rL   rX   ra   rG   rh   rm   rD   rS    r/   r-   r   r   +  s9    D 9,"jr/   r   c                  &
   t        t        dFi dt        ddddg      dt        dddd	g
      dt        dd      dt        dg d      dt        d      dt        dd      dt        ddg      dt        d      dt        d      dt        d      dt        d      dt        d      dt        d      d t        d!      d"t        d!      d#t        d!      d$t        dd%g      d&t        d      d't        dd(g      d)t        dd*g      d+t        d      d,t        d      d-t        dd      d.t        dd      d/t        d      d0t        d!      d1t        d!      d2t        d      ddddgfdddgfg3      } t        s&t        s | j	                  t        d4      t        5       t        |       }|j                  |j                  d<   |j                         s| j	                  d67       |j                  dk(  r|j                         \  }}|r| j                  r| j                  d8       |j                         \  }}}|d9k7  r| j	                  |j                  ||:       d|j                  d;<   ||j                  d<<   d=|j                  z  |j                  d><   nd|j                  d;<   d?|j                  d><   |j                  dk(  r|j                         \  }}|s| j                  r| j                  d8       |j!                         \  }}}|d9k7  r| j	                  |j                  ||:       |j#                         \  }}}t%        j&                  |      |j                  d@<   ||j                  d<<   dA|j                  z  |j                  d><   n2|r|j)                         \  }}	n:d|j                  d;<   dB|j                  d><    | j                  dFi |j                   | j                  r | j                  dFi |j                   |j                  d;   r;| j+                  	C      \  }}}|d9k7  r| j	                  |j                  ||dD       |j#                         \  }}}t%        j&                  |      |j                  d@<   ||j                  d<<   |j                  d;   rdE|j                  z  |j                  d><    | j                  dFi |j                   y )GNr   strpresentrA   )typedefaultchoicesr   Tuserusername)r   requiredaliasesr   )r   no_logr   )classicluks	directory	subvolumefscryptcifs)r   r   r   )r   r   boolF)r   r   r   comment)r   r   r   r   r   r   r   pathr   r   intr   r   r    setenvr!   r   groupsr   skelr   r"   r#   r$   r%   r&   r'   r(   )argument_specsupports_check_moderequired_ifzHcrypt (part of standard library up to Python 3.12) or legacycrypt (PyPI))msg	exceptionz#systemd-homed.service is not active)r   )rl   r   )r   r   r<   rl   r<   zUser %s removed!r   zUser does not exist!rR   zUser %s created!z&User exists but password is incorrect!rQ   )r   r   r<   rl   zUser %s modifiedr   )r   dict	HAS_CRYPTHAS_LEGACYCRYPT	fail_jsonr   CRYPT_IMPORT_ERRORr   r   r+   r?   rL   
check_mode	exit_jsonrh   r   rX   rD   rE   rF   rm   r7   )
r)   rO   rL   valid_pwhashr<   rJ   r>   r   r;   rW   s
             r-   mainr   D  s    
E9x>ST
54&*9MN
 uT2
 e-mn	

 u%
 VU3
 uyk:
 E"
 E"
 u%
 u%
 f%
 '
 % 
 % 
  E"!
" %(<#
$ u%%
& uxj9'
( vx8)
* E"+
, V$-
. 56/
0 eD11
2 u%3
4 &5
6 u%7
8 &9
< ! i*.tj\*
C%FN _$%op( 	 	

 foG%mmGNN7 '')BC }} $+$7$7$9!\     .!(!4!4!6BQw  gll2 F(,GNN9%#%GNN4 $6$EGNN5!(-GNN9%$:GNN5! }}	!$+$7$7$9!\     .!(!4!4!6BQw  gll2 F(/(A(A(C%Bv%)ZZ%>GNN6"#%GNN4 $6$EGNN5!%AACV -2y)(Pu%   27>>2     27>>2 ~~i(%+%7%7&%7%I"FF7$$',,FrSX$Y(/(A(A(C%Bv%)ZZ%>GNN6"#%GNN4 ~~i((:W\\(Iu%F&w~~&r/   __main__)
__future__r   r   r   r   __metaclass__DOCUMENTATIONEXAMPLESRETURNrE   	tracebackansible.module_utils.basicr   r   r   +ansible.module_utils.common.text.formattersr	   r[   r   r   ImportError
format_exclegacycryptr   LEGACYCRYPT_IMPORT_ERRORobjectr   r   r   r   r/   r-   <module>r      s    A @pd<3
j   J . F
 I	$
 O#Vf Vrj'Z zF s  0I---/0  6O3y3356s"   A! A? !A<;A<?BB