1
/* Copyright (C) 2005 Luke Howard.
2
This file is part of the nss_ldap library.
3
Contributed by Luke Howard, <lukeh@padl.com>, 2005.
5
The nss_ldap library is free software; you can redistribute it and/or
6
modify it under the terms of the GNU Library General Public License as
7
published by the Free Software Foundation; either version 2 of the
8
License, or (at your option) any later version.
10
The nss_ldap library is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
Library General Public License for more details.
15
You should have received a copy of the GNU Library General Public
16
License along with the nss_ldap library; see the file COPYING.LIB. If not,
17
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
Boston, MA 02111-1307, USA.
20
$Id: ldap-automount.c,v 2.9 2006/01/13 16:15:33 lukeh Exp $
24
static char rcsId[] = "$Id: ldap-automount.c,v 2.9 2006/01/13 16:15:33 lukeh Exp $";
28
#ifdef HAVE_PORT_BEFORE_H
29
#include <port_before.h>
32
#if defined(HAVE_THREAD_H) && !defined(_AIX)
34
#elif defined(HAVE_PTHREAD_H)
43
#include <sys/types.h>
44
#include <sys/socket.h>
45
#include <netinet/in.h>
55
#include "ldap-automount.h"
58
#ifdef HAVE_PORT_AFTER_H
59
#include <port_after.h>
63
_nss_ldap_parse_automount (LDAPMessage * e,
65
void *result, char *buffer, size_t buflen)
68
char ***keyval = result;
71
_nss_ldap_assign_attrval (e, AT (automountKey), keyval[0],
73
if (stat != NSS_SUCCESS)
77
_nss_ldap_assign_attrval (e, AT (automountInformation), keyval[1],
79
if (stat != NSS_SUCCESS)
86
_nss_ldap_am_context_alloc(ldap_automount_context_t **pContext)
88
ldap_automount_context_t *context;
90
context = (ldap_automount_context_t *)malloc (sizeof(*context));
96
context->lac_state = NULL;
98
context->lac_dn_size = 1; /* number of slots allocated */
99
context->lac_dn_count = 0; /* number of slots used */
100
context->lac_dn_index = 0; /* enumeration index */
102
/* List of DNs, grown on demand */
103
context->lac_dn_list = (char **)malloc (context->lac_dn_size *
105
if (context->lac_dn_list == NULL)
111
if (_nss_ldap_ent_context_init_locked (&context->lac_state) == NULL)
113
free (context->lac_dn_list);
124
_nss_ldap_am_context_free(ldap_automount_context_t **pContext)
126
ldap_automount_context_t *context;
134
if (context->lac_dn_list != NULL)
136
for (i = 0; i < context->lac_dn_count; i++)
138
#ifdef HAVE_LDAP_MEMFREE
139
ldap_memfree (context->lac_dn_list[i]);
141
free (context->lac_dn_list[i]);
142
#endif /* HAVE_LDAP_MEMFREE */
144
free (context->lac_dn_list);
147
if (context->lac_state != NULL)
149
_nss_ldap_ent_context_release (context->lac_state);
150
free (context->lac_state);
153
memset (context, 0, sizeof (*context));
162
am_context_add_dn (LDAPMessage * e,
164
void *result, char *buffer, size_t buflen)
166
ldap_automount_context_t *context = (ldap_automount_context_t *) result;
169
dn = _nss_ldap_get_dn (e);
175
if (context->lac_dn_count >= context->lac_dn_size)
179
new_dns = (char **)realloc(context->lac_dn_list,
180
2 * context->lac_dn_size * sizeof(char *));
183
#ifdef HAVE_LDAP_MEMFREE
187
#endif /* HAVE_LDAP_MEMFREE */
191
context->lac_dn_list = new_dns;
192
context->lac_dn_size *= 2;
195
context->lac_dn_list[context->lac_dn_count++] = dn;
201
_nss_ldap_am_context_init(const char *mapname, ldap_automount_context_t **pContext)
204
ldap_automount_context_t *context = NULL;
205
const char *no_attrs[] = { NULL };
207
ent_context_t *key = NULL;
212
stat = _nss_ldap_am_context_alloc (&context);
213
if (stat != NSS_SUCCESS)
217
LA_TYPE (a) = LA_TYPE_STRING;
218
LA_STRING (a) = mapname;
222
stat = _nss_ldap_getent_ex (&a, &key,
225
_nss_ldap_filt_setautomntent,
230
while (stat == NSS_SUCCESS);
234
_nss_ldap_ent_context_release (key);
238
if (context->lac_dn_count == 0)
240
_nss_ldap_am_context_free (&context);
243
else if (stat == NSS_NOTFOUND)
248
context->lac_dn_index = 0;
255
NSS_STATUS _nss_ldap_setautomntent(const char *mapname, void **private)
257
ldap_automount_context_t *context = NULL;
260
debug ("==> _nss_ldap_setautomntent");
264
stat = _nss_ldap_init ();
265
if (stat != NSS_SUCCESS)
268
debug ("<== _nss_ldap_setautomntent");
272
stat = _nss_ldap_am_context_init (mapname, &context);
273
if (stat != NSS_SUCCESS)
276
debug ("<== _nss_ldap_setautomntent");
280
*private = (void *)context;
283
debug ("<== _nss_ldap_setautomntent");
288
NSS_STATUS _nss_ldap_getautomntent_r(void *private, const char **key, const char **value,
289
char *buffer, size_t buflen, int *errnop)
292
ldap_automount_context_t *context = (ldap_automount_context_t *)private;
299
debug ("==> _nss_ldap_getautomntent_r");
301
keyval[0] = (char **)key;
302
keyval[1] = (char **)value;
308
assert (context->lac_dn_index < context->lac_dn_count);
311
LA_TYPE (a) = LA_TYPE_NONE;
312
LA_BASE (a) = context->lac_dn_list[context->lac_dn_index];
314
stat = _nss_ldap_getent_ex (&a, &context->lac_state,
316
buffer, buflen, errnop,
317
_nss_ldap_filt_getautomntent,
320
_nss_ldap_parse_automount);
321
if (stat == NSS_NOTFOUND)
323
if (context->lac_dn_index < context->lac_dn_count - 1)
324
context->lac_dn_index++;
326
break; /* move along, nothing more to see here */
329
while (stat == NSS_NOTFOUND);
333
debug ("<== _nss_ldap_getautomntent_r");
338
NSS_STATUS _nss_ldap_endautomntent(void **private)
340
ldap_automount_context_t **pContext = (ldap_automount_context_t **)private;
342
debug ("==> _nss_ldap_endautomntent");
345
_nss_ldap_am_context_free (pContext);
346
/* workaround because Linux automounter spawns a lot of processes */
350
debug ("<== _nss_ldap_endautomntent");
355
NSS_STATUS _nss_ldap_getautomntbyname_r(void *private, const char *key,
356
const char **canon_key, const char **value,
357
char *buffer, size_t buflen, int *errnop)
359
NSS_STATUS stat = NSS_NOTFOUND;
360
ldap_automount_context_t *context = (ldap_automount_context_t *)private;
368
debug ("==> _nss_ldap_getautomntbyname_r");
370
keyval[0] = (char **)canon_key;
371
keyval[1] = (char **)value;
373
for (i = 0; i < context->lac_dn_count; i++)
376
LA_TYPE (a) = LA_TYPE_STRING;
378
LA_BASE (a) = context->lac_dn_list[i];
380
/* we do not acquire lock in this case */
381
stat = _nss_ldap_getbyname (&a,
383
buffer, buflen, errnop,
384
_nss_ldap_filt_getautomntbyname,
386
_nss_ldap_parse_automount);
388
if (stat != NSS_NOTFOUND)
390
break; /* on success or error other than not found */
394
debug ("<== _nss_ldap_getautomntbyname_r");
399
#endif /* HAVE_NSS_H */