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