~ubuntu-branches/ubuntu/precise/autofs5/precise

« back to all changes in this revision

Viewing changes to debian/patches/01UPSTREAM_autofs-5.0.5-add-external-bind-method.dpatch

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2011-05-27 09:21:06 UTC
  • Revision ID: james.westby@ubuntu.com-20110527092106-8f4jioajbyi3bctn
Tags: 5.0.5-0ubuntu7
* Refresh upstream patches.
* Convert to dpkg-source 3.0 quilt format.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#! /bin/sh /usr/share/dpatch/dpatch-run
2
 
## 01UPSTREAM_autofs-5.0.5-add-external-bind-method.dpatch 
3
 
##
4
 
## DP: Upstream patch on top of 5.0.5
5
 
 
6
 
@DPATCH@
7
 
autofs-5.0.5 - add external bind method
8
 
 
9
 
From: Ian Kent <raven@themaw.net>
10
 
 
11
 
Add sasl external bind handler.
12
 
---
13
 
 
14
 
 CHANGELOG                      |    1 
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
23
 
 
24
 
 
25
 
diff --git a/CHANGELOG b/CHANGELOG
26
 
index 46eb3ce..b107515 100644
27
 
--- a/CHANGELOG
28
 
+++ b/CHANGELOG
29
 
@@ -52,6 +52,7 @@
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.
34
 
 
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
41
 
@@ -10,6 +10,7 @@
42
 
 #include <krb5.h>
43
 
 #endif
44
 
 
45
 
+#include "list.h"
46
 
 #include "dclist.h"
47
 
 
48
 
 struct ldap_schema {
49
 
@@ -76,9 +77,13 @@ struct lookup_context {
50
 
        int          kinit_done;
51
 
        int          kinit_successful;
52
 
 #ifdef WITH_SASL
53
 
+       /* Kerberos */
54
 
        krb5_context krb5ctxt;
55
 
        krb5_ccache  krb5_ccache;
56
 
        sasl_conn_t  *sasl_conn;
57
 
+       /* SASL external */
58
 
+       char         *extern_cert;
59
 
+       char         *extern_key;
60
 
 #endif
61
 
        /* keytab file name needs to be added */
62
 
 
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);
69
 
 #endif
70
 
 
71
 
 #endif
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.
79
 
 .TP
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.
92
 
+.sp
93
 
+If using authtype EXTERNAL two additional configuration entries are
94
 
+required:
95
 
+.sp
96
 
+\fBexternal_cert="<client certificate path>"\fP
97
 
+.sp
98
 
+This specifies the path of the file containing the client certificate.
99
 
+.sp
100
 
+\fBexternal_key="<client certificate key path>"\fP
101
 
+.sp
102
 
+This specifies the path of the file containing the client certificate key.
103
 
+.sp
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.
107
 
 .TP
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
117
 
   ifeq ($(SASL), 1)
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)
122
 
   endif
123
 
@@ -92,6 +92,9 @@ lookup_hesiod.so: lookup_hesiod.c
124
 
 cyrus-sasl.o: cyrus-sasl.c
125
 
        $(CC) $(CFLAGS) $(LDAP_FLAGS) -c $<
126
 
 
127
 
+cyrus-sasl-extern.o: cyrus-sasl-extern.c
128
 
+       $(CC) $(CFLAGS) $(LDAP_FLAGS) -c $<
129
 
+
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
134
 
new file mode 100644
135
 
index 0000000..5bb3028
136
 
--- /dev/null
137
 
+++ b/modules/cyrus-sasl-extern.c
138
 
@@ -0,0 +1,117 @@
139
 
+/*
140
 
+ * cyrus-sasl-extern.c - Module for Cyrus sasl external authentication.
141
 
+ *
142
 
+ *   Copyright 2010 Ian Kent <raven@themaw.net>
143
 
+ *   Copyright 2010 Red Hat, Inc.
144
 
+ *   All rights reserved.
145
 
+ *
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
150
 
+ *   version.
151
 
+ *
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.
156
 
+ */
157
 
