~ubuntu-branches/ubuntu/trusty/libnss-ldap/trusty-proposed

« back to all changes in this revision

Viewing changes to ldap-automount.c

  • Committer: Bazaar Package Importer
  • Author(s): Richard A Nelson (Rick)
  • Date: 2007-05-14 19:40:00 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070514194000-40u9ndh540lgliqe
Tags: 255-1
Survived i386 and amd64, let it loose

Show diffs side-by-side

added added

removed removed

Lines of Context:
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.
4
 
 
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.
9
 
 
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.
14
 
 
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.
19
 
 
20
 
   $Id: ldap-automount.c,v 2.9 2006/01/13 16:15:33 lukeh Exp $
21
 
 */
22
 
 
23
 
 
24
 
static char rcsId[] = "$Id: ldap-automount.c,v 2.9 2006/01/13 16:15:33 lukeh Exp $";
25
 
 
26
 
#include "config.h"
27
 
 
28
 
#ifdef HAVE_PORT_BEFORE_H
29
 
#include <port_before.h>
30
 
#endif
31
 
 
32
 
#if defined(HAVE_THREAD_H) && !defined(_AIX)
33
 
#include <thread.h>
34
 
#elif defined(HAVE_PTHREAD_H)
35
 
#include <pthread.h>
36
 
#endif
37
 
 
38
 
#include <stdio.h>
39
 
#include <stdlib.h>
40
 
#include <string.h>
41
 
#include <assert.h>
42
 
#include <netdb.h>
43
 
#include <sys/types.h>
44
 
#include <sys/socket.h>
45
 
#include <netinet/in.h>
46
 
 
47
 
#ifdef HAVE_LBER_H
48
 
#include <lber.h>
49
 
#endif
50
 
#ifdef HAVE_LDAP_H
51
 
#include <ldap.h>
52
 
#endif
53
 
 
54
 
#include "ldap-nss.h"
55
 
#include "ldap-automount.h"
56
 
#include "util.h"
57
 
 
58
 
#ifdef HAVE_PORT_AFTER_H
59
 
#include <port_after.h>
60
 
#endif
61
 
 
62
 
static NSS_STATUS
63
 
_nss_ldap_parse_automount (LDAPMessage * e,
64
 
                           ldap_state_t * pvt,
65
 
                           void *result, char *buffer, size_t buflen)
66
 
{
67
 
  NSS_STATUS stat;
68
 
  char ***keyval = result;
69
 
 
70
 
  stat = 
71
 
    _nss_ldap_assign_attrval (e, AT (automountKey), keyval[0],
72
 
                              &buffer, &buflen);
73
 
  if (stat != NSS_SUCCESS)
74
 
    return stat;
75
 
 
76
 
  stat = 
77
 
    _nss_ldap_assign_attrval (e, AT (automountInformation), keyval[1],
78
 
                              &buffer, &buflen);
79
 
  if (stat != NSS_SUCCESS)
80
 
    return stat;
81
 
 
82
 
  return NSS_SUCCESS;
83
 
}
84
 
 
85
 
NSS_STATUS
86
 
_nss_ldap_am_context_alloc(ldap_automount_context_t **pContext)
87
 
{
88
 
  ldap_automount_context_t *context;
89
 
 
90
 
  context = (ldap_automount_context_t *)malloc (sizeof(*context));
91
 
  if (context == NULL)
92
 
    {
93
 
      return NSS_TRYAGAIN;
94
 
    }
95
 
 
96
 
  context->lac_state = NULL;
97
 
 
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 */
101
 
 
102
 
  /* List of DNs, grown on demand */
103
 
  context->lac_dn_list = (char **)malloc (context->lac_dn_size *
104
 
                                          sizeof(char *));
105
 
  if (context->lac_dn_list == NULL)
106
 
    {
107
 
      free (context);
108
 
      return NSS_TRYAGAIN;
109
 
    }
110
 
 
111
 
  if (_nss_ldap_ent_context_init_locked (&context->lac_state) == NULL)
112
 
    {
113
 
      free (context->lac_dn_list);
114
 
      free (context);
115
 
      return NSS_UNAVAIL;
116
 
    }
117
 
 
118
 
  *pContext = context;
119
 
 
120
 
  return NSS_SUCCESS;
121
 
}
122
 
 
123
 
void
124
 
_nss_ldap_am_context_free(ldap_automount_context_t **pContext)
125
 
