CLI ldapsearch tool with json and table output
Go to file
Stefan Bühler 8928973ee7 ldaptool-0.5
-----BEGIN PGP SIGNATURE-----
 
 iQJYBAABCgBCFiEEcdms641aWv8vJSXMIcx4mUG+20gFAmRb2iIkHHN0ZWZhbi5i
 dWVobGVyQHRpay51bmktc3R1dHRnYXJ0LmRlAAoJECHMeJlBvttIscwP/inWA7tN
 X0AvSGyRAd6Gfo6AsND+IH26gdCjHSTeq4EGf94Am7KSx2IPOplWDxcPm7Shvz3D
 Qz1zfsDXIp58mC5/mrwu2RMsrOAm2Xymu6QUgCzKrork1/QRzjGrhLaDsxFdGUt+
 8yPAx5YVUTOww6FjmaYQpTTQdpkZh7LxnToTTS8uh+90kjyJ5ttMoje2JL427rPh
 wpaioD2BJqHJncS7d+wI8UOyH6lnM8GyFaiJ8szMWAim8i4YlSh98/m4xHvTLxKU
 qA2h5rfisgQttuYrFvX1Bdb+TboFOjq0TsNE0Ot/2T5J72iERy9kuwNhtBQbDfvm
 B/n+DLOwIkzIWndVqP+UWMl0SKZNNuF09d4Ppo4E1LJJ1WFj1+1+cDO40t18SJGB
 vz6P8gCADt3OfuxBAUe+F6KeP7nDG+ghp6t8gWHrtz0E9tuq9BpA3UDVhcQsGCcI
 slwg9SukdZ/6DhgtGt5Da2YlDfWu+8HTcO2O/vsICAVQd/1Pe/Vh34DYARP2KKBD
 6/P4qTZURj2w/RK+Dg3XvUp9EjcZRoP/34b/JpvZj7k4sZFcMxi+jh/gEY+2rcg0
 qvJdZxfD5UENmGDI8d2W8nzqQ8Mhb1cTeFHK+Cy2wOZLhGhK5yB0DcPjALqHtgLD
 au9ib49D8kvE8XlafoRRv66aWwSjQkBJnGL5
 =ZgyQ
 -----END PGP SIGNATURE-----

Merge tag 'ldaptool-0.5' into debian

ldaptool-0.5
2023-05-10 19:53:44 +02:00
debian ldaptool 0.4-1 2023-05-02 16:54:12 +02:00
src/ldaptool decode securityIdentifier attribute as SID 2023-05-10 19:53:03 +02:00
.gitignore Initial 2023-04-28 14:14:03 +02:00
.pycodestyle Initial 2023-04-28 14:14:03 +02:00
fmt.sh Initial 2023-04-28 14:14:03 +02:00
LICENSE Initial 2023-04-28 14:14:03 +02:00
lints.sh Initial 2023-04-28 14:14:03 +02:00
pyproject.toml :Fix version requirement for python3.10 2023-05-02 17:47:11 +02:00
README.md add argument to postprocess steps and support index/slicing in DN-related hooks; document them 2023-05-10 19:52:44 +02:00

ldaptool

CLI tool to query LDAP/AD servers

  • Configuration file to configure "realms"
    • DNS domain (mapping to ldap search base as DC labels)
    • LDAP servers in that domain
    • Bind account
    • Integration with password managers
  • Various output formats
    • Classic LDIF
    • JSON stream (with detailed or simplified attribute values)
    • CSV
    • Markdown table with stretched columns (for viewing in CLI/for monospaces fonts); requires csvlook from csvkit
    • HTML
  • Decodes certain well-known attributes (UUIDs, Timestamps, SID, userAccountControl)
  • Requires server to support RFC 2696: Simple Paged Results for proper pagination
    • By default the first 1000 entries are shown, and it errors if there are more results
    • Use --all to show all results

Virtual attributes