+
158
 
+#include "config.h"
159
 
+
160
 
+#ifdef WITH_SASL
161
 
+#include <stdio.h>
162
 
+#include <stdlib.h>
163
 
+#include <string.h>
164
 
+#include <unistd.h>
165
 
+#include <sasl/sasl.h>
166
 
+#include <ldap.h>
167
 
+#include <ldap_cdefs.h>
168
 
+#include <lber_types.h>
169
 
+
170
 
+#include "lookup_ldap.h"
171
 
+
172
 
+struct values {
173
 
+       char *mech;
174
 
+       char *realm;
175
 
+       char *authcid;
176
 
+       char *authzid;
177
 
+       char *password;
178
 
+       char **resps;
179
 
+       int nresps;
180
 
+};
181
 
+
182
 
+static int interaction(unsigned flags, sasl_interact_t *interact, void *values)
183
 
+{
184
 
+       const char *val = interact->defresult;
185
 
+       struct values *vals = values;
186
 
+
187
 
+       switch(interact->id) {
188
 
+       case SASL_CB_GETREALM:
189
 
+               if (values)
190
 
+                       val = vals->realm;
191
 
+               break;
192
 
+
193
 
+       case SASL_CB_AUTHNAME:
194
 
+               if (values)
195
 
+                       val = vals->authcid;
196
 
+               break;
197
 
+
198
 
+       case SASL_CB_PASS:
199
 
+               if (values)
200
 
+                       val = vals->password;
201
 
+               break;
202
 
+
203
 
+       case SASL_CB_USER:
204
 
+               if (values)
205
 
+                       val = vals->authzid;
206
 
+               break;
207
 
+
208
 
+       case SASL_CB_NOECHOPROMPT:
209
 
+       case SASL_CB_ECHOPROMPT:
210
 
+               break;
211
 
+       }
212
 
+
213
 
+       if (val && !*val)
214
 
+               val = NULL;
215
 
+
216
 
+       if (val || interact->id == SASL_CB_USER) {
217
 
+               interact->result = (val && *val) ? val : "";
218
 
+               interact->len = strlen(interact->result);
219
 
+       }
220
 
+
221
 
+       return LDAP_SUCCESS;
222
 
+}
223
 
+
224
 
+int sasl_extern_interact(LDAP *ldap, unsigned flags, void *values, void *list)
225
 
+{
226
 
+       sasl_interact_t *interact = list;
227
 
+
228
 
+       if (!ldap)
229
 
+               return LDAP_PARAM_ERROR;
230
 
+
231
 
+       while (interact->id != SASL_CB_LIST_END) {
232
 
+               int rc = interaction(flags, interact, values);
233
 
+               if (rc)
234
 
+                       return rc;
235
 
+               interact++;
236
 
+       }
237
 
+
238
 
+       return LDAP_SUCCESS;
239
 
+}
240
 
+
241
 
+int do_sasl_extern(LDAP *ldap, struct lookup_context *ctxt)
242
 
+{
243
 
+       int flags = LDAP_SASL_QUIET;
244
 
+       char *mech = ctxt->sasl_mech;
245
 
+       struct values values;
246
 
+       int rc;
247
 
+
248
 
+       memset(&values, 0, sizeof(struct values));
249
 
+       values.mech = mech;
250
 
+
251
 
+       rc = ldap_sasl_interactive_bind_s(ldap, NULL, mech, NULL, NULL,
252
 
+                                         flags, sasl_extern_interact, &values);
253
 
+       return rc;
254
 
+}
255
 
+#endif
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)
261
 
        if (ctxt->sasl_conn)
262
 
                return 0;
263
 
 
264
 
+       if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "EXTERNAL", 8)) {
265
 
+               int result;
266
 
+
267
 
+               debug(logopt,
268
 
+                     "Attempting sasl bind with mechanism %s",
269
 
+                     ctxt->sasl_mech);
270
 
+
271
 
+               result = do_sasl_extern(ldap, ctxt);
272
 
+               if (result)
273
 
+                       debug(logopt,
274
 
+                             "Failed to authenticate with mech %s",
275
 
+                             ctxt->sasl_mech);
276
 
+               else
277
 
+                       debug(logopt,
278
 
+                             "sasl bind with mechanism %s succeeded",
279
 
+                             ctxt->sasl_mech);
280
 
+
281
 
+               return result;
282
 
+       }
283
 
