"Fossies" - the Fresh Open Source Software Archive 
Member "nss_ldap-265/ldap-sldap.c" (6 Nov 2009, 27553 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) 2006 Luke Howard.
2 This file is part of the nss_ldap library.
3 Contributed by Luke Howard, <lukeh@padl.com>, 2006.
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-sldap.c,v 2.14 2009/11/06 10:15:26 lukeh Exp $
21 */
22
23
24 static char rcsId[] =
25 "$Id: ldap-sldap.c,v 2.14 2009/11/06 10:15:26 lukeh Exp $";
26
27 #include "config.h"
28
29 #ifdef HAVE_PORT_BEFORE_H
30 #include <port_before.h>
31 #endif
32
33 #if defined(HAVE_THREAD_H) && !defined(_AIX)
34 #include <thread.h>
35 #elif defined(HAVE_PTHREAD_H)
36 #include <pthread.h>
37 #endif
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <netdb.h>
43 #include <assert.h>
44
45 #ifdef HAVE_LBER_H
46 #include <lber.h>
47 #endif
48 #ifdef HAVE_LDAP_H
49 #include <ldap.h>
50 #endif
51
52 #include <sys/types.h>
53 #include <sys/socket.h>
54 #ifdef HAVE_NET_ROUTE_H
55 #include <net/route.h>
56 #endif
57 #include <net/if.h>
58 #include <netinet/in.h>
59
60 #include "ldap-nss.h"
61 #include "ldap-automount.h"
62 #include "ldap-sldap.h"
63 #include "util.h"
64
65 #ifdef HAVE_PORT_AFTER_H
66 #include <port_after.h>
67 #endif
68
69 #ifdef HAVE_NSSWITCH_H
70
71 /*
72 * This implements enough of the Solaris libsldap interface in order
73 * for the automounter to work.
74 */
75
76 static ns_ldap_return_code __ns_ldap_initResult (ns_ldap_result_t ** pResult);
77 static ns_ldap_return_code __ns_ldap_initSearch (ns_ldap_cookie_t * cookie);
78 static ldap_map_selector_t __ns_ldap_str2selector (const char *map);
79 static ns_ldap_return_code __ns_ldap_unmapObjectClasses (ns_ldap_cookie_t *
80 cookie,
81 char **mappedClasses,
82 char
83 ***pOrigClasses);
84
85 static const char *
86 NS_LDAP_ERR2STR (ns_ldap_return_code err)
87 {
88 char *str = NULL;
89
90 __ns_ldap_err2str (err, &str);
91
92 return str;
93 }
94
95 static void **
96 __ns_ldap_makeStringParam (const char *string)
97 {
98 void **p;
99
100 p = (void **) malloc (2 * sizeof (void *));
101 if (p == NULL)
102 {
103 return NULL;
104 }
105 p[0] = strdup (string);
106 if (p[0] == NULL)
107 {
108 free (p);
109 return NULL;
110 }
111 p[1] = NULL;
112
113 return p;
114 }
115
116 char **
117 __ns_ldap_getMappedAttributes (const char *service, const char *attribute)
118 {
119 const char *mapped;
120
121 mapped = _nss_ldap_map_at (__ns_ldap_str2selector (service), attribute);
122 if (mapped == NULL)
123 {
124 return NULL;
125 }
126
127 return (char **) __ns_ldap_makeStringParam (mapped);
128 }
129
130 char **
131 __ns_ldap_getMappedObjectClass (const char *service, const char *objectClass)
132 {
133 const char *mapped;
134
135 mapped = _nss_ldap_map_oc (__ns_ldap_str2selector (service), objectClass);
136 if (mapped == NULL)
137 {
138 return NULL;
139 }
140
141 return (char **) __ns_ldap_makeStringParam (mapped);
142 }
143
144 static ns_ldap_return_code
145 __ns_ldap_mapError (NSS_STATUS error)
146 {
147 ns_ldap_return_code code;
148
149 switch (error)
150 {
151 case NSS_SUCCESS:
152 code = NS_LDAP_SUCCESS;
153 break;
154 case NSS_TRYAGAIN:
155 code = NS_LDAP_MEMORY;
156 break;
157 case NSS_NOTFOUND:
158 code = NS_LDAP_NOTFOUND;
159 break;
160 case NSS_UNAVAIL:
161 default:
162 code = NS_LDAP_OP_FAILED;
163 break;
164 }
165
166 return code;
167 }
168
169 static ns_ldap_return_code
170 __ns_ldap_mapErrorDetail (ns_ldap_return_code code, ns_ldap_error_t ** errorp)
171 {
172 char *m = NULL;
173 char *s = NULL;
174
175 *errorp = (ns_ldap_error_t *) calloc (1, sizeof (ns_ldap_error_t));
176 if (*errorp == NULL)
177 {
178 return NS_LDAP_MEMORY;
179 }
180
181 (*errorp)->status = _nss_ldap_get_ld_errno (&m, &s);
182 (*errorp)->message = (m != NULL) ? strdup (m) : NULL;
183
184 return code;
185 }
186
187 ns_ldap_return_code
188 __ns_ldap_freeError (ns_ldap_error_t ** errorp)
189 {
190 if (errorp == NULL)
191 {
192 return NS_LDAP_INVALID_PARAM;
193 }
194 if (*errorp != NULL)
195 {
196 if ((*errorp)->message != NULL)
197 {
198 free ((*errorp)->message);
199 (*errorp)->message = NULL;
200 }
201 free (*errorp);
202 *errorp = NULL;
203 }
204 return NS_LDAP_SUCCESS;
205 }
206
207 ns_ldap_return_code
208 __ns_ldap_freeParam (void ***data)
209 {
210 void **p;
211
212 if (*data != NULL)
213 {
214 for (p = *data; *p != NULL; p++)
215 {
216 free (*p);
217 *p = NULL;
218 }
219 free (*data);
220 *data = NULL;
221 }
222
223 return NS_LDAP_SUCCESS;
224 }
225
226
227 ns_ldap_return_code
228 __ns_ldap_getParam (const ParamIndexType type, void ***data,
229 ns_ldap_error_t ** errorp)
230 {
231 ns_ldap_return_code ret;
232
233 *errorp = NULL;
234
235 debug ("==> __ns_ldap_getParam (param=%d)", type);
236
237 switch (type)
238 {
239 case NS_LDAP_FILE_VERSION_P:
240 *data = __ns_ldap_makeStringParam (NS_LDAP_VERSION);
241 ret = NS_LDAP_SUCCESS;
242 break;
243 default:
244 ret = NS_LDAP_INVALID_PARAM;
245 break;
246 }
247
248 debug ("<== __ns_ldap_getParam (ret=%s)", NS_LDAP_ERR2STR (ret));
249
250 return ret;
251 }
252
253 ns_ldap_return_code
254 __ns_ldap_freeAttr (ns_ldap_attr_t ** pAttr)
255 {
256 int i;
257 ns_ldap_attr_t *attr = *pAttr;
258
259 if (attr != NULL)
260 {
261 if (attr->attrname != NULL)
262 {
263 free (attr->attrname);
264 }
265 if (attr->attrvalue != NULL)
266 {
267 for (i = 0; i < attr->value_count; i++)
268 {
269 free (attr->attrvalue[i]);
270 }
271 free (attr->attrvalue);
272 }
273 }
274
275 return NS_LDAP_SUCCESS;
276 }
277
278 ns_ldap_return_code
279 __ns_ldap_freeEntry (ns_ldap_entry_t ** pentry)
280 {
281 int i;
282 ns_ldap_entry_t *entry = *pentry;
283
284 if (entry != NULL)
285 {
286 if (entry->attr_pair != NULL)
287 {
288 for (i = 0; i < entry->attr_count; i++)
289 {
290 __ns_ldap_freeAttr (&entry->attr_pair[i]);
291 }
292 free (entry->attr_pair);
293 }
294 free (entry);
295 *pentry = NULL;
296 }
297
298 return NS_LDAP_SUCCESS;
299 }
300
301 ns_ldap_return_code
302 __ns_ldap_freeResult (ns_ldap_result_t ** pResult)
303 {
304 ns_ldap_result_t *result;
305 ns_ldap_entry_t *entry, *next = NULL;
306
307 if (pResult == NULL)
308 {
309 return NS_LDAP_INVALID_PARAM;
310 }
311
312 result = *pResult;
313 if (result == NULL)
314 {
315 return NS_LDAP_SUCCESS;
316 }
317
318 entry = result->entry;
319
320 while (entry != NULL)
321 {
322 next = entry->next;
323 __ns_ldap_freeEntry (&entry);
324 entry = next;
325 }
326
327 free (result);
328 *pResult = NULL;
329
330 return NS_LDAP_SUCCESS;
331 }
332
333 ns_ldap_return_code
334 __ns_ldap_allocAttr (ns_ldap_attr_t ** pAttr)
335 {
336 ns_ldap_attr_t *attr;
337
338 *pAttr = NULL;
339
340 attr = (ns_ldap_attr_t *) malloc (sizeof (*attr));
341 if (attr == NULL)
342 {
343 return NS_LDAP_MEMORY;
344 }
345
346 attr->attrname = NULL;
347 attr->attrvalue = NULL;
348 attr->value_count = 0;
349
350 *pAttr = attr;
351
352 return NS_LDAP_SUCCESS;
353 }
354
355 ns_ldap_return_code
356 __ns_ldap_parseAttr (ns_ldap_cookie_t * cookie,
357 LDAPMessage * entry,
358 const char *attribute, ns_ldap_attr_t ** pAttr)
359 {
360 ns_ldap_attr_t *attr;
361 const char *unmappedAttribute;
362 ns_ldap_return_code ret;
363 char **values;
364 int freeValues = 1;
365
366 ret = __ns_ldap_allocAttr (&attr);
367 if (ret != NS_LDAP_SUCCESS)
368 {
369 return ret;
370 }
371
372 if ((cookie->flags & NS_LDAP_NOMAP) == 0)
373 {
374 unmappedAttribute = _nss_ldap_unmap_at (cookie->sel, attribute);
375 if (unmappedAttribute == NULL)
376 {
377 __ns_ldap_freeAttr (&attr);
378 return NS_LDAP_INVALID_PARAM;
379 }
380 }
381 else
382 {
383 unmappedAttribute = attribute;
384 }
385
386 attr->attrname = strdup (unmappedAttribute);
387 if (attr->attrname == NULL)
388 {
389 __ns_ldap_freeAttr (&attr);
390 return NS_LDAP_MEMORY;
391 }
392 attr->attrvalue = NULL;
393
394 values = _nss_ldap_get_values (entry, attribute);
395
396 if ((cookie->flags & NS_LDAP_NOMAP) == 0)
397 {
398 if (strcasecmp (attribute, "objectClass") == 0)
399 {
400 /* Map object class values */
401 ret =
402 __ns_ldap_unmapObjectClasses (cookie, values, &attr->attrvalue);
403 if (ret != NS_LDAP_SUCCESS)
404 {
405 __ns_ldap_freeAttr (&attr);
406 return ret;
407 }
408 }
409 }
410
411 if (attr->attrvalue == NULL)
412 {
413 attr->attrvalue = values;
414 freeValues = 0;
415 }
416
417 attr->value_count =
418 (attr->attrvalue != NULL) ? ldap_count_values (attr->attrvalue) : 0;
419
420 if (freeValues)
421 {
422 ldap_value_free (values);
423 }
424
425 *pAttr = attr;
426
427 return NS_LDAP_SUCCESS;
428 }
429
430 ns_ldap_return_code
431 __ns_ldap_parseDn (ns_ldap_cookie_t * cookie, LDAPMessage * entry,
432 ns_ldap_attr_t ** pAttr)
433 {
434 ns_ldap_attr_t *attr;
435 ns_ldap_return_code ret;
436
437 ret = __ns_ldap_allocAttr (&attr);
438 if (ret != NS_LDAP_SUCCESS)
439 {
440 return ret;
441 }
442
443 attr->attrname = strdup ("dn");
444 if (attr->attrname == NULL)
445 {
446 __ns_ldap_freeAttr (&attr);
447 return NS_LDAP_MEMORY;
448 }
449
450 attr->value_count = 1;
451
452 attr->attrvalue = (char **) malloc (1 * sizeof (char *));
453 if (attr->attrvalue == NULL)
454 {
455 __ns_ldap_freeAttr (&attr);
456 return NS_LDAP_MEMORY;
457 }
458
459 attr->attrvalue[0] = _nss_ldap_get_dn (entry);
460 if (attr->attrvalue[0] == NULL)
461 {
462 __ns_ldap_freeAttr (&attr);
463 return NS_LDAP_MEMORY;
464 }
465
466 *pAttr = attr;
467
468 return NS_LDAP_SUCCESS;
469 }
470
471 NSS_STATUS
472 __ns_ldap_parseEntry (LDAPMessage * msg, ldap_state_t * state,
473 void *result, char *buffer, size_t buflen)
474 {
475 ns_ldap_cookie_t *cookie = (ns_ldap_cookie_t *) result;
476 char *attribute;
477 BerElement *ber = NULL;
478 ns_ldap_return_code ret = NS_LDAP_SUCCESS;
479 ns_ldap_entry_t *entry;
480 int attr_count;
481
482 #ifdef DEBUG
483 {
484 char *dn = _nss_ldap_get_dn (msg);
485 debug ("==> __ns_ldap_parseEntry (%s)", dn);
486 ldap_memfree (dn);
487 }
488 #endif
489
490 entry = (ns_ldap_entry_t *) malloc (sizeof (*entry));
491 if (entry == NULL)
492 {
493 cookie->ret = NS_LDAP_MEMORY;
494 debug ("<== __ns_ldap_parseEntry (no memory)");
495 return NSS_NOTFOUND;
496 }
497
498 entry->attr_count = 0;
499 entry->attr_pair = NULL;
500 entry->next = NULL;
501
502 attr_count = 1; /* for DN */
503
504 for (attribute = _nss_ldap_first_attribute (msg, &ber);
505 attribute != NULL; attribute = _nss_ldap_next_attribute (msg, ber))
506 {
507 attr_count++;
508 #ifdef HAVE_LDAP_MEMFREE
509 ldap_memfree (attribute);
510 #endif
511 }
512
513 if (ber != NULL)
514 ber_free (ber, 0);
515
516 entry->attr_pair =
517 (ns_ldap_attr_t **) calloc (attr_count, sizeof (ns_ldap_attr_t *));
518 if (entry->attr_pair == NULL)
519 {
520 __ns_ldap_freeEntry (&entry);
521 cookie->ret = NS_LDAP_MEMORY;
522 debug ("<== __ns_ldap_parseEntry (no memory)");
523 return NSS_NOTFOUND;
524 }
525
526 ret = __ns_ldap_parseDn (cookie, msg, &entry->attr_pair[entry->attr_count]);
527 if (ret != NS_LDAP_SUCCESS)
528 {
529 __ns_ldap_freeEntry (&entry);
530 cookie->ret = ret;
531 debug ("<== __ns_ldap_parseEntry (failed to parse DN)");
532 return ret;
533 }
534
535 entry->attr_count++;
536
537 for (attribute = _nss_ldap_first_attribute (msg, &ber);
538 attribute != NULL; attribute = _nss_ldap_next_attribute (msg, ber))
539 {
540 ns_ldap_attr_t *attr;
541
542 ret = __ns_ldap_parseAttr (cookie, msg, attribute, &attr);
543 #ifdef HAVE_LDAP_MEMFREE
544 ldap_memfree (attribute);
545 #endif
546 if (ret != NS_LDAP_SUCCESS)
547 {
548 continue;
549 }
550 entry->attr_pair[entry->attr_count++] = attr;
551 }
552
553 if (ber != NULL)
554 ber_free (ber, 0);
555
556 if (ret == NS_LDAP_SUCCESS)
557 {
558 ns_ldap_entry_t *last;
559
560 if (cookie->result == NULL)
561 {
562 ret = __ns_ldap_initResult (&cookie->result);
563 if (ret != NS_LDAP_SUCCESS)
564 {
565 __ns_ldap_freeEntry (&entry);
566 cookie->ret = ret;
567 debug ("<== __ns_ldap_parseEntry (failed to init result: %s)",
568 NS_LDAP_ERR2STR (ret));
569 return __ns_ldap_mapError (ret);
570 }
571 cookie->result->entry = entry;
572 }
573 else
574 {
575 assert (cookie->entry != NULL);
576
577 for (last = cookie->entry; last->next != NULL; last = last->next)
578 ;
579 last->next = entry;
580 }
581
582 cookie->entry = entry;
583
584 if (cookie->callback != NULL)
585 {
586 cookie->cb_ret = (*cookie->callback) (entry, cookie->userdata);
587 }
588
589 cookie->result->entries_count++;
590 }
591 else
592 {
593 __ns_ldap_freeEntry (&entry);
594 }
595
596 cookie->ret = ret;
597
598 debug ("<== __ns_ldap_parseEntry (ret=%s)", NS_LDAP_ERR2STR (ret));
599
600 return __ns_ldap_mapError (ret);
601 }
602
603 static ns_ldap_return_code
604 __ns_ldap_initResult (ns_ldap_result_t ** pResult)
605 {
606 ns_ldap_result_t *result;
607
608 result = (ns_ldap_result_t *) malloc (sizeof (ns_ldap_result_t));
609 if (result == NULL)
610 {
611 return NS_LDAP_MEMORY;
612 }
613
614 result->entries_count = 0;
615 result->entry = NULL;
616
617 *pResult = result;
618
619 return NS_LDAP_SUCCESS;
620 }
621
622 static ldap_map_selector_t
623 __ns_ldap_str2selector (const char *map)
624 {
625 ldap_map_selector_t sel;
626
627 if (map == NULL)
628 {
629 sel = LM_NONE;
630 }
631 else
632 {
633 sel = _nss_ldap_str2selector (map);
634
635 if (strcmp (map, "automount") == 0)
636 {
637 sel = LM_NONE; /* for enumeration only */
638 }
639 else if (sel == LM_NONE && (strncmp (map, "auto_", 5)) == 0)
640 {
641 sel = LM_AUTOMOUNT;
642 }
643 else
644 {
645 sel = _nss_ldap_str2selector (map);
646 }
647 }
648
649 return sel;
650 }
651
652 static ns_ldap_return_code
653 __ns_ldap_unmapObjectClasses (ns_ldap_cookie_t * cookie, char **mappedClasses,
654 char ***pOrigClasses)
655 {
656 char **origClasses = NULL;
657 int count, i;
658
659 count = ldap_count_values (mappedClasses);
660 origClasses = (char **) calloc (count + 1, sizeof (char *));
661 if (origClasses == NULL)
662 {
663 return NS_LDAP_MEMORY;
664 }
665
666 for (i = 0; i < count; i++)
667 {
668 origClasses[i] =
669 strdup (_nss_ldap_unmap_oc (cookie->sel, mappedClasses[i]));
670 if (origClasses[i] == NULL)
671 {
672 ldap_value_free (origClasses);
673 return NS_LDAP_MEMORY;
674 }
675 }
676 origClasses[i] = NULL;
677 *pOrigClasses = origClasses;
678
679 return NS_LDAP_SUCCESS;
680 }
681
682 static ns_ldap_return_code
683 __ns_ldap_mapAttributes (ns_ldap_cookie_t * cookie, const char ***pAttributes)
684 {
685 const char **attributes;
686 int i;
687
688 *pAttributes = NULL;
689
690 if (cookie->attribute == NULL)
691 {
692 return NS_LDAP_SUCCESS;
693 }
694
695 for (i = 0; cookie->attribute[i] != NULL; i++)
696 ;
697
698 attributes = (const char **) calloc (i + 1, sizeof (char **));
699 if (attributes == NULL)
700 {
701 return NS_LDAP_MEMORY;
702 }
703
704 for (i = 0; cookie->attribute[i] != NULL; i++)
705 {
706 attributes[i] = _nss_ldap_map_at (cookie->sel, cookie->attribute[i]);
707 assert (attributes[i] != NULL);
708 }
709 attributes[i] = NULL;
710 *pAttributes = attributes;
711
712 return NS_LDAP_SUCCESS;
713 }
714
715 static ns_ldap_return_code
716 __ns_ldap_emitFilterString (char **pFilter, size_t * len, size_t * size,
717 const char *s)
718 {
719 size_t slen = strlen (s);
720 char *filter;
721
722 if (*len + slen >= *size)
723 {
724 /* need some more space */
725 size_t newSize = *size;
726 char *newFilter;
727
728 if (newSize == 0)
729 newSize = NSS_BUFSIZ;
730 else
731 newSize *= 2;
732
733 newFilter = realloc (*pFilter, newSize);
734 if (newFilter == NULL)
735 {
736 return NS_LDAP_MEMORY;
737 }
738 *pFilter = newFilter;
739 *size = newSize;
740 }
741
742 filter = *pFilter;
743
744 memcpy (&filter[*len], s, slen);
745 filter[*len + slen] = '\0';
746
747 *len += slen;
748
749 return NS_LDAP_SUCCESS;
750 }
751
752
753 #define EMIT_STRING(_s) do { \
754 ns_ldap_return_code ret = __ns_ldap_emitFilterString(&filter, &len, &size, (_s)); \
755 if (ret != NS_LDAP_SUCCESS) { \
756 if (filter != NULL) free(filter); \
757 return ret; \
758 } \
759 } while (0)
760
761 #define EMIT_CHAR(_c) do { \
762 char _s[2]; \
763 ns_ldap_return_code ret; \
764 _s[0] = _c; \
765 _s[1] = '\0'; \
766 ret = __ns_ldap_emitFilterString(&filter, &len, &size, (_s)); \
767 if (ret != NS_LDAP_SUCCESS) { \
768 if (filter != NULL) free(filter); \
769 return ret; \
770 } \
771 } while (0)
772
773
774 static ns_ldap_return_code
775 __ns_ldap_mapFilter (ns_ldap_cookie_t * cookie, char **pFilter)
776 {
777 enum
778 { EXPECT_LHS, FOUND_LHS, EXPECT_RHS, FOUND_RHS } state;
779 char *lhs = NULL;
780 char *rhs = NULL;
781 size_t len = 0, size = 0;
782 char tmp;
783 size_t i;
784 char *filter = NULL;
785 size_t filterLen = strlen (cookie->filter);
786
787 state = EXPECT_LHS;
788
789 for (i = 0; i <= filterLen; i++)
790 {
791 switch (state)
792 {
793 case EXPECT_LHS:
794 switch (cookie->filter[i])
795 {
796 case '(':
797 case ')':
798 case '&':
799 case '|':
800 case '!':
801 EMIT_CHAR (cookie->filter[i]);
802 break;
803 default:
804 state = FOUND_LHS;
805 lhs = &cookie->filter[i];
806 break;
807 }
808 break;
809 case FOUND_LHS:
810 switch (cookie->filter[i])
811 {
812 case '<':
813 case '=':
814 case '>':
815 case '~':
816 state = EXPECT_RHS;
817 tmp = cookie->filter[i];
818 cookie->filter[i] = '\0';
819 /* map LHS (attribute type) */
820 EMIT_STRING (_nss_ldap_map_at (cookie->sel, lhs));
821 EMIT_CHAR (tmp);
822 break;
823 default:
824 break;
825 }
826 break;
827 case EXPECT_RHS:
828 switch (cookie->filter[i])
829 {
830 case '<':
831 case '=':
832 case '>':
833 case '~':
834 EMIT_CHAR (cookie->filter[i]);
835 break;
836 default:
837 state = FOUND_RHS;
838 rhs = &cookie->filter[i];
839 break;
840 }
841 break;
842 case FOUND_RHS:
843 switch (cookie->filter[i])
844 {
845 case '&':
846 case '|':
847 case '!':
848 case ')':
849 case '\0':
850 state = EXPECT_LHS;
851 tmp = cookie->filter[i];;
852 cookie->filter[i] = '\0';
853 if (strcasecmp (lhs, "objectClass") == 0)
854 EMIT_STRING (_nss_ldap_map_oc (cookie->sel, rhs));
855 else
856 EMIT_STRING (rhs);
857 if (strcasecmp (rhs, "automount") == 0)
858 cookie->sel = LM_AUTOMOUNT;
859 EMIT_CHAR (tmp);
860 break;
861 default:
862 break;
863 }
864 break;
865 }
866 }
867
868 *pFilter = filter;
869
870 return NS_LDAP_SUCCESS;
871 }
872
873 static ns_ldap_return_code
874 __ns_ldap_freeCookie (ns_ldap_cookie_t ** pCookie)
875 {
876 ns_ldap_cookie_t *cookie;
877
878 cookie = *pCookie;
879
880 if (cookie != NULL)
881 {
882 if (cookie->map != NULL)
883 free (cookie->map);
884 if (cookie->filter != NULL)
885 free (cookie->filter);
886 if (cookie->attribute != NULL)
887 ldap_value_free (cookie->attribute);
888 if (cookie->state != NULL)
889 {
890 _nss_ldap_ent_context_release (&(cookie->state));
891 }
892 if (cookie->mapped_filter != NULL)
893 free (cookie->mapped_filter);
894 if (cookie->mapped_attribute != NULL)
895 free (cookie->mapped_attribute);
896 _nss_ldap_am_context_free (&cookie->am_state);
897 __ns_ldap_freeResult (&cookie->result);
898 free (cookie);
899 }
900
901 *pCookie = NULL;
902
903 return NS_LDAP_SUCCESS;
904 }
905
906 static ns_ldap_return_code
907 __ns_ldap_initCookie (const char *map,
908 const char *filter,
909 int (*init_filter_cb) (const ns_ldap_search_desc_t *
910 desc, char **realfilter,
911 const void *userdata),
912 const char *const *attribute, const ns_cred_t * cred,
913 const int flags, ns_ldap_cookie_t ** pCookie,
914 int (*callback) (const ns_ldap_entry_t * entry,
915 const void *userdata),
916 const void *userdata)
917 {
918 ns_ldap_cookie_t *cookie;
919 ns_ldap_return_code ret;
920 size_t i;
921
922 assert (pCookie != NULL && *pCookie == NULL);
923
924 ret = __ns_ldap_mapError (_nss_ldap_init ());
925 if (ret != NS_LDAP_SUCCESS)
926 {
927 return ret;
928 }
929
930 cookie = (ns_ldap_cookie_t *) calloc (1, sizeof (*cookie));
931 if (cookie == NULL)
932 {
933 return NS_LDAP_MEMORY;
934 }
935
936 if (filter == NULL)
937 {
938 __ns_ldap_freeCookie (&cookie);
939 return NS_LDAP_INVALID_PARAM;
940 }
941
942 if (map != NULL)
943 {
944 cookie->map = strdup (map);
945 if (cookie->map == NULL)
946 {
947 __ns_ldap_freeCookie (&cookie);
948 return NS_LDAP_MEMORY;
949 }
950 }
951
952 cookie->filter = strdup (filter);
953 if (cookie->filter == NULL)
954 {
955 __ns_ldap_freeCookie (&cookie);
956 return NS_LDAP_MEMORY;
957 }
958
959 if (attribute != NULL)
960 {
961 for (i = 0; attribute[i] != NULL; i++)
962 ;
963
964 cookie->attribute = (char **) calloc (i + 1, sizeof (char *));
965 if (cookie->attribute == NULL)
966 {
967 __ns_ldap_freeCookie (&cookie);
968 return NS_LDAP_MEMORY;
969 }
970
971 for (i = 0; attribute[i] != NULL; i++)
972 {
973 cookie->attribute[i] = strdup (attribute[i]);
974 if (cookie->attribute[i] == NULL)
975 {
976 __ns_ldap_freeCookie (&cookie);
977 return NS_LDAP_MEMORY;
978 }
979 }
980 cookie->attribute[i] = NULL;
981 }
982
983 cookie->flags = flags;
984 cookie->init_filter_cb = init_filter_cb;
985 cookie->callback = callback;
986 cookie->userdata = userdata;
987 cookie->ret = -1;
988 cookie->cb_ret = NS_LDAP_CB_NEXT;
989 cookie->erange = 0;
990 cookie->sel = __ns_ldap_str2selector (map);
991
992 if (_nss_ldap_ent_context_init_locked (&cookie->state) == NULL)
993 {
994 __ns_ldap_freeCookie (&cookie);
995 return NS_LDAP_INTERNAL;
996 }
997
998 cookie->result = NULL;
999 cookie->entry = NULL;
1000
1001 ret = __ns_ldap_initSearch (cookie);
1002 if (ret != NS_LDAP_SUCCESS)
1003 {
1004 __ns_ldap_freeCookie (&cookie);
1005 return ret;
1006 }
1007
1008 *pCookie = cookie;
1009
1010 return NS_LDAP_SUCCESS;
1011 }
1012
1013 static ns_ldap_return_code
1014 __ns_ldap_initSearch (ns_ldap_cookie_t * cookie)
1015 {
1016 ns_ldap_return_code ret;
1017 NSS_STATUS stat;
1018
1019 assert (cookie != NULL);
1020 assert (cookie->state != NULL);
1021
1022 ret = __ns_ldap_mapAttributes (cookie, &cookie->mapped_attribute);
1023 if (ret != NS_LDAP_SUCCESS)
1024 {
1025 return ret;
1026 }
1027
1028 ret = __ns_ldap_mapFilter (cookie, &cookie->mapped_filter);
1029 if (ret != NS_LDAP_SUCCESS)
1030 {
1031 return ret;
1032 }
1033
1034 /*
1035 * In the automount case, we need to do a search for a list of
1036 * search bases
1037 */
1038 if (cookie->sel == LM_AUTOMOUNT)
1039 {
1040 assert (cookie->am_state == NULL);
1041 assert (cookie->map != NULL);
1042
1043 stat = _nss_ldap_am_context_init (cookie->map, &cookie->am_state);
1044 if (stat != NSS_SUCCESS)
1045 {
1046 return __ns_ldap_mapError (stat);
1047 }
1048 }
1049
1050 return ret;
1051 }
1052
1053 /*
1054 * Performs a search given an existing cookie
1055 *
1056 * If cookie->result != NULL then the entry will be appended to
1057 * the result list. Use this for implementing __ns_ldap_list().
1058 *
1059 * If cookie->result == NULL then a new result list will be
1060 * allocated. Use this for implementing __ns_ldap_nextEntry().
1061 *
1062 * cookie->entry always points to the last entry in cookie->result
1063 *
1064 * Caller should acquire global lock
1065 */
1066 static ns_ldap_return_code
1067 __ns_ldap_search (ns_ldap_cookie_t * cookie)
1068 {
1069 ldap_args_t a;
1070 NSS_STATUS stat;
1071 ldap_automount_context_t *am = cookie->am_state;
1072
1073 LA_INIT (a);
1074 LA_TYPE (a) = LA_TYPE_NONE;
1075
1076 if (cookie->sel == LM_AUTOMOUNT)
1077 {
1078 assert (am != NULL);
1079 assert (am->lac_dn_count > 0);
1080
1081 LA_BASE (a) = am->lac_dn_list[am->lac_dn_index];
1082 } /* XXX todo is support maps that are RDNs relative to default search base */
1083
1084 assert (cookie->mapped_filter != NULL);
1085
1086 retry_search:
1087 cookie->ret = -1;
1088
1089 stat = _nss_ldap_getent_ex (&a, &cookie->state, cookie,
1090 NULL, 0, &cookie->erange,
1091 cookie->mapped_filter,
1092 cookie->sel,
1093 cookie->mapped_attribute, __ns_ldap_parseEntry);
1094
1095 if (stat == NSS_NOTFOUND &&
1096 cookie->sel == LM_AUTOMOUNT && am->lac_dn_index < am->lac_dn_count - 1)
1097 {
1098 am->lac_dn_index++;
1099 goto retry_search;
1100 }
1101
1102 if (cookie->ret < 0)
1103 {
1104 cookie->ret = __ns_ldap_mapError (stat);
1105 }
1106
1107 return cookie->ret;
1108 }
1109
1110 ns_ldap_return_code
1111 __ns_ldap_firstEntry (const char *service,
1112 const char *filter,
1113 int (*init_filter_cb) (const ns_ldap_search_desc_t *
1114 desc, char **realfilter,
1115 const void *userdata),
1116 const char *const *attribute, const ns_cred_t * cred,
1117 const int flags, void **pCookie,
1118 ns_ldap_result_t ** result, ns_ldap_error_t ** errorp,
1119 const void *userdata)
1120 {
1121 ns_ldap_return_code ret;
1122 ns_ldap_cookie_t *cookie = NULL;
1123
1124 *pCookie = NULL;
1125 *result = NULL;
1126 *errorp = NULL;
1127
1128 debug ("==> __ns_ldap_firstEntry (map=%s filter=%s)",
1129 service != NULL ? service : "(null)", filter);
1130
1131 _nss_ldap_enter ();
1132
1133 ret = __ns_ldap_initCookie (service, filter, init_filter_cb,
1134 attribute, cred, flags, &cookie, NULL,
1135 userdata);
1136 if (ret == NS_LDAP_SUCCESS)
1137 {
1138 ret = __ns_ldap_search (cookie);
1139
1140 *result = cookie->result;
1141 cookie->result = NULL;
1142 }
1143
1144 __ns_ldap_mapErrorDetail (ret, errorp);
1145
1146 _nss_ldap_leave ();
1147
1148 *pCookie = cookie;
1149
1150 debug ("<== __ns_ldap_firstEntry ret=%s cookie=%p", NS_LDAP_ERR2STR (ret),
1151 cookie);
1152
1153 return ret;
1154 }
1155
1156 ns_ldap_return_code
1157 __ns_ldap_nextEntry (void *_cookie,
1158 ns_ldap_result_t ** result, ns_ldap_error_t ** errorp)
1159 {
1160 ns_ldap_return_code ret;
1161 ns_ldap_cookie_t *cookie;
1162
1163 *result = NULL;
1164 *errorp = NULL;
1165
1166 cookie = (ns_ldap_cookie_t *) _cookie;
1167 if (cookie == NULL)
1168 {
1169 return NS_LDAP_INVALID_PARAM;
1170 }
1171
1172 debug ("==> __ns_ldap_nextEntry cookie=%p", cookie);
1173
1174 _nss_ldap_enter ();
1175
1176 ret = __ns_ldap_search (cookie);
1177
1178 *result = cookie->result;
1179 cookie->result = NULL;
1180
1181 __ns_ldap_mapErrorDetail (ret, errorp);
1182
1183 _nss_ldap_leave ();
1184
1185 debug ("<== __ns_ldap_nextEntry ret=%s", NS_LDAP_ERR2STR (ret));
1186
1187 return ret;
1188 }
1189
1190 ns_ldap_return_code
1191 __ns_ldap_endEntry (void **pCookie, ns_ldap_error_t ** errorp)
1192 {
1193 ns_ldap_cookie_t *cookie;
1194
1195 _nss_ldap_enter ();
1196
1197 cookie = (ns_ldap_cookie_t *) * pCookie;
1198
1199 debug ("==> __ns_ldap_freeEntry cookie=%p", cookie);
1200
1201 __ns_ldap_mapErrorDetail (cookie->ret, errorp);
1202 __ns_ldap_freeCookie (&cookie);
1203
1204 *pCookie = NULL;
1205
1206 _nss_ldap_leave ();
1207
1208 debug ("<== __ns_ldap_freeEntry");
1209
1210 return NS_LDAP_SUCCESS;
1211 }
1212
1213 ns_ldap_return_code
1214 __ns_ldap_list (const char *map,
1215 const char *filter,
1216 int (*init_filter_cb) (const ns_ldap_search_desc_t * desc,
1217 char **realfilter,
1218 const void *userdata),
1219 const char *const *attribute, const ns_cred_t * cred,
1220 const int flags, ns_ldap_result_t ** pResult,
1221 ns_ldap_error_t ** errorp,
1222 int (*callback) (const ns_ldap_entry_t * entry,
1223 const void *userdata), const void *userdata)
1224 {
1225 ns_ldap_cookie_t *cookie = NULL;
1226 ns_ldap_result_t *result = NULL;
1227 ns_ldap_return_code ret;
1228
1229 debug ("==> __ns_ldap_list map=%s filter=%s",
1230 map != NULL ? map : "(null)", filter);
1231
1232 *pResult = NULL;
1233 *errorp = NULL;
1234
1235 _nss_ldap_enter ();
1236
1237 ret = __ns_ldap_initCookie (map, filter, init_filter_cb,
1238 attribute, cred, flags, &cookie, callback,
1239 userdata);
1240
1241 while (ret == NS_LDAP_SUCCESS)
1242 {
1243 ret = __ns_ldap_search (cookie);
1244
1245 if (result == NULL)
1246 {
1247 result = cookie->result;
1248 }
1249
1250 if (cookie->cb_ret != NS_LDAP_CB_NEXT)
1251 {
1252 assert (cookie->callback != NULL);
1253 break;
1254 }
1255 }
1256
1257 if (cookie != NULL)
1258 {
1259 if (ret == NS_LDAP_NOTFOUND && cookie->entry != NULL)
1260 {
1261 ret = NS_LDAP_SUCCESS;
1262 }
1263
1264 *pResult = result;
1265 cookie->result = NULL;
1266 }
1267
1268 __ns_ldap_freeCookie (&cookie);
1269 __ns_ldap_mapErrorDetail (ret, errorp);
1270
1271 _nss_ldap_leave ();
1272
1273 debug ("<== __ns_ldap_list ret=%s", NS_LDAP_ERR2STR (ret));
1274
1275 return ret;
1276 }
1277
1278 ns_ldap_return_code
1279 __ns_ldap_err2str (ns_ldap_return_code err, char **strmsg)
1280 {
1281 switch (err)
1282 {
1283 case NS_LDAP_SUCCESS:
1284 case NS_LDAP_SUCCESS_WITH_INFO:
1285 *strmsg = "Success";
1286 break;
1287 case NS_LDAP_OP_FAILED:
1288 *strmsg = "Operation failed";
1289 break;
1290 case NS_LDAP_NOTFOUND:
1291 *strmsg = "Not found";
1292 break;
1293 case NS_LDAP_MEMORY:
1294 *strmsg = "Out of memory";
1295 break;
1296 case NS_LDAP_CONFIG:
1297 *strmsg = "Configuration error";
1298 break;
1299 case NS_LDAP_PARTIAL:
1300 *strmsg = "Partial results received";
1301 break;
1302 case NS_LDAP_INTERNAL:
1303 *strmsg = "Internal LDAP error";
1304 break;
1305 case NS_LDAP_INVALID_PARAM:
1306 *strmsg = "Invalid parameter";
1307 break;
1308 default:
1309 *strmsg = "Unknown error";
1310 return NS_LDAP_INVALID_PARAM;
1311 break;
1312 }
1313
1314 return NS_LDAP_SUCCESS;
1315 }
1316
1317 #endif /* HAVE_NSSWITCH_H */