The TUI LDAP editor — a terminal UI for administering an OpenLDAP directory — adding, modifying and removing users and groups, and managing group memberships — built in Rust with tvision-rs.
The name is editor and LDAP, creatively merged.
Screencast recorded with ansidrama, a deterministic terminal-session → animated-WebP recorder.
📖 Documentation: https://oposs.github.io/edaptor
eDAPtor derives the directory's structure from the LDAP server itself via
full schema introspection (cn=subschema) and generates its edit forms
dynamically from objectClass definitions. A config file holds all connection
properties plus a small set of entry profiles describing what a "user" and a
"group" mean in your directory.
It is designed against the
oposs.openldap server configuration (OUs
people/groups/…, groupOfNames membership, the memberOf / refint / ppolicy
overlays, and the Samba schema).
Working. The core milestones are implemented on a three-pane tvision-rs
interface: schema-driven create/edit/rename/delete, defaults and auto-numbering,
inline passwords with the Samba lifecycle, unified candidate pickers, symmetric
membership editing, and inline multi-value editing (free-text and ordered
multi-value attributes are edited in place as a bulleted list — no modal). See
the documentation for usage, and
docs/superpowers/specs/ for the design specifications.
- Two-tier object model: a generic schema-driven entry engine, with a pervasive users & groups understanding layered over it (passwords, memberships, Samba) that acts naturally across view/create/edit/delete/rename.
- Responsive: all LDAP I/O runs on a background worker thread; the UI never freezes on the network.
- Safe & transparent: immediate apply with an on-demand LDIF preview of the exact change.
- Human-friendly:
cn-based labels everywhere (raw DNs only on demand); symmetric membership editing with incremental search on both panes. - Full Samba lifecycle: client-side NT-hash, synced Unix+Samba passwords,
SID discovered from the directory's
sambaDomainentry.
scripts/test-ldap.sh start launches a podman OpenLDAP that mirrors the
oposs.openldap role — Samba + mail schemas, the memberOf/refint/ppolicy
overlays, password policies — and seeds it with ~600 users across 5 departments
and ~25 groups (see scripts/ldap-provision/). Point eDAPtor at it with:
scripts/test-ldap.sh start
export EDAPTOR_TEST_ADMIN_PW=adminpassword
edaptor --config examples/demo-config.tomlAll generated users share the password test123.
A single TOML file (--config <path>, default ~/.config/edaptor/config.toml)
declares the LDAP connection, how to authenticate, and a set of entry profiles
describing what a "user", "group", or "posixgroup" means in your directory. The
skeleton is:
[server]
uri = "ldaps://ldap.example.com"
base_dn = "dc=example,dc=com"
start_tls = false
timeout_secs = 10
[auth]
method = "simple"
bind_dn = "cn=ldapmanager,dc=example,dc=com"
# Password is NEVER stored here. Sources: "prompt", "env:VAR", "command:cmd"
password_source = "prompt"
[[profile]]
name = "user"
object_classes = ["inetOrgPerson", "posixAccount", "shadowAccount"]
rdn_attr = "uid"
search_base = "ou=people,dc=example,dc=com"
show = ["uid", "cn", "sn", "mail", "uidNumber", "gidNumber"]
# Defaults fill empty fields on create; widgets give fields a richer editor
# (passwords, choice lists, candidate/membership pickers).
[profile.defaults]
homeDirectory = "/home/{uid}"
uidNumber = "{next:10000-60000}"
[profile.widget.userPassword]
kind = "password"This README intentionally stops here — the full, annotated reference lives in the documentation rather than being duplicated:
- Entry Profiles and Defaults
- Widgets — the
[profile.widget.<attr>]palette:password,choice,lookup,picker,membership(these replaced the former[profile.picker]/[profile.password]layers) - Full Example
— the complete annotated
examples/config.toml, copy-pasteable as a starting point
MIT © Tobias Oetiker
