aboutsummaryrefslogtreecommitdiff
path: root/src/backend/libpq/auth.c
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2017-09-12 09:46:14 -0400
committerPeter Eisentraut <peter_e@gmx.net>2017-09-12 09:49:04 -0400
commit83aaac41c66959a3ebaec7daadc4885b5f98f561 (patch)
tree2e96d2fe57254ebdf90aad0ceee2ee5b95321aa4 /src/backend/libpq/auth.c
parent35e15688269a2af13f4cddff0c13536a9a42115d (diff)
downloadpostgresql-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.c44
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,