Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / libnfsidmap / umich_ldap.c
blobf6204c312dfdd5c7927e78397d7ff98943bc6f79
1 /*
2 * umich_ldap.c
4 * Copyright (c) 2000 The Regents of the University of Michigan.
5 * All rights reserved.
7 * Copyright (c) 2004 Andy Adamson <andros@UMICH.EDU>
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
29 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #ifdef ENABLE_LDAP
37 #include <sys/types.h>
38 #include <sys/socket.h>
39 #include <netdb.h>
40 #include <errno.h>
41 #include <unistd.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <stdio.h>
45 #include <limits.h>
46 #include <pwd.h>
47 #include <err.h>
48 /* We are using deprecated functions, get the prototypes... */
49 #define LDAP_DEPRECATED 1
50 #include <ldap.h>
51 #include "nfsidmap.h"
52 #include "nfsidmap_internal.h"
53 #include "cfg.h"
55 /* attribute/objectclass default mappings */
56 #define DEFAULT_UMICH_OBJCLASS_REMOTE_PERSON "NFSv4RemotePerson"
57 #define DEFAULT_UMICH_OBJCLASS_REMOTE_GROUP "NFSv4RemoteGroup"
58 #define DEFAULT_UMICH_ATTR_NFSNAME "NFSv4Name"
59 #define DEFAULT_UMICH_ATTR_ACCTNAME "uid"
60 #define DEFAULT_UMICH_ATTR_UIDNUMBER "uidNumber"
61 #define DEFAULT_UMICH_ATTR_GROUP_NFSNAME "NFSv4Name"
62 #define DEFAULT_UMICH_ATTR_GIDNUMBER "gidNumber"
63 #define DEFAULT_UMICH_ATTR_MEMBERUID "memberUid"
64 #define DEFAULT_UMICH_ATTR_GSSAUTHNAME "GSSAuthName"
65 #define DEFAULT_UMICH_ATTR_MEMBEROF "memberof"
67 #define DEFAULT_UMICH_SEARCH_TIMEOUT 4
69 /* config section */
70 #define LDAP_SECTION "UMICH_SCHEMA"
72 #ifndef LDAP_FILT_MAXSIZ
73 #define LDAP_FILT_MAXSIZ 1024
74 #endif
77 /* Local structure definitions */
79 struct ldap_map_names{
80 char *NFSv4_person_objcls;
81 char *NFSv4_nfsname_attr;
82 char *NFSv4_acctname_attr;
83 char *NFSv4_uid_attr;
84 char *NFSv4_group_objcls;
85 char *NFSv4_group_nfsname_attr;
86 char *NFSv4_gid_attr;
87 char *NFSv4_member_attr;
88 char *NFSv4_member_of_attr;
89 char *GSS_principal_attr;
90 char *NFSv4_grouplist_filter; /* Filter for grouplist lookups */
93 struct umich_ldap_info {
94 char *server; /* server name/address */
95 int port; /* server port */
96 char *base; /* base DN */
97 char *people_tree; /* base DN to start searches for people */
98 char *group_tree; /* base DN to start searches for groups */
99 char *user_dn; /* optional DN for user account when binding */
100 char *passwd; /* Password to use when binding to directory */
101 int use_ssl; /* SSL flag */
102 char *ca_cert; /* File location of the ca_cert */
103 int memberof_for_groups;/* Use 'memberof' attribute when
104 looking up user groups */
105 int ldap_timeout; /* Timeout in seconds for searches
106 by ldap_search_st */
109 /* GLOBAL data */
111 static struct umich_ldap_info ldap_info = {
112 .server = NULL,
113 .port = 0,
114 .base = NULL,
115 .people_tree = NULL,
116 .group_tree = NULL,
117 .user_dn = NULL,
118 .passwd = NULL,
119 .use_ssl = 0,
120 .ca_cert = NULL,
121 .memberof_for_groups = 0,
122 .ldap_timeout = DEFAULT_UMICH_SEARCH_TIMEOUT,
125 static struct ldap_map_names ldap_map = {
126 .NFSv4_person_objcls = NULL,
127 .NFSv4_nfsname_attr = NULL,
128 .NFSv4_uid_attr = NULL,
129 .NFSv4_acctname_attr = NULL,
130 .NFSv4_group_objcls = NULL,
131 .NFSv4_group_nfsname_attr = NULL,
132 .NFSv4_gid_attr = NULL,
133 .NFSv4_member_attr = NULL,
134 .NFSv4_member_of_attr = NULL,
135 .GSS_principal_attr = NULL,
136 .NFSv4_grouplist_filter = NULL,
139 /* Local routines */
141 static int
142 ldap_init_and_bind(LDAP **pld,
143 int *sizelimit,
144 struct umich_ldap_info *linfo)
146 LDAP *ld;
147 int lerr;
148 int err = -1;
149 int current_version, new_version;
150 char server_url[1024];
151 int debug_level = 65535;
152 int i;
153 LDAPAPIInfo apiinfo = {.ldapai_info_version = LDAP_API_INFO_VERSION};
155 snprintf(server_url, sizeof(server_url), "%s://%s:%d",
156 (linfo->use_ssl && linfo->ca_cert) ? "ldaps" : "ldap",
157 linfo->server, linfo->port);
160 * XXX We really, REALLY only want to initialize once, not for
161 * each request. Figure out how to do that!
163 if ((lerr = ldap_initialize(&ld, server_url)) != LDAP_SUCCESS) {
164 IDMAP_LOG(0, ("ldap_init_and_bind: ldap_initialize() failed "
165 "to [%s]: %s (%d)\n", server_url,
166 ldap_err2string(lerr), lerr));
167 goto out;
170 if ((ldap_set_option(ld, LDAP_OPT_DEBUG_LEVEL, &debug_level)
171 != LDAP_SUCCESS)) {
172 IDMAP_LOG(0, ("ldap_init_and_bind: error setting ldap "
173 "library debugging level\n"));
174 goto out;
178 * Get LDAP API information and compare the protocol version there
179 * to the protocol version returned directly from get_option.
181 ldap_get_option(ld, LDAP_OPT_API_INFO, &apiinfo);
182 if (apiinfo.ldapai_info_version != LDAP_API_INFO_VERSION) {
183 IDMAP_LOG(0, ("ldap_init_and_bind: APIInfo version mismatch: "
184 "library %d, header %d\n",
185 apiinfo.ldapai_info_version, LDAP_API_INFO_VERSION));
186 goto out;
188 ldap_get_option(ld, LDAP_OPT_PROTOCOL_VERSION, &current_version);
189 if (apiinfo.ldapai_protocol_version == LDAP_VERSION3 &&
190 current_version != LDAP_VERSION3) {
191 new_version = LDAP_VERSION3;
192 IDMAP_LOG(4, ("ldap_init_and_bind: version mismatch between "
193 "API information and protocol version. Setting "
194 "protocol version to %d\n", new_version));
195 ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &new_version);
198 for (i = 0; apiinfo.ldapai_extensions[i]; i++) {
199 char *extension = apiinfo.ldapai_extensions[i];
200 ldap_memfree (extension);
202 ldap_memfree (apiinfo.ldapai_extensions);
203 ldap_memfree(apiinfo.ldapai_vendor_name);
205 /* Set sizelimit option if requested */
206 if (sizelimit) {
207 ldap_set_option(ld, LDAP_OPT_SIZELIMIT, (void *)sizelimit);
210 /* Set option to to use SSL/TLS if requested */
211 if (linfo->use_ssl && linfo->ca_cert) {
212 int tls_type = LDAP_OPT_X_TLS_HARD;
214 lerr = ldap_set_option(ld, LDAP_OPT_X_TLS, &tls_type);
215 if (lerr != LDAP_SUCCESS) {
216 IDMAP_LOG(2, ("ldap_init_and_bind: setting SSL "
217 "failed : %s (%d)\n",
218 ldap_err2string(lerr), lerr));
219 goto out;
221 lerr = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
222 linfo->ca_cert);
223 if (lerr != LDAP_SUCCESS) {
224 IDMAP_LOG(2, ("ldap_init_and_bind: setting CA "
225 "certificate file failed : %s (%d)\n",
226 ldap_err2string(lerr), lerr));
227 goto out;
231 /* If we have a DN (and password) attempt an authenticated bind */
232 if (linfo->user_dn) {
233 retry_bind:
234 lerr = ldap_simple_bind_s(ld, linfo->user_dn, linfo->passwd);
235 if (lerr) {
236 char *errmsg;
237 if (lerr == LDAP_PROTOCOL_ERROR) {
238 ldap_get_option(ld, LDAP_OPT_PROTOCOL_VERSION,
239 &current_version);
240 new_version = current_version == LDAP_VERSION2 ?
241 LDAP_VERSION3 : LDAP_VERSION2;
242 ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
243 &new_version);
244 IDMAP_LOG(2, ("ldap_init_and_bind: "
245 "got protocol error while attempting "
246 "bind with protocol version %d, "
247 "trying protocol version %d\n",
248 current_version, new_version));
249 if ((ldap_get_option(ld, LDAP_OPT_ERROR_STRING, &errmsg) == LDAP_SUCCESS)
250 && (errmsg != NULL) && (*errmsg != '\0')) {
251 IDMAP_LOG(2, ("ldap_init_and_bind: "
252 "Additional info: %s\n", errmsg));
253 ldap_memfree(errmsg);
255 goto retry_bind;
257 IDMAP_LOG(2, ("ldap_init_and_bind: ldap_simple_bind_s "
258 "to [%s] as user '%s': %s (%d)\n",
259 server_url, linfo->user_dn,
260 ldap_err2string(lerr), lerr));
261 if ((ldap_get_option(ld, LDAP_OPT_ERROR_STRING, &errmsg) == LDAP_SUCCESS)
262 && (errmsg != NULL)&& (*errmsg != '\0')) {
263 IDMAP_LOG(2, ("ldap_init_and_bind: "
264 "Additional info: %s\n", errmsg));
265 ldap_memfree(errmsg);
267 goto out;
270 #ifdef LDAP_ANONYMOUS_BIND_REQUIRED
271 else {
272 lerr = ldap_simple_bind_s(ld, NULL, NULL);
273 if (lerr) {
274 char *errmsg;
276 IDMAP_LOG(2, ("ldap_init_and_bind: ldap_simple_bind_s "
277 "to [%s] as anonymous: %s (%d)\n", server_url,
278 ldap_err2string(lerr), lerr));
279 if ((ldap_get_option(ld, LDAP_OPT_ERROR_STRING, &errmsg) == LDAP_SUCCESS)
280 && (errmsg != NULL) && (*errmsg != '\0')) {
281 IDMAP_LOG(2, ("ldap_init_and_bind: "
282 "Additional info: %s\n", errmsg));
283 ldap_memfree(errmsg);
285 goto out;
288 #endif
290 *pld = ld;
291 err = 0;
292 out:
293 return err;
296 static int
297 umich_name_to_ids(char *name, int idtype, uid_t *uid, gid_t *gid,
298 char *attrtype, struct umich_ldap_info *linfo)
300 LDAP *ld = NULL;
301 struct timeval timeout = {
302 .tv_sec = linfo->ldap_timeout,
304 LDAPMessage *result = NULL, *entry;
305 BerElement *ber = NULL;
306 char **idstr, filter[LDAP_FILT_MAXSIZ], *base;
307 char *attrs[3];
308 char *attr_res;
309 int count = 0, err, lerr, f_len;
310 int sizelimit = 1;
312 err = -EINVAL;
313 if (uid == NULL || gid == NULL || name == NULL ||
314 attrtype == NULL || linfo == NULL || linfo->server == NULL ||
315 linfo->people_tree == NULL || linfo->group_tree == NULL)
316 goto out;
318 *uid = -1;
319 *gid = -1;
321 if (idtype == IDTYPE_USER) {
322 if ((f_len = snprintf(filter, LDAP_FILT_MAXSIZ,
323 "(&(objectClass=%s)(%s=%s))",
324 ldap_map.NFSv4_person_objcls,
325 attrtype, name))
326 == LDAP_FILT_MAXSIZ) {
327 IDMAP_LOG(0, ("ERROR: umich_name_to_ids: filter "
328 "too long!\n"));
329 goto out;
331 base = linfo->people_tree;
333 else if (idtype == IDTYPE_GROUP) {
334 if ((f_len = snprintf(filter, LDAP_FILT_MAXSIZ,
335 "(&(objectClass=%s)(%s=%s))",
336 ldap_map.NFSv4_group_objcls,
337 attrtype, name))
338 == LDAP_FILT_MAXSIZ) {
339 IDMAP_LOG(0, ("ERROR: umich_name_to_ids: filter "
340 "too long!\n"));
341 goto out;
343 base = linfo->group_tree;
345 else {
346 IDMAP_LOG(0, ("ERROR: umich_name_to_ids: invalid idtype (%d)\n",
347 idtype));
348 goto out;
351 if (ldap_init_and_bind(&ld, &sizelimit, linfo))
352 goto out;
354 attrs[0] = ldap_map.NFSv4_uid_attr;
355 attrs[1] = ldap_map.NFSv4_gid_attr;
356 attrs[2] = NULL;
358 err = ldap_search_st(ld, base, LDAP_SCOPE_SUBTREE,
359 filter, (char **)attrs,
360 0, &timeout, &result);
361 if (err) {
362 char *errmsg;
364 IDMAP_LOG(2, ("umich_name_to_ids: ldap_search_st for "
365 "base '%s', filter '%s': %s (%d)\n",
366 base, filter, ldap_err2string(err), err));
367 if ((ldap_get_option(ld, LDAP_OPT_ERROR_STRING, &errmsg) == LDAP_SUCCESS)
368 && (errmsg != NULL) && (*errmsg != '\0')) {
369 IDMAP_LOG(2, ("umich_name_to_ids: "
370 "Additional info: %s\n", errmsg));
371 ldap_memfree(errmsg);
373 err = -ENOENT;
374 goto out_unbind;
377 err = -ENOENT;
378 count = ldap_count_entries(ld, result);
379 if (count != 1) {
380 goto out_unbind;
383 if (!(entry = ldap_first_entry(ld, result))) {
384 lerr = ldap_result2error(ld, result, 0);
385 IDMAP_LOG(2, ("umich_name_to_ids: ldap_first_entry: "
386 "%s (%d)\n", ldap_err2string(lerr), lerr));
387 goto out_unbind;
391 * Attributes come back in no particular order, so we need
392 * to check each one to see what it is before assigning values.
393 * XXX There must be a better way than comparing the
394 * name of each attribute?
396 for (attr_res = ldap_first_attribute(ld, result, &ber);
397 attr_res != NULL;
398 attr_res = ldap_next_attribute(ld, result, ber)) {
400 unsigned long tmp_u, tmp_g;
401 uid_t tmp_uid;
402 gid_t tmp_gid;
404 if ((idstr = ldap_get_values(ld, result, attr_res)) == NULL) {
405 lerr = ldap_result2error(ld, result, 0);
406 IDMAP_LOG(2, ("umich_name_to_ids: ldap_get_values: "
407 "%s (%d)\n", ldap_err2string(lerr), lerr));
408 goto out_memfree;
410 if (strcasecmp(attr_res, ldap_map.NFSv4_uid_attr) == 0) {
411 tmp_u = strtoul(*idstr, (char **)NULL, 10);
412 tmp_uid = tmp_u;
413 if (tmp_uid != tmp_u ||
414 (errno == ERANGE && tmp_u == ULONG_MAX)) {
415 IDMAP_LOG(0, ("ERROR: umich_name_to_ids: "
416 "uidNumber too long converting '%s'\n",
417 *idstr));
418 ldap_memfree(attr_res);
419 ldap_value_free(idstr);
420 goto out_memfree;
422 *uid = tmp_uid;
423 } else if (strcasecmp(attr_res, ldap_map.NFSv4_gid_attr) == 0) {
424 tmp_g = strtoul(*idstr, (char **)NULL, 10);
425 tmp_gid = tmp_g;
426 if (tmp_gid != tmp_g ||
427 (errno == ERANGE && tmp_g == ULONG_MAX)) {
428 IDMAP_LOG(0, ("ERROR: umich_name_to_ids: "
429 "gidNumber too long converting '%s'\n",
430 *idstr));
431 ldap_memfree(attr_res);
432 ldap_value_free(idstr);
433 goto out_memfree;
435 *gid = tmp_gid;
436 } else {
437 IDMAP_LOG(0, ("umich_name_to_ids: received attr "
438 "'%s' ???\n", attr_res));
439 ldap_memfree(attr_res);
440 ldap_value_free(idstr);
441 goto out_memfree;
443 ldap_memfree(attr_res);
444 ldap_value_free(idstr);
447 err = 0;
448 out_memfree:
449 ber_free(ber, 0);
450 out_unbind:
451 if (result)
452 ldap_msgfree(result);
453 ldap_unbind(ld);
454 out:
455 return err;
458 static int
459 umich_id_to_name(uid_t id, int idtype, char **name, size_t len,
460 struct umich_ldap_info *linfo)
462 LDAP *ld = NULL;
463 struct timeval timeout = {
464 .tv_sec = linfo->ldap_timeout,
466 LDAPMessage *result = NULL, *entry;
467 BerElement *ber;
468 char **names = NULL, filter[LDAP_FILT_MAXSIZ], *base;
469 char idstr[16];
470 char *attrs[2];
471 char *attr_res;
472 int count = 0, err, lerr, f_len;
473 int sizelimit = 1;
475 err = -EINVAL;
476 if (name == NULL || linfo == NULL || linfo->server == NULL ||
477 linfo->people_tree == NULL || linfo->group_tree == NULL)
478 goto out;
480 snprintf(idstr, sizeof(idstr), "%d", id);
483 if (idtype == IDTYPE_USER) {
484 if ((f_len = snprintf(filter, LDAP_FILT_MAXSIZ,
485 "(&(objectClass=%s)(%s=%s))",
486 ldap_map.NFSv4_person_objcls,
487 ldap_map.NFSv4_uid_attr, idstr))
488 == LDAP_FILT_MAXSIZ) {
489 IDMAP_LOG(0, ("ERROR: umich_id_to_name: "
490 "uid filter too long!\n"));
491 goto out;
493 base = linfo->people_tree;
494 } else if (idtype == IDTYPE_GROUP) {
495 if ((f_len = snprintf(filter, LDAP_FILT_MAXSIZ,
496 "(&(objectClass=%s)(%s=%s))",
497 ldap_map.NFSv4_group_objcls,
498 ldap_map.NFSv4_gid_attr,idstr))
499 == LDAP_FILT_MAXSIZ) {
500 IDMAP_LOG(0, ("ERROR: umich_id_to_name: "
501 "gid filter too long!\n"));
502 goto out;
504 base = linfo->group_tree;
505 } else {
506 IDMAP_LOG(0, ("ERROR: umich_id_to_name: invalid idtype (%d)\n",
507 idtype));
508 err = -EINVAL;
509 goto out;
512 if (ldap_init_and_bind(&ld, &sizelimit, linfo))
513 goto out;
515 if (idtype == IDTYPE_USER)
516 attrs[0] = ldap_map.NFSv4_nfsname_attr;
517 else
518 attrs[0] = ldap_map.NFSv4_group_nfsname_attr;
519 attrs[1] = NULL;
521 err = ldap_search_st(ld, base, LDAP_SCOPE_SUBTREE,
522 filter, (char **)attrs,
523 0, &timeout, &result);
524 if (err) {
525 char * errmsg;
527 IDMAP_LOG(2, ("umich_id_to_name: ldap_search_st for "
528 "base '%s, filter '%s': %s (%d)\n", base, filter,
529 ldap_err2string(err), err));
530 if ((ldap_get_option(ld, LDAP_OPT_ERROR_STRING, &errmsg) == LDAP_SUCCESS)
531 && (errmsg != NULL) && (*errmsg != '\0')) {
532 IDMAP_LOG(2, ("umich_id_to_name: "
533 "Additional info: %s\n", errmsg));
534 ldap_memfree(errmsg);
537 err = -ENOENT;
538 goto out_unbind;
541 err = -ENOENT;
542 count = ldap_count_entries(ld, result);
543 if (count != 1)
544 goto out_unbind;
546 if (!(entry = ldap_first_entry(ld, result))) {
547 lerr = ldap_result2error(ld, result, 0);
548 IDMAP_LOG(2, ("umich_id_to_name: ldap_first_entry: "
549 "%s (%d)\n", ldap_err2string(lerr), lerr));
550 goto out_unbind;
553 if (!(attr_res = ldap_first_attribute(ld, result, &ber))) {
554 lerr = ldap_result2error(ld, result, 0);
555 IDMAP_LOG(2, ("umich_id_to_name: ldap_first_attribute: "
556 "%s (%d)\n", ldap_err2string(lerr), lerr));
557 goto out_unbind;
560 if ((names = ldap_get_values(ld, result, attr_res)) == NULL) {
561 lerr = ldap_result2error(ld, result, 0);
562 IDMAP_LOG(2, ("umich_id_to_name: ldap_get_values: "
563 "%s (%d)\n", ldap_err2string(lerr), lerr));
564 goto out_memfree;
568 * Verify there is enough room in the output buffer before
569 * copying returned string. (strlen doesn't count the null,
570 * we make sure there is room for the null also, therefore
571 * we use ">=" not just ">")
573 if (strlen(names[0]) >= len) {
574 /* not enough space to return the name */
575 IDMAP_LOG(1, ("umich_id_to_name: output buffer size (%d) "
576 "too small to return string, '%s', of length %d\n",
577 len, names[0], strlen(names[0])));
578 goto out_memfree;
580 strcpy(*name, names[0]);
582 err = 0;
583 out_memfree:
584 if (names)
585 ldap_value_free(names);
586 ldap_memfree(attr_res);
587 ber_free(ber, 0);
588 out_unbind:
589 if (result)
590 ldap_msgfree(result);
591 ldap_unbind(ld);
592 out:
593 return err;
596 static int
597 umich_gss_princ_to_grouplist(char *principal, gid_t *groups, int *ngroups,
598 struct umich_ldap_info *linfo)
600 LDAP *ld = NULL;
601 struct timeval timeout = {
602 .tv_sec = linfo->ldap_timeout,
604 LDAPMessage *result, *entry;
605 char **names, filter[LDAP_FILT_MAXSIZ];
606 char *attrs[2];
607 int count = 0, err = -ENOMEM, lerr, f_len;
608 int i, num_gids;
609 gid_t *curr_group = groups;
611 err = -EINVAL;
612 if (linfo == NULL || linfo->server == NULL ||
613 linfo->people_tree == NULL || linfo->group_tree == NULL)
614 goto out;
617 if (ldap_init_and_bind(&ld, NULL, linfo))
618 goto out;
621 * First we need to map the gss principal name to a uid (name) string
623 err = -EINVAL;
624 if ((f_len = snprintf(filter, LDAP_FILT_MAXSIZ,
625 "(&(objectClass=%s)(%s=%s))",
626 ldap_map.NFSv4_person_objcls,
627 ldap_map.GSS_principal_attr, principal))
628 == LDAP_FILT_MAXSIZ) {
629 IDMAP_LOG(0, ("ERROR: umich_gss_princ_to_grouplist: "
630 "filter too long!\n"));
631 goto out;
634 attrs[0] = ldap_map.NFSv4_acctname_attr;
635 attrs[1] = NULL;
637 err = ldap_search_st(ld, linfo->people_tree, LDAP_SCOPE_SUBTREE,
638 filter, attrs, 0, &timeout, &result);
639 if (err) {
640 char *errmsg;
642 IDMAP_LOG(2, ("umich_gss_princ_to_grouplist: ldap_search_st "
643 "for tree '%s, filter '%s': %s (%d)\n",
644 linfo->people_tree, filter,
645 ldap_err2string(err), err));
646 if ((ldap_get_option(ld, LDAP_OPT_ERROR_STRING, &errmsg) == LDAP_SUCCESS)
647 && (errmsg != NULL) && (*errmsg != '\0')) {
648 IDMAP_LOG(2, ("umich_gss_princ_to_grouplist: "
649 "Additional info: %s\n", errmsg));
650 ldap_memfree(errmsg);
652 err = -ENOENT;
653 goto out_unbind;
656 err = -ENOENT;
657 count = ldap_count_entries(ld, result);
658 if (count != 1) {
659 IDMAP_LOG(2, ("umich_gss_princ_to_grouplist: "
660 "ldap account lookup of gssauthname %s returned %d accounts\n",
661 principal,count));
662 goto out_unbind;
665 if (!(entry = ldap_first_entry(ld, result))) {
666 lerr = ldap_result2error(ld, result, 0);
667 IDMAP_LOG(2, ("umich_gss_princ_to_grouplist: ldap_first_entry: "
668 "%s (%d)\n", ldap_err2string(lerr), lerr));
669 goto out_unbind;
672 if ((names = ldap_get_values(ld, result, attrs[0])) == NULL) {
673 lerr = ldap_result2error(ld, result, 0);
674 IDMAP_LOG(2, ("umich_gss_princ_to_grouplist: ldap_get_values: "
675 "%s (%d)\n", ldap_err2string(lerr), lerr));
676 goto out_unbind;
679 if (ldap_info.memberof_for_groups) {
682 * Collect the groups the user belongs to
684 if ((f_len = snprintf(filter, LDAP_FILT_MAXSIZ,
685 "(&(objectClass=%s)(%s=%s))",
686 ldap_map.NFSv4_person_objcls,
687 ldap_map.NFSv4_acctname_attr,
688 names[0])) == LDAP_FILT_MAXSIZ ) {
689 IDMAP_LOG(2, ("ERROR: umich_gss_princ_to_grouplist: "
690 "filter too long!\n"));
691 ldap_value_free(names);
692 goto out_unbind;
695 ldap_value_free(names);
697 attrs[0] = ldap_map.NFSv4_member_of_attr;
698 attrs[1] = NULL;
700 err = ldap_search_st(ld, linfo->people_tree, LDAP_SCOPE_SUBTREE,
701 filter, attrs, 0, &timeout, &result);
703 if (err) {
704 char *errmsg;
706 IDMAP_LOG(2, ("umich_gss_princ_to_grouplist: ldap_search_st "
707 "for tree '%s, filter '%s': %s (%d)\n",
708 linfo->people_tree, filter,
709 ldap_err2string(err), err));
710 if ((ldap_get_option(ld, LDAP_OPT_ERROR_STRING, &errmsg) == LDAP_SUCCESS)
711 && (errmsg != NULL) && (*errmsg != '\0')) {
712 IDMAP_LOG(2, ("umich_gss_princ_to_grouplist: "
713 "Additional info: %s\n", errmsg));
714 ldap_memfree(errmsg);
716 err = -ENOENT;
717 goto out_unbind;
719 err = -ENOENT;
721 /* pull the list of groups and place into names */
722 count = ldap_count_entries(ld, result);
723 if (count != 1) {
724 IDMAP_LOG(2, ("umich_gss_princ_to_grouplist: "
725 "ldap group member lookup of gssauthname %s returned %d multiple entries\n",
726 principal,count));
727 goto out_unbind;
730 if (!(entry = ldap_first_entry(ld, result))) {
731 lerr = ldap_result2error(ld, result, 0);
732 IDMAP_LOG(2, ("umich_gss_princ_to_grouplist: ldap_first_entry: "
733 "%s (%d)\n", ldap_err2string(lerr), lerr));
734 goto out_unbind;
737 if ((names = ldap_get_values(ld, result, attrs[0])) == NULL) {
738 lerr = ldap_result2error(ld, result, 0);
739 IDMAP_LOG(2, ("umich_gss_princ_to_grouplist: ldap_get_values: "
740 "%s (%d)\n", ldap_err2string(lerr), lerr));
741 goto out_unbind;
744 /* Count the groups first before doing a lookup of the group.
745 If it exceeds the desired number of groups set the needed value
746 and abort. */
747 for (i = 0; names[i] != NULL; i++);
748 if ( i > *ngroups ) {
749 ldap_value_free(names);
750 err = -EINVAL;
751 IDMAP_LOG(2, ("umich_gss_princ_to_grouplist: User %s, "
752 "number of groups %d, exceeds requested number %d\n",
753 principal, i, *ngroups));
754 *ngroups = i;
755 goto out_unbind;
758 /* Loop through the groupnames (names) and get the group gid */
759 num_gids = 0;
760 for (i = 0; names[i] != NULL; i++){
761 char **vals;
762 int valcount;
763 unsigned long tmp_g;
764 gid_t tmp_gid;
765 char *cnptr = NULL;
767 cnptr = strchr(names[i],',');
768 if (cnptr) *cnptr = '\0';
770 err = -ENOENT;
771 if (ldap_map.NFSv4_grouplist_filter)
772 f_len = snprintf(filter, LDAP_FILT_MAXSIZ,
773 "(&(objectClass=%s)(%s)%s)",
774 ldap_map.NFSv4_group_objcls,
775 names[i],
776 ldap_map.NFSv4_grouplist_filter);
777 else
778 f_len = snprintf(filter, LDAP_FILT_MAXSIZ,
779 "(&(objectClass=%s)(%s))",
780 ldap_map.NFSv4_group_objcls,
781 names[i]);
783 if ( f_len == LDAP_FILT_MAXSIZ ) {
784 IDMAP_LOG(2, ("ERROR: umich_gss_princ_to_grouplist: "
785 "filter too long!\n"));
786 ldap_value_free(names);
787 goto out_unbind;
789 attrs[0] = ldap_map.NFSv4_gid_attr;
790 attrs[1] = NULL;
792 err = ldap_search_st(ld, linfo->group_tree, LDAP_SCOPE_SUBTREE,
793 filter, attrs, 0, &timeout, &result);
794 if (err) {
795 char *errmsg;
797 IDMAP_LOG(2, ("umich_gss_princ_to_grouplist: ldap_search_st "
798 "for tree '%s, filter '%s': %s (%d)\n",
799 linfo->group_tree, filter,
800 ldap_err2string(err), err));
801 if ((ldap_get_option(ld, LDAP_OPT_ERROR_STRING, &errmsg)==LDAP_SUCCESS)
803 (errmsg != NULL) && (*errmsg != '\0')) {
804 IDMAP_LOG(2, ("umich_gss_princ_to_grouplist: "
805 "Additional info: %s\n", errmsg));
806 ldap_memfree(errmsg);
808 continue;
811 count = ldap_count_entries(ld, result);
812 if (count == 0)
813 continue;
814 if (count != 1 ){
815 IDMAP_LOG(2, ("umich_gss_princ_to_grouplist:"
816 "Group %s has %d gids defined - aborting", names[i], count));
817 ldap_value_free(names);
818 err = -ENOENT;
819 goto out_unbind;
822 vals = ldap_get_values(ld, result, ldap_map.NFSv4_gid_attr);
824 /* There should be only one gidNumber attribute per group */
825 if ((valcount = ldap_count_values(vals)) != 1) {
826 IDMAP_LOG(2, ("DB problem getting gidNumber of "
827 "posixGroup! (count was %d)\n", valcount));
828 ldap_value_free(vals);
829 continue;
832 tmp_g = strtoul(vals[0], (char **)NULL, 10);
833 tmp_gid = tmp_g;
834 if (tmp_gid != tmp_g ||
835 (errno == ERANGE && tmp_g == ULONG_MAX)) {
836 IDMAP_LOG(2, ("ERROR: umich_gss_princ_to_grouplist: "
837 "gidNumber too long converting '%s'\n",
838 vals[0]));
839 ldap_value_free(vals);
840 continue;
842 *curr_group++ = tmp_gid;
843 num_gids++;
844 ldap_value_free(vals);
846 ldap_value_free(names);
847 *ngroups = num_gids;
848 err = 0;
849 } else {
852 * Then determine the groups that uid (name) string is a member of
854 err = -EINVAL;
855 if (ldap_map.NFSv4_grouplist_filter)
856 f_len = snprintf(filter, LDAP_FILT_MAXSIZ,
857 "(&(objectClass=%s)(%s=%s)%s)",
858 ldap_map.NFSv4_group_objcls,
859 ldap_map.NFSv4_member_attr,
860 names[0],
861 ldap_map.NFSv4_grouplist_filter);
863 else
864 f_len = snprintf(filter, LDAP_FILT_MAXSIZ,
865 "(&(objectClass=%s)(%s=%s))",
866 ldap_map.NFSv4_group_objcls,
867 ldap_map.NFSv4_member_attr,
868 names[0]);
870 if ( f_len == LDAP_FILT_MAXSIZ ) {
871 IDMAP_LOG(0, ("ERROR: umich_gss_princ_to_grouplist: "
872 "filter too long!\n"));
873 ldap_value_free(names);
874 goto out_unbind;
877 ldap_value_free(names);
879 attrs[0] = ldap_map.NFSv4_gid_attr;
880 attrs[1] = NULL;
882 err = ldap_search_st(ld, linfo->group_tree, LDAP_SCOPE_SUBTREE,
883 filter, attrs, 0, &timeout, &result);
885 if (err) {
886 char *errmsg;
888 IDMAP_LOG(2, ("umich_gss_princ_to_grouplist: ldap_search_st "
889 "for tree '%s, filter '%s': %s (%d)\n",
890 linfo->group_tree, filter,
891 ldap_err2string(err), err));
892 if ((ldap_get_option(ld, LDAP_OPT_ERROR_STRING, &errmsg) == LDAP_SUCCESS) &&
893 (errmsg != NULL) && (*errmsg != '\0')) {
894 IDMAP_LOG(2, ("umich_gss_princ_to_grouplist: "
895 "Additional info: %s\n", errmsg));
896 ldap_memfree(errmsg);
898 err = -ENOENT;
899 goto out_unbind;
903 * If we can't determine count, return that error
904 * If we have nothing to return, return success
905 * If we have more than they asked for, tell them the
906 * number required and return an error
908 count = ldap_count_entries(ld, result);
910 if (count < 0) {
911 err = count;
912 goto out_unbind;
914 if (count == 0) {
915 *ngroups = 0;
916 err = 0;
917 goto out_unbind;
919 if (count > *ngroups) {
920 *ngroups = count;
921 err = -EINVAL;
922 goto out_unbind;
924 *ngroups = count;
926 curr_group = groups;
928 err = -ENOENT;
929 for (entry = ldap_first_entry(ld, result);
930 entry != NULL;
931 entry = ldap_next_entry(ld, entry)) {
933 char **vals;
934 int valcount;
935 unsigned long tmp_g;
936 gid_t tmp_gid;
938 vals = ldap_get_values(ld, entry, ldap_map.NFSv4_gid_attr);
940 /* There should be only one gidNumber attribute per group */
941 if ((valcount = ldap_count_values(vals)) != 1) {
942 IDMAP_LOG(0, ("DB problem getting gidNumber of "
943 "posixGroup! (count was %d)\n", valcount));
944 goto out_unbind;
946 tmp_g = strtoul(vals[0], (char **)NULL, 10);
947 tmp_gid = tmp_g;
948 if (tmp_gid != tmp_g ||
949 (errno == ERANGE && tmp_g == ULONG_MAX)) {
950 IDMAP_LOG(0, ("ERROR: umich_gss_princ_to_grouplist: "
951 "gidNumber too long converting '%s'\n",
952 vals[0]));
953 ldap_value_free(vals);
954 goto out_unbind;
956 *curr_group++ = tmp_gid;
957 ldap_value_free(vals);
959 err = 0;
962 out_unbind:
963 ldap_unbind(ld);
964 out:
965 return err;
970 * principal: krb5 - princ@realm, use KrbName ldap attribute
971 * spkm3 - X.509 dn, use X509Name ldap attribute
973 static int
974 umichldap_gss_princ_to_ids(char *secname, char *principal,
975 uid_t *uid, gid_t *gid, extra_mapping_params **ex)
977 uid_t rtnd_uid = -1;
978 gid_t rtnd_gid = -1;
979 int err = -EINVAL;
981 if ((strcmp(secname, "krb5") != 0) && (strcmp(secname, "spkm3") != 0)) {
982 IDMAP_LOG(0, ("ERROR: umichldap_gss_princ_to_ids: "
983 "invalid secname '%s'\n", secname));
984 return err;
987 err = umich_name_to_ids(principal, IDTYPE_USER, &rtnd_uid, &rtnd_gid,
988 ldap_map.GSS_principal_attr, &ldap_info);
989 if (err < 0)
990 goto out;
992 *uid = rtnd_uid;
993 *gid = rtnd_gid;
994 out:
995 return err;
998 static int
999 umichldap_name_to_uid(char *name, uid_t *uid)
1001 gid_t gid;
1003 return umich_name_to_ids(name, IDTYPE_USER, uid,
1004 &gid, ldap_map.NFSv4_nfsname_attr, &ldap_info);
1007 static int
1008 umichldap_name_to_gid(char *name, gid_t *gid)
1010 uid_t uid;
1012 return umich_name_to_ids(name, IDTYPE_GROUP, &uid, gid,
1013 ldap_map.NFSv4_group_nfsname_attr, &ldap_info);
1016 static int
1017 umichldap_uid_to_name(uid_t uid, char *domain, char *name, size_t len)
1019 return umich_id_to_name(uid, IDTYPE_USER, &name, len, &ldap_info);
1022 static int
1023 umichldap_gid_to_name(gid_t gid, char *domain, char *name, size_t len)
1025 return umich_id_to_name(gid, IDTYPE_GROUP, &name, len, &ldap_info);
1028 static int
1029 umichldap_gss_princ_to_grouplist(char *secname, char *principal,
1030 gid_t *groups, int *ngroups, extra_mapping_params **ex)
1032 int err = -EINVAL;
1034 if ((strcmp(secname, "krb5") != 0) && (strcmp(secname, "spkm3") != 0)) {
1035 IDMAP_LOG(0, ("ERROR: umichldap_gss_princ_to_grouplist: "
1036 "invalid secname '%s'\n", secname));
1037 return err;
1040 return umich_gss_princ_to_grouplist(principal, groups, ngroups,
1041 &ldap_info);
1045 * TLS connections require that the hostname we specify matches
1046 * the hostname in the certificate that the server uses.
1047 * Get a canonical name for the host specified in the config file.
1049 static char *
1050 get_canonical_hostname(const char *inname)
1052 int aierr, error;
1053 struct addrinfo *ap, aihints;
1054 char *return_name = NULL;
1055 char tmphost[NI_MAXHOST];
1057 memset(&aihints, 0, sizeof(aihints));
1058 aihints.ai_socktype = SOCK_STREAM;
1059 aihints.ai_flags = AI_CANONNAME;
1060 aihints.ai_family = PF_INET;
1061 aierr = getaddrinfo(inname, NULL, &aihints, &ap);
1062 if (aierr) {
1063 const char *msg;
1064 /* We want to customize some messages. */
1065 switch (aierr) {
1066 case EAI_NONAME:
1067 msg = "host unknown";
1068 break;
1069 default:
1070 msg = gai_strerror(aierr);
1071 break;
1073 IDMAP_LOG(1, ("%s: '%s': %s\n", __FUNCTION__, inname, msg));
1074 goto out_err;
1076 if (ap == 0) {
1077 IDMAP_LOG(1, ("%s: no addresses for host '%s'?\n",
1078 __FUNCTION__, inname));
1079 goto out_err;
1082 error = getnameinfo (ap->ai_addr, ap->ai_addrlen, tmphost,
1083 sizeof(tmphost), NULL, 0, 0);
1084 if (error) {
1085 IDMAP_LOG(1, ("%s: getnameinfo for host '%s' failed (%d)\n",
1086 __FUNCTION__, inname));
1087 goto out_err;
1089 return_name = strdup (tmphost);
1091 out_free:
1092 freeaddrinfo(ap);
1093 out_err:
1094 return return_name;
1097 static int
1098 umichldap_init(void)
1100 char *tssl, *canonicalize, *memberof;
1101 int missing_server = 0, missing_base = 0;
1102 char missing_msg[128] = "";
1103 char *server_in, *canon_name;
1105 server_in = conf_get_str(LDAP_SECTION, "LDAP_server");
1106 ldap_info.base = conf_get_str(LDAP_SECTION, "LDAP_base");
1107 ldap_info.people_tree = conf_get_str(LDAP_SECTION, "LDAP_people_base");
1108 ldap_info.group_tree = conf_get_str(LDAP_SECTION, "LDAP_group_base");
1109 ldap_info.user_dn = conf_get_str(LDAP_SECTION, "LDAP_user_dn");
1110 ldap_info.passwd = conf_get_str(LDAP_SECTION, "LDAP_passwd");
1111 tssl = conf_get_str_with_def(LDAP_SECTION, "LDAP_use_ssl", "false");
1112 if ((strcasecmp(tssl, "true") == 0) ||
1113 (strcasecmp(tssl, "on") == 0) ||
1114 (strcasecmp(tssl, "yes") == 0))
1115 ldap_info.use_ssl = 1;
1116 else
1117 ldap_info.use_ssl = 0;
1118 ldap_info.ca_cert = conf_get_str(LDAP_SECTION, "LDAP_CA_CERT");
1119 /* vary the default port depending on whether they use SSL or not */
1120 ldap_info.port = conf_get_num(LDAP_SECTION, "LDAP_port",
1121 (ldap_info.use_ssl) ?
1122 LDAPS_PORT : LDAP_PORT);
1124 /* Verify required information is supplied */
1125 if (server_in == NULL || strlen(server_in) == 0)
1126 strncat(missing_msg, "LDAP_server ", sizeof(missing_msg));
1127 if (ldap_info.base == NULL || strlen(ldap_info.base) == 0)
1128 strncat(missing_msg, "LDAP_base ", sizeof(missing_msg));
1129 if (strlen(missing_msg) != 0) {
1130 IDMAP_LOG(0, ("umichldap_init: Missing required information: "
1131 "%s\n", missing_msg));
1132 goto fail;
1135 ldap_info.server = server_in;
1136 canonicalize = conf_get_str_with_def(LDAP_SECTION, "LDAP_canonicalize_name", "yes");
1137 if ((strcasecmp(canonicalize, "true") == 0) ||
1138 (strcasecmp(canonicalize, "on") == 0) ||
1139 (strcasecmp(canonicalize, "yes") == 0)) {
1140 canon_name = get_canonical_hostname(server_in);
1141 if (canon_name == NULL)
1142 IDMAP_LOG(0, ("umichldap_init: Warning! Unable to "
1143 "canonicalize server name '%s' as requested.\n",
1144 server_in));
1145 else
1146 ldap_info.server = canon_name;
1149 /* get the ldap mapping attributes/objectclasses (all have defaults) */
1150 ldap_map.NFSv4_person_objcls =
1151 conf_get_str_with_def(LDAP_SECTION, "NFSv4_person_objectclass",
1152 DEFAULT_UMICH_OBJCLASS_REMOTE_PERSON);
1154 ldap_map.NFSv4_group_objcls =
1155 conf_get_str_with_def(LDAP_SECTION, "NFSv4_group_objectclass",
1156 DEFAULT_UMICH_OBJCLASS_REMOTE_GROUP);
1158 ldap_map.NFSv4_nfsname_attr =
1159 conf_get_str_with_def(LDAP_SECTION, "NFSv4_name_attr",
1160 DEFAULT_UMICH_ATTR_NFSNAME);
1162 ldap_map.NFSv4_uid_attr =
1163 conf_get_str_with_def(LDAP_SECTION, "NFSv4_uid_attr",
1164 DEFAULT_UMICH_ATTR_UIDNUMBER);
1166 ldap_map.NFSv4_acctname_attr =
1167 conf_get_str_with_def(LDAP_SECTION, "NFSv4_acctname_attr",
1168 DEFAULT_UMICH_ATTR_ACCTNAME);
1170 ldap_map.NFSv4_group_nfsname_attr =
1171 conf_get_str_with_def(LDAP_SECTION, "NFSv4_group_attr",
1172 DEFAULT_UMICH_ATTR_GROUP_NFSNAME);
1174 ldap_map.NFSv4_gid_attr =
1175 conf_get_str_with_def(LDAP_SECTION, "NFSv4_gid_attr",
1176 DEFAULT_UMICH_ATTR_GIDNUMBER);
1178 ldap_map.NFSv4_member_attr =
1179 conf_get_str_with_def(LDAP_SECTION, "NFSv4_member_attr",
1180 DEFAULT_UMICH_ATTR_MEMBERUID);
1182 ldap_map.GSS_principal_attr =
1183 conf_get_str_with_def(LDAP_SECTION, "GSS_principal_attr",
1184 DEFAULT_UMICH_ATTR_GSSAUTHNAME);
1186 ldap_map.NFSv4_grouplist_filter =
1187 conf_get_str_with_def(LDAP_SECTION, "NFSv4_grouplist_filter",
1188 NULL);
1190 ldap_map.NFSv4_member_of_attr =
1191 conf_get_str_with_def(LDAP_SECTION, "NFSv4_member_of_attr",
1192 DEFAULT_UMICH_ATTR_MEMBEROF);
1194 ldap_info.ldap_timeout =
1195 conf_get_num(LDAP_SECTION, "LDAP_timeout_seconds",
1196 DEFAULT_UMICH_SEARCH_TIMEOUT);
1200 * Some LDAP servers do a better job with indexing where searching
1201 * through all the groups searching for the user in the memberuid
1202 * list. Others like SunOne directory that search can takes minutes
1203 * if there are thousands of groups. So setting
1204 * LDAP_use_memberof_for_groups to true in the configuration file
1205 * will use the memberof lists of the account and search through
1206 * only those groups to obtain gids.
1208 memberof = conf_get_str_with_def(LDAP_SECTION,
1209 "LDAP_use_memberof_for_groups", "false");
1210 if ((strcasecmp(memberof, "true") == 0) ||
1211 (strcasecmp(memberof, "on") == 0) ||
1212 (strcasecmp(memberof, "yes") == 0))
1213 ldap_info.memberof_for_groups = 1;
1214 else
1215 ldap_info.memberof_for_groups = 0;
1218 * If they specified a search base for the
1219 * people tree or group tree we use that.
1220 * Otherwise we use the default search base.
1221 * Note: We no longer append the default base to the tree --
1222 * that should already be specified.
1223 * this functions much like the NSS_LDAP modules
1225 if (ldap_info.people_tree == NULL || strlen(ldap_info.people_tree) == 0)
1226 ldap_info.people_tree = ldap_info.base;
1227 if (ldap_info.group_tree == NULL || strlen(ldap_info.group_tree) == 0)
1228 ldap_info.group_tree = ldap_info.base;
1230 if (ldap_info.use_ssl && ldap_info.ca_cert == NULL) {
1231 IDMAP_LOG(0, ("umichldap_init: You must specify LDAP_ca_cert "
1232 "with LDAP_use_ssl=yes\n"));
1233 goto fail;
1237 /* print out some good debugging info */
1238 IDMAP_LOG(1, ("umichldap_init: canonicalize_name: %s\n",
1239 canonicalize));
1240 IDMAP_LOG(1, ("umichldap_init: server : %s (from config value '%s')\n",
1241 ldap_info.server, server_in));
1242 IDMAP_LOG(1, ("umichldap_init: port : %d\n", ldap_info.port));
1243 IDMAP_LOG(1, ("umichldap_init: people : %s\n", ldap_info.people_tree));
1244 IDMAP_LOG(1, ("umichldap_init: groups : %s\n", ldap_info.group_tree));
1246 IDMAP_LOG(1, ("umichldap_init: user_dn : %s\n",
1247 (ldap_info.user_dn && strlen(ldap_info.user_dn) != 0)
1248 ? ldap_info.user_dn : "<not-supplied>"));
1249 /* Don't print actual password into the log. */
1250 IDMAP_LOG(1, ("umichldap_init: passwd : %s\n",
1251 (ldap_info.passwd && strlen(ldap_info.passwd) != 0) ?
1252 "<supplied>" : "<not-supplied>"));
1253 IDMAP_LOG(1, ("umichldap_init: use_ssl : %s\n",
1254 ldap_info.use_ssl ? "yes" : "no"));
1255 IDMAP_LOG(1, ("umichldap_init: ca_cert : %s\n",
1256 ldap_info.ca_cert ? ldap_info.ca_cert : "<not-supplied>"));
1257 IDMAP_LOG(1, ("umichldap_init: use_memberof_for_groups : %s\n",
1258 ldap_info.memberof_for_groups ? "yes" : "no"));
1260 IDMAP_LOG(1, ("umichldap_init: NFSv4_person_objectclass : %s\n",
1261 ldap_map.NFSv4_person_objcls));
1262 IDMAP_LOG(1, ("umichldap_init: NFSv4_nfsname_attr : %s\n",
1263 ldap_map.NFSv4_nfsname_attr));
1264 IDMAP_LOG(1, ("umichldap_init: NFSv4_acctname_attr : %s\n",
1265 ldap_map.NFSv4_acctname_attr));
1266 IDMAP_LOG(1, ("umichldap_init: NFSv4_uid_attr : %s\n",
1267 ldap_map.NFSv4_uid_attr));
1268 IDMAP_LOG(1, ("umichldap_init: NFSv4_group_objectclass : %s\n",
1269 ldap_map.NFSv4_group_objcls));
1270 IDMAP_LOG(1, ("umichldap_init: NFSv4_gid_attr : %s\n",
1271 ldap_map.NFSv4_gid_attr));
1272 IDMAP_LOG(1, ("umichldap_init: NFSv4_group_nfsname_attr : %s\n",
1273 ldap_map.NFSv4_group_nfsname_attr));
1274 IDMAP_LOG(1, ("umichldap_init: NFSv4_member_attr : %s\n",
1275 ldap_map.NFSv4_member_attr));
1276 IDMAP_LOG(1, ("umichldap_init: NFSv4_member_of_attr : %s\n",
1277 ldap_map.NFSv4_member_of_attr));
1278 IDMAP_LOG(1, ("umichldap_init: NFSv4_grouplist_filter : %s\n",
1279 ldap_map.NFSv4_grouplist_filter ?
1280 ldap_map.NFSv4_grouplist_filter : "<not-specified>"));
1281 IDMAP_LOG(1, ("umichldap_init: GSS_principal_attr : %s\n",
1282 ldap_map.GSS_principal_attr));
1283 return 0;
1284 fail:
1285 return -1;
1289 /* The external interface */
1291 struct trans_func umichldap_trans = {
1292 .name = "umich_ldap",
1293 .init = umichldap_init,
1294 .princ_to_ids = umichldap_gss_princ_to_ids,
1295 .name_to_uid = umichldap_name_to_uid,
1296 .name_to_gid = umichldap_name_to_gid,
1297 .uid_to_name = umichldap_uid_to_name,
1298 .gid_to_name = umichldap_gid_to_name,
1299 .gss_princ_to_grouplist = umichldap_gss_princ_to_grouplist,
1302 struct trans_func *libnfsidmap_plugin_init()
1304 return (&umichldap_trans);
1306 #endif