1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-22 12:22:45 +03:00

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
This commit is contained in:
Peter Eisentraut
2017-09-12 09:46:14 -04:00
parent 35e1568826
commit 83aaac41c6
4 changed files with 110 additions and 25 deletions

View File

@@ -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,