+
284
 
        sasl_auth_id = ctxt->user;
285
 
        sasl_auth_secret = ctxt->secret;
286
 
 
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
291
 
@@ -41,6 +41,9 @@
292
 
 
293
 
 int lookup_version = AUTOFS_LOOKUP_VERSION;    /* Required by protocol */
294
 
 
295
 
+#define ENV_LDAPTLS_CERT       "LDAPTLS_CERT"
296
 
+#define ENV_LDAPTLS_KEY                "LDAPTLS_KEY"
297
 
+
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 {
302
 
 
303
 
 static int decode_percent_hack(const char *, char **);
304
 
 
305
 
+static int set_env(unsigned logopt, const char *name, const char *val)
306
 
+{
307
 
+       int ret = setenv(name, val, 1);
308
 
+       if (ret == -1) {
309
 
+               error(logopt, "failed to set config value for %s", name);
310
 
+               return 0;
311
 
+       }
312
 
+       return 1;
313
 
+}
314
 
+
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
319
 
 {
320
 
        LDAP *ldap;
321
 
 
322
 
-       ldap = init_ldap_connection(logopt, uri, ctxt);
323
 
-       if (!ldap)
324
 
-               return NULL;
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);
328
 
+       }
329
 
 
330
 
-       if (!do_bind(logopt, ldap, uri, ctxt)) {
331
 
-               unbind_ldap_connection(logopt, ldap, ctxt);
332
 
-               return NULL;
333
 
+       ldap = init_ldap_connection(logopt, uri, ctxt);
334
 
+       if (ldap) {
335
 
+               if (!do_bind(logopt, ldap, uri, ctxt)) {
336
 
+                       unbind_ldap_connection(logopt, ldap, ctxt);
337
 
+                       ldap = NULL;
338
 
+               }
339
 
        }
340
 
 
341
 
        return ldap;
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;
349
 
 
350
 
@@ -1023,6 +1041,26 @@ int parse_ldap_config(unsigned logopt, struct lookup_context *ctxt)
351
 
                        ret = -1;
352
 
                        goto out;
353
 
                }
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);
358
 
+               /*
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.
367
 
+                */
368
 
+               if (ret != 0 || !extern_cert || !extern_key) {
369
 
+                       if (extern_cert)
370
 
+                               free(extern_cert);
371
 
+                       if (extern_key)
372
 
+                               free(extern_key);
373
 
+               }
374
 
        }
375
 
 
376
 
        /*
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;
383
 
 
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, "
388
 
              "sasl_mech: %s",
389
 
              use_tls, tls_required, auth_required, authtype);
390
 
-       debug(logopt, MODPREFIX
391
 
-             "user: %s, "
392
 
-             "secret: %s, "
393
 
-             "client principal: %s "
394
 
-             "credential cache: %s",
395
 
-             user, secret ? "specified" : "unspecified",
396
 
-             client_princ, client_cc);
397
 
-
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");
403
 
+       } else {
404
 
+               debug(logopt, MODPREFIX
405
 
+                     "user: %s, "
406
 
+                     "secret: %s, "
407
 
+                     "client principal: %s "
408
 
+                     "credential cache: %s",
409
 
+                     user, secret ? "specified" : "unspecified",
410
 
+                     client_princ, client_cc);
411
 
+       }
412
 
 out:
413
 
        xmlFreeDoc(doc);
414
 
 
415
 
@@ -1326,6 +1372,10 @@ static void free_context(struct lookup_context *ctxt)
416
 
                defaults_free_searchdns(ctxt->sdns);
417
 
        if (ctxt->dclist)
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);
423
 
        free(ctxt);
424
 
 
425
 
        return;