{
126
 
  ldap_automount_context_t *context;
127
 
  size_t i;
128
 
 
129
 
  context = *pContext;
130
 
 
131
 
  if (context == NULL)
132
 
    return;
133
 
 
134
 
  if (context->lac_dn_list != NULL)
135
 
    {
136
 
      for (i = 0; i < context->lac_dn_count; i++)
137
 
        {
138
 
#ifdef HAVE_LDAP_MEMFREE
139
 
          ldap_memfree (context->lac_dn_list[i]);
140
 
#else
141
 
          free (context->lac_dn_list[i]);
142
 
#endif /* HAVE_LDAP_MEMFREE */
143
 
        }
144
 
      free (context->lac_dn_list);
145
 
    }
146
 
 
147
 
  if (context->lac_state != NULL)
148
 
    {
149
 
      _nss_ldap_ent_context_release (context->lac_state);
150
 
      free (context->lac_state);
151
 
    }
152
 
 
153
 
  memset (context, 0, sizeof (*context));
154
 
  free (context);
155
 
 
156
 
  *pContext = NULL;
157
 
 
158
 
  return;
159
 
}
160
 
 
161
 
static NSS_STATUS
162
 
am_context_add_dn (LDAPMessage * e,
163
 
                   ldap_state_t * pvt,
164
 
                   void *result, char *buffer, size_t buflen)
165
 
{
166
 
  ldap_automount_context_t *context = (ldap_automount_context_t *) result;
167
 
  char *dn;
168
 
 
169
 
  dn = _nss_ldap_get_dn (e);
170
 
  if (dn == NULL)
171
 
    {
172
 
      return NSS_NOTFOUND;
173
 
    }
174
 
 
175
 
  if (context->lac_dn_count >= context->lac_dn_size)
176
 
    {
177
 
      char **new_dns;
178
 
 
179
 
      new_dns = (char **)realloc(context->lac_dn_list,
180
 
                                 2 * context->lac_dn_size * sizeof(char *));
181
 
      if (new_dns == NULL)
182
 
        {
183
 
#ifdef HAVE_LDAP_MEMFREE
184
 
          ldap_memfree (dn);
185
 
#else
186
 
          free (dn);
187
 
#endif /* HAVE_LDAP_MEMFREE */
188
 
          return NSS_TRYAGAIN;
189
 
        }
190
 
 
191
 
      context->lac_dn_list = new_dns;
192
 
      context->lac_dn_size *= 2;
193
 
    }
194
 
 
195
 
  context->lac_dn_list[context->lac_dn_count++] = dn;
196
 
 
197
 
  return NSS_SUCCESS;
198
 
}
199
 
 
200
 
NSS_STATUS
201
 
_nss_ldap_am_context_init(const char *mapname, ldap_automount_context_t **pContext)
202
 
{
203
 
  NSS_STATUS stat;
204
 
  ldap_automount_context_t *context = NULL;
205
 
  const char *no_attrs[] = { NULL };
206
 
  ldap_args_t a;
207
 
  ent_context_t *key = NULL;
208
 
  int errnop;
209
 
 
210
 
  *pContext = NULL;
211
 
 
212
 
  stat = _nss_ldap_am_context_alloc (&context);
213
 
  if (stat != NSS_SUCCESS)
214
 
      return stat;
215
 
 
216
 
  LA_INIT (a);
217
 
  LA_TYPE (a) = LA_TYPE_STRING;
218
 
  LA_STRING (a) = mapname;
219
 
 
220
 
  do
221
 
    {
222
 
      stat = _nss_ldap_getent_ex (&a, &key,
223
 
                                  (void *)context,
224
 
                                  NULL, 0, &errnop,
225
 
                                  _nss_ldap_filt_setautomntent,
226
 
                                  LM_AUTOMOUNT,
227
 
                                  no_attrs,
228
 
                                  am_context_add_dn);
229
 
    }
230
 
  while (stat == NSS_SUCCESS);
231
 
 
232
 
  if (key != NULL)
233
 
    {
234
 
      _nss_ldap_ent_context_release (key);
235
 
      free (key);
236
 
    }
237
 
 
238
 
  if (context->lac_dn_count == 0)
239
 
    {
240
 
      _nss_ldap_am_context_free (&context);
241
 
      return NSS_NOTFOUND;
242
 
    }
243
 
  else if (stat == NSS_NOTFOUND)
244
 
    {
245
 
      stat = NSS_SUCCESS;
246
 
    }
247
 
 
248
 
  context->lac_dn_index = 0;
249
 
 
250
 
  *pContext = context;
251
 
  return NSS_SUCCESS;
252
 
}
253
 
 
254
 
#ifdef HAVE_NSS_H
255
 
NSS_STATUS _nss_ldap_setautomntent(const char *mapname, void **private)
256
 
{
257
 
  ldap_automount_context_t *context = NULL;
258
 
  NSS_STATUS stat;
259
 
 
260
 
  debug ("==> _nss_ldap_setautomntent");
261
 
 
262
 
  _nss_ldap_enter ();
263
 
 
264
 
  stat = _nss_ldap_init ();
265
 
  if (stat != NSS_SUCCESS)
266
 
    {
267
 
      _nss_ldap_leave ();
268
 
      debug ("<== _nss_ldap_setautomntent");
269
 
      return stat;
270
 
    }
271
 
 
272
 
  stat = _nss_ldap_am_context_init (mapname, &context);
273
 
  if (stat != NSS_SUCCESS)
274
 
    {
275
 
      _nss_ldap_leave ();
276
 
      debug ("<== _nss_ldap_setautomntent");
277
 
      return stat;
278
 
    }
279
 
 
280
 
  *private = (void *)context;
281
 
  _nss_ldap_leave ();
282
 
 
283
 
  debug ("<== _nss_ldap_setautomntent");
284
 
 
285
 
  return stat;
286
 
}
287
 
 
288
 
