"Fossies" - the Fresh Open Source Software Archive 
Member "nss_ldap-265/ldap-automount.c" (6 Nov 2009, 8929 Bytes) of package /linux/privat/old/nss_ldap-265.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
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.10 2009/11/06 10:15:26 lukeh Exp $
21 */
22
23
24 static char rcsId[] = "$Id: ldap-automount.c,v 2.10 2009/11/06 10:15:26 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 }
151
152 memset (context, 0, sizeof (*context));
153 free (context);
154
155 *pContext = NULL;
156
157 return;
158 }
159
160 static NSS_STATUS
161 am_context_add_dn (LDAPMessage * e,
162 ldap_state_t * pvt,
163 void *result, char *buffer, size_t buflen)
164 {
165 ldap_automount_context_t *context = (ldap_automount_context_t *) result;
166 char *dn;
167
168 dn = _nss_ldap_get_dn (e);
169 if (dn == NULL)
170 {
171 return NSS_NOTFOUND;
172 }
173
174 if (context->lac_dn_count >= context->lac_dn_size)
175 {
176 char **new_dns;
177
178 new_dns = (char **)realloc(context->lac_dn_list,
179 2 * context->lac_dn_size * sizeof(char *));
180 if (new_dns == NULL)
181 {
182 #ifdef HAVE_LDAP_MEMFREE
183 ldap_memfree (dn);
184 #else
185 free (dn);
186 #endif /* HAVE_LDAP_MEMFREE */
187 return NSS_TRYAGAIN;
188 }
189
190 context->lac_dn_list = new_dns;
191 context->lac_dn_size *= 2;
192 }
193
194 context->lac_dn_list[context->lac_dn_count++] = dn;
195
196 return NSS_SUCCESS;
197 }
198
199 NSS_STATUS
200 _nss_ldap_am_context_init(const char *mapname, ldap_automount_context_t **pContext)
201 {
202 NSS_STATUS stat;
203 ldap_automount_context_t *context = NULL;
204 const char *no_attrs[] = { NULL };
205 ldap_args_t a;
206 ent_context_t *key = NULL;
207 int errnop;
208
209 *pContext = NULL;
210
211 stat = _nss_ldap_am_context_alloc (&context);
212 if (stat != NSS_SUCCESS)
213 return stat;
214
215 LA_INIT (a);
216 LA_TYPE (a) = LA_TYPE_STRING;
217 LA_STRING (a) = mapname;
218
219 do
220 {
221 stat = _nss_ldap_getent_ex (&a, &key,
222 (void *)context,
223 NULL, 0, &errnop,
224 _nss_ldap_filt_setautomntent,
225 LM_AUTOMOUNT,
226 no_attrs,
227 am_context_add_dn);
228 }
229 while (stat == NSS_SUCCESS);
230
231 if (key != NULL)
232 {
233 _nss_ldap_ent_context_release (&key);
234 }
235
236 if (context->lac_dn_count == 0)
237 {
238 _nss_ldap_am_context_free (&context);
239 return NSS_NOTFOUND;
240 }
241 else if (stat == NSS_NOTFOUND)
242 {
243 stat = NSS_SUCCESS;
244 }
245
246 context->lac_dn_index = 0;
247
248 *pContext = context;
249 return NSS_SUCCESS;
250 }
251
252 #ifdef HAVE_NSS_H
253 NSS_STATUS _nss_ldap_setautomntent(const char *mapname, void **private)
254 {
255 ldap_automount_context_t *context = NULL;
256 NSS_STATUS stat;
257
258 debug ("==> _nss_ldap_setautomntent");
259
260 _nss_ldap_enter ();
261
262 stat = _nss_ldap_init ();
263 if (stat != NSS_SUCCESS)
264 {
265 _nss_ldap_leave ();
266 debug ("<== _nss_ldap_setautomntent");
267 return stat;
268 }
269
270 stat = _nss_ldap_am_context_init (mapname, &context);
271 if (stat != NSS_SUCCESS)
272 {
273 _nss_ldap_leave ();
274 debug ("<== _nss_ldap_setautomntent");
275 return stat;
276 }
277
278 *private = (void *)context;
279 _nss_ldap_leave ();
280
281 debug ("<== _nss_ldap_setautomntent");
282
283 return stat;
284 }
285
286 NSS_STATUS _nss_ldap_getautomntent_r(void *private, const char **key, const char **value,
287 char *buffer, size_t buflen, int *errnop)
288 {
289 NSS_STATUS stat;
290 ldap_automount_context_t *context = (ldap_automount_context_t *)private;
291 ldap_args_t a;
292 char **keyval[2];
293
294 if (context == NULL)
295 return NSS_NOTFOUND;
296
297 debug ("==> _nss_ldap_getautomntent_r");
298
299 keyval[0] = (char **)key;
300 keyval[1] = (char **)value;
301
302 _nss_ldap_enter ();
303
304 do
305 {
306 assert (context->lac_dn_index < context->lac_dn_count);
307
308 LA_INIT (a);
309 LA_TYPE (a) = LA_TYPE_NONE;
310 LA_BASE (a) = context->lac_dn_list[context->lac_dn_index];
311
312 stat = _nss_ldap_getent_ex (&a, &context->lac_state,
313 (void *)keyval,
314 buffer, buflen, errnop,
315 _nss_ldap_filt_getautomntent,
316 LM_AUTOMOUNT,
317 NULL,
318 _nss_ldap_parse_automount);
319 if (stat == NSS_NOTFOUND)
320 {
321 if (context->lac_dn_index < context->lac_dn_count - 1)
322 context->lac_dn_index++;
323 else
324 break; /* move along, nothing more to see here */
325 }
326 }
327 while (stat == NSS_NOTFOUND);
328
329 _nss_ldap_leave ();
330
331 debug ("<== _nss_ldap_getautomntent_r");
332
333 return stat;
334 }
335
336 NSS_STATUS _nss_ldap_endautomntent(void **private)
337 {
338 ldap_automount_context_t **pContext = (ldap_automount_context_t **)private;
339
340 debug ("==> _nss_ldap_endautomntent");
341
342 _nss_ldap_enter ();
343 _nss_ldap_am_context_free (pContext);
344 /* workaround because Linux automounter spawns a lot of processes */
345 _nss_ldap_close ();
346 _nss_ldap_leave ();
347
348 debug ("<== _nss_ldap_endautomntent");
349
350 return NSS_SUCCESS;
351 }
352
353 NSS_STATUS _nss_ldap_getautomntbyname_r(void *private, const char *key,
354 const char **canon_key, const char **value,
355 char *buffer, size_t buflen, int *errnop)
356 {
357 NSS_STATUS stat = NSS_NOTFOUND;
358 ldap_automount_context_t *context = (ldap_automount_context_t *)private;
359 ldap_args_t a;
360 char **keyval[2];
361 size_t i;
362
363 if (context == NULL)
364 return NSS_NOTFOUND;
365
366 debug ("==> _nss_ldap_getautomntbyname_r");
367
368 keyval[0] = (char **)canon_key;
369 keyval[1] = (char **)value;
370
371 for (i = 0; i < context->lac_dn_count; i++)
372 {
373 LA_INIT (a);
374 LA_TYPE (a) = LA_TYPE_STRING;
375 LA_STRING (a) = key;
376 LA_BASE (a) = context->lac_dn_list[i];
377
378 /* we do not acquire lock in this case */
379 stat = _nss_ldap_getbyname (&a,
380 (void *)keyval,
381 buffer, buflen, errnop,
382 _nss_ldap_filt_getautomntbyname,
383 LM_AUTOMOUNT,
384 _nss_ldap_parse_automount);
385
386 if (stat != NSS_NOTFOUND)
387 {
388 break; /* on success or error other than not found */
389 }
390 }
391
392 debug ("<== _nss_ldap_getautomntbyname_r");
393
394 return stat;
395 }
396
397 #endif /* HAVE_NSS_H */
398