1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 #include <stdlib.h>
26 #include <strings.h>
27 #include <ctype.h>
28 #include <locale.h>
29 #include <syslog.h>
30 #include "ns_internal.h"
31
32 /*
33 * Calculate a hash for a string
34 * Based on elf_hash algorithm, hash is case insensitive
35 * Uses tolower instead of _tolower because of I18N
36 */
37
38 static unsigned long
ns_hash(const char * str)39 ns_hash(const char *str)
40 {
41 unsigned int hval = 0;
42
43 while (*str) {
44 unsigned int g;
45
46 hval = (hval << 4) + tolower(*str++);
47 if ((g = (hval & 0xf0000000)) != 0)
48 hval ^= g >> 24;
49 hval &= ~g;
50 }
51 return ((unsigned long)hval);
52 }
53
54 /*
55 * Scan a hash table hit for a matching hash entry.
56 * Assume service and str are non-NULL.
57 */
58
59 static ns_hash_t *
ns_scan_hash(ns_hashtype_t type,const char * service,const char * str,ns_hash_t * idx)60 ns_scan_hash(ns_hashtype_t type, const char *service,
61 const char *str, ns_hash_t *idx)
62 {
63 while (idx) {
64 if (idx->h_type == type &&
65 strcasecmp(service, idx->h_map->service) == 0 &&
66 strcasecmp(str, idx->h_map->orig) == 0) {
67 return (idx);
68 }
69 idx = idx->h_next;
70 }
71 return ((ns_hash_t *)NULL);
72 }
73
74 /*
75 * Find an entry in the hash table
76 */
77
78 static ns_hash_t *
ns_get_hash(const ns_config_t * config,ns_hashtype_t type,const char * service,const char * str)79 ns_get_hash(const ns_config_t *config,
80 ns_hashtype_t type, const char *service, const char *str)
81 {
82 ns_hash_t *idx, *hashp;
83 unsigned long hash;
84
85 if (config == NULL || service == NULL || str == NULL)
86 return (NULL);
87
88 hash = ns_hash(str) % NS_HASH_MAX;
89 idx = config->hashTbl[hash];
90 hashp = ns_scan_hash(type, service, str, idx);
91
92 return (hashp);
93 }
94
95 /*
96 * free a map entry
97 */
98
99 static void
ns_free_map(ns_mapping_t * mapp)100 ns_free_map(ns_mapping_t *mapp)
101 {
102 char **ptr;
103
104 if (mapp == NULL)
105 return;
106 if (mapp->service) {
107 free(mapp->service);
108 mapp->service = NULL;
109 }
110 if (mapp->orig) {
111 free(mapp->orig);
112 mapp->orig = NULL;
113 }
114 if (mapp->map) {
115 for (ptr = mapp->map; *ptr; ptr++)
116 free(*ptr);
117 free(mapp->map);
118 mapp->map = NULL;
119 }
120 free(mapp);
121 }
122
123 /*
124 * Remove a hash table entry.
125 * This function is not MT safe.
126 */
127
128 static ns_hash_t *
ns_free_hash(ns_hash_t * p)129 ns_free_hash(ns_hash_t *p)
130 {
131 ns_mapping_t *map;
132 ns_hash_t *next;
133
134 map = p->h_map;
135 next = p->h_next;
136 ns_free_map(map);
137 free(p);
138 return (next);
139 }
140
141 /*
142 * destroy the hash table.
143 * This function is not MT safe.
144 */
145
146 void
__s_api_destroy_hash(ns_config_t * config)147 __s_api_destroy_hash(ns_config_t *config)
148 {
149 ns_hash_t *next;
150 int i;
151
152 if (config == NULL)
153 return;
154 for (i = 0; i < NS_HASH_MAX; i++) {
155 next = config->hashTbl[i];
156 while (next != NULL) {
157 next = ns_free_hash(next);
158 }
159 config->hashTbl[i] = NULL;
160 }
161 }
162
163 /*
164 * Add a hash entry to the hash table.
165 * This function is not MT safe.
166 * Assume map, map->orig, map->service are non-NULL.
167 */
168
169 int
__s_api_add_map2hash(ns_config_t * config,ns_hashtype_t type,ns_mapping_t * map)170 __s_api_add_map2hash(ns_config_t *config, ns_hashtype_t type,
171 ns_mapping_t *map)
172 {
173 ns_hash_t *idx, *newp;
174 unsigned long hash;
175
176 if (config == NULL)
177 return (NS_HASH_RC_CONFIG_ERROR);
178
179 hash = ns_hash(map->orig) % NS_HASH_MAX;
180 idx = config->hashTbl[hash];
181 if (idx != NULL &&
182 ns_scan_hash(type, map->service, map->orig, idx) != NULL) {
183 return (NS_HASH_RC_EXISTED);
184 }
185
186 newp = (ns_hash_t *)malloc(sizeof (ns_hash_t));
187 if (newp == NULL)
188 return (NS_HASH_RC_NO_MEMORY);
189 newp->h_type = type;
190 newp->h_map = map;
191 newp->h_next = idx;
192 config->hashTbl[hash] = newp;
193 newp->h_llnext = config->llHead;
194 config->llHead = newp;
195 return (NS_HASH_RC_SUCCESS);
196 }
197
198
199 /*
200 * Parse an attribute map string.
201 * Assume space is the only legal whitespace.
202 * attributeMap syntax:
203 * attributeMap = serviceId ":" origAttribute "="
204 * attributes
205 * origAttribute = attribute
206 * attributes = wattribute *( space wattribute )
207 * wattribute = whsp newAttribute whsp
208 * newAttribute = descr | "*NULL*"
209 * attribute = descr
210 *
211 * objectclassMap syntax:
212 * objectclassMap = serviceId ":" origObjectclass "="
213 * objectclass
214 * origObjectclass = objectclass
215 * objectclass = keystring
216 */
217
218 int
__s_api_parse_map(char * cp,char ** sid,char ** origA,char *** mapA)219 __s_api_parse_map(char *cp, char **sid, char **origA, char ***mapA)
220 {
221 char *sptr, *dptr, **mapp;
222 int i, max;
223
224 *sid = NULL;
225 *origA = NULL;
226 *mapA = NULL;
227
228 sptr = cp;
229 dptr = strchr(sptr, COLONTOK);
230 if (dptr == NULL)
231 return (NS_HASH_RC_SYNTAX_ERROR);
232 i = dptr - sptr + 1;
233 *sid = (char *)malloc(i);
234 if (*sid == NULL)
235 return (NS_HASH_RC_NO_MEMORY);
236 (void) strlcpy(*sid, sptr, i);
237 sptr = dptr+1;
238
239 dptr = strchr(sptr, TOKENSEPARATOR);
240 if (dptr == NULL) {
241 free(*sid);
242 *sid = NULL;
243 return (NS_HASH_RC_SYNTAX_ERROR);
244 }
245 i = dptr - sptr + 1;
246 *origA = (char *)malloc(i);
247 if (*origA == NULL) {
248 free(*sid);
249 *sid = NULL;
250 return (NS_HASH_RC_NO_MEMORY);
251 }
252 (void) strlcpy(*origA, sptr, i);
253 sptr = dptr+1;
254
255 max = 1;
256 for (dptr = sptr; *dptr; dptr++) {
257 if (*dptr == SPACETOK) {
258 max++;
259 while (*(dptr+1) == SPACETOK)
260 dptr++;
261 }
262 }
263 *mapA = (char **)calloc(max+1, sizeof (char *));
264 if (*mapA == NULL) {
265 free(*sid);
266 *sid = NULL;
267 free(*origA);
268 *origA = NULL;
269 return (NS_HASH_RC_NO_MEMORY);
270 }
271 mapp = *mapA;
272
273 while (*sptr) {
274 while (*sptr == SPACETOK)
275 sptr++;
276 dptr = sptr;
277 while (*dptr && *dptr != SPACETOK)
278 dptr++;
279 i = dptr - sptr + 1;
280 *mapp = (char *)malloc(i);
281 if (*mapp == NULL) {
282 free(*sid);
283 *sid = NULL;
284 free(*origA);
285 *origA = NULL;
286 __s_api_free2dArray(*mapA);
287 *mapA = NULL;
288 return (NS_HASH_RC_NO_MEMORY);
289 }
290 (void) strlcpy(*mapp, sptr, i);
291 mapp++;
292 sptr = dptr;
293 }
294 return (NS_HASH_RC_SUCCESS);
295 }
296
297
298 static void
__ns_ldap_freeASearchDesc(ns_ldap_search_desc_t * ptr)299 __ns_ldap_freeASearchDesc(ns_ldap_search_desc_t *ptr)
300 {
301 if (ptr == NULL)
302 return;
303 if (ptr->basedn)
304 free(ptr->basedn);
305 if (ptr->filter)
306 free(ptr->filter);
307 free(ptr);
308 }
309
310 /*
311 * Parse a service descriptor
312 * and create a service descriptor struct
313 * SD Format:
314 * serviceid:[base][?[scope][?[filter]]];[[base][?[scope][?[filter]]]]
315 * desc format:
316 * [base][?[scope][?[filter]]]
317 */
318
319 typedef enum _ns_parse_state {
320 P_ERROR, P_INIT, P_BASEDN, P_SCOPE,
321 P_INIFILTER, P_FILTER, P_END, P_EXIT, P_MEMERR
322 } _ns_parse_state_t;
323
324 static
325 int
__s_api_parseASearchDesc(const char * service,char ** cur,ns_ldap_search_desc_t ** ret)326 __s_api_parseASearchDesc(const char *service,
327 char **cur, ns_ldap_search_desc_t **ret)
328 {
329 ns_ldap_search_desc_t *ptr;
330 char *sptr, *dptr;
331 char buf[BUFSIZ];
332 int i, rc;
333 ns_ldap_error_t **errorp = NULL;
334 ns_ldap_error_t *error = NULL;
335 void **paramVal = NULL;
336 char **dns = NULL;
337 _ns_parse_state_t state = P_INIT;
338 int quoted = 0;
339 int wasquoted = 0;
340 int empty = 1;
341
342 if (ret == NULL)
343 return (NS_LDAP_INVALID_PARAM);
344 *ret = NULL;
345 if (cur == NULL)
346 return (NS_LDAP_INVALID_PARAM);
347
348 ptr = (ns_ldap_search_desc_t *)
349 calloc(1, sizeof (ns_ldap_search_desc_t));
350 if (ptr == NULL)
351 return (NS_LDAP_MEMORY);
352
353 sptr = *cur;
354
355 /* Get the default scope */
356 if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_SCOPE_P,
357 ¶mVal, errorp)) != NS_LDAP_SUCCESS) {
358 (void) __ns_ldap_freeError(errorp);
359 __ns_ldap_freeASearchDesc(ptr);
360 ptr = NULL;
361 return (NS_LDAP_MEMORY);
362 }
363 if (paramVal && *paramVal)
364 ptr->scope = * (ScopeType_t *)(*paramVal);
365 else
366 ptr->scope = NS_LDAP_SCOPE_ONELEVEL;
367 (void) __ns_ldap_freeParam(¶mVal);
368 paramVal = NULL;
369
370 for (/* none */; state != P_EXIT && sptr && *sptr; sptr++) {
371 empty = 0;
372 switch (state) {
373 case P_INIT:
374 if (*sptr == QUESTTOK) {
375 /* No basedn */
376 ptr->basedn = strdup("");
377 if (!ptr->basedn) {
378 state = P_MEMERR;
379 break;
380 }
381 state = P_SCOPE;
382 break;
383 }
384 if (*sptr == SEMITOK) {
385 /* No SSD */
386 ptr->basedn = strdup("");
387 if (!ptr->basedn) {
388 state = P_MEMERR;
389 break;
390 }
391 state = P_EXIT;
392 break;
393 }
394 /* prepare to copy DN */
395 i = strlen(sptr) + 1;
396 ptr->basedn = dptr = (char *)calloc(i, sizeof (char));
397 if (!ptr->basedn) {
398 state = P_MEMERR;
399 break;
400 }
401 if (*sptr == BSLTOK) {
402 if (*(sptr+1) == '\0') {
403 /* error */
404 state = P_ERROR;
405 break;
406 }
407 if (*(sptr+1) == QUOTETOK ||
408 *(sptr+1) == BSLTOK) {
409 /* escaped CHARS */
410 sptr++;
411 } else {
412 *dptr++ = *sptr++;
413 }
414 *dptr++ = *sptr;
415 } else if (*sptr == QUOTETOK) {
416 quoted = 1;
417 wasquoted = 1;
418 } else {
419 *dptr++ = *sptr;
420 }
421 state = P_BASEDN;
422 break;
423 case P_INIFILTER:
424 if (*sptr == SEMITOK) {
425 /* No filter and no more SSD */
426 state = P_EXIT;
427 break;
428 }
429 /* prepare to copy DN */
430 i = strlen(sptr) + 1;
431 ptr->filter = dptr = (char *)calloc(i, sizeof (char));
432 if (!ptr->filter) {
433 state = P_MEMERR;
434 break;
435 }
436 if (*sptr == BSLTOK) {
437 if (*(sptr+1) == '\0') {
438 /* error */
439 state = P_ERROR;
440 break;
441 }
442 if (*(sptr+1) == QUOTETOK ||
443 *(sptr+1) == BSLTOK) {
444 /* escaped CHARS */
445 sptr++;
446 } else {
447 *dptr++ = *sptr++;
448 }
449 *dptr++ = *sptr;
450 } else if (*sptr == QUOTETOK) {
451 quoted = 1;
452 wasquoted = 1;
453 } else {
454 *dptr++ = *sptr;
455 }
456 state = P_FILTER;
457 break;
458 case P_SCOPE:
459 buf[0] = '\0';
460 if (*sptr == SEMITOK) {
461 /* no more SSD */
462 state = P_EXIT;
463 break;
464 }
465 if (strncasecmp(sptr, "base", 4) == 0) {
466 sptr += 4;
467 ptr->scope = NS_LDAP_SCOPE_BASE;
468 } else if (strncasecmp(sptr, "one", 3) == 0) {
469 ptr->scope = NS_LDAP_SCOPE_ONELEVEL;
470 sptr += 3;
471 } else if (strncasecmp(sptr, "sub", 3) == 0) {
472 ptr->scope = NS_LDAP_SCOPE_SUBTREE;
473 sptr += 3;
474 }
475 if (*sptr == '\0' || (*sptr == SEMITOK)) {
476 /* no more SSD */
477 state = P_EXIT;
478 sptr--;
479 break;
480 }
481 if (*sptr != QUESTTOK) {
482 state = P_ERROR;
483 break;
484 }
485 state = P_INIFILTER;
486 quoted = 0;
487 wasquoted = 0;
488 break;
489 case P_BASEDN:
490 case P_FILTER:
491 if (quoted) {
492 /* Quoted */
493 if (*sptr == BSLTOK) {
494 if (*(sptr+1) == '\0') {
495 state = P_ERROR;
496 break;
497 }
498 if (*(sptr+1) == QUOTETOK ||
499 *(sptr+1) == BSLTOK) {
500 /* escaped CHARS */
501 sptr++;
502 } else {
503 *dptr++ = *sptr++;
504 }
505 /* fall through to char copy */
506 } else if (*sptr == QUOTETOK) {
507 /* end of string */
508 *dptr = '\0';
509 quoted = 0;
510 break;
511 }
512 /* else fall through to char copy */
513 } else {
514 /* Unquoted */
515 if (wasquoted && *sptr != QUESTTOK) {
516 /* error past end of quoted string */
517 state = P_ERROR;
518 break;
519 }
520 if (*sptr == BSLTOK) {
521 if (*(sptr+1) == '\0') {
522 state = P_ERROR;
523 break;
524 }
525 if (*(sptr+1) == SEMITOK ||
526 *(sptr+1) == QUESTTOK ||
527 *(sptr+1) == QUOTETOK ||
528 *(sptr+1) == BSLTOK) {
529 /* escaped chars */
530 sptr++;
531 }
532 /* fall through to char copy */
533 } else if (*sptr == QUOTETOK) {
534 /* error */
535 state = P_ERROR;
536 break;
537 } else if (*sptr == QUESTTOK) {
538 /* if filter error */
539 if (state == P_FILTER) {
540 state = P_ERROR;
541 break;
542 }
543 /* end of basedn goto scope */
544 *dptr = '\0';
545 state = P_SCOPE;
546 break;
547 } else if (*sptr == SEMITOK) {
548 /* end of current SSD */
549 *dptr = '\0';
550 state = P_EXIT;
551 break;
552 }
553 }
554 /* normal character to copy */
555 *dptr++ = *sptr;
556 break;
557 case P_END:
558 if (*sptr == SEMITOK) {
559 state = P_EXIT;
560 break;
561 }
562 __ns_ldap_freeASearchDesc(ptr);
563 ptr = NULL;
564 *cur = NULL;
565 return (NS_LDAP_CONFIG);
566 default: /* error should never arrive here */
567 case P_ERROR:
568 __ns_ldap_freeASearchDesc(ptr);
569 ptr = NULL;
570 *cur = NULL;
571 return (NS_LDAP_CONFIG);
572 case P_MEMERR:
573 __ns_ldap_freeASearchDesc(ptr);
574 ptr = NULL;
575 *cur = NULL;
576 return (NS_LDAP_MEMORY);
577 }
578 }
579
580 if (quoted) {
581 __ns_ldap_freeASearchDesc(ptr);
582 ptr = NULL;
583 *cur = NULL;
584 return (NS_LDAP_INVALID_PARAM);
585 }
586
587 if (empty || strlen(ptr->basedn) == 0) {
588 if (ptr->basedn)
589 free(ptr->basedn);
590 /* get default base */
591 rc = __s_api_getDNs(&dns, service, &error);
592 if (rc != NS_LDAP_SUCCESS) {
593 if (dns) {
594 __s_api_free2dArray(dns);
595 dns = NULL;
596 }
597 (void) __ns_ldap_freeError(&error);
598 __ns_ldap_freeASearchDesc(ptr);
599 ptr = NULL;
600 return (NS_LDAP_MEMORY);
601 }
602 ptr->basedn = strdup(dns[0]);
603 __s_api_free2dArray(dns);
604 dns = NULL;
605 }
606
607 *cur = sptr;
608 *ret = ptr;
609 return (NS_LDAP_SUCCESS);
610 }
611
612
613 /*
614 * Build up the service descriptor array
615 */
616 #define NS_SDESC_MAX 4
617
618 static int
__ns_ldap_saveSearchDesc(ns_ldap_search_desc_t *** sdlist,int * cnt,int * max,ns_ldap_search_desc_t * ret)619 __ns_ldap_saveSearchDesc(ns_ldap_search_desc_t ***sdlist,
620 int *cnt, int *max, ns_ldap_search_desc_t *ret)
621 {
622 ns_ldap_search_desc_t **tmplist;
623
624 if (*sdlist == NULL) {
625 *cnt = 0;
626 *max = NS_SDESC_MAX;
627 *sdlist = (ns_ldap_search_desc_t **)
628 calloc(*max, sizeof (ns_ldap_search_desc_t *));
629 if (*sdlist == NULL)
630 return (-1);
631 } else if (*cnt+1 >= *max) {
632 *max += NS_SDESC_MAX;
633 tmplist = (ns_ldap_search_desc_t **)
634 realloc((void *)(*sdlist),
635 *max * sizeof (ns_ldap_search_desc_t *));
636 if (tmplist == NULL)
637 return (-1);
638 else
639 *sdlist = tmplist;
640 }
641 (*sdlist)[*cnt] = ret;
642 (*cnt)++;
643 (*sdlist)[*cnt] = NULL;
644 return (0);
645 }
646
647
648 /*
649 * Exported Search Descriptor Routines
650 */
651
__ns_ldap_getSearchDescriptors(const char * service,ns_ldap_search_desc_t *** desc,ns_ldap_error_t ** errorp)652 int __ns_ldap_getSearchDescriptors(
653 const char *service,
654 ns_ldap_search_desc_t ***desc,
655 ns_ldap_error_t **errorp)
656 {
657 int rc;
658 int slen;
659 void **param = NULL;
660 void **paramVal = NULL;
661 char **sdl, *srv, **sdl_save;
662 char errstr[2 * MAXERROR];
663 ns_ldap_search_desc_t **sdlist;
664 int cnt, max;
665 int vers;
666 ns_config_t *cfg;
667 ns_ldap_search_desc_t *ret;
668
669 if ((desc == NULL) || (errorp == NULL))
670 return (NS_LDAP_INVALID_PARAM);
671
672 *desc = NULL;
673 *errorp = NULL;
674
675 rc = __ns_ldap_getParam(NS_LDAP_SERVICE_SEARCH_DESC_P,
676 (void ***)¶m, errorp);
677 if (rc != NS_LDAP_SUCCESS) {
678 return (rc);
679 }
680 sdl = (char **)param;
681 cnt = 0;
682 max = 0;
683 sdlist = NULL;
684
685 cfg = __s_api_get_default_config();
686
687 if (cfg == NULL) {
688 (void) snprintf(errstr, sizeof (errstr),
689 gettext("No configuration information available."));
690 MKERROR(LOG_ERR, *errorp, NS_CONFIG_NOTLOADED, strdup(errstr),
691 NULL);
692 return (NS_LDAP_CONFIG);
693 }
694
695 vers = cfg->version;
696 __s_api_release_config(cfg);
697
698 /* If using version1 or no sd's process SEARCH_DN if available */
699 if (vers == NS_LDAP_V1 && param == NULL) {
700 rc = __s_api_get_search_DNs_v1(&sdl, service, errorp);
701 if (rc != NS_LDAP_SUCCESS || sdl == NULL) {
702 return (rc);
703 }
704 sdl_save = sdl;
705 /* Convert a SEARCH_DN to a search descriptor */
706 for (; *sdl; sdl++) {
707 ret = (ns_ldap_search_desc_t *)
708 calloc(1, sizeof (ns_ldap_search_desc_t));
709 if (ret == NULL) {
710 (void) __ns_ldap_freeSearchDescriptors(&sdlist);
711 __s_api_free2dArray(sdl_save);
712 return (NS_LDAP_MEMORY);
713 }
714 ret->basedn = strdup(*sdl);
715 if (ret->basedn == NULL) {
716 free(ret);
717 (void) __ns_ldap_freeASearchDesc(ret);
718 (void) __ns_ldap_freeSearchDescriptors(&sdlist);
719 __s_api_free2dArray(sdl_save);
720 return (NS_LDAP_MEMORY);
721 }
722
723 /* default scope */
724 if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_SCOPE_P,
725 ¶mVal, errorp)) != NS_LDAP_SUCCESS) {
726 (void) __ns_ldap_freeASearchDesc(ret);
727 (void) __ns_ldap_freeSearchDescriptors(&sdlist);
728 __s_api_free2dArray(sdl_save);
729 return (rc);
730 }
731 if (paramVal && *paramVal)
732 ret->scope = * (ScopeType_t *)(*paramVal);
733 else
734 ret->scope = NS_LDAP_SCOPE_ONELEVEL;
735 (void) __ns_ldap_freeParam(¶mVal);
736 paramVal = NULL;
737
738 rc = __ns_ldap_saveSearchDesc(&sdlist, &cnt, &max, ret);
739 if (rc < 0) {
740 (void) __ns_ldap_freeASearchDesc(ret);
741 (void) __ns_ldap_freeSearchDescriptors(&sdlist);
742 __s_api_free2dArray(sdl_save);
743 return (NS_LDAP_MEMORY);
744 }
745 }
746 __s_api_free2dArray(sdl_save);
747 *desc = sdlist;
748 return (NS_LDAP_SUCCESS);
749 }
750
751 if (sdl == NULL || service == NULL) {
752 (void) __ns_ldap_freeParam(¶m);
753 param = NULL;
754 *desc = NULL;
755 return (NS_LDAP_SUCCESS);
756 }
757 slen = strlen(service);
758
759 /* Process the version2 sd's */
760 for (; *sdl; sdl++) {
761 srv = *sdl;
762 if (strncasecmp(service, srv, slen) != 0)
763 continue;
764 srv += slen;
765 if (*srv != COLONTOK)
766 continue;
767 srv++;
768 while (srv != NULL && *srv != NULL) {
769 /* Process 1 */
770 rc = __s_api_parseASearchDesc(service, &srv, &ret);
771 if (rc != NS_LDAP_SUCCESS) {
772 (void) __ns_ldap_freeSearchDescriptors(&sdlist);
773 (void) snprintf(errstr, (2 * MAXERROR), gettext(
774 "Invalid serviceSearchDescriptor (%s). "
775 "Illegal configuration"), *sdl);
776 (void) __ns_ldap_freeParam(¶m);
777 param = NULL;
778 MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX,
779 strdup(errstr), NULL);
780 return (rc);
781 }
782 if (ret != NULL) {
783 rc = __ns_ldap_saveSearchDesc(
784 &sdlist, &cnt, &max, ret);
785 }
786 if (rc < 0) {
787 (void) __ns_ldap_freeSearchDescriptors(&sdlist);
788 (void) __ns_ldap_freeParam(¶m);
789 param = NULL;
790 return (NS_LDAP_MEMORY);
791 }
792 }
793 }
794
795 (void) __ns_ldap_freeParam(¶m);
796 param = NULL;
797 *desc = sdlist;
798 return (NS_LDAP_SUCCESS);
799 }
800
801 int
__ns_ldap_freeSearchDescriptors(ns_ldap_search_desc_t *** desc)802 __ns_ldap_freeSearchDescriptors(ns_ldap_search_desc_t ***desc)
803 {
804 ns_ldap_search_desc_t **dptr;
805 ns_ldap_search_desc_t *ptr;
806
807 if (*desc == NULL)
808 return (NS_LDAP_SUCCESS);
809 for (dptr = *desc; (ptr = *dptr) != NULL; dptr++) {
810 __ns_ldap_freeASearchDesc(ptr);
811 }
812 free(*desc);
813 *desc = NULL;
814
815 return (NS_LDAP_SUCCESS);
816 }
817
818
819
820
821 /*
822 * Exported Attribute/Objectclass mapping functions.
823 */
824
825 /*
826 * This function is not supported.
827 */
828 /* ARGSUSED */
__ns_ldap_getAttributeMaps(const char * service,ns_ldap_attribute_map_t *** maps,ns_ldap_error_t ** errorp)829 int __ns_ldap_getAttributeMaps(
830 const char *service,
831 ns_ldap_attribute_map_t ***maps,
832 ns_ldap_error_t **errorp)
833 {
834 *maps = NULL;
835 return (NS_LDAP_OP_FAILED);
836 }
837
838 int
__ns_ldap_freeAttributeMaps(ns_ldap_attribute_map_t *** maps)839 __ns_ldap_freeAttributeMaps(ns_ldap_attribute_map_t ***maps)
840 {
841 ns_ldap_attribute_map_t **dptr;
842 ns_ldap_attribute_map_t *ptr;
843 char **cpp, *cp;
844
845 if (*maps == NULL)
846 return (NS_LDAP_SUCCESS);
847 for (dptr = *maps; (ptr = *dptr) != NULL; dptr++) {
848 if (ptr->origAttr) {
849 free(ptr->origAttr);
850 ptr->origAttr = NULL;
851 }
852 if (ptr->mappedAttr) {
853 for (cpp = ptr->mappedAttr; (cp = *cpp) != NULL; cpp++)
854 free(cp);
855 free(ptr->mappedAttr);
856 ptr->mappedAttr = NULL;
857 }
858 free(ptr);
859 }
860 free(*maps);
861 *maps = NULL;
862
863 return (NS_LDAP_SUCCESS);
864 }
865
__ns_ldap_getMappedAttributes(const char * service,const char * origAttribute)866 char **__ns_ldap_getMappedAttributes(
867 const char *service,
868 const char *origAttribute)
869 {
870 ns_config_t *ptr = __s_api_loadrefresh_config();
871 ns_hash_t *hp;
872 char **ret;
873
874 if (ptr == NULL)
875 return (NULL);
876
877 hp = ns_get_hash(ptr, NS_HASH_AMAP, service, origAttribute);
878
879 if (hp == NULL || hp->h_map == NULL)
880 ret = NULL;
881 else
882 ret = __s_api_cp2dArray(hp->h_map->map);
883 __s_api_release_config(ptr);
884 return (ret);
885 }
886
__ns_ldap_getOrigAttribute(const char * service,const char * mappedAttribute)887 char **__ns_ldap_getOrigAttribute(
888 const char *service,
889 const char *mappedAttribute)
890 {
891 ns_config_t *ptr = __s_api_loadrefresh_config();
892 ns_hash_t *hp;
893 char **ret;
894
895 if (ptr == NULL)
896 return (NULL);
897
898 hp = ns_get_hash(ptr, NS_HASH_RAMAP, service, mappedAttribute);
899
900 if (hp == NULL || hp->h_map == NULL)
901 ret = NULL;
902 else
903 ret = __s_api_cp2dArray(hp->h_map->map);
904 __s_api_release_config(ptr);
905 return (ret);
906 }
907
908 /*
909 * This function is not supported.
910 */
911 /* ARGSUSED */
__ns_ldap_getObjectClassMaps(const char * service,ns_ldap_objectclass_map_t *** maps,ns_ldap_error_t ** errorp)912 int __ns_ldap_getObjectClassMaps(
913 const char *service,
914 ns_ldap_objectclass_map_t ***maps,
915 ns_ldap_error_t **errorp)
916 {
917 *maps = NULL;
918 return (NS_LDAP_OP_FAILED);
919 }
920
921 int
__ns_ldap_freeObjectClassMaps(ns_ldap_objectclass_map_t *** maps)922 __ns_ldap_freeObjectClassMaps(ns_ldap_objectclass_map_t ***maps)
923 {
924 ns_ldap_objectclass_map_t **dptr;
925 ns_ldap_objectclass_map_t *ptr;
926
927 if (*maps == NULL)
928 return (NS_LDAP_SUCCESS);
929 for (dptr = *maps; (ptr = *dptr) != NULL; dptr++) {
930 if (ptr->origOC) {
931 free(ptr->origOC);
932 ptr->origOC = NULL;
933 }
934 if (ptr->mappedOC) {
935 free(ptr->mappedOC);
936 ptr->mappedOC = NULL;
937 }
938 free(ptr);
939 }
940 free(*maps);
941 *maps = NULL;
942
943 return (NS_LDAP_SUCCESS);
944 }
945
__ns_ldap_getMappedObjectClass(const char * service,const char * origObjectClass)946 char **__ns_ldap_getMappedObjectClass(
947 const char *service,
948 const char *origObjectClass)
949 {
950 ns_config_t *ptr = __s_api_loadrefresh_config();
951 ns_hash_t *hp;
952 char **ret;
953
954 if (ptr == NULL)
955 return (NULL);
956
957 hp = ns_get_hash(ptr, NS_HASH_OMAP, service, origObjectClass);
958
959 if (hp == NULL || hp->h_map == NULL)
960 ret = NULL;
961 else
962 ret = __s_api_cp2dArray(hp->h_map->map);
963 __s_api_release_config(ptr);
964 return (ret);
965 }
966
__ns_ldap_getOrigObjectClass(const char * service,const char * mappedObjectClass)967 char **__ns_ldap_getOrigObjectClass(
968 const char *service,
969 const char *mappedObjectClass)
970 {
971 ns_config_t *ptr = __s_api_loadrefresh_config();
972 ns_hash_t *hp;
973 char **ret;
974
975 if (ptr == NULL)
976 return (NULL);
977
978 hp = ns_get_hash(ptr, NS_HASH_ROMAP, service, mappedObjectClass);
979
980 if (hp == NULL || hp->h_map == NULL)
981 ret = NULL;
982 else
983 ret = __s_api_cp2dArray(hp->h_map->map);
984 __s_api_release_config(ptr);
985 return (ret);
986 }
987
__ns_ldap_mapAttributeList(const char * service,const char * const * origAttrList)988 char **__ns_ldap_mapAttributeList(
989 const char *service,
990 const char * const *origAttrList)
991 {
992 const char * const *opp;
993 char **cpp, **npp;
994 int i;
995
996 if (origAttrList == NULL)
997 return (NULL);
998
999 opp = origAttrList;
1000 for (i = 0; *opp; i++, opp++)
1001 ;
1002 cpp = (char **)calloc(i+1, sizeof (char *));
1003 if (cpp == NULL)
1004 return (NULL);
1005
1006 opp = origAttrList;
1007 for (i = 0; *opp; i++, opp++) {
1008 npp = __ns_ldap_getMappedAttributes(service, *opp);
1009 if (npp && npp[0]) {
1010 cpp[i] = strdup(npp[0]);
1011 __s_api_free2dArray(npp);
1012 npp = NULL;
1013 if (cpp[i] == NULL) {
1014 __s_api_free2dArray(cpp);
1015 return (NULL);
1016 }
1017 } else {
1018 cpp[i] = strdup(*opp);
1019 if (cpp[i] == NULL) {
1020 __s_api_free2dArray(cpp);
1021 return (NULL);
1022 }
1023 }
1024 }
1025 return (cpp);
1026 }
1027
1028 char *
__ns_ldap_mapAttribute(const char * service,const char * origAttr)1029 __ns_ldap_mapAttribute(
1030 const char *service,
1031 const char *origAttr)
1032 {
1033 char **npp;
1034 char *mappedAttr;
1035
1036 if (origAttr == NULL)
1037 return (NULL);
1038
1039 npp = __ns_ldap_getMappedAttributes(service, origAttr);
1040 if (npp && npp[0]) {
1041 mappedAttr = strdup(npp[0]);
1042 __s_api_free2dArray(npp);
1043 } else {
1044 mappedAttr = strdup(origAttr);
1045 }
1046 return (mappedAttr);
1047 }
1048