From 55f46b33df08e8e0ea520ade5f73b321bc01d705 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 17 Feb 2021 17:31:36 +0100 Subject: [PATCH] dirmngr: Support new gpgNtds parameter in LDAP keyserver URLs. * dirmngr/ldap-parse-uri.c (ldap_parse_uri): Support a new gpgNtds extension. * dirmngr/ks-engine-ldap.c (my_ldap_connect): Do ldap_init always with hostname - which is NULL and thus the same if not given. Fix minor error in error code handling. -- Note that "gpgNtds" is per RFC-4512 case insensitive and has not yet been officially regisetered. Thus for correctness the OID can be used: 1.3.6.1.4.1.11591.2.5 LDAP URL extensions 1.3.6.1.4.1.11591.2.5.1 gpgNtds=1 (auth. with current user) Note that the value must be 1; all other values won't enable AD authentication and are resevered for future use. --- dirmngr/ks-engine-ldap.c | 19 +++++++------------ dirmngr/ldap-parse-uri.c | 18 ++++++++++++++++-- doc/dirmngr.texi | 2 ++ doc/gpg.texi | 14 +++++++------- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/dirmngr/ks-engine-ldap.c b/dirmngr/ks-engine-ldap.c index bd6f8d5c5..daf8e133a 100644 --- a/dirmngr/ks-engine-ldap.c +++ b/dirmngr/ks-engine-ldap.c @@ -521,18 +521,12 @@ my_ldap_connect (parsed_uri_t uri, LDAP **ldap_connp, #endif } - if (uri->ad_current) - ldap_conn = ldap_init (NULL, uri->port); - else - ldap_conn = ldap_init (uri->host, uri->port); + ldap_conn = ldap_init (uri->host, uri->port); if (!ldap_conn) { err = gpg_err_code_from_syserror (); - if (uri->ad_current) - log_error ("error initializing LDAP for current user\n"); - else - log_error ("error initializing LDAP for (%s://%s:%d)\n", - uri->scheme, uri->host, uri->port); + log_error ("error initializing LDAP for (%s://%s:%d)\n", + uri->scheme, uri->host, uri->port); goto out; } @@ -613,15 +607,16 @@ my_ldap_connect (parsed_uri_t uri, LDAP **ldap_connp, npth_unprotect (); err = ldap_bind_s (ldap_conn, NULL, NULL, LDAP_AUTH_NEGOTIATE); npth_protect (); -#else - err = gpg_error (GPG_ERR_NOT_SUPPORTED); -#endif if (err != LDAP_SUCCESS) { log_error ("error binding to LDAP via AD: %s\n", ldap_err2string (err)); goto out; } +#else + err = gpg_error (GPG_ERR_NOT_SUPPORTED); + goto out; +#endif } else if (uri->auth) { diff --git a/dirmngr/ldap-parse-uri.c b/dirmngr/ldap-parse-uri.c index 86f6ce032..c36763eee 100644 --- a/dirmngr/ldap-parse-uri.c +++ b/dirmngr/ldap-parse-uri.c @@ -74,6 +74,7 @@ ldap_parse_uri (parsed_uri_t *purip, const char *uri) char *dn = NULL; char *bindname = NULL; char *password = NULL; + char *gpg_ntds = NULL; char **s; @@ -110,6 +111,15 @@ ldap_parse_uri (parsed_uri_t *purip, const char *uri) else password = *s + 9; } + else if (!ascii_strncasecmp (*s, "gpgNtds=", 8) + || !strncmp (*s, "1.3.6.1.4.1.11591.2.5.1=", 24)) + { + if (gpg_ntds) + log_error ("gpgNtds given multiple times in URL '%s', ignoring.\n", + uri); + else + gpg_ntds = *s + (**s == 'g'? 8 : 24); + } else log_error ("Unhandled extension (%s) in URL '%s', ignoring.", *s, uri); @@ -170,10 +180,14 @@ ldap_parse_uri (parsed_uri_t *purip, const char *uri) puri->port = lud->lud_port; /* On Windows detect whether this is ldap:// or ldaps:// to indicate - * that authentication via AD and the current user is requested. */ + * that authentication via AD and the current user is requested. + * This is shortform of adding "gpgNtDs=1" as extension parameter to + * the URL. */ puri->ad_current = 0; + if (gpg_ntds && atoi (gpg_ntds) == 1) + puri->ad_current = 1; #ifdef HAVE_W32_SYSTEM - if ((!puri->host || !*puri->host) + else if ((!puri->host || !*puri->host) && (!puri->path || !*puri->path) && (!puri->auth || !*puri->auth) && !password diff --git a/doc/dirmngr.texi b/doc/dirmngr.texi index 843fdbf67..12ab2b3ee 100644 --- a/doc/dirmngr.texi +++ b/doc/dirmngr.texi @@ -332,6 +332,8 @@ built-in default of @code{hkps://hkps.pool.sks-keyservers.net}. Windows users with a keyserver running on their Active Directory should use @code{ldap:///} for @var{name} to access this directory. +As an alternative it is also possible to add @code{gpgNtds=1} as +extension (i.e. after the fourth question mark). For accessing anonymous LDAP keyservers @var{name} is in general just a @code{ldaps://ldap.example.com}. A BaseDN parameter should never be diff --git a/doc/gpg.texi b/doc/gpg.texi index 7b603d7da..cd8ded982 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -1910,13 +1910,13 @@ Use @var{name} as your keyserver. This is the server that will communicate with to receive keys from, send keys to, and search for keys on. The format of the @var{name} is a URI: `scheme:[//]keyservername[:port]' The scheme is the type of keyserver: -"hkp" for the HTTP (or compatible) keyservers, "ldap" for the LDAP -keyservers, or "mailto" for the Graff email keyserver. Note that your -particular installation of GnuPG may have other keyserver types -available as well. Keyserver schemes are case-insensitive. After the -keyserver name, optional keyserver configuration options may be -provided. These are the same as the global @option{--keyserver-options} -from below, but apply only to this particular keyserver. +"hkp"/"hkps" for the HTTP (or compatible) keyservers or "ldap"/"ldaps" +for the LDAP keyservers. Note that your particular installation of +GnuPG may have other keyserver types available as well. Keyserver +schemes are case-insensitive. After the keyserver name, optional +keyserver configuration options may be provided. These are the same as +the global @option{--keyserver-options} from below, but apply only to +this particular keyserver. Most keyservers synchronize with each other, so there is generally no need to send keys to more than one server. The keyserver