X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/3a2ac12bcabf06f73ef372dfa23e6edead237aa7..d4ff61d1edff4054497632be7f36ede86bb8ebec:/src/src/lookups/ldap.c diff --git a/src/src/lookups/ldap.c b/src/src/lookups/ldap.c index 6aedfaa1c..0f78a9452 100644 --- a/src/src/lookups/ldap.c +++ b/src/src/lookups/ldap.c @@ -156,7 +156,7 @@ uschar *error1 = NULL; /* string representation of errcode (static) */ uschar *error2 = NULL; /* error message from the server */ uschar *matched = NULL; /* partially matched DN */ -int attr_count = 0; +int attrs_requested = 0; int error_yield = DEFER; int msgid; int rc, ldap_rc, ldap_parse_rc; @@ -248,7 +248,7 @@ if (host != NULL) /* Count the attributes; we need this later to tell us how to format results */ for (attrp = USS ludp->lud_attrs; attrp != NULL && *attrp != NULL; attrp++) - attr_count++; + attrs_requested++; /* See if we can find a cached connection to this host. The port is not relevant for ldapi. The host name pointer is set to NULL if no host was given @@ -713,10 +713,15 @@ while ((rc = ldap_result(lcp->ld, msgid, 0, timeoutptr, &result)) == LDAP_RES_SEARCH_ENTRY) { LDAPMessage *e; + int valuecount; /* We can see an attr spread across several + entries. If B is derived from A and we request + A and the directory contains both, A and B, + then we get two entries, one for A and one for B. + Here we just count the values per entry */ - DEBUG(D_lookup) debug_printf("ldap_result loop\n"); + DEBUG(D_lookup) debug_printf("LDAP result loop\n"); - for(e = ldap_first_entry(lcp->ld, result); + for(e = ldap_first_entry(lcp->ld, result), valuecount = 0; e != NULL; e = ldap_next_entry(lcp->ld, e)) { @@ -774,6 +779,12 @@ while ((rc = ldap_result(lcp->ld, msgid, 0, timeoutptr, &result)) == attr != NULL; attr = US ldap_next_attribute(lcp->ld, e, ber)) { + DEBUG(D_lookup) debug_printf("LDAP attr loop\n"); + + /* In case of attrs_requested == 1 we just count the values, in all other cases + (0, >1) we count the values per attribute */ + if (attrs_requested != 1) valuecount = 0; + if (attr[0] != 0) { /* Get array of values for this attribute. */ @@ -781,7 +792,8 @@ while ((rc = ldap_result(lcp->ld, msgid, 0, timeoutptr, &result)) == if ((firstval = values = USS ldap_get_values(lcp->ld, e, CS attr)) != NULL) { - if (attr_count != 1) + + if (attrs_requested != 1) { if (insert_space) data = string_cat(data, &size, &ptr, US" ", 1); @@ -795,22 +807,23 @@ while ((rc = ldap_result(lcp->ld, msgid, 0, timeoutptr, &result)) == { uschar *value = *values; int len = Ustrlen(value); + ++valuecount; + + DEBUG(D_lookup) debug_printf("LDAP value loop %s:%s\n", attr, value); - DEBUG(D_lookup) debug_printf("LDAP attr loop %s:%s\n", attr, value); + /* In case we requested one attribute only but got several times + into that attr loop, we need to append the additional values. + (This may happen if you derive attributeTypes B and C from A and + then query for A.) In all other cases we detect the different + attribute and append only every non first value. */ - /* In case we requested one attribute only but got - * several times into that attr loop, we need to append - * the additional values. (This may happen if you derive - * attributeTypes B and C from A and then query for A.) - * In all other cases we detect the different attribute - * and append only every non first value. */ - if ((attr_count == 1 && data) || (values != firstval)) + if (data && valuecount > 1) data = string_cat(data, &size, &ptr, US",", 1); /* For multiple attributes, the data is in quotes. We must escape internal quotes, backslashes, newlines, and must double commas. */ - if (attr_count != 1) + if (attrs_requested != 1) { int j; for (j = 0; j < len; j++) @@ -834,12 +847,10 @@ while ((rc = ldap_result(lcp->ld, msgid, 0, timeoutptr, &result)) == { int j; for (j = 0; j < len; j++) - { if (value[j] == ',') data = string_cat(data, &size, &ptr, US",,", 2); else data = string_cat(data, &size, &ptr, value+j, 1); - } } @@ -851,7 +862,7 @@ while ((rc = ldap_result(lcp->ld, msgid, 0, timeoutptr, &result)) == /* Closing quote at the end of the data for a named attribute. */ - if (attr_count != 1) + if (attrs_requested != 1) data = string_cat(data, &size, &ptr, US"\"", 1); /* Free the values */