# glapi Go Ldap API is an HTTP API to an LDAP backend. Only supporting read at the moment, maybe one day it will write, and break LDAP backends with ease and joy! UPDATE: Yay, the day has come! ## Usage Start glapi with parameters on command line: ``` glapi -ldap-host ldap://ldap.example.org -ldap-base-dn dc=example,dc=org -ldap-user cn=yo,dc=example,dc=org -ldap-pass 'here_is_the_password' ``` or point it to a configuration file : ``` glapi -config glapi.env ``` ## Configuration file ``` LISTEN="0.0.0.0:8443" LDAP_HOST="ldap://ldap.example.org" # The base DN exposed to API. Could be buried in LDAP tree so we expose only a subset of directory. LDAP_BASE_DN="dc=example,dc=org" # This account search for valid user provided by authenticating client. # Then glapi bind with client provided credentials to operate LDAP. # Thus this account only needs bind privilege, and read access to users organizational unit LDAP_USER="cn=ldapreaduser,dc=example,dc=org" LDAP_PASS='here_lies_the_password' # This base DN is where we seach for authenticating accounts. This way we can chose not to expose them to the API. LDAP_AUTH_BASE_DN="ou=users,dc=example,dc=org" # Https support HTTPS=true SSL_CERTIFICATE=/etc/ssl/certs/server.pem SSL_PRIVATE_KEY=/etc/ssl/private/server.key ``` ## Querying API ### Search Entries Search LDAP entries through the whole subtree, specifying organizationalUnit, commnName, objectClass, attribute to retrieve. Each of these parameters can be replaced by "ALL" to act like a wildcard. ``` % curl -u admin:admin http://127.0.0.1:8080/ou=domains/yo/person | jq [ { "DN": "cn=yo,dc=example.org,ou=domains,dc=example,dc=org", "Attributes": [ { "Name": "sn", "Values": [ "yo" ], "ByteValues": [ "eW8=" ] }, { "Name": "cn", "Values": [ "yo" ], "ByteValues": [ "eW8=" ] }, { "Name": "objectClass", "Values": [ "inetOrgPerson", "organizationalPerson", "person", "top", "inetLocalMailRecipient" ], "ByteValues": [ "aW5ldE9yZ1BlcnNvbg==", "b3JnYW5pemF0aW9uYWxQZXJzb24=", "cGVyc29u", "dG9w", "aW5ldExvY2FsTWFpbFJlY2lwaWVudA==" ] }, { "Name": "mail", "Values": [ "yo@example.org" ], "ByteValues": [ "eW9AcGxvcGl0by50aw==" ] }, { "Name": "mailLocalAddress", "Values": [ "root@example.org", "postmaster@example.org", ], "ByteValues": [ "cm9vdEBleGFtcGxlLm9yZw==", "cG9zdG1hc3RlckBleGFtcGxlLm9yZw==", ] }, { "Name": "uid", "Values": [ "yo" ], "ByteValues": [ "eW8=" ] } ] } ] ``` Using wildcards everywhere and ldif format, you can get a dump of ldap: ``` % curl -u admin:admin "http://127.0.0.1:8080/ALL/ALL/ALL?format=ldif" dn: dc=example,dc=org objectClass: organization objectClass: top objectClass: dcObject dc: example o: example.org dn: cn=admin,dc=example,dc=org objectClass: organizationalRole objectClass: top objectClass: simpleSecurityObject cn: admin dn: cn=yo,dc=example,dc=org objectClass: organizationalRole objectClass: top objectClass: simpleSecurityObject cn: yo userPassword: {SSHA}edited [...] ``` Add operational attributes with "*,+": ``` % curl -u admin:admin "http://127.0.0.1:8080/ALL/ALL/ALL/*,+?format=ldif" dn: dc=example,dc=org objectClass: organization objectClass: top objectClass: dcObject dc: example o: example.org structuralObjectClass: organization entryUUID: af93fd38-3139-103a-8d41-05c00494facf creatorsName: cn=admin,dc=example,dc=org createTimestamp: 20200523120715Z entryCSN: 20200523120715.282611Z#000000#000#000000 modifiersName: cn=admin,dc=example,dc=org modifyTimestamp: 20200523120715Z entryDN: dc=example,dc=org subschemaSubentry: cn=Subschema hasSubordinates: TRUE dn: cn=admin,dc=example,dc=org objectClass: organizationalRole objectClass: top objectClass: simpleSecurityObject cn: admin structuralObjectClass: organizationalRole entryUUID: af9a1556-3139-103a-8d42-05c00494facf creatorsName: cn=admin,dc=example,dc=org createTimestamp: 20200523120715Z entryCSN: 20200523120715.322559Z#000000#000#000000 modifiersName: cn=admin,dc=example,dc=org modifyTimestamp: 20200523120715Z entryDN: cn=admin,dc=example,dc=org subschemaSubentry: cn=Subschema hasSubordinates: FALSE [...] ``` #### Output format Default output is in json. The following formats are supported: - json (default) - text (ini style) - ldif - textvalue (only attribute values are returned) - textvalue-nodn (only attribute values, no dn, no linefeed between entries. Made for Rspamd multimap module) Specify with "format" query parameter: ``` % curl -u admin:admin "http://127.0.0.1:8080/ou=domains/yo/person?format=text" dn=cn=yo,dc=example.org,ou=domains,dc=example,dc=org sn=yo cn=yo objectClass=inetOrgPerson objectClass=organizationalPerson objectClass=person objectClass=top objectClass=inetLocalMailRecipient mail=yo@example.org mailLocalAddress=root@example.org mailLocalAddress=postmaster@example.org uid=yo % curl -u admin:admin "http://127.0.0.1:8080/ou=domains/yo/person?format=ldif" dn: cn=yo,dc=example.org,ou=domains,dc=example,dc=org sn: yo cn: yo objectClass: inetOrgPerson objectClass: organizationalPerson objectClass: person objectClass: top objectClass: inetLocalMailRecipient mail: yo@example.org mailLocalAddress: root@example.org mailLocalAddress=postmaster@example.org uid: yo ``` #### Select attributes to get You can select attributes to get by adding them in 4th position : ``` % curl -u admin:admin "http://127.0.0.1:8080/ou=domains/yo/person/mail?format=textvalue" cn=yo,dc=example.org,ou=domains,dc=example,dc=org yo@example.org % curl -u admin:admin "http://127.0.0.1:8080/ou=domains/yo/person/mail?format=textvalue-nodn" yo@example.org ``` ### Create entries Create a new OU =users", then a new user : ``` % curl -u "admin:admin" --header "Content-Type: application/json" -X POST --data '{"objectClass":["organizationalUnit","top"],"ou":"users"' \ https://127.0.0.1:8443/ou=users,dc=example,dc=org % curl -u "admin:admin" --header "Content-Type: application/json" -X POST --data '{"objectClass":["person","top"],"cn":"newuser","sn":"New"}' \ https://127.0.0.1:8443/cn=newuser,ou=users,dc=example,dc=org ``` ### Modify entries Add a description to the new account: ``` % curl -u "admin:admin" --header "Content-Type: application/json" -X PUT --data '{"objectClass":["person","top"],"cn":"newuser","sn":"New","description":"Test account"}' \ https://127.0.0.1:8443/cn=newuser,ou=users,dc=example,dc=org ``` Missing attributes will be removed from entry. ### Delete entries Remove newuser : ``` % curl -u "admin:admin" -X DELETE \ https://127.0.0.1:8443/cn=newuser,ou=users,dc=example,dc=org ```