CLI power tools for sysadmins who run OpenLDAP and refuse to touch a web UI.
Project description
ldap-manager
Tests:
Demo
CLI power tools for sysadmins who run OpenLDAP and refuse to touch a web UI.
Manage users, groups, backups, SSH keys, password policies, and server operations — all from one command. Replace your pile of bash scripts and raw ldapmodify commands with something that actually has --dry-run.
pip install ldap-manager
ldap-manager user list --enabled --json
Why?
If you manage OpenLDAP, your options are:
| Tool | Problem |
|---|---|
ldapmodify / ldapsearch |
LDIF by hand for every operation |
| phpLDAPadmin | Abandoned, PHP, browser-only |
| LDAP Account Manager | Java, $$$, overkill for CLI admins |
| Your 15 bash scripts | Fragile, no error handling, no dry-run |
ldap-manager is the missing CLI. One tool, tab completion, JSON output, dry-run on destructive operations, and actual tests.
Features
| Category | What you get |
|---|---|
| Users | Create, update, delete, enable/disable, search with filters, dump as JSON |
| Groups | Create, delete, add/remove members, list, supports posixGroup and groupOfNames |
| Backup & Restore | Full slapcat/slapadd dumps with gzip, metadata, and config backup |
| Batch Operations | Bulk create/update/delete from JSON/CSV/TSV with --dry-run |
| Password Reset | Reset all users at once, CSV output with new passwords |
| SSH Keys | Add, remove, list ldapPublicKey attributes per user |
| Server Ops | Status, start/stop/restart, reindex with --auto |
| Password Policy | View policy config, check user expiry/lockout status |
| LDIF Export/Import | Standards-compliant RFC 2849 export and import with dry-run |
| Tree Management | List/create/delete OUs, visualize your DIT |
| Audit Logging | JSON-lines audit trail of all operations |
| JSON Output | --json flag on 12+ commands for scripting and pipelines |
Quickstart
Install
# Rocky/RHEL 8+
dnf install epel-release -y
dnf install python3-ldap python3-pyyaml python3-click python3-passlib \
openldap-clients openldap-servers -y
pip install ldap-manager
Configure
cp config.example.yaml /etc/ldap-manager/config.yaml
vim /etc/ldap-manager/config.yaml
Or use environment variables:
export LDAP_URI="ldap://localhost:389"
export LDAP_BIND_DN="cn=admin,dc=example,dc=com"
export LDAP_BIND_PASSWORD="secret"
export LDAP_BASE_DN="dc=example,dc=com"
Go
ldap-manager user list
Usage
Users
ldap-manager user list --enabled --json
ldap-manager user get jdoe
ldap-manager user create jdoe --cn "John Doe" --mail john@example.com
ldap-manager user update jdoe --set mail=new@example.com --set loginShell=/bin/zsh
ldap-manager user delete jdoe --yes
ldap-manager user disable jdoe
ldap-manager user enable jdoe
ldap-manager user passwd jdoe
# Search with filters
ldap-manager user search --uid "j*"
ldap-manager user search --mail "*@engineering.com" --enabled
ldap-manager user search --filter "(description=contractor*)" --json
Groups
ldap-manager group list
ldap-manager group create devops --gid 5000
ldap-manager group add-member devops jdoe
ldap-manager group remove-member devops jdoe
ldap-manager group members devops --json
ldap-manager group delete old_team --yes
Backup & Restore
ldap-manager backup dump --tag pre-migration
ldap-manager backup list
ldap-manager backup restore /var/backups/ldap/ldap_backup_20240101_120000
ldap-manager backup restore /path/to/backup --with-config --yes
Batch Operations
# Bulk create from CSV/JSON
ldap-manager batch create users.csv --dry-run
ldap-manager batch create users.json --yes
# Bulk delete
ldap-manager batch delete terminations.csv --dry-run
Bulk Password Reset
ldap-manager passwd-all --dry-run
ldap-manager passwd-all --output /secure/passwords.csv --length 24
SSH Keys
ldap-manager user ssh-key-list jdoe
ldap-manager user ssh-key-add jdoe ~/.ssh/id_ed25519.pub
ldap-manager user ssh-key-remove jdoe 1
Server Operations
ldap-manager server status
ldap-manager server start
ldap-manager server stop
ldap-manager server restart
ldap-manager server reindex --auto # stops slapd, reindexes, restarts
Password Policy
ldap-manager ppolicy status jdoe # expiry, lockout, grace logins
ldap-manager ppolicy policy # view current policy config
ldap-manager ppolicy check-all # find expired/locked accounts
LDIF Export & Import
ldap-manager user export --format ldif --scope all -o backup.ldif
ldap-manager user export --format json --enabled -o active_users.json
ldap-manager import users.ldif --dry-run
Tree Management
ldap-manager tree show # visualize DIT
ldap-manager tree list-ous
ldap-manager tree create-ou "ou=Contractors,dc=example,dc=com"
ldap-manager tree delete-ou "ou=OldDept,dc=example,dc=com" --recursive
Audit Log
ldap-manager audit log --since 2024-01-01
ldap-manager audit log --action create --target jdoe
ldap-manager audit status
Global Options
ldap-manager -c /path/to/config.yaml user list # custom config
ldap-manager -v user list # verbose logging
Configuration
Config is loaded from (in order, later overrides earlier):
/etc/ldap-manager/config.yaml(system)~/.ldap-manager.yaml(user)--configflag (explicit)- Environment variables (highest priority)
See config.example.yaml for all options.
Development
git clone https://github.com/YOURUSERNAME/ldap-manager.git
cd ldap-manager
make install # creates venv, installs deps
make ci # lint + typecheck + security + tests
Tests use mocked LDAP connections — no live server needed.
make lint # ruff check + format
make typecheck # mypy
make security # bandit
make test # pytest with coverage
make ci # all of the above
Project Structure
ldap_manager/
├── __init__.py # Package metadata
├── cli.py # Click CLI — 40+ commands
├── config.py # YAML + env config loading
├── connection.py # LDAP connection context manager
├── users.py # User CRUD, enable/disable, search
├── groups.py # Group management (posixGroup + groupOfNames)
├── passwords.py # Bulk password generation + reset
├── backup.py # slapcat/slapadd dump + restore
├── batch.py # Bulk operations from CSV/JSON/TSV
├── server.py # Server status, start/stop, reindex
├── sshkeys.py # SSH public key management
├── ppolicy.py # Password policy status + checks
├── ldif_ops.py # RFC 2849 LDIF export/import
├── tree.py # OU/DIT management + visualization
└── audit.py # JSON-lines audit logging
Design Decisions
slapcat/slapaddfor backup — protocol-level export (ldapsearch) is lossy. It missescn=config, overlays, ACLs, and operational attributes.slapcatcaptures everything.loginShellfor enable/disable — simpler and more portable thanshadowExpireornsAccountLock. No overlay needed.- SSHA passwords — most universally supported LDAP hash. Change
hash_schemein config if your server haspw-argon2. - Dry-run on destructive ops — batch, import, delete, and password reset all support
--dry-run. - JSON output everywhere —
--jsonon 12+ commands for piping tojq, scripts, and monitoring.
Requirements
- Python 3.10+
- OpenLDAP client libraries (
libldap2-dev/openldap-devel) - OpenLDAP server tools on the LDAP host (for backup/restore and server ops)
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ldap_manager-1.0.17.tar.gz.
File metadata
- Download URL: ldap_manager-1.0.17.tar.gz
- Upload date:
- Size: 58.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b39e17cb14b7ea8fc9c5af5a3572767dcbb80657ac00fabd7e747a8df2799179
|
|
| MD5 |
722908443754c38931b56d1085b40624
|
|
| BLAKE2b-256 |
8f9e2a462339b1df47c162ee227e99cc50bc6e14a652433773edcf863982cc55
|
Provenance
The following attestation bundles were made for ldap_manager-1.0.17.tar.gz:
Publisher:
makefile.yml on israelhen153/ldap-manager
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ldap_manager-1.0.17.tar.gz -
Subject digest:
b39e17cb14b7ea8fc9c5af5a3572767dcbb80657ac00fabd7e747a8df2799179 - Sigstore transparency entry: 1017603171
- Sigstore integration time:
-
Permalink:
israelhen153/ldap-manager@697696d88e25504f6a6c42ec700a52f2d7472233 -
Branch / Tag:
refs/tags/v1.0.17 - Owner: https://github.com/israelhen153
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
makefile.yml@697696d88e25504f6a6c42ec700a52f2d7472233 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ldap_manager-1.0.17-py3-none-any.whl.
File metadata
- Download URL: ldap_manager-1.0.17-py3-none-any.whl
- Upload date:
- Size: 50.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b42aca793f8e0afc7de31d867901e8206b7021de2160163a70e62cb95e66de4a
|
|
| MD5 |
ce5c8527db19c510cbbce73081069487
|
|
| BLAKE2b-256 |
2cab7d1199de2791b8560e7516dbd58af0b00e276a11441f61147d7626d46297
|
Provenance
The following attestation bundles were made for ldap_manager-1.0.17-py3-none-any.whl:
Publisher:
makefile.yml on israelhen153/ldap-manager
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ldap_manager-1.0.17-py3-none-any.whl -
Subject digest:
b42aca793f8e0afc7de31d867901e8206b7021de2160163a70e62cb95e66de4a - Sigstore transparency entry: 1017603183
- Sigstore integration time:
-
Permalink:
israelhen153/ldap-manager@697696d88e25504f6a6c42ec700a52f2d7472233 -
Branch / Tag:
refs/tags/v1.0.17 - Owner: https://github.com/israelhen153
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
makefile.yml@697696d88e25504f6a6c42ec700a52f2d7472233 -
Trigger Event:
push
-
Statement type: