Une fois la configuration du nouvel annuaire terminée, vous pouvez ajouter de nouvelles entrées. Comme le fil conducteur de cette série de travaux pratiques est la gestion d'une base de comptes utilisateurs, vous devez ajouter les objets suivants :
-
Les branches : Trois unités organisationnelles (
users,groupsethosts). -
Les feuilles : Quatre comptes utilisateurs (papa et maman Skywalker ainsi que leurs deux enfants).
|
Q127. |
Quelle est la syntaxe du fichier LDIF qui permet de créer l'arbre et les branches de l'annuaire LDAP ? Recherchez la syntaxe de définition d'une organisation ( Déclarez trois branches : |
|
Voici un exemple de fichier LDIF contenant les déclarations des trois unités organisationnelles à ajouter. rm -f add_tree.ldif cat <<EOF >add_tree.ldif # DIT root (Base DN) dn: dc=lab,dc=local objectClass: top objectClass: dcObject objectClass: organization o: Lab Local Organisation dc: lab # Users branch dn: ou=users,dc=lab,dc=local objectClass: organizationalUnit ou: users # Groups branch dn: ou=groups,dc=lab,dc=local objectClass: organizationalUnit ou: groups # Hosts branch dn: ou=hosts,dc=lab,dc=local objectClass: organizationalUnit ou: hosts EOF |
|
|
Q128. |
Comment ajouter de nouveaux éléments à l'annuaire à partir des définitions d'un fichier LDIF ? Recherchez la commande d'ajout dans la liste des outils fournis avec le paquet |
|
Utilisez la commande ldapadd pour créer les branches de l'annuaire de travaux pratiques à partir des entrées définies dans le fichier LDIF ldapadd -x -H ldap://localhost \
-D "cn=admin,dc=lab,dc=local" \
-y ~/.ldap_admin_pass \
-f add_tree.ldif
adding new entry "dc=lab,dc=local" adding new entry "ou=users,dc=lab,dc=local" adding new entry "ou=groups,dc=lab,dc=local" adding new entry "ou=hosts,dc=lab,dc=local" Vérifiez ensuite la présence des branches dans l'annuaire avec la commande ldapsearch. ldapsearch -LLL -x -H ldap://localhost \
-D "cn=admin,dc=lab,dc=local" \
-y .ldap_admin_pass \
-b "dc=lab,dc=local"
dn: dc=lab,dc=local objectClass: top objectClass: dcObject objectClass: organization o: Lab Local Organisation dc: lab dn: ou=users,dc=lab,dc=local objectClass: organizationalUnit ou: users dn: ou=groups,dc=lab,dc=local objectClass: organizationalUnit ou: groups dn: ou=hosts,dc=lab,dc=local objectClass: organizationalUnit ou: hosts |
|
|
Q129. |
Quelle est la syntaxe du fichier LDIF qui permet de retirer les branches et l'arbre de l'annuaire LDAP ? Recherchez la syntaxe de suppression d'une organisation ( |
|
Voici un exemple de fichier LDIF contenant les suppressions des unités organisationnelles et de l'organisation racine. rm -f delete_tree.ldif cat <<EOF >delete_tree.ldif # Hosts branch dn: ou=hosts,dc=lab,dc=local changetype: delete # Users branch dn: ou=users,dc=lab,dc=local changetype: delete # Groups branch dn: ou=groups,dc=lab,dc=local changetype: delete # DIT root dn: dc=lab,dc=local changetype: delete |
|
|
Q130. |
Comment supprimer les éléments de l'annuaire à partir des définitions d'un fichier LDIF ? Recherchez la commande d'ajout dans la liste des outils fournis avec le paquet |
|
Utilisez la commande ldapmodify pour supprimer les branches de l'annuaire de travaux pratiques à partir des entrées définies dans le fichier LDIF ldapmodify -x -H ldap://localhost \
-D "cn=admin,dc=lab,dc=local" \
-y .ldap_admin_pass \
-f delete_tree.ldif
deleting entry "ou=hosts,dc=lab,dc=local" deleting entry "ou=users,dc=lab,dc=local" deleting entry "ou=groups,dc=lab,dc=local" deleting entry "dc=lab,dc=local" Vérifiez que l'annuaire LDAP est à nouveau vide avec la commande ldapsearch. ldapsearch -LLL -x -H ldap://localhost \
-D "cn=admin,dc=lab,dc=local" \
-y .ldap_admin_pass \
-b "dc=lab,dc=local"
No such object (32) |
![]() |
Attention |
|---|---|
|
Assurez-vous que l'annuaire contient un arbre avec les deux branches |
|
Q131. |
Comment générer un mot de passe utilisateur aléatoire et le condensat correspondant à insérer dans l'annuaire ? Recherchez les options de la commande openssl qui permettent de générer une chaîne de caractères lisibles de 24 caractères. Recherchez les options de la commande slappasswd qui permettent d'appliquer le module Argon2 au calcul de condensat (ou au hachage) du mot de passe de l'utilisateur. |
|
Pour créer un mot de passe sécurisé, commencez par générer 28 octets aléatoires en base64. Ensuite, réduisez la sortie à 24 caractères lisibles. openssl rand -base64 28 | cut -c -24 Utilisez ce secret pour le calcul de condensat avec l'algorithme Argon2. USER_PASS=$(openssl rand -base64 28 | cut -c -24)
USER_PASS_HASH=$(sudo slappasswd -o module-load=argon2.la -h "{ARGON2}" -s "${USER_PASS}")
echo "${USER_PASS_HASH}"
Dans le contexte de ces travaux pratiques, vous devez attribuer un mot de passe aux quatre membres de la famille Skywalker. |
|
|
Q132. |
Comment générer un mot de passe distinct pour chaque utilisateur et comment sauvegarder le hachage correspondant dans un fichier TOML qui servira à la génération LDIF ? Suivez une démarche en plusieurs étapes :
|
|
|
|
Q133. |
Comment coder le script Python qui génère le format LDIF à partir de la description TOML des attributs des comptes utilisateurs ? À partir de l'exemple de liste d'attributs LDAP ci-dessous, codez le formatage LDIF de chaque compte utilisateur. dn: uid=luke,ou=users,dc=lab,dc=local
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: luke
cn: Luke Skywalker
givenName: Luke
sn: Skywalker
mail: luke@lab.local
userPassword: {ARGON2}$argon2id$v=19$m=7168,t=5,p=1$hTdc...
shadowLastChange: 20586
loginShell: /bin/bash
uidNumber: 10003
gidNumber: 10003
homeDirectory: /ahome/luke
gecos: Luke Skywalker
De plus, il faut aussi créer un groupe privé pour chaque utilisateur avec le Codez le script Python |
|
Copiez l'exemple de code ci-dessous dans le fichier #!/usr/bin/env python3
import argparse
import time
import tomllib
def generate_ldif(toml_path, output_path):
# 1. Directly read the TOML file
with open(toml_path, "rb") as f:
data = tomllib.load(f)
cfg, users = data["global"], data["users"]
base_dn = cfg["base_dn"]
domain = ".".join(p[3:] for p in base_dn.split(",") if p.startswith("dc="))
shadow_day = int(time.time() // 86400)
with open(output_path, "w", encoding="utf-8") as ldif:
# 2. Generate private groups (UPG)
ldif.write("# --- PRIVATE GROUPS (UPG) ---\n")
for idx, u in enumerate(users):
gid = cfg["start_id"] + idx
ldif.write(
f"dn: cn={u['uid']},{cfg['groups_ou']},{base_dn}\n"
f"objectClass: posixGroup\ncn: {u['uid']}\ngidNumber: {gid}\n\n"
)
# 3. Generate user accounts
ldif.write("# --- USER ACCOUNTS ---\n")
for idx, u in enumerate(users):
uid = cfg["start_id"] + idx
full_name = f"{u['firstname']} {u['lastname']}"
password_hash = u["password_hash"]
ldif.write(
f"dn: uid={u['uid']},{cfg['users_ou']},{base_dn}\n"
"objectClass: inetOrgPerson\nobjectClass: posixAccount\nobjectClass: shadowAccount\n"
f"uid: {u['uid']}\ncn: {full_name}\ngivenName: {u['firstname']}\nsn: {u['lastname']}\n"
f"mail: {u['uid']}@{domain}\nuserPassword: {password_hash}\n"
f"shadowLastChange: {shadow_day}\nloginShell: {cfg['default_shell']}\n"
f"uidNumber: {uid}\ngidNumber: {uid}\n"
f"homeDirectory: {cfg['default_home_base']}/{u['uid']}\ngecos: {full_name}\n\n"
)
# 4. Generate the shared system group
ldif.write(
"# --- SHARED SYSTEM GROUP ---\n"
f"dn: cn={cfg['shared_group_name']},{cfg['groups_ou']},{base_dn}\n"
f"objectClass: posixGroup\ncn: {cfg['shared_group_name']}\n"
f"gidNumber: {cfg['shared_group_gid']}\n"
)
for u in users:
ldif.write(f"memberUid: {u['uid']}\n")
print(
f"Success: generated '{output_path}' with membership in group {cfg['shared_group_name']}."
)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Directory LDIF generator.")
parser.add_argument("toml", nargs="?", default="skywalkers.toml")
parser.add_argument("output", nargs="?", default="import_skywalkers.ldif")
args = parser.parse_args()
generate_ldif(args.toml, args.output)
Lancez le script : python3 generate_users_ldif.py Success: generated 'import_skywalkers.ldif' with membership in group users. Affichez le contenu du fichier cat import_skywalkers.ldif # --- PRIVATE GROUPS (UPG) ---
dn: cn=padme,ou=groups,dc=lab,dc=local
objectClass: posixGroup
cn: padme
gidNumber: 10000
dn: cn=anakin,ou=groups,dc=lab,dc=local
objectClass: posixGroup
cn: anakin
gidNumber: 10001
dn: cn=leia,ou=groups,dc=lab,dc=local
objectClass: posixGroup
cn: leia
gidNumber: 10002
dn: cn=luke,ou=groups,dc=lab,dc=local
objectClass: posixGroup
cn: luke
gidNumber: 10003
# --- USER ACCOUNTS ---
dn: uid=padme,ou=users,dc=lab,dc=local
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: padme
cn: Padme Amidala
givenName: Padme
sn: Amidala
mail: padme@lab.local
userPassword: {ARGON2}$argon2id$v=19$m=7168,t=5,p=1$/973y...
shadowLastChange: 20586
loginShell: /bin/bash
uidNumber: 10000
gidNumber: 10000
homeDirectory: /ahome/padme
gecos: Padme Amidala
... |
|
|
Q134. |
Comment insérer les nouveaux utilisateurs dans l'annuaire LDAP et comment tester l'accès d'un utilisateur particulier à l'annuaire ? Utilisez la commande ldapadd pour importer les nouvelles « feuilles » sur les branches existantes de l'annuaire LDAP. Une fois l'importation faite, utilisez la commande ldapsearch pour afficher la liste des objets de l'annuaire en tant qu'utilisateur membre de la famille Skywalker. |
|
Lancez l'importation du fichier LDIF ldapadd -x -H ldap://localhost \
-D "cn=admin,dc=lab,dc=local" \
-y ~/.ldap_admin_pass \
-f import_skywalkers.ldif
adding new entry "cn=padme,ou=groups,dc=lab,dc=local" adding new entry "cn=anakin,ou=groups,dc=lab,dc=local" adding new entry "cn=leia,ou=groups,dc=lab,dc=local" adding new entry "cn=luke,ou=groups,dc=lab,dc=local" adding new entry "uid=padme,ou=users,dc=lab,dc=local" adding new entry "uid=anakin,ou=users,dc=lab,dc=local" adding new entry "uid=leia,ou=users,dc=lab,dc=local" adding new entry "uid=luke,ou=users,dc=lab,dc=local" adding new entry "cn=users,ou=groups,dc=lab,dc=local" Notez que les entrées ont été ajoutées dans les unités organisationnelles Lancez des recherches dans l'annuaire en tant qu'utilisateur
|

![[Important]](/images/important.png)
![[Note]](/images/note.png)
![[Attention]](/images/caution.png)