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.

This has been cherry-picked from the 2.2 branch,
commit 55f46b33df

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2021-02-17 17:31:36 +01:00
parent 3fa1fa747b
commit ab7dc4b524
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
5 changed files with 40 additions and 22 deletions

View File

@ -519,18 +519,12 @@ my_ldap_connect (parsed_uri_t uri, LDAP **ldap_connp,
#endif #endif
} }
if (uri->ad_current) ldap_conn = ldap_init (uri->host, uri->port);
ldap_conn = ldap_init (NULL, uri->port);
else
ldap_conn = ldap_init (uri->host, uri->port);
if (!ldap_conn) if (!ldap_conn)
{ {
err = gpg_err_code_from_syserror (); err = gpg_err_code_from_syserror ();
if (uri->ad_current) log_error ("error initializing LDAP for (%s://%s:%d)\n",
log_error ("error initializing LDAP for current user\n"); uri->scheme, uri->host, uri->port);
else
log_error ("error initializing LDAP for (%s://%s:%d)\n",
uri->scheme, uri->host, uri->port);
goto out; goto out;
} }
@ -611,15 +605,16 @@ my_ldap_connect (parsed_uri_t uri, LDAP **ldap_connp,
npth_unprotect (); npth_unprotect ();
err = ldap_bind_s (ldap_conn, NULL, NULL, LDAP_AUTH_NEGOTIATE); err = ldap_bind_s (ldap_conn, NULL, NULL, LDAP_AUTH_NEGOTIATE);
npth_protect (); npth_protect ();
#else
err = gpg_error (GPG_ERR_NOT_SUPPORTED);
#endif
if (err != LDAP_SUCCESS) if (err != LDAP_SUCCESS)
{ {
log_error ("error binding to LDAP via AD: %s\n", log_error ("error binding to LDAP via AD: %s\n",
ldap_err2string (err)); ldap_err2string (err));
goto out; goto out;
} }
#else
err = gpg_error (GPG_ERR_NOT_SUPPORTED);
goto out;
#endif
} }
else if (uri->auth) else if (uri->auth)
{ {

View File

@ -71,6 +71,7 @@ ldap_parse_uri (parsed_uri_t *purip, const char *uri)
char *dn = NULL; char *dn = NULL;
char *bindname = NULL; char *bindname = NULL;
char *password = NULL; char *password = NULL;
char *gpg_ntds = NULL;
char **s; char **s;
@ -107,6 +108,15 @@ ldap_parse_uri (parsed_uri_t *purip, const char *uri)
else else
password = *s + 9; 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 else
log_error ("Unhandled extension (%s) in URL '%s', ignoring.", log_error ("Unhandled extension (%s) in URL '%s', ignoring.",
*s, uri); *s, uri);
@ -167,10 +177,14 @@ ldap_parse_uri (parsed_uri_t *purip, const char *uri)
puri->port = lud->lud_port; puri->port = lud->lud_port;
/* On Windows detect whether this is ldap:// or ldaps:// to indicate /* 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; puri->ad_current = 0;
if (gpg_ntds && atoi (gpg_ntds) == 1)
puri->ad_current = 1;
#ifdef HAVE_W32_SYSTEM #ifdef HAVE_W32_SYSTEM
if ((!puri->host || !*puri->host) else if ((!puri->host || !*puri->host)
&& (!puri->path || !*puri->path) && (!puri->path || !*puri->path)
&& (!puri->auth || !*puri->auth) && (!puri->auth || !*puri->auth)
&& !password && !password

View File

@ -541,7 +541,7 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
Mark the start of the actual decryption process. This is also Mark the start of the actual decryption process. This is also
emitted when in --list-only mode. emitted when in --list-only mode.
*** END_DECRYPTION *** END_DECRYPTION
Mark the end of the actual decryption process. This are also Mark the end of the actual decryption process. This is also
emitted when in --list-only mode. emitted when in --list-only mode.
*** DECRYPTION_KEY <fpr> <fpr2> <otrust> *** DECRYPTION_KEY <fpr> <fpr2> <otrust>
This line is emitted when a public key decryption succeeded in This line is emitted when a public key decryption succeeded in
@ -1167,6 +1167,11 @@ pkd:0:1024:B665B1435F4C2 .... FF26ABB:
These were used for the ancient shared memory based co-processing. These were used for the ancient shared memory based co-processing.
*** BEGIN_STREAM, END_STREAM *** BEGIN_STREAM, END_STREAM
Used to issued by the experimental pipemode. Used to issued by the experimental pipemode.
*** GOODMDC
This is not anymore needed. Checking the DECRYPTION_OKAY status is
sufficient.
*** BADMDC
This is not anymore needed.
** Inter-component codes ** Inter-component codes
Status codes are also used between the components of the GnuPG Status codes are also used between the components of the GnuPG
@ -1555,6 +1560,8 @@ Status codes are:
1.3.6.1.4.1.11591.2.4.1.2 gpgSubFingerprint attribute 1.3.6.1.4.1.11591.2.4.1.2 gpgSubFingerprint attribute
1.3.6.1.4.1.11591.2.4.1.3 gpgMailbox attribute 1.3.6.1.4.1.11591.2.4.1.3 gpgMailbox attribute
1.3.6.1.4.1.11591.2.4.1.4 gpgSubCertID attribute 1.3.6.1.4.1.11591.2.4.1.4 gpgSubCertID attribute
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 AD user)
1.3.6.1.4.1.11591.2.12242973 invalid encoded OID 1.3.6.1.4.1.11591.2.12242973 invalid encoded OID
#+end_example #+end_example

View File

@ -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 Windows users with a keyserver running on their Active Directory
should use @code{ldap:///} for @var{name} to access this 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 For accessing anonymous LDAP keyservers @var{name} is in general just
a @code{ldaps://ldap.example.com}. A BaseDN parameter should never be a @code{ldaps://ldap.example.com}. A BaseDN parameter should never be

View File

@ -1911,13 +1911,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 will communicate with to receive keys from, send keys to, and search for
keys on. The format of the @var{name} is a URI: keys on. The format of the @var{name} is a URI:
`scheme:[//]keyservername[:port]' The scheme is the type of keyserver: `scheme:[//]keyservername[:port]' The scheme is the type of keyserver:
"hkp" for the HTTP (or compatible) keyservers, "ldap" for the LDAP "hkp"/"hkps" for the HTTP (or compatible) keyservers or "ldap"/"ldaps"
keyservers, or "mailto" for the Graff email keyserver. Note that your for the LDAP keyservers. Note that your particular installation of
particular installation of GnuPG may have other keyserver types GnuPG may have other keyserver types available as well. Keyserver
available as well. Keyserver schemes are case-insensitive. After the schemes are case-insensitive. After the keyserver name, optional
keyserver name, optional keyserver configuration options may be keyserver configuration options may be provided. These are the same as
provided. These are the same as the global @option{--keyserver-options} the global @option{--keyserver-options} from below, but apply only to
from below, but apply only to this particular keyserver. this particular keyserver.
Most keyservers synchronize with each other, so there is generally no Most keyservers synchronize with each other, so there is generally no
need to send keys to more than one server. The keyserver need to send keys to more than one server. The keyserver