diff --git a/dirmngr/ks-engine-ldap.c b/dirmngr/ks-engine-ldap.c index d52151978..7d7319666 100644 --- a/dirmngr/ks-engine-ldap.c +++ b/dirmngr/ks-engine-ldap.c @@ -333,7 +333,8 @@ ks_ldap_help (ctrl_t ctrl, parsed_uri_t uri) *filter. It is the caller's responsibility to free *filter. *filter is only set if this function returns success (i.e., 0). */ static gpg_error_t -keyspec_to_ldap_filter (const char *keyspec, char **filter, int only_exact) +keyspec_to_ldap_filter (const char *keyspec, char **filter, int only_exact, + unsigned int serverinfo) { /* Remove search type indicator and adjust PATTERN accordingly. Note: don't include a preceding 0x when searching by keyid. */ @@ -361,9 +362,14 @@ keyspec_to_ldap_filter (const char *keyspec, char **filter, int only_exact) break; case KEYDB_SEARCH_MODE_MAIL: - if (! only_exact) - f = xasprintf ("(pgpUserID=*<%s>*)", - (freeme = ldap_escape_filter (desc.u.name))); + if (only_exact) + break; + if ((serverinfo & SERVERINFO_SCHEMAV2)) + f = xasprintf ("(gpgMailbox=%s)", + (freeme = ldap_escape_filter (desc.u.name))); + else + f = xasprintf ("(pgpUserID=*<%s>*)", + (freeme = ldap_escape_filter (desc.u.name))); break; case KEYDB_SEARCH_MODE_MAILSUB: @@ -389,6 +395,19 @@ keyspec_to_ldap_filter (const char *keyspec, char **filter, int only_exact) case KEYDB_SEARCH_MODE_FPR16: case KEYDB_SEARCH_MODE_FPR20: case KEYDB_SEARCH_MODE_FPR: + if ((serverinfo & SERVERINFO_SCHEMAV2)) + { + freeme = bin2hex (desc.u.fpr, 20, NULL); + if (!freeme) + return gpg_error_from_syserror (); + f = xasprintf ("(|(gpgFingerprint=%s)(gpgSubFingerprint=%s))", + freeme, freeme); + /* FIXME: For an exact search and in case of a match on + * gpgSubFingerprint we need to check that there is only one + * matching value. */ + } + break; + case KEYDB_SEARCH_MODE_ISSUER: case KEYDB_SEARCH_MODE_ISSUER_SN: case KEYDB_SEARCH_MODE_SN: @@ -874,13 +893,6 @@ ks_ldap_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, return gpg_error (GPG_ERR_NOT_SUPPORTED); } - /* Before connecting to the server, make sure we have a sane - keyspec. If not, there is no need to establish a network - connection. */ - err = keyspec_to_ldap_filter (keyspec, &filter, 1); - if (err) - return (err); - /* Make sure we are talking to an OpenPGP LDAP server. */ ldap_err = my_ldap_connect (uri, &ldap_conn, &basedn, &serverinfo); if (ldap_err || !basedn) @@ -888,10 +900,17 @@ ks_ldap_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, if (ldap_err) err = ldap_err_to_gpg_err (ldap_err); else - err = GPG_ERR_GENERAL; + err = gpg_error (GPG_ERR_GENERAL); goto out; } + /* Now that we have information about the server we can construct a + * query best suited for the capabilities of the server. */ + err = keyspec_to_ldap_filter (keyspec, &filter, 1, serverinfo); + if (err) + goto out; + + { /* The ordering is significant. Specifically, "pgpcertid" needs to be the second item in the list, since everything after it @@ -1056,16 +1075,6 @@ ks_ldap_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern, return gpg_error (GPG_ERR_NOT_SUPPORTED); } - /* Before connecting to the server, make sure we have a sane - keyspec. If not, there is no need to establish a network - connection. */ - err = keyspec_to_ldap_filter (pattern, &filter, 0); - if (err) - { - log_error ("Bad search pattern: '%s'\n", pattern); - return (err); - } - /* Make sure we are talking to an OpenPGP LDAP server. */ ldap_err = my_ldap_connect (uri, &ldap_conn, &basedn, &serverinfo); if (ldap_err || !basedn) @@ -1077,6 +1086,15 @@ ks_ldap_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern, goto out; } + /* Now that we have information about the server we can construct a + * query best suited for the capabilities of the server. */ + err = keyspec_to_ldap_filter (pattern, &filter, 0, serverinfo); + if (err) + { + log_error ("Bad search pattern: '%s'\n", pattern); + goto out; + } + /* Even if we have no results, we want to return a stream. */ fp = es_fopenmem(0, "rw"); if (!fp)