NSS_STATUS _nss_ldap_getautomntent_r(void *private, const char **key, const char **value,
289
 
                                     char *buffer, size_t buflen, int *errnop)
290
 
{
291
 
  NSS_STATUS stat;
292
 
  ldap_automount_context_t *context = (ldap_automount_context_t *)private;
293
 
  ldap_args_t a;
294
 
  char **keyval[2];
295
 
 
296
 
  if (context == NULL)
297
 
    return NSS_NOTFOUND;
298
 
 
299
 
  debug ("==> _nss_ldap_getautomntent_r");
300
 
 
301
 
  keyval[0] = (char **)key;
302
 
  keyval[1] = (char **)value;
303
 
 
304
 
  _nss_ldap_enter ();
305
 
 
306
 
  do
307
 
    {
308
 
      assert (context->lac_dn_index < context->lac_dn_count);
309
 
 
310
 
      LA_INIT (a);
311
 
      LA_TYPE (a) = LA_TYPE_NONE;
312
 
      LA_BASE (a) = context->lac_dn_list[context->lac_dn_index];
313
 
 
314
 
      stat = _nss_ldap_getent_ex (&a, &context->lac_state,
315
 
                                  (void *)keyval,
316
 
                                  buffer, buflen, errnop,
317
 
                                  _nss_ldap_filt_getautomntent,
318
 
                                  LM_AUTOMOUNT,
319
 
                                  NULL,
320
 
                                  _nss_ldap_parse_automount);
321
 
      if (stat == NSS_NOTFOUND)
322
 
        {
323
 
          if (context->lac_dn_index < context->lac_dn_count - 1)
324
 
            context->lac_dn_index++;
325
 
          else
326
 
            break; /* move along, nothing more to see here */
327
 
        }
328
 
    }
329
 
  while (stat == NSS_NOTFOUND);
330
 
 
331
 
  _nss_ldap_leave ();
332
 
 
333
 
  debug ("<== _nss_ldap_getautomntent_r");
334
 
 
335
 
  return stat;
336
 
}
337
 
 
338
 
NSS_STATUS _nss_ldap_endautomntent(void **private)
339
 
{
340
 
  ldap_automount_context_t **pContext = (ldap_automount_context_t **)private;
341
 
 
342
 
  debug ("==> _nss_ldap_endautomntent");
343
 
 
344
 
  _nss_ldap_enter ();
345
 
  _nss_ldap_am_context_free (pContext);
346
 
  /* workaround because Linux automounter spawns a lot of processes */
347
 
  _nss_ldap_close ();
348
 
  _nss_ldap_leave ();
349
 
 
350
 
  debug ("<== _nss_ldap_endautomntent");
351
 
 
352
 
  return NSS_SUCCESS;
353
 
}
354
 
 
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)
358
 
{
359
 
  NSS_STATUS stat = NSS_NOTFOUND;
360
 
  ldap_automount_context_t *context = (ldap_automount_context_t *)private;
361
 
  ldap_args_t a;
362
 
  char **keyval[2];
363
 
  size_t i;
364
 
 
365
 
  if (context == NULL)
366
 
    return NSS_NOTFOUND;
367
 
 
368
 
  debug ("==> _nss_ldap_getautomntbyname_r");
369
 
 
370
 
  keyval[0] = (char **)canon_key;
371
 
  keyval[1] = (char **)value;
372
 
 
373
 
  for (i = 0; i < context->lac_dn_count; i++)
374
 
    {
375
 
      LA_INIT (a);
376
 
      LA_TYPE (a) = LA_TYPE_STRING;
377
 
      LA_STRING (a) = key;
378
 
      LA_BASE (a) = context->lac_dn_list[i];
379
 
 
380
 
      /* we do not acquire lock in this case */
381
 
      stat = _nss_ldap_getbyname (&a,
382
 
                                  (void *)keyval,
383
 
                                  buffer, buflen, errnop,
384
 
                                  _nss_ldap_filt_getautomntbyname,
385
 
                                  LM_AUTOMOUNT,
386
 
                                  _nss_ldap_parse_automount);
387
 
 
388
 
      if (stat != NSS_NOTFOUND)
389
 
        {
390
 
          break; /* on success or error other than not found */
391
 
        }
392
 
    }
393
 
 
394
 
  debug ("<== _nss_ldap_getautomntbyname_r");
395
 
 
396
 
  return stat;
397
 
}
398
 
 
399
 
#endif /* HAVE_NSS_H */
400