1
#! /bin/sh /usr/share/dpatch/dpatch-run
2
## 01UPSTREAM_autofs-5.0.5-add-external-bind-method.dpatch
4
## DP: Upstream patch on top of 5.0.5
7
autofs-5.0.5 - add external bind method
9
From: Ian Kent <raven@themaw.net>
11
Add sasl external bind handler.
15
include/lookup_ldap.h | 7 ++
16
man/autofs_ldap_auth.conf.5.in | 24 +++++++-
17
modules/Makefile | 5 +-
18
modules/cyrus-sasl-extern.c | 117 ++++++++++++++++++++++++++++++++++++++++
19
modules/cyrus-sasl.c | 20 +++++++
20
modules/lookup_ldap.c | 78 ++++++++++++++++++++++-----
21
7 files changed, 234 insertions(+), 18 deletions(-)
22
create mode 100644 modules/cyrus-sasl-extern.c
25
diff --git a/CHANGELOG b/CHANGELOG
26
index 46eb3ce..b107515 100644
30
- fix init script status privilege error.
31
- always read file maps mount lookup map read fix.
32
- fix direct map not updating on reread.
33
+- add external bind method.
35
03/09/2009 autofs-5.0.5
36
-----------------------
37
diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h
38
index 1e1c7a4..4067ccc 100644
39
--- a/include/lookup_ldap.h
40
+++ b/include/lookup_ldap.h
49
@@ -76,9 +77,13 @@ struct lookup_context {
54
krb5_context krb5ctxt;
55
krb5_ccache krb5_ccache;
56
sasl_conn_t *sasl_conn;
61
/* keytab file name needs to be added */
63
@@ -111,6 +116,8 @@ int autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt);
64
void autofs_sasl_unbind(struct lookup_context *ctxt);
65
void autofs_sasl_dispose(struct lookup_context *ctxt);
66
void autofs_sasl_done(void);
67
+/* cyrus-sasl-extern */
68
+int do_sasl_extern(LDAP *ldap, struct lookup_context *ctxt);
72
diff --git a/man/autofs_ldap_auth.conf.5.in b/man/autofs_ldap_auth.conf.5.in
73
index ecec20d..2260952 100644
74
--- a/man/autofs_ldap_auth.conf.5.in
75
+++ b/man/autofs_ldap_auth.conf.5.in
76
@@ -60,12 +60,30 @@ authentication mechanism. If no suitable mechanism can be found, connections
77
to the ldap server are made without authentication. Finally, if it is set to
78
simple, then simple authentication will be used instead of SASL.
80
-\fBauthtype="GSSAPI"|"LOGIN"|"PLAIN"|"ANONYMOUS"|"DIGEST-MD5"\fP
81
+\fBauthtype="GSSAPI"|"LOGIN"|"PLAIN"|"ANONYMOUS"|"DIGEST-MD5|EXTERNAL"\fP
82
This attribute can be used to specify a preferred authentication mechanism.
83
- In normal operations, the automounter will attempt to authenticate to the
84
+In normal operations, the automounter will attempt to authenticate to the
85
ldap server using the list of supportedSASLmechanisms obtained from the
86
directory server. Explicitly setting the authtype will bypass this selection
87
-and only try the mechanism specified.
88
+and only try the mechanism specified. The EXTERNAL mechanism may be used to
89
+authenticate using a client certificate and requires that authrequired
90
+set to "yes" if using SSL or usetls, tlsrequired and authrequired all set to
91
+"yes" if using TLS, in addition to authtype being set to EXTERNAL.
93
+If using authtype EXTERNAL two additional configuration entries are
96
+\fBexternal_cert="<client certificate path>"\fP
98
+This specifies the path of the file containing the client certificate.
100
+\fBexternal_key="<client certificate key path>"\fP
102
+This specifies the path of the file containing the client certificate key.
104
+These two configuration entries are mandatory when using the EXTERNAL method
105
+as the HOME environment variable cannot be assumed to be set or, if it is,
106
+to be set to the location we expect.
108
\fBuser="<username>"\fP
109
This attribute holds the authentication identity used by authentication
110
diff --git a/modules/Makefile b/modules/Makefile
111
index 164d412..9ad3915 100644
112
--- a/modules/Makefile
113
+++ b/modules/Makefile
114
@@ -41,7 +41,7 @@ ifeq ($(LDAP), 1)
115
SRCS += lookup_ldap.c
116
MODS += lookup_ldap.so
118
- SASL_OBJ = cyrus-sasl.o
119
+ SASL_OBJ = cyrus-sasl.o cyrus-sasl-extern.o
120
LDAP_FLAGS += $(SASL_FLAGS) $(XML_FLAGS) $(KRB5_FLAGS) -DLDAP_THREAD_SAFE
121
LIBLDAP += $(LIBSASL) $(XML_LIBS) $(KRB5_LIBS)
123
@@ -92,6 +92,9 @@ lookup_hesiod.so: lookup_hesiod.c
124
cyrus-sasl.o: cyrus-sasl.c
125
$(CC) $(CFLAGS) $(LDAP_FLAGS) -c $<
127
+cyrus-sasl-extern.o: cyrus-sasl-extern.c
128
+ $(CC) $(CFLAGS) $(LDAP_FLAGS) -c $<
130
lookup_ldap.so: lookup_ldap.c dclist.o $(SASL_OBJ)
131
$(CC) $(SOLDFLAGS) $(CFLAGS) $(LDAP_FLAGS) -o lookup_ldap.so \
132
lookup_ldap.c dclist.o $(SASL_OBJ) \
133
diff --git a/modules/cyrus-sasl-extern.c b/modules/cyrus-sasl-extern.c
135
index 0000000..5bb3028
137
+++ b/modules/cyrus-sasl-extern.c
140
+ * cyrus-sasl-extern.c - Module for Cyrus sasl external authentication.
142
+ * Copyright 2010 Ian Kent <raven@themaw.net>
143
+ * Copyright 2010 Red Hat, Inc.
144
+ * All rights reserved.
146
+ * This program is free software; you can redistribute it and/or modify
147
+ * it under the terms of the GNU General Public License as published by
148
+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
149
+ * USA; either version 2 of the License, or (at your option) any later
152
+ * This program is distributed in the hope that it will be useful,
153
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
154
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
155
+ * GNU General Public License for more details.
165
+#include <sasl/sasl.h>
167
+#include <ldap_cdefs.h>
168
+#include <lber_types.h>
170
+#include "lookup_ldap.h"
182
+static int interaction(unsigned flags, sasl_interact_t *interact, void *values)
184
+ const char *val = interact->defresult;
185
+ struct values *vals = values;
187
+ switch(interact->id) {
188
+ case SASL_CB_GETREALM:
193
+ case SASL_CB_AUTHNAME:
195
+ val = vals->authcid;
200
+ val = vals->password;
205
+ val = vals->authzid;
208
+ case SASL_CB_NOECHOPROMPT:
209
+ case SASL_CB_ECHOPROMPT:
216
+ if (val || interact->id == SASL_CB_USER) {
217
+ interact->result = (val && *val) ? val : "";
218
+ interact->len = strlen(interact->result);
221
+ return LDAP_SUCCESS;
224
+int sasl_extern_interact(LDAP *ldap, unsigned flags, void *values, void *list)
226
+ sasl_interact_t *interact = list;
229
+ return LDAP_PARAM_ERROR;
231
+ while (interact->id != SASL_CB_LIST_END) {
232
+ int rc = interaction(flags, interact, values);
238
+ return LDAP_SUCCESS;
241
+int do_sasl_extern(LDAP *ldap, struct lookup_context *ctxt)
243
+ int flags = LDAP_SASL_QUIET;
244
+ char *mech = ctxt->sasl_mech;
245
+ struct values values;
248
+ memset(&values, 0, sizeof(struct values));
249
+ values.mech = mech;
251
+ rc = ldap_sasl_interactive_bind_s(ldap, NULL, mech, NULL, NULL,
252
+ flags, sasl_extern_interact, &values);
256
diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c
257
index d117f0a..967edc3 100644
258
--- a/modules/cyrus-sasl.c
259
+++ b/modules/cyrus-sasl.c
260
@@ -875,6 +875,26 @@ autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
264
+ if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "EXTERNAL", 8)) {
268
+ "Attempting sasl bind with mechanism %s",
271
+ result = do_sasl_extern(ldap, ctxt);
274
+ "Failed to authenticate with mech %s",
278
+ "sasl bind with mechanism %s succeeded",
284
sasl_auth_id = ctxt->user;
285
sasl_auth_secret = ctxt->secret;
287
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
288
index 3d47048..1432056 100644
289
--- a/modules/lookup_ldap.c
290
+++ b/modules/lookup_ldap.c
293
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
295
+#define ENV_LDAPTLS_CERT "LDAPTLS_CERT"
296
+#define ENV_LDAPTLS_KEY "LDAPTLS_KEY"
298
static struct ldap_schema common_schema[] = {
299
{"nisMap", "nisMapName", "nisObject", "cn", "nisMapEntry"},
300
{"automountMap", "ou", "automount", "cn", "automountInformation"},
301
@@ -61,6 +64,16 @@ struct ldap_search_params {
303
static int decode_percent_hack(const char *, char **);
305
+static int set_env(unsigned logopt, const char *name, const char *val)
307
+ int ret = setenv(name, val, 1);
309
+ error(logopt, "failed to set config value for %s", name);
315
#ifndef HAVE_LDAP_CREATE_PAGE_CONTROL
316
int ldap_create_page_control(LDAP *ldap, ber_int_t pagesize,
317
struct berval *cookie, char isCritical,
318
@@ -578,13 +591,17 @@ static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context
322
- ldap = init_ldap_connection(logopt, uri, ctxt);
325
+ if (ctxt->extern_cert && ctxt->extern_key) {
326
+ set_env(logopt, ENV_LDAPTLS_CERT, ctxt->extern_cert);
327
+ set_env(logopt, ENV_LDAPTLS_KEY, ctxt->extern_key);
330
- if (!do_bind(logopt, ldap, uri, ctxt)) {
331
- unbind_ldap_connection(logopt, ldap, ctxt);
333
+ ldap = init_ldap_connection(logopt, uri, ctxt);
335
+ if (!do_bind(logopt, ldap, uri, ctxt)) {
336
+ unbind_ldap_connection(logopt, ldap, ctxt);
342
@@ -839,6 +856,7 @@ int parse_ldap_config(unsigned logopt, struct lookup_context *ctxt)
343
xmlNodePtr root = NULL;
344
char *authrequired, *auth_conf, *authtype;
345
char *user = NULL, *secret = NULL;
346
+ char *extern_cert = NULL, *extern_key = NULL;
347
char *client_princ = NULL, *client_cc = NULL;
348
char *usetls, *tlsrequired;
350
@@ -1023,6 +1041,26 @@ int parse_ldap_config(unsigned logopt, struct lookup_context *ctxt)
354
+ } else if (auth_required == LDAP_AUTH_REQUIRED &&
355
+ (authtype && !strncmp(authtype, "EXTERNAL", 8))) {
356
+ ret = get_property(logopt, root, "external_cert", &extern_cert);
357
+ ret |= get_property(logopt, root, "external_key", &extern_key);
359
+ * For EXTERNAL auth to function we need a client certificate
360
+ * and and certificate key. The ca certificate used to verify
361
+ * the server certificate must also be set correctly in the
362
+ * global configuration as the connection must be encrypted
363
+ * and the server and client certificates must have been
364
+ * verified for the EXTERNAL method to be offerred by the
365
+ * server. If the cert and key have not been set in the autofs
366
+ * configuration they must be set in the ldap rc file.
368
+ if (ret != 0 || !extern_cert || !extern_key) {
377
@@ -1043,6 +1081,8 @@ int parse_ldap_config(unsigned logopt, struct lookup_context *ctxt)
378
ctxt->secret = secret;
379
ctxt->client_princ = client_princ;
380
ctxt->client_cc = client_cc;
381
+ ctxt->extern_cert = extern_cert;
382
+ ctxt->extern_key = extern_key;
384
debug(logopt, MODPREFIX
385
"ldap authentication configured with the following options:");
386
@@ -1052,14 +1092,20 @@ int parse_ldap_config(unsigned logopt, struct lookup_context *ctxt)
387
"auth_required: %u, "
389
use_tls, tls_required, auth_required, authtype);
390
- debug(logopt, MODPREFIX
393
- "client principal: %s "
394
- "credential cache: %s",
395
- user, secret ? "specified" : "unspecified",
396
- client_princ, client_cc);
398
+ if (authtype && !strncmp(authtype, "EXTERNAL", 8)) {
399
+ debug(logopt, MODPREFIX "external cert: %s",
400
+ extern_cert ? extern_cert : "ldap default");
401
+ debug(logopt, MODPREFIX "external key: %s ",
402
+ extern_key ? extern_key : "ldap default");
404
+ debug(logopt, MODPREFIX
407
+ "client principal: %s "
408
+ "credential cache: %s",
409
+ user, secret ? "specified" : "unspecified",
410
+ client_princ, client_cc);
415
@@ -1326,6 +1372,10 @@ static void free_context(struct lookup_context *ctxt)
416
defaults_free_searchdns(ctxt->sdns);
418
free_dclist(ctxt->dclist);
419
+ if (ctxt->extern_cert)
420
+ free(ctxt->extern_cert);
421
+ if (ctxt->extern_key)
422
+ free(ctxt->extern_key);