diff options
author | Peter Eisentraut <peter_e@gmx.net> | 2017-09-12 09:46:14 -0400 |
---|---|---|
committer | Peter Eisentraut <peter_e@gmx.net> | 2017-09-12 09:49:04 -0400 |
commit | 83aaac41c66959a3ebaec7daadc4885b5f98f561 (patch) | |
tree | 2e96d2fe57254ebdf90aad0ceee2ee5b95321aa4 /src/backend/libpq/auth.c | |
parent | 35e15688269a2af13f4cddff0c13536a9a42115d (diff) | |
download | postgresql-83aaac41c66959a3ebaec7daadc4885b5f98f561.tar.gz postgresql-83aaac41c66959a3ebaec7daadc4885b5f98f561.zip |
Allow custom search filters to be configured for LDAP auth
Before, only filters of the form "(<ldapsearchattribute>=<user>)"
could be used to search an LDAP server. Introduce ldapsearchfilter
so that more general filters can be configured using patterns, like
"(|(uid=$username)(mail=$username))" and "(&(uid=$username)
(objectClass=posixAccount))". Also allow search filters to be included
in an LDAP URL.
Author: Thomas Munro
Reviewed-By: Peter Eisentraut, Mark Cave-Ayland, Magnus Hagander
Discussion: https://postgr.es/m/CAEepm=0XTkYvMci0WRubZcf_1am8=gP=7oJErpsUfRYcKF2gwg@mail.gmail.com
Diffstat (limited to 'src/backend/libpq/auth.c')
-rw-r--r-- | src/backend/libpq/auth.c | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index cb30fc7b714..62ff624dbd7 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -2394,6 +2394,34 @@ InitializeLDAPConnection(Port *port, LDAP **ldap) return STATUS_OK; } +/* Placeholders recognized by FormatSearchFilter. For now just one. */ +#define LPH_USERNAME "$username" +#define LPH_USERNAME_LEN (sizeof(LPH_USERNAME) - 1) + +/* + * Return a newly allocated C string copied from "pattern" with all + * occurrences of the placeholder "$username" replaced with "user_name". + */ +static char * +FormatSearchFilter(const char *pattern, const char *user_name) +{ + StringInfoData output; + + initStringInfo(&output); + while (*pattern != '\0') + { + if (strncmp(pattern, LPH_USERNAME, LPH_USERNAME_LEN) == 0) + { + appendStringInfoString(&output, user_name); + pattern += LPH_USERNAME_LEN; + } + else + appendStringInfoChar(&output, *pattern++); + } + + return output.data; +} + /* * Perform LDAP authentication */ @@ -2437,7 +2465,7 @@ CheckLDAPAuth(Port *port) char *filter; LDAPMessage *search_message; LDAPMessage *entry; - char *attributes[2]; + char *attributes[] = { LDAP_NO_ATTRS, NULL }; char *dn; char *c; int count; @@ -2479,13 +2507,13 @@ CheckLDAPAuth(Port *port) return STATUS_ERROR; } - /* Fetch just one attribute, else *all* attributes are returned */ - attributes[0] = port->hba->ldapsearchattribute ? port->hba->ldapsearchattribute : "uid"; - attributes[1] = NULL; - - filter = psprintf("(%s=%s)", - attributes[0], - port->user_name); + /* Build a custom filter or a single attribute filter? */ + if (port->hba->ldapsearchfilter) + filter = FormatSearchFilter(port->hba->ldapsearchfilter, port->user_name); + else if (port->hba->ldapsearchattribute) + filter = psprintf("(%s=%s)", port->hba->ldapsearchattribute, port->user_name); + else + filter = psprintf("(uid=%s)", port->user_name); r = ldap_search_s(ldap, port->hba->ldapbasedn, |