Files
tuxgyverandClaude Opus 5 eba4d0b843 feat: sortie de domaine, et corrections issues d'un echec reel de jointure
Sortie de domaine (demandee) :
- Bouton « Quitter le domaine » et commande CLI `leave`, via Remove-Computer
  sous Windows et realm leave sous Linux.
- Nettoyage optionnel des paquets sous Linux. packagekit est exclu de la
  liste : il sert aussi au gestionnaire de logiciels du bureau.
- Le champ « Nom de la machine » passe en lecture seule : il ne peut pas
  etre modifie depuis cette fenetre.

Corrections tirees de la sortie PowerShell rapportee :
- Les barres de progression etaient serialisees en CLIXML et polluaient le
  journal ; les accents arrivaient illisibles (console OEM lue en cp1252).
  Progression desactivee, console en UTF-8, CLIXML residuel filtre.
- Le marqueur interne JOIN_FAILURE: n'apparait plus dans le message affiche.

Diagnostic :
- Ajout du SRV `_ldap._tcp.dc._msdcs`, celui que DsGetDcName utilise pour
  localiser un DC. Son absence donne exactement l'erreur rencontree, et le
  diagnostic ne le verifiait pas.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-09 07:11:20 +02:00

129 lines
5.2 KiB
Markdown

# JoinDomainGUI
Outil de **diagnostic réseau Active Directory** et de **jointure de domaine**,
avec interface graphique (PySide6) et interface en ligne de commande.
Fonctionne sous **Linux** (`realmd`) et sous **Windows** (PowerShell `Add-Computer`),
le backend étant choisi automatiquement selon la plateforme.
## Fonctionnalités
- **Diagnostic réseau AD** : résolution DNS du domaine, enregistrements SRV
(LDAP / Kerberos), ping des contrôleurs de domaine, test des ports AD
(53, 88, 389, 445, 464, 636, 3268), synchronisation NTP et présence des
outils système requis.
- **Jointure de domaine** avec unité d'organisation optionnelle et détection du
besoin de redémarrage. Le nom de la machine est affiché mais non modifiable :
il vient du nom d'hôte système (Linux) ou des paramètres système (Windows).
- **Sortie de domaine** (`Remove-Computer` sous Windows, `realm leave` sous
Linux), avec sous Linux une option de désinstallation des paquets devenus
inutiles.
- **Installation des prérequis Linux** manquants en un clic ou une commande
(`realmd`, `sssd`, `adcli`, `samba-common-bin`, `packagekit` via `apt-get`).
- **Interface graphique** à trois onglets : Diagnostic réseau, Rejoindre le
domaine, À propos.
- **Interface en ligne de commande** utilisable sans environnement graphique
(SSH, déploiement scripté) : la CLI n'importe jamais PySide6.
- **Le mot de passe ne transite jamais par la ligne de commande** : il est
transmis au sous-processus via stdin ou son environnement, et n'apparaît
donc pas dans `ps` ni dans l'historique du shell.
## Installation
```bash
make install # crée l'environnement virtuel et installe les dépendances
```
Dépendances : Python 3.11+, `PySide6`, `dnspython`, `ntplib`.
## Utilisation
### Interface graphique
```bash
make run # depuis les sources
sudo ./dist/JoinDomainGUI # binaire autonome Linux
```
La jointure de domaine nécessite les droits root / administrateur ; le
diagnostic, non.
### Ligne de commande
```bash
# Diagnostic réseau
python main.py diagnose --domain exemple.lan
make diagnose DOMAIN=exemple.lan
# Jointure de domaine (root / administrateur requis)
echo 'motdepasse' | sudo python main.py join \
--domain exemple.lan --username administrateur --password-stdin
# Sortie de domaine (--username optionnel sous Linux, requis sous Windows)
sudo python main.py leave --domain exemple.lan --remove-packages
# Installation des prérequis système (Linux / apt uniquement)
sudo python main.py install-prereqs
```
Sans mot de passe fourni, il est demandé de façon interactive et masquée.
`--password` existe mais est déconseillé (visible dans `ps` et l'historique).
Code de sortie : `0` si tout va bien, `1` si un test échoue ou si la jointure
échoue, `2` en cas de droits insuffisants ou de backend indisponible.
## Compilation des binaires
```bash
make build-linux # -> dist/JoinDomainGUI (ELF autonome)
make build-windows # -> dist/windows/JoinDomainGUI.exe (PE64 autonome)
make build # les deux
```
PyInstaller ne fait pas de cross-compilation. Le binaire Windows est donc
produit depuis Linux en exécutant un vrai PyInstaller Windows dans un
préfixe **Wine** dédié (`packaging/build_windows_wine.sh`) : le `.exe` obtenu
est un binaire Windows natif. Le premier appel télécharge un Python Windows
embarqué et les dépendances (plusieurs minutes) ; les suivants sont
incrémentaux.
Sur une machine Windows, `packaging/build_windows.bat` fait le même travail
nativement.
La build Wine épingle **Qt 6.9** (`PySide6<6.10`) : à partir de Qt 6.10,
`Qt6Core.dll` dépend de l'ICU fourni par Windows (`icuuc.dll` dans `System32`),
que Wine n'implémente pas. PySide6 y devient inimportable — et le hook PySide6
de PyInstaller, qui importe QtCore pour localiser les plugins Qt, échoue alors
*silencieusement* et produit un `.exe` sans plugin de plateforme, qui refuse de
démarrer sous Windows (« could not initialize Qt platform plugin windows »). Le
script vérifie donc, avant compilation, que PySide6 s'importe, et après
compilation, que `qwindows.dll` est bien embarqué.
## Publication
```bash
make publish # pousse la branche courante et les tags vers tous les dépôts
```
Le projet est publié sur deux instances Gitea :
[git.tuxtech.fr](https://git.tuxtech.fr/tuxgyver/JoinDomainGUI) (`origin`) et
[git.h3campus.fr](https://git.h3campus.fr/Johnny/JoinDomainGUI) (`h3campus`).
## Structure
```
main.py Point d'entrée : GUI sans argument, CLI sinon
domainjoin/
├── cli.py Interface en ligne de commande
├── gui.py Interface PySide6
├── diagnostics.py Moteur de diagnostic réseau
├── worker.py Exécution en arrière-plan pour la GUI
├── privileges.py Détection des droits root/administrateur
└── backend/
├── base.py Interface commune de jointure
├── linux_realmd.py Backend Linux (realmd / adcli)
└── windows_addcomputer.py Backend Windows (Add-Computer)
packaging/ Scripts de compilation PyInstaller
```
Voir [CHANGELOG.md](CHANGELOG.md) pour l'historique des versions.