ldaptool supports constructing new values from existing attributes by adding a :<postprocess> suffix (which can be chained apart from the length limit).

  • Some suffixes support an argument as :<postprocess>[<arg>].
  • A single integer as postprocess suffix limits the length of the value; it replaces the last character of the output with if it cut something off.
  • Multi-valued attributes generate multiple virtual attrites; each value is processed individually. (The values are joined afterwards for table output if needed.)

DN handling

DNs are decoded into lists of lists of (name, value) pairs (the inner list usually contains exactly one entry). Attributes with a DC name are considered part of the "domain", everything else belongs to the "path". (Usually a DN will start with path segments and end with domain segments.) The path is read from back to front.

The following postprocess hooks are available:

  • domain: extracts the domain as DNS FQDN (CN=Someone,OU=Dep1,DC=example,DC=com becomes example.com)
  • path: extracts the non-domain parts without names and separates them by / (CN=Someone,OU=Dep1,DC=example,DC=com becomes Dep1/Someone)
  • fullpath: uses the domain as first segment in a path (CN=Someone,OU=Dep1,DC=example,DC=com becomes example.com/Dep1/Someone)
  • dnslice: extracts a "slice" from a DN (outer list only); the result is still in DN format.

path, fullpath and dnslice take an optional index/slice as argument, written in python syntax. For path and fullpath this extracts only the given index/slice from the path (fullpath always includes the full FQDN as first segment), dnslice operates on the outer list of decoded (lists of) pairs:

  • dn:dnslice[1:] on dn: CN=Someone,OU=Dep1,DC=example,DC=com returns OU=Dep1,DC=example,DC=com
  • dn:fullpath[:-1] on dn: CN=Someone,OU=Dep1,DC=example,DC=com returns example.com/Dep1
  • dn:path[-1] on dn: CN=Someone,OU=Dep1,DC=example,DC=com returns Someone

Authentication, Protocol, Ports

ldaptool always uses TLS for password based authentication, and SASL GSS-API over non-TLS for Kerberos ones.

Config file

Location: ~/.config/ldaptool.yaml

Realms

realms:
  EXAMPLE:
    domain: "example.com"
    servers: server1 server2
    account: "bind@example.com"
    password_folder: mainaccounts
  EXAMPLE.admin:
    domain: "example.com"
    servers: server1 server2
    account: "CN=admin,OU=Admins,DC=example,DC=com"
    password_folder: adminaccounts
  EXAMPLE.admin2:
    domain: "example.com"
    servers: server1 server2
    account: "CN=admin,OU=Admins,DC=example,DC=com"
    password_file: localadmin2
    password_folder: adminaccounts
  SUB:
    domain: "sub.example.com"
    servers: subserver1 subserver2
    forest_root_domain: "example.com"

The servers field is a whitespace separates list of hostnames in the domain.

If a password manager is used, the password_file (defaults to names derived from account) and password_folder fields determine the name of the file ("secret") queried from the password manager. Here the following file names would be used:

  • EXAMPLE: mainaccounts/bind
  • EXAMPLE.admin: adminaccounts/example.com/Admins/admin
  • EXAMPLE.admin2: adminaccounts/localadmin2

If the account field isn't present ldaptool always uses kerberos; if --krb is used, account is ignored.

Windows AD has a concept of a "global catalog" across all domains in a AD Forest; it uses separate ports (3268 without TLS and 3269 with TLS). The forest_root_domain field can be used to set a search base for global catalog (--gc) queries (usually the forest root should be parent domain).

Unless specified with --base the search base is derived from domain (or forest_root_domain with --gc) as DC=... for each DNS label.

Script as password manager

password-script: keyring local decrypt

This configures a script as password manager.

Either takes a string (split by shlex.split) or a list of strings. The password name is appended as last argument.

keyringer

keyringer:
  keyring: yourkeyringname
  folder: ldapquery

This configures keyringer (based on GPG) as password manager.

keyringer need a "keyring" to search in, and you can (optionally) specify a folder to be prefixed to the password names created from the realm.

keepass

keepass: /home/me/mypasswords.kdbx

This configures KeePass as password manager; it will prompt for your master password every time.