2026-08-07 13:42:27 -04:00
|
|
|
---
|
|
|
|
|
# Amorcage des acces — D-67. Voir defaults/main.yml pour la doctrine, et
|
|
|
|
|
# docs/autorisation.md §6 pour le runbook de reprise.
|
|
|
|
|
|
|
|
|
|
- name: Résoudre la connexion à l'annuaire
|
|
|
|
|
ansible.builtin.include_role:
|
|
|
|
|
name: resoudre_annuaire
|
|
|
|
|
|
|
|
|
|
- name: Exiger le secret d'amorçage et le mot de passe d'annuaire (Vault)
|
|
|
|
|
ansible.builtin.assert:
|
|
|
|
|
that:
|
|
|
|
|
- amorcage_acces_secret | length > 0
|
|
|
|
|
- amorcage_acces_admin_password | length > 0
|
|
|
|
|
fail_msg: >-
|
|
|
|
|
`vault_sysadmin_amorcage` et `vault_openldap_admin` sont requis (voûte).
|
|
|
|
|
Le premier est un jeton d'amorçage à usage unique — pas un mot de passe
|
|
|
|
|
permanent : voir docs/autorisation.md §6.
|
|
|
|
|
when: amorcage_acces_actif | bool
|
|
|
|
|
|
|
|
|
|
# --- LE CŒUR DU RÔLE : on REGARDE avant d'agir --------------------------------
|
|
|
|
|
# La condition n'est pas la conformité, c'est l'EXISTENCE. Un compte présent est
|
|
|
|
|
# laissé strictement intact, quel que soit son état — c'est ce qui distingue ce
|
|
|
|
|
# rôle de tous les autres du dépôt (D-67).
|
|
|
|
|
- name: Le compte d'amorçage existe-t-il déjà ?
|
|
|
|
|
community.general.ldap_search:
|
|
|
|
|
dn: "ou=people,{{ resoudre_annuaire_base_dn }}"
|
|
|
|
|
scope: onelevel
|
|
|
|
|
filter: "(uid={{ amorcage_acces_uid }})"
|
|
|
|
|
server_uri: "ldapi:///"
|
|
|
|
|
bind_dn: "{{ resoudre_annuaire_bind_dn }}"
|
|
|
|
|
bind_pw: "{{ amorcage_acces_admin_password }}"
|
|
|
|
|
register: amorcage_acces_existant
|
|
|
|
|
changed_when: false
|
|
|
|
|
no_log: true
|
|
|
|
|
when: amorcage_acces_actif | bool
|
|
|
|
|
|
|
|
|
|
- name: Retenir si l'amorçage a déjà eu lieu
|
|
|
|
|
ansible.builtin.set_fact:
|
|
|
|
|
amorcage_acces_deja_fait: >-
|
|
|
|
|
{{ (amorcage_acces_existant.results | default([]) | length) > 0 }}
|
|
|
|
|
when: amorcage_acces_actif | bool
|
|
|
|
|
|
|
|
|
|
- name: Annoncer que l'amorçage est déjà fait (aucune action)
|
|
|
|
|
ansible.builtin.debug:
|
|
|
|
|
msg: >-
|
|
|
|
|
Compte `{{ amorcage_acces_uid }}` déjà présent : Set-OPS n'y touche pas.
|
|
|
|
|
Les habilitations sont gouvernées par une personne (D-67) — voir
|
|
|
|
|
docs/autorisation.md §6.
|
|
|
|
|
when:
|
|
|
|
|
- amorcage_acces_actif | bool
|
|
|
|
|
- amorcage_acces_deja_fait | bool
|
|
|
|
|
|
|
|
|
|
# --- Tout ce qui suit ne s'exécute QUE si le compte est absent -----------------
|
|
|
|
|
|
2026-08-08 06:08:06 -04:00
|
|
|
# Verifie ICI et non plus haut : un ecosysteme deja amorce ne doit pas se mettre
|
|
|
|
|
# a echouer parce qu'on a durci la regle apres coup.
|
|
|
|
|
- name: Exiger une adresse de courriel pour le compte d'amorçage
|
|
|
|
|
ansible.builtin.assert:
|
|
|
|
|
that:
|
|
|
|
|
- amorcage_acces_courriel | length > 0
|
|
|
|
|
fail_msg: >-
|
|
|
|
|
`amorcage_acces_courriel` est vide. Ce compte est le seul recours quand
|
|
|
|
|
plus rien d'autre ne repond : sans adresse joignable, « mot de passe
|
|
|
|
|
oublie » ne mene nulle part et la reprise repasse par un tiers qui
|
|
|
|
|
manipule le mot de passe de quelqu'un d'autre. Declarer une adresse que
|
|
|
|
|
la personne lit DEJA, hors de l'ecosysteme qu'on amorce.
|
|
|
|
|
when:
|
|
|
|
|
- amorcage_acces_actif | bool
|
|
|
|
|
- not (amorcage_acces_deja_fait | bool)
|
|
|
|
|
|
2026-08-07 13:42:27 -04:00
|
|
|
# Le mot de passe est HACHÉ par slapd lui-même. `ldap_entry` écrirait la chaîne
|
|
|
|
|
# littéralement : le jeton d'amorçage se retrouverait en clair dans la base, lisible
|
|
|
|
|
# par quiconque peut lire l'annuaire.
|
|
|
|
|
- name: Hacher le jeton d'amorçage (slappasswd, SSHA)
|
|
|
|
|
ansible.builtin.command:
|
|
|
|
|
argv:
|
|
|
|
|
- slappasswd
|
|
|
|
|
- "-h"
|
|
|
|
|
- "{SSHA}"
|
|
|
|
|
- "-s"
|
|
|
|
|
- "{{ amorcage_acces_secret }}"
|
|
|
|
|
register: amorcage_acces_hache
|
|
|
|
|
changed_when: false
|
|
|
|
|
no_log: true
|
|
|
|
|
when:
|
|
|
|
|
- amorcage_acces_actif | bool
|
|
|
|
|
- not amorcage_acces_deja_fait | bool
|
|
|
|
|
|
|
|
|
|
# Le changement forcé s'appuie sur `pwdReset`, qui vient de l'overlay `ppolicy`.
|
|
|
|
|
# On le DÉTECTE au lieu de le supposer : sans l'overlay, l'attribut est inconnu du
|
|
|
|
|
# schéma et l'entrée entière est rejetée — panne obscure, et le compte n'existe pas
|
|
|
|
|
# du tout. Mesuré le 2026-08-07 : seul `back_mdb` était chargé.
|
|
|
|
|
- name: L'overlay ppolicy est-il chargé (attribut `pwdReset` connu) ?
|
|
|
|
|
ansible.builtin.command:
|
|
|
|
|
argv:
|
|
|
|
|
- ldapsearch
|
|
|
|
|
- "-Y"
|
|
|
|
|
- EXTERNAL
|
|
|
|
|
- "-H"
|
|
|
|
|
- "ldapi:///"
|
|
|
|
|
- "-b"
|
|
|
|
|
- "cn=schema,cn=config"
|
|
|
|
|
- "(olcAttributeTypes=*pwdReset*)"
|
|
|
|
|
- dn
|
|
|
|
|
register: amorcage_acces_ppolicy
|
|
|
|
|
changed_when: false
|
|
|
|
|
failed_when: false
|
|
|
|
|
when:
|
|
|
|
|
- amorcage_acces_actif | bool
|
|
|
|
|
- not amorcage_acces_deja_fait | bool
|
|
|
|
|
|
|
|
|
|
- name: Retenir si le changement forcé est applicable
|
|
|
|
|
ansible.builtin.set_fact:
|
|
|
|
|
amorcage_acces_reset_possible: >-
|
|
|
|
|
{{ amorcage_acces_changement_force | bool
|
|
|
|
|
and 'dn:' in (amorcage_acces_ppolicy.stdout | default('')) }}
|
|
|
|
|
when:
|
|
|
|
|
- amorcage_acces_actif | bool
|
|
|
|
|
- not amorcage_acces_deja_fait | bool
|
|
|
|
|
|
|
|
|
|
- name: Créer le compte d'amorçage du sysadmin
|
|
|
|
|
community.general.ldap_entry:
|
|
|
|
|
dn: "uid={{ amorcage_acces_uid }},ou=people,{{ resoudre_annuaire_base_dn }}"
|
|
|
|
|
objectClass:
|
|
|
|
|
- inetOrgPerson
|
|
|
|
|
- organizationalPerson
|
|
|
|
|
- person
|
|
|
|
|
- top
|
|
|
|
|
attributes:
|
|
|
|
|
uid: "{{ amorcage_acces_uid }}"
|
|
|
|
|
cn: "{{ amorcage_acces_nom }}"
|
|
|
|
|
sn: "{{ amorcage_acces_nom.split(' ') | last }}"
|
|
|
|
|
userPassword: "{{ amorcage_acces_hache.stdout | trim }}"
|
|
|
|
|
pwdReset: "{{ 'TRUE' if amorcage_acces_reset_possible | bool else omit }}"
|
|
|
|
|
mail: "{{ amorcage_acces_courriel | default(omit, true) }}"
|
|
|
|
|
server_uri: "ldapi:///"
|
|
|
|
|
bind_dn: "{{ resoudre_annuaire_bind_dn }}"
|
|
|
|
|
bind_pw: "{{ amorcage_acces_admin_password }}"
|
|
|
|
|
no_log: true
|
|
|
|
|
when:
|
|
|
|
|
- amorcage_acces_actif | bool
|
|
|
|
|
- not amorcage_acces_deja_fait | bool
|
|
|
|
|
|
|
|
|
|
# `groupOfNames` EXIGE au moins un membre : un groupe vide est refusé par le
|
|
|
|
|
# schéma — ce qui tombe bien, un groupe d'habilitation sans personne n'aurait
|
|
|
|
|
# aucun sens à l'amorçage.
|
|
|
|
|
- name: Créer le groupe d'habilitation avec le sysadmin pour membre
|
|
|
|
|
community.general.ldap_entry:
|
|
|
|
|
dn: "cn={{ amorcage_acces_groupe }},ou=groups,{{ resoudre_annuaire_base_dn }}"
|
|
|
|
|
objectClass:
|
|
|
|
|
- groupOfNames
|
|
|
|
|
- top
|
|
|
|
|
attributes:
|
|
|
|
|
cn: "{{ amorcage_acces_groupe }}"
|
|
|
|
|
member: "uid={{ amorcage_acces_uid }},ou=people,{{ resoudre_annuaire_base_dn }}"
|
|
|
|
|
description: >-
|
|
|
|
|
Habilitation d'administration. Amorcé par Set-OPS, gouverné ensuite par
|
|
|
|
|
une personne — le dépôt ne réconcilie pas ses membres (D-67).
|
|
|
|
|
server_uri: "ldapi:///"
|
|
|
|
|
bind_dn: "{{ resoudre_annuaire_bind_dn }}"
|
|
|
|
|
bind_pw: "{{ amorcage_acces_admin_password }}"
|
|
|
|
|
no_log: true
|
|
|
|
|
when:
|
|
|
|
|
- amorcage_acces_actif | bool
|
|
|
|
|
- not amorcage_acces_deja_fait | bool
|
|
|
|
|
|
|
|
|
|
- name: Annoncer la reprise en main
|
|
|
|
|
ansible.builtin.debug:
|
|
|
|
|
msg: >-
|
|
|
|
|
{{ [
|
|
|
|
|
'Accès d amorçage créé : uid=' ~ amorcage_acces_uid ~ ', groupe=' ~ amorcage_acces_groupe ~ '.',
|
|
|
|
|
'Mot de passe en voûte sous `vault_sysadmin_amorcage`.',
|
|
|
|
|
(amorcage_acces_reset_possible | bool)
|
|
|
|
|
| ternary('Changement FORCÉ à la première ouverture (ppolicy actif).',
|
|
|
|
|
'ATTENTION : rien ne force le changement — l overlay ppolicy n est pas chargé. '
|
|
|
|
|
~ 'Le changer à la main dès la première connexion (docs/autorisation.md §6).'),
|
|
|
|
|
'À partir d ici, Set-OPS ne touche plus aux habilitations (D-67).'
|
|
|
|
|
] }}
|
|
|
|
|
when:
|
|
|
|
|
- amorcage_acces_actif | bool
|
|
|
|
|
- not amorcage_acces_deja_fait | bool
|