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.
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.
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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * libsldap - library side configuration components
28 * Routines to manage the config structure
45 #include <arpa/inet.h>
46 #include <sys/types.h>
50 #include <sys/systeminfo.h>
55 #include "ns_internal.h"
56 #include "ns_cache_door.h"
57 #include "ns_connmgmt.h"
59 #pragma fini(__s_api_shutdown_conn_mgmt, \
60 _free_config, __ns_ldap_doorfd_close)
62 static mutex_t ns_parse_lock
= DEFAULTMUTEX
;
63 static mutex_t ns_loadrefresh_lock
= DEFAULTMUTEX
;
64 static ns_config_t
*current_config
= NULL
;
66 static int cache_server
= FALSE
;
67 extern thread_key_t ns_cmgkey
;
70 * Parameter Index Type validation routines
73 __s_val_postime(ParamIndexType i
, ns_default_config
*def
,
74 ns_param_t
*param
, char *errbuf
);
76 __s_val_basedn(ParamIndexType i
, ns_default_config
*def
,
77 ns_param_t
*param
, char *errbuf
);
80 __s_val_binddn(ParamIndexType i
, ns_default_config
*def
,
81 ns_param_t
*param
, char *errbuf
);
84 __s_val_bindpw(ParamIndexType i
, ns_default_config
*def
,
85 ns_param_t
*param
, char *errbuf
);
88 __s_val_serverList(ParamIndexType i
, ns_default_config
*def
,
89 ns_param_t
*param
, char *errbuf
);
92 * Forward declarations
95 static ns_parse_status
96 verify_value(ns_config_t
*cfg
, char *name
, char *value
, char *errstr
);
99 set_default_value(ns_config_t
*configptr
, char *name
, char *value
,
100 ns_ldap_error_t
**error
);
103 set_curr_config(ns_config_t
*ptr
);
106 __door_getldapconfig(char **buffer
, int *buflen
, ns_ldap_error_t
**error
);
109 SetDoorInfo(char *buffer
, ns_ldap_error_t
**errorp
);
112 timetorefresh(ns_config_t
*cfg
);
115 LoadCacheConfiguration(ns_config_t
*, ns_ldap_error_t
**error
);
118 dupParam(ns_param_t
*ptr
);
124 * Structures used in enum <-> string mapping routines
127 static ns_enum_map ns_auth_enum_v1
[] = {
128 { ENUM2INT(NS_LDAP_EA_NONE
), "NS_LDAP_AUTH_NONE" },
129 { ENUM2INT(NS_LDAP_EA_SIMPLE
), "NS_LDAP_AUTH_SIMPLE" },
130 { ENUM2INT(NS_LDAP_EA_SASL_CRAM_MD5
), "NS_LDAP_AUTH_SASL_CRAM_MD5" },
134 static ns_enum_map ns_auth_enum_v2
[] = {
135 { ENUM2INT(NS_LDAP_EA_NONE
), "none" },
136 { ENUM2INT(NS_LDAP_EA_SIMPLE
), "simple" },
137 { ENUM2INT(NS_LDAP_EA_SASL_CRAM_MD5
), "sasl/CRAM-MD5" },
138 { ENUM2INT(NS_LDAP_EA_SASL_DIGEST_MD5
), "sasl/DIGEST-MD5" },
139 { ENUM2INT(NS_LDAP_EA_SASL_DIGEST_MD5_INT
),
140 "sasl/DIGEST-MD5:auth-int" },
141 { ENUM2INT(NS_LDAP_EA_SASL_DIGEST_MD5_CONF
),
142 "sasl/DIGEST-MD5:auth-conf" },
143 { ENUM2INT(NS_LDAP_EA_SASL_EXTERNAL
), "sasl/EXTERNAL" },
144 { ENUM2INT(NS_LDAP_EA_SASL_GSSAPI
), "sasl/GSSAPI" },
145 { ENUM2INT(NS_LDAP_EA_TLS_NONE
), "tls:none" },
146 { ENUM2INT(NS_LDAP_EA_TLS_SIMPLE
), "tls:simple" },
147 { ENUM2INT(NS_LDAP_EA_TLS_SASL_CRAM_MD5
), "tls:sasl/CRAM-MD5" },
148 { ENUM2INT(NS_LDAP_EA_TLS_SASL_DIGEST_MD5
), "tls:sasl/DIGEST-MD5" },
149 { ENUM2INT(NS_LDAP_EA_TLS_SASL_DIGEST_MD5_INT
),
150 "tls:sasl/DIGEST-MD5:auth-int" },
151 { ENUM2INT(NS_LDAP_EA_TLS_SASL_DIGEST_MD5_CONF
),
152 "tls:sasl/DIGEST-MD5:auth-conf" },
153 { ENUM2INT(NS_LDAP_EA_TLS_SASL_EXTERNAL
), "tls:sasl/EXTERNAL" },
158 static ns_enum_map ns_sec_enum_v1
[] = {
159 { ENUM2INT(NS_LDAP_TLS_NONE
), "NS_LDAP_SEC_NONE" },
164 static ns_enum_map ns_cred_enum_v2
[] = {
165 { ENUM2INT(NS_LDAP_CRED_ANON
), "anonymous" },
166 { ENUM2INT(NS_LDAP_CRED_PROXY
), "proxy" },
167 { ENUM2INT(NS_LDAP_CRED_SELF
), "self" },
171 static ns_enum_map ns_ref_enum_v1
[] = {
172 { ENUM2INT(NS_LDAP_FOLLOWREF
), "NS_LDAP_FOLLOWREF" },
173 { ENUM2INT(NS_LDAP_NOREF
), "NS_LDAP_NOREF" },
177 static ns_enum_map ns_ref_enum_v2
[] = {
178 { ENUM2INT(NS_LDAP_FOLLOWREF
), "TRUE" },
179 { ENUM2INT(NS_LDAP_NOREF
), "FALSE" },
183 static ns_enum_map ns_scope_enum_v1
[] = {
184 { ENUM2INT(NS_LDAP_SCOPE_BASE
), "NS_LDAP_SCOPE_BASE" },
185 { ENUM2INT(NS_LDAP_SCOPE_ONELEVEL
), "NS_LDAP_SCOPE_ONELEVEL" },
186 { ENUM2INT(NS_LDAP_SCOPE_SUBTREE
), "NS_LDAP_SCOPE_SUBTREE" },
190 static ns_enum_map ns_scope_enum_v2
[] = {
191 { ENUM2INT(NS_LDAP_SCOPE_BASE
), "base" },
192 { ENUM2INT(NS_LDAP_SCOPE_ONELEVEL
), "one" },
193 { ENUM2INT(NS_LDAP_SCOPE_SUBTREE
), "sub" },
197 static ns_enum_map ns_pref_enum
[] = {
198 { ENUM2INT(NS_LDAP_PREF_FALSE
), "NS_LDAP_FALSE" },
199 { ENUM2INT(NS_LDAP_PREF_TRUE
), "NS_LDAP_TRUE" },
203 static ns_enum_map ns_shadow_update_enum
[] = {
204 { ENUM2INT(NS_LDAP_ENABLE_SHADOW_UPDATE_FALSE
), "FALSE" },
205 { ENUM2INT(NS_LDAP_ENABLE_SHADOW_UPDATE_TRUE
), "TRUE" },
209 static int ns_def_auth_v1
[] = {
210 ENUM2INT(NS_LDAP_EA_NONE
),
214 static int ns_def_auth_v2
[] = {
215 ENUM2INT(NS_LDAP_EA_NONE
),
219 static int ns_def_cred_v1
[] = {
220 ENUM2INT(NS_LDAP_CRED_PROXY
),
224 static int ns_def_cred_v2
[] = {
225 ENUM2INT(NS_LDAP_CRED_ANON
),
230 * The next macro places an integer in the first sizeof(int) bytes of a
231 * void pointer location. For 32-bit, it is the same as "(void *) i". It
232 * is used to solve a problem found during 64-bit testing. The problem
233 * was that for a configuration parameter such as NS_LDAP_SEARCH_REF_P,
234 * which is of type INT and has defined default value, an int
235 * variable(ns_param.ns_pu.i) defined inside an union(ns_pu) structure, is
236 * used to access the defined default value. This requires the default
237 * value to be in the first sizeof(int) bytes of the union element. If
238 * just using "(void *) intval" to declare the default value in the
239 * following defconfig[] structure, the intval data will be placed is the
240 * last sizeof(int) bytes. In which case, when accessing via ns_pu_i in
241 * a 64-bit system, ZERO will be returned as the default value, not the
244 * Note since amd64 is little-endian, the problem is not an issue.
245 * INT2VOIDPTR will just leave the data (i) unchanged.
248 #define INT2VOIDPTR(i) (void *)i
250 #define INT2VOIDPTR(i) \
251 (void *)(((long)(i))<<(8*(sizeof (void *) - sizeof (int))))
254 * The default configuration table
255 * Version 1 entries are first, V2 entries follow.
257 static ns_default_config defconfig
[] = {
258 /* optional V1 profile */
259 {"NS_LDAP_FILE_VERSION", NS_LDAP_FILE_VERSION_P
,
260 CLIENTCONFIG
, CHARPTR
, TRUE
, NS_LDAP_V1
,
261 NULL
, /* No version number defined in V1 */
262 { CHARPTR
, 0, (void *)NS_LDAP_VERSION_1
},
265 /* ---------- V1 profile ---------- */
266 {"NS_LDAP_BINDDN", NS_LDAP_BINDDN_P
,
267 CREDCONFIG
, CHARPTR
, TRUE
, NS_LDAP_V1
,
269 { CHARPTR
, 0, NULL
},
270 __s_val_binddn
, NULL
},
272 {"NS_LDAP_BINDPASSWD", NS_LDAP_BINDPASSWD_P
,
273 CREDCONFIG
, CHARPTR
, TRUE
, NS_LDAP_V1
,
275 { CHARPTR
, 0, NULL
},
276 __s_val_bindpw
, NULL
},
278 {"NS_LDAP_SERVERS", NS_LDAP_SERVERS_P
,
279 SERVERCONFIG
, ARRAYCP
, FALSE
, NS_LDAP_V1
,
281 { ARRAYCP
, 0, NULL
},
282 __s_val_serverList
, NULL
},
284 {"NS_LDAP_SEARCH_BASEDN", NS_LDAP_SEARCH_BASEDN_P
,
285 SERVERCONFIG
, CHARPTR
, TRUE
, NS_LDAP_V1
,
287 { CHARPTR
, 0, NULL
},
288 __s_val_basedn
, NULL
},
290 {"NS_LDAP_AUTH", NS_LDAP_AUTH_P
,
291 CLIENTCONFIG
, ARRAYAUTH
, FALSE
, NS_LDAP_V1
,
293 { ARRAYAUTH
, 1, (void *)&ns_def_auth_v1
[0] },
294 NULL
, ns_auth_enum_v1
},
296 {"NS_LDAP_TRANSPORT_SEC", NS_LDAP_TRANSPORT_SEC_P
,
297 CLIENTCONFIG
, INT
, TRUE
, NS_LDAP_V1
,
298 _P1_TRANSPORTSECURITY
,
299 { INT
, 0, INT2VOIDPTR(NS_LDAP_TLS_NONE
) },
300 NULL
, ns_sec_enum_v1
},
302 {"NS_LDAP_SEARCH_REF", NS_LDAP_SEARCH_REF_P
,
303 CLIENTCONFIG
, INT
, TRUE
, NS_LDAP_V1
,
305 { INT
, 0, INT2VOIDPTR(NS_LDAP_FOLLOWREF
) },
306 NULL
, ns_ref_enum_v1
},
308 {"NS_LDAP_DOMAIN", NS_LDAP_DOMAIN_P
,
309 CLIENTCONFIG
, CHARPTR
, TRUE
, NS_LDAP_V1
,
310 NULL
, /* not defined in the Profile */
311 { CHARPTR
, 0, NULL
},
314 {"NS_LDAP_EXP", NS_LDAP_EXP_P
,
315 SERVERCONFIG
, TIMET
, TRUE
, NS_LDAP_V1
,
316 NULL
, /* initialized by code to time+NS_LDAP_CACHETTL */
320 {"NS_LDAP_CERT_PATH", NS_LDAP_CERT_PATH_P
,
321 CREDCONFIG
, CHARPTR
, TRUE
, NS_LDAP_V1
,
323 { CHARPTR
, 0, NULL
},
326 {"NS_LDAP_CERT_PASS", NS_LDAP_CERT_PASS_P
,
327 CREDCONFIG
, CHARPTR
, TRUE
, NS_LDAP_V1
,
328 _P1_CERTIFICATEPASSWORD
,
329 { CHARPTR
, 0, NULL
},
332 {"NS_LDAP_SEARCH_DN", NS_LDAP_SEARCH_DN_P
,
333 CLIENTCONFIG
, SSDLIST
, FALSE
, NS_LDAP_V1
,
335 { SSDLIST
, 0, NULL
},
338 {"NS_LDAP_SEARCH_SCOPE", NS_LDAP_SEARCH_SCOPE_P
,
339 CLIENTCONFIG
, INT
, TRUE
, NS_LDAP_V1
,
341 { INT
, 0, INT2VOIDPTR(NS_LDAP_SCOPE_ONELEVEL
) },
342 NULL
, ns_scope_enum_v1
},
344 {"NS_LDAP_SEARCH_TIME", NS_LDAP_SEARCH_TIME_P
,
345 CLIENTCONFIG
, INT
, TRUE
, NS_LDAP_V1
,
347 { INT
, 0, INT2VOIDPTR(NS_DEFAULT_SEARCH_TIMEOUT
) },
350 {"NS_LDAP_SERVER_PREF", NS_LDAP_SERVER_PREF_P
,
351 CLIENTCONFIG
, ARRAYCP
, FALSE
, NS_LDAP_V1
,
353 { ARRAYCP
, 0, NULL
},
354 __s_val_serverList
, NULL
},
356 {"NS_LDAP_PREF_ONLY", NS_LDAP_PREF_ONLY_P
,
357 CLIENTCONFIG
, INT
, TRUE
, NS_LDAP_V1
,
358 _P1_PREFERREDSERVERONLY
,
359 { INT
, 0, INT2VOIDPTR(NS_LDAP_PREF_FALSE
) },
360 NULL
, ns_pref_enum
},
362 {"NS_LDAP_CACHETTL", NS_LDAP_CACHETTL_P
,
363 CLIENTCONFIG
, CHARPTR
, TRUE
, NS_LDAP_V1
,
365 { CHARPTR
, 0, (void *)EXP_DEFAULT_TTL
},
366 __s_val_postime
, NULL
},
368 {"NS_LDAP_PROFILE", NS_LDAP_PROFILE_P
,
369 CLIENTCONFIG
, CHARPTR
, TRUE
, NS_LDAP_V1
,
371 { CHARPTR
, 0, (void *)DEFAULTCONFIGNAME
},
374 {"NS_LDAP_BIND_TIME", NS_LDAP_BIND_TIME_P
,
375 CLIENTCONFIG
, INT
, TRUE
, NS_LDAP_V1
,
377 { INT
, 0, INT2VOIDPTR(NS_DEFAULT_BIND_TIMEOUT
) },
380 /* This configuration option is not visible in V1 */
381 {"NS_LDAP_CREDENTIAL_LEVEL", NS_LDAP_CREDENTIAL_LEVEL_P
,
382 CLIENTCONFIG
, ARRAYCRED
, TRUE
, NS_LDAP_V1
,
383 NULL
, /* No version defined in V1 */
384 { ARRAYCRED
, 0, (void *)&ns_def_cred_v1
[0] },
387 /* ---------- V2 profile ---------- */
388 {"NS_LDAP_FILE_VERSION", NS_LDAP_FILE_VERSION_P
,
389 CLIENTCONFIG
, CHARPTR
, TRUE
, NS_LDAP_V2
,
390 NULL
, /* No version number defined in V1 */
391 { CHARPTR
, 0, (void *)NS_LDAP_VERSION_2
},
394 {"NS_LDAP_BINDDN", NS_LDAP_BINDDN_P
,
395 CREDCONFIG
, CHARPTR
, TRUE
, NS_LDAP_V2
,
396 NULL
, /* not defined in the Profile */
397 { CHARPTR
, 0, NULL
},
398 __s_val_binddn
, NULL
},
400 {"NS_LDAP_BINDPASSWD", NS_LDAP_BINDPASSWD_P
,
401 CREDCONFIG
, CHARPTR
, TRUE
, NS_LDAP_V2
,
402 NULL
, /* not defined in the Profile */
403 { CHARPTR
, 0, NULL
},
404 __s_val_bindpw
, NULL
},
406 {"NS_LDAP_ENABLE_SHADOW_UPDATE", NS_LDAP_ENABLE_SHADOW_UPDATE_P
,
407 CREDCONFIG
, INT
, TRUE
, NS_LDAP_V2
,
408 NULL
, /* not defined in the Profile */
409 { INT
, 0, INT2VOIDPTR(NS_LDAP_ENABLE_SHADOW_UPDATE_FALSE
) },
410 NULL
, ns_shadow_update_enum
},
412 {"NS_LDAP_ADMIN_BINDDN", NS_LDAP_ADMIN_BINDDN_P
,
413 CREDCONFIG
, CHARPTR
, TRUE
, NS_LDAP_V2
,
414 NULL
, /* not defined in the Profile */
415 { CHARPTR
, 0, NULL
},
416 __s_val_binddn
, NULL
},
418 {"NS_LDAP_ADMIN_BINDPASSWD", NS_LDAP_ADMIN_BINDPASSWD_P
,
419 CREDCONFIG
, CHARPTR
, TRUE
, NS_LDAP_V2
,
420 NULL
, /* not defined in the Profile */
421 { CHARPTR
, 0, NULL
},
422 __s_val_bindpw
, NULL
},
424 {"NS_LDAP_EXP", NS_LDAP_EXP_P
,
425 SERVERCONFIG
, TIMET
, TRUE
, NS_LDAP_V2
,
426 NULL
, /* initialized by code to time+NS_LDAP_CACHETTL */
430 {"NS_LDAP_SERVER_PREF", NS_LDAP_SERVER_PREF_P
,
431 CLIENTCONFIG
, SERVLIST
, FALSE
, NS_LDAP_V2
,
433 { SERVLIST
, 0, NULL
},
434 __s_val_serverList
, NULL
},
436 {"NS_LDAP_SERVERS", NS_LDAP_SERVERS_P
,
437 SERVERCONFIG
, SERVLIST
, FALSE
, NS_LDAP_V2
,
439 { SERVLIST
, 0, NULL
},
440 __s_val_serverList
, NULL
},
442 {"NS_LDAP_SEARCH_BASEDN", NS_LDAP_SEARCH_BASEDN_P
,
443 SERVERCONFIG
, CHARPTR
, TRUE
, NS_LDAP_V2
,
445 { CHARPTR
, 0, NULL
},
446 __s_val_basedn
, NULL
},
448 {"NS_LDAP_SEARCH_SCOPE", NS_LDAP_SEARCH_SCOPE_P
,
449 CLIENTCONFIG
, INT
, TRUE
, NS_LDAP_V2
,
451 { INT
, 0, INT2VOIDPTR(NS_LDAP_SCOPE_ONELEVEL
) },
452 NULL
, ns_scope_enum_v2
},
454 {"NS_LDAP_AUTH", NS_LDAP_AUTH_P
,
455 CLIENTCONFIG
, ARRAYAUTH
, FALSE
, NS_LDAP_V2
,
457 { ARRAYAUTH
, 2, (void *)&ns_def_auth_v2
[0] },
458 NULL
, ns_auth_enum_v2
},
460 {"NS_LDAP_CREDENTIAL_LEVEL", NS_LDAP_CREDENTIAL_LEVEL_P
,
461 CLIENTCONFIG
, ARRAYCRED
, FALSE
, NS_LDAP_V2
,
463 { ARRAYCRED
, 0, (void *)&ns_def_cred_v2
[0] },
464 NULL
, ns_cred_enum_v2
},
466 {"NS_LDAP_SERVICE_SEARCH_DESC", NS_LDAP_SERVICE_SEARCH_DESC_P
,
467 CLIENTCONFIG
, SSDLIST
, FALSE
, NS_LDAP_V2
,
468 _P2_SERVICESEARCHDESC
,
469 { SSDLIST
, 0, NULL
},
472 {"NS_LDAP_SEARCH_TIME", NS_LDAP_SEARCH_TIME_P
,
473 CLIENTCONFIG
, INT
, TRUE
, NS_LDAP_V2
,
475 { INT
, 0, INT2VOIDPTR(NS_DEFAULT_SEARCH_TIMEOUT
) },
478 {"NS_LDAP_BIND_TIME", NS_LDAP_BIND_TIME_P
,
479 CLIENTCONFIG
, INT
, TRUE
, NS_LDAP_V2
,
481 { INT
, 0, INT2VOIDPTR(NS_DEFAULT_BIND_TIMEOUT
) },
484 {"NS_LDAP_SEARCH_REF", NS_LDAP_SEARCH_REF_P
,
485 CLIENTCONFIG
, INT
, TRUE
, NS_LDAP_V2
,
487 { INT
, 0, INT2VOIDPTR(NS_LDAP_FOLLOWREF
) },
488 NULL
, ns_ref_enum_v2
},
490 {"NS_LDAP_CACHETTL", NS_LDAP_CACHETTL_P
,
491 CLIENTCONFIG
, CHARPTR
, TRUE
, NS_LDAP_V2
,
493 { CHARPTR
, 0, (void *)EXP_DEFAULT_TTL
},
494 __s_val_postime
, NULL
},
496 {"NS_LDAP_ATTRIBUTEMAP", NS_LDAP_ATTRIBUTEMAP_P
,
497 CLIENTCONFIG
, ATTRMAP
, FALSE
, NS_LDAP_V2
,
499 { ATTRMAP
, 0, NULL
},
502 {"NS_LDAP_OBJECTCLASSMAP", NS_LDAP_OBJECTCLASSMAP_P
,
503 CLIENTCONFIG
, OBJMAP
, FALSE
, NS_LDAP_V2
,
508 {"NS_LDAP_PROFILE", NS_LDAP_PROFILE_P
,
509 CLIENTCONFIG
, CHARPTR
, TRUE
, NS_LDAP_V2
,
511 { CHARPTR
, 0, (void *)DEFAULTCONFIGNAME
},
514 {"NS_LDAP_SERVICE_AUTH_METHOD", NS_LDAP_SERVICE_AUTH_METHOD_P
,
515 CLIENTCONFIG
, SAMLIST
, FALSE
, NS_LDAP_V2
,
516 _P2_SERVICEAUTHMETHOD
,
517 { SAMLIST
, 0, NULL
},
520 {"NS_LDAP_SERVICE_CRED_LEVEL", NS_LDAP_SERVICE_CRED_LEVEL_P
,
521 CLIENTCONFIG
, SCLLIST
, FALSE
, NS_LDAP_V2
,
522 _P2_SERVICECREDLEVEL
,
523 { SCLLIST
, 0, NULL
},
526 {"NS_LDAP_HOST_CERTPATH", NS_LDAP_HOST_CERTPATH_P
,
527 CREDCONFIG
, CHARPTR
, TRUE
, NS_LDAP_V2
,
528 NULL
, /* not defined in the Profile */
529 { CHARPTR
, 0, (void *)NSLDAPDIRECTORY
},
532 /* array terminator [not an entry] */
533 {NULL
, NS_LDAP_FILE_VERSION_P
,
534 CLIENTCONFIG
, NS_UNKNOWN
, TRUE
, 0,
536 { NS_UNKNOWN
, 0, NULL
},
544 * The sysinfo man page recommends using a buffer size
545 * of 257 bytes. MAXHOSTNAMELEN is 256. So add 1 here.
547 char buf
[MAXHOSTNAMELEN
+ 1];
550 status
= sysinfo(SI_SRPC_DOMAIN
, buf
, MAXHOSTNAMELEN
);
553 /* error: not enough space to hold returned value */
554 if (status
> sizeof (buf
))
556 return (strdup(buf
));
560 __ns_ldap_setServer(int set
)
566 timetorefresh(ns_config_t
*cfg
)
569 static time_t expire
= 0;
571 if (cfg
== NULL
|| gettimeofday(&tp
, NULL
) == -1)
574 if (cfg
->paramList
[NS_LDAP_EXP_P
].ns_ptype
== TIMET
)
575 expire
= cfg
->paramList
[NS_LDAP_EXP_P
].ns_tm
;
579 return (expire
!= 0 && tp
.tv_sec
> expire
);
583 __s_get_enum_value(ns_config_t
*ptr
, char *value
, ParamIndexType i
)
585 register ns_enum_map
*mapp
;
586 char *pstart
= value
;
593 /* skip leading spaces */
594 while (*pstart
== SPACETOK
)
596 /* skip trailing spaces */
597 pend
= pstart
+ strlen(pstart
) - 1;
598 for (; pend
>= pstart
&& *pend
== SPACETOK
; pend
--)
600 len
= pend
- pstart
+ 1;
606 if (ptr
->version
== NS_LDAP_V1
)
607 mapp
= &ns_auth_enum_v1
[0];
609 mapp
= &ns_auth_enum_v2
[0];
611 case NS_LDAP_TRANSPORT_SEC_P
:
613 case NS_LDAP_SEARCH_SCOPE_P
:
614 if (ptr
->version
== NS_LDAP_V1
)
615 mapp
= &ns_scope_enum_v1
[0];
617 mapp
= &ns_scope_enum_v2
[0];
619 case NS_LDAP_SEARCH_REF_P
:
620 if (ptr
->version
== NS_LDAP_V1
)
621 mapp
= &ns_ref_enum_v1
[0];
623 mapp
= &ns_ref_enum_v2
[0];
625 case NS_LDAP_PREF_ONLY_P
:
626 mapp
= &ns_pref_enum
[0];
628 case NS_LDAP_ENABLE_SHADOW_UPDATE_P
:
629 mapp
= &ns_shadow_update_enum
[0];
631 case NS_LDAP_CREDENTIAL_LEVEL_P
:
632 if (ptr
->version
== NS_LDAP_V1
)
635 mapp
= &ns_cred_enum_v2
[0];
637 case NS_LDAP_SERVICE_AUTH_METHOD_P
:
638 mapp
= &ns_auth_enum_v2
[0];
640 case NS_LDAP_SERVICE_CRED_LEVEL_P
:
641 mapp
= &ns_cred_enum_v2
[0];
647 for (; mapp
->name
!= NULL
; mapp
++) {
648 if (strncasecmp(pstart
, mapp
->name
, len
) == 0 &&
649 (strlen(mapp
->name
) == len
)) {
650 return (mapp
->value
);
657 __s_get_auth_name(ns_config_t
*ptr
, AuthType_t type
)
659 register ns_enum_map
*mapp
;
661 if (ptr
->version
== NS_LDAP_V1
)
662 mapp
= &ns_auth_enum_v1
[0];
664 mapp
= &ns_auth_enum_v2
[0];
666 for (; mapp
->name
!= NULL
; mapp
++) {
667 if (type
== INT2AUTHENUM(mapp
->value
)) {
671 return ("Unknown AuthType_t type specified");
676 __s_get_security_name(ns_config_t
*ptr
, TlsType_t type
)
678 register ns_enum_map
*mapp
;
680 if (ptr
->version
== NS_LDAP_V1
) {
681 mapp
= &ns_sec_enum_v1
[0];
683 for (; mapp
->name
!= NULL
; mapp
++) {
684 if (type
== INT2SECENUM(mapp
->value
)) {
689 return ("Unknown TlsType_t type specified");
694 __s_get_scope_name(ns_config_t
*ptr
, ScopeType_t type
)
696 register ns_enum_map
*mapp
;
698 if (ptr
->version
== NS_LDAP_V1
)
699 mapp
= &ns_scope_enum_v1
[0];
701 mapp
= &ns_scope_enum_v2
[0];
703 for (; mapp
->name
!= NULL
; mapp
++) {
704 if (type
== INT2SCOPEENUM(mapp
->value
)) {
708 return ("Unknown ScopeType_t type specified");
713 __s_get_pref_name(PrefOnly_t type
)
715 register ns_enum_map
*mapp
= &ns_pref_enum
[0];
717 for (; mapp
->name
!= NULL
; mapp
++) {
718 if (type
== INT2PREFONLYENUM(mapp
->value
)) {
722 return ("Unknown PrefOnly_t type specified");
726 __s_get_searchref_name(ns_config_t
*ptr
, SearchRef_t type
)
728 register ns_enum_map
*mapp
;
730 if (ptr
->version
== NS_LDAP_V1
)
731 mapp
= &ns_ref_enum_v1
[0];
733 mapp
= &ns_ref_enum_v2
[0];
735 for (; mapp
->name
!= NULL
; mapp
++) {
736 if (type
== INT2SEARCHREFENUM(mapp
->value
)) {
740 return ("Unknown SearchRef_t type specified");
744 __s_get_shadowupdate_name(enableShadowUpdate_t type
)
746 register ns_enum_map
*mapp
;
748 mapp
= &ns_shadow_update_enum
[0];
750 for (; mapp
->name
!= NULL
; mapp
++) {
751 if (type
== INT2SHADOWUPDATENUM(mapp
->value
)) {
755 return ("Unknown enableShadowUpdate_t type specified");
759 __s_get_credlvl_name(ns_config_t
*ptr
, CredLevel_t type
)
761 register ns_enum_map
*mapp
;
763 if (ptr
->version
== NS_LDAP_V2
) {
764 mapp
= &ns_cred_enum_v2
[0];
765 for (; mapp
->name
!= NULL
; mapp
++) {
766 if (type
== INT2CREDLEVELENUM(mapp
->value
)) {
771 return ("Unknown CredLevel_t type specified");
775 destroy_param(ns_config_t
*ptr
, ParamIndexType type
)
784 * This routine is not lock protected because
785 * the config param it may be destroying is not
786 * necessarily THE config. Mutex protect elsewhere.
788 switch (ptr
->paramList
[type
].ns_ptype
) {
790 if (ptr
->paramList
[type
].ns_pc
) {
791 free(ptr
->paramList
[type
].ns_pc
);
792 ptr
->paramList
[type
].ns_pc
= NULL
;
800 if (ptr
->paramList
[type
].ns_ppc
) {
801 ppc
= ptr
->paramList
[type
].ns_ppc
;
802 j
= ptr
->paramList
[type
].ns_acnt
;
803 for (i
= 0; i
< j
&& ppc
[i
] != NULL
; i
++) {
804 free((void *)ppc
[i
]);
807 ptr
->paramList
[type
].ns_ppc
= NULL
;
812 if (ptr
->paramList
[type
].ns_pi
) {
813 free(ptr
->paramList
[type
].ns_pi
);
814 ptr
->paramList
[type
].ns_pi
= NULL
;
818 ptr
->paramList
[type
].ns_i
= 0;
827 ptr
->paramList
[type
].ns_ptype
= NS_UNKNOWN
;
831 destroy_config(ns_config_t
*ptr
)
836 if (ptr
== current_config
)
837 current_config
= NULL
;
838 free(ptr
->domainName
);
839 ptr
->domainName
= NULL
;
840 for (i
= 0; i
<= LAST_VALUE
; i
++) {
841 destroy_param(ptr
, i
);
843 __s_api_destroy_hash(ptr
);
849 * Marks the ns_config_t to be deleted and then releases it. (If no other
850 * caller is using, then __s_api_release_config will destroy it.)
852 * Note that __s_api_destroy_config should only be called if the caller has
853 * created the ns_config_t with __s_api_create_config (with the exception
854 * of set_curr_config). The ns_config_t should be private to the caller.
856 * This function should not be called with the current_config except by
857 * set_curr_config which locks ns_parse_lock to ensure that no thread
858 * will be waiting on current_config->config_mutex. This ensures that
859 * no caller with be waiting on cfg->config_mutex while it is being
860 * destroyed by __s_api_release_config.
864 __s_api_destroy_config(ns_config_t
*cfg
)
867 (void) mutex_lock(&cfg
->config_mutex
);
869 (void) mutex_unlock(&cfg
->config_mutex
);
870 __s_api_release_config(cfg
);
876 * Increment the configuration use count by one - assumes ns_parse_lock has
881 get_curr_config_unlocked(ns_config_t
*cfg
, boolean_t global
)
887 (void) mutex_lock(&cfg
->config_mutex
);
889 * allow access to per connection management (non-global)
890 * config so operations on connection being closed can still
893 if (cfg
->delete && global
== B_TRUE
)
897 (void) mutex_unlock(&cfg
->config_mutex
);
903 * set_curr_config_global sets the current global config to the
904 * specified ns_config_t. Note that this function is similar
905 * to the project private function __s_api_init_config_global
906 * except that it does not release the new ns_config_t.
909 set_curr_config_global(ns_config_t
*ptr
)
912 ns_config_t
*cur_cfg
;
914 (void) mutex_lock(&ns_parse_lock
);
915 cur_cfg
= current_config
;
916 cfg
= get_curr_config_unlocked(cur_cfg
, B_TRUE
);
918 __s_api_destroy_config(cfg
);
919 current_config
= ptr
;
921 (void) mutex_unlock(&ns_parse_lock
);
926 * set_curr_config sets the current config or the per connection
927 * management one to the specified ns_config_t. Note that this function
928 * is similar to the project private function __s_api_init_config
929 * except that it does not release the new ns_config_t. Also note
930 * that if there's no per connection management one to set, the
931 * global current config will be set.
935 set_curr_config(ns_config_t
*ptr
)
938 ns_config_t
*cur_cfg
;
942 rc
= thr_getspecific(ns_cmgkey
, (void **)&cmg
);
944 /* set the per connection management config if possible */
945 if (rc
== 0 && cmg
!= NULL
&& cmg
->config
!= NULL
) {
946 (void) mutex_lock(&cmg
->cfg_lock
);
947 cur_cfg
= cmg
->config
;
948 cfg
= get_curr_config_unlocked(cur_cfg
, B_FALSE
);
950 __s_api_destroy_config(cfg
);
953 (void) mutex_unlock(&cmg
->cfg_lock
);
957 /* else set the global current config */
958 set_curr_config_global(ptr
);
962 * Decrements the ns_config_t usage count by one. Delete if delete flag
963 * is set and no other callers are using.
967 __s_api_release_config(ns_config_t
*cfg
)
970 (void) mutex_lock(&cfg
->config_mutex
);
972 if (cfg
->nUse
== 0 && cfg
->delete) {
975 (void) mutex_unlock(&cfg
->config_mutex
);
980 * __s_api_init_config function destroys the previous global configuration
981 * sets the new global configuration and then releases it
984 __s_api_init_config_global(ns_config_t
*ptr
)
986 set_curr_config_global(ptr
);
987 __s_api_release_config(ptr
);
991 * __s_api_init_config function destroys the previous configuration
992 * sets the new configuration and then releases it. The configuration
993 * may be the global one or the per connection management one.
996 __s_api_init_config(ns_config_t
*ptr
)
998 set_curr_config(ptr
);
999 __s_api_release_config(ptr
);
1004 * Create an ns_config_t, set the usage count to one
1008 __s_api_create_config(void)
1011 ret
= (ns_config_t
*)calloc(1, sizeof (ns_config_t
));
1015 ret
->domainName
= __getdomainname();
1016 if (ret
->domainName
== NULL
) {
1020 ret
->version
= NS_LDAP_V1
;
1021 (void) mutex_init(&ret
->config_mutex
, USYNC_THREAD
, NULL
);
1023 ret
->delete = B_FALSE
;
1028 * __s_api_get_default_config_global returns the current global config
1031 __s_api_get_default_config_global(void)
1034 ns_config_t
*cur_cfg
;
1036 (void) mutex_lock(&ns_parse_lock
);
1037 cur_cfg
= current_config
;
1038 cfg
= get_curr_config_unlocked(cur_cfg
, B_TRUE
);
1039 (void) mutex_unlock(&ns_parse_lock
);
1045 * __s_api_get_default_config returns the current global config or the
1046 * per connection management one.
1049 __s_api_get_default_config(void)
1052 ns_config_t
*cur_cfg
;
1053 ns_conn_mgmt_t
*cmg
;
1056 rc
= thr_getspecific(ns_cmgkey
, (void **)&cmg
);
1058 /* get the per connection management config if available */
1059 if (rc
== 0 && cmg
!= NULL
&& cmg
->config
!= NULL
) {
1060 (void) mutex_lock(&cmg
->cfg_lock
);
1061 cur_cfg
= cmg
->config
;
1062 cfg
= get_curr_config_unlocked(cur_cfg
, B_FALSE
);
1063 (void) mutex_unlock(&cmg
->cfg_lock
);
1067 /* else get the global current config */
1068 return (__s_api_get_default_config_global());
1072 stripdup(const char *instr
)
1074 char *pstart
= (char *)instr
;
1080 /* remove leading spaces */
1081 while (*pstart
== SPACETOK
)
1083 /* remove trailing spaces */
1084 pend
= pstart
+ strlen(pstart
) - 1;
1085 for (; pend
>= pstart
&& *pend
== SPACETOK
; pend
--)
1087 len
= pend
- pstart
+ 1;
1088 if ((ret
= malloc(len
+ 1)) == NULL
)
1091 (void) strncpy(ret
, pstart
, len
);
1098 * Note that __s_api_crosscheck is assumed to be called with an ns_config_t
1099 * that is properly protected - so that it will not change during the
1100 * duration of the call
1103 /* Size of errstr needs to be MAXERROR */
1105 __s_api_crosscheck(ns_config_t
*ptr
, char *errstr
, int check_dn
)
1109 const char *str
, *str1
;
1114 return (NS_SUCCESS
);
1116 /* check for no server specified */
1117 if (ptr
->paramList
[NS_LDAP_SERVERS_P
].ns_ppc
== NULL
) {
1118 if (ptr
->version
== NS_LDAP_V1
) {
1119 str
= NULL_OR_STR(__s_api_get_configname(
1120 NS_LDAP_SERVERS_P
));
1121 (void) snprintf(errstr
, MAXERROR
,
1122 gettext("Configuration Error: No entry for "
1123 "'%s' found"), str
);
1124 return (NS_PARSE_ERR
);
1125 } else if (ptr
->paramList
[NS_LDAP_SERVER_PREF_P
].ns_ppc
==
1127 str
= NULL_OR_STR(__s_api_get_configname(
1128 NS_LDAP_SERVERS_P
));
1129 str1
= NULL_OR_STR(__s_api_get_configname(
1130 NS_LDAP_SERVER_PREF_P
));
1131 (void) snprintf(errstr
, MAXERROR
,
1132 gettext("Configuration Error: "
1133 "Neither '%s' nor '%s' is defined"), str
, str1
);
1134 return (NS_PARSE_ERR
);
1137 if (ptr
->paramList
[NS_LDAP_CERT_PASS_P
].ns_pc
!= NULL
&&
1138 ptr
->paramList
[NS_LDAP_CERT_PATH_P
].ns_pc
== NULL
) {
1139 str
= NULL_OR_STR(__s_api_get_configname(
1140 NS_LDAP_CERT_PASS_P
));
1141 str1
= NULL_OR_STR(__s_api_get_configname(
1142 NS_LDAP_CERT_PATH_P
));
1143 (void) snprintf(errstr
, MAXERROR
,
1144 gettext("Configuration Error: %s specified "
1145 "but no value for '%s' found"), str
, str1
);
1146 return (NS_PARSE_ERR
);
1148 if (ptr
->paramList
[NS_LDAP_CERT_PASS_P
].ns_pc
== NULL
&&
1149 ptr
->paramList
[NS_LDAP_CERT_PATH_P
].ns_pc
!= NULL
) {
1150 str
= NULL_OR_STR(__s_api_get_configname(
1151 NS_LDAP_CERT_PATH_P
));
1152 str1
= NULL_OR_STR(__s_api_get_configname(
1153 NS_LDAP_CERT_PASS_P
));
1154 (void) snprintf(errstr
, MAXERROR
,
1155 gettext("Configuration Error: %s specified "
1156 "but no value for '%s' found"), str
, str1
);
1157 return (NS_PARSE_ERR
);
1159 /* check if search basedn has been specified */
1160 if (ptr
->paramList
[NS_LDAP_SEARCH_BASEDN_P
].ns_ppc
== NULL
) {
1161 str
= NULL_OR_STR(__s_api_get_configname(
1162 NS_LDAP_SEARCH_BASEDN_P
));
1163 (void) snprintf(errstr
, MAXERROR
,
1164 gettext("Configuration Error: No entry for "
1165 "'%s' found"), str
);
1166 return (NS_PARSE_ERR
);
1170 /* check for auth value....passwd/bindn if necessary */
1172 for (j
= 0; ptr
->paramList
[NS_LDAP_AUTH_P
].ns_pi
!= NULL
&&
1173 ptr
->paramList
[NS_LDAP_AUTH_P
].ns_pi
[j
] != 0; j
++) {
1174 value
= ptr
->paramList
[NS_LDAP_AUTH_P
].ns_pi
[j
];
1176 case NS_LDAP_EA_SIMPLE
:
1177 case NS_LDAP_EA_SASL_CRAM_MD5
:
1178 case NS_LDAP_EA_SASL_DIGEST_MD5
:
1179 case NS_LDAP_EA_SASL_DIGEST_MD5_INT
:
1180 case NS_LDAP_EA_SASL_DIGEST_MD5_CONF
:
1181 case NS_LDAP_EA_TLS_SIMPLE
:
1182 case NS_LDAP_EA_TLS_SASL_CRAM_MD5
:
1183 case NS_LDAP_EA_TLS_SASL_DIGEST_MD5
:
1184 case NS_LDAP_EA_TLS_SASL_DIGEST_MD5_INT
:
1185 case NS_LDAP_EA_TLS_SASL_DIGEST_MD5_CONF
:
1186 if (ptr
->paramList
[NS_LDAP_BINDDN_P
].ns_ppc
== NULL
) {
1187 str
= NULL_OR_STR(__s_api_get_configname(
1189 (void) snprintf(errstr
, MAXERROR
,
1190 gettext("Configuration Error: No entry for "
1191 "'%s' found"), str
);
1192 return (NS_PARSE_ERR
);
1194 if (ptr
->paramList
[NS_LDAP_BINDPASSWD_P
].ns_ppc
1196 str
= NULL_OR_STR(__s_api_get_configname(
1197 NS_LDAP_BINDPASSWD_P
));
1198 (void) snprintf(errstr
, MAXERROR
,
1199 gettext("Configuration Error: No entry for "
1200 "'%s' found"), str
);
1201 return (NS_PARSE_ERR
);
1209 * If NS_LDAP_CACHETTL is not specified,
1210 * init NS_LDAP_EXP_P here. Otherwise,
1211 * ldap_cachemgr will never refresh the profile.
1212 * Set it to current time + default
1215 if (ptr
->paramList
[NS_LDAP_CACHETTL_P
].ns_pc
== NULL
) {
1217 defconfig
[NS_LDAP_CACHETTL_P
].defval
.ns_pc
);
1218 ptr
->paramList
[NS_LDAP_EXP_P
].ns_ptype
= TIMET
;
1222 ptr
->paramList
[NS_LDAP_EXP_P
].ns_tm
= tm
;
1225 * If credential level self is defined, there should be
1226 * at least an auth method sasl/GSSAPI and vice versa.
1229 cnt
= ptr
->paramList
[NS_LDAP_CREDENTIAL_LEVEL_P
].ns_acnt
;
1230 for (i
= 0; i
< cnt
; i
++) {
1231 if (ptr
->paramList
[NS_LDAP_CREDENTIAL_LEVEL_P
].ns_pi
[i
] ==
1236 cnt
= ptr
->paramList
[NS_LDAP_AUTH_P
].ns_acnt
;
1237 for (i
= 0; i
< cnt
; i
++) {
1238 if (ptr
->paramList
[NS_LDAP_AUTH_P
].ns_pi
[i
] ==
1239 NS_LDAP_EA_SASL_GSSAPI
)
1242 if (gssapi
== 0 && self
> 0) {
1243 (void) snprintf(errstr
, MAXERROR
,
1244 gettext("Configuration Error: "
1245 "Credential level self requires "
1246 "authentication method sasl/GSSAPI"));
1247 return (NS_PARSE_ERR
);
1249 if (gssapi
> 0 && self
== 0) {
1250 (void) snprintf(errstr
, MAXERROR
,
1251 gettext("Configuration Error: "
1252 "Authentication method sasl/GSSAPI "
1253 "requires credential level self"));
1254 return (NS_PARSE_ERR
);
1256 return (NS_SUCCESS
);
1261 __s_api_get_type(const char *value
, ParamIndexType
*type
)
1265 for (i
= 0; defconfig
[i
].name
!= NULL
; i
++) {
1266 if (strcasecmp(defconfig
[i
].name
, value
) == 0) {
1267 *type
= defconfig
[i
].index
;
1275 * Externally defined version of get_type.
1276 * Includes extra error checking
1280 __ns_ldap_getParamType(const char *value
, ParamIndexType
*type
)
1282 if (value
== NULL
|| type
== NULL
)
1284 return (__s_api_get_type(value
, type
));
1288 __s_api_get_versiontype(ns_config_t
*ptr
, char *value
, ParamIndexType
*type
)
1298 for (i
= 0; defconfig
[i
].name
!= NULL
; i
++) {
1299 if (strcasecmp(defconfig
[i
].name
, value
) == 0) {
1300 if (defconfig
[i
].version
== ver
) {
1301 *type
= defconfig
[i
].index
;
1310 __s_api_get_profiletype(char *value
, ParamIndexType
*type
)
1314 for (i
= 0; defconfig
[i
].name
!= NULL
; i
++) {
1315 if (defconfig
[i
].profile_name
== NULL
)
1317 if (strcasecmp(defconfig
[i
].profile_name
, value
) == 0) {
1318 *type
= defconfig
[i
].index
;
1326 __s_api_get_configtype(ParamIndexType type
)
1330 for (i
= 0; defconfig
[i
].name
!= NULL
; i
++) {
1331 if (defconfig
[i
].index
== type
) {
1332 return (defconfig
[i
].config_type
);
1339 __s_api_get_configname(ParamIndexType type
)
1343 for (i
= 0; defconfig
[i
].name
!= NULL
; i
++) {
1344 if (defconfig
[i
].index
== type
) {
1345 if (defconfig
[i
].name
[0] == '\0')
1348 return (defconfig
[i
].name
);
1354 static ns_default_config
*
1355 get_defconfig(ns_config_t
*ptr
, ParamIndexType type
)
1362 for (i
= 0; defconfig
[i
].name
!= NULL
; i
++) {
1363 if (defconfig
[i
].index
== type
&&
1364 defconfig
[i
].version
== ver
) {
1365 return (&defconfig
[i
]);
1372 set_default_value(ns_config_t
*configptr
, char *name
,
1373 char *value
, ns_ldap_error_t
**error
)
1377 char errstr
[MAXERROR
];
1379 if (__s_api_get_type(name
, &i
) < 0) {
1380 (void) snprintf(errstr
, sizeof (errstr
), gettext(
1381 "Illegal type name (%s).\n"), name
);
1382 MKERROR(LOG_ERR
, *error
, NS_CONFIG_SYNTAX
, strdup(errstr
),
1384 return (NS_LDAP_CONFIG
);
1387 if (i
!= NS_LDAP_SERVERS_P
&&
1388 i
!= NS_LDAP_SERVICE_AUTH_METHOD_P
&&
1389 i
!= NS_LDAP_SERVICE_CRED_LEVEL_P
&&
1390 i
!= NS_LDAP_SERVICE_SEARCH_DESC_P
&&
1391 i
!= NS_LDAP_SERVER_PREF_P
&&
1392 i
!= NS_LDAP_SEARCH_DN_P
) {
1393 if (configptr
->paramList
[i
].ns_ptype
!= NS_UNKNOWN
) {
1394 destroy_param(configptr
, i
);
1398 ret
= __ns_ldap_setParamValue(configptr
, i
, value
, error
);
1404 * Initialize config to a default state
1405 * By default leave configuration empty
1406 * getParam will automatically get the
1407 * appropriate default value if none exists
1411 __ns_ldap_default_config()
1415 ptr
= __s_api_create_config();
1419 set_curr_config(ptr
);
1420 __s_api_release_config(ptr
);
1424 * Get the current configuration pointer and return it.
1425 * If necessary initialize or refresh the current
1426 * configuration as applicable. If global is set, returns
1430 static ns_config_t
*
1431 loadrefresh_config(boolean_t global
)
1434 ns_config_t
*new_cfg
;
1435 ns_ldap_error_t
*errorp
;
1437 /* We want to refresh only one configuration at a time */
1438 (void) mutex_lock(&ns_loadrefresh_lock
);
1439 if (global
== B_TRUE
)
1440 cfg
= __s_api_get_default_config_global();
1442 cfg
= __s_api_get_default_config();
1444 /* (re)initialize configuration if necessary */
1445 if (!__s_api_isStandalone() && timetorefresh(cfg
)) {
1446 new_cfg
= LoadCacheConfiguration(cfg
, &errorp
);
1447 if (new_cfg
!= NULL
&& new_cfg
!= cfg
) {
1448 __s_api_release_config(cfg
);
1449 if (global
== B_TRUE
)
1450 set_curr_config_global(new_cfg
);
1452 set_curr_config(new_cfg
);
1456 (void) __ns_ldap_freeError(&errorp
);
1458 (void) mutex_unlock(&ns_loadrefresh_lock
);
1463 * Get the current global configuration pointer and return it.
1464 * If necessary initialize or refresh the current
1465 * configuration as applicable.
1469 __s_api_loadrefresh_config_global()
1471 return (loadrefresh_config(B_TRUE
));
1475 * Get the current configuration pointer and return it.
1476 * If necessary initialize or refresh the current
1477 * configuration as applicable. The configuration may
1478 * be the global one or the per connection management one.
1482 __s_api_loadrefresh_config()
1484 return (loadrefresh_config(B_FALSE
));
1488 * In general this routine is not very usefull. Individual routines can be
1489 * created to do this job. Once that is done, this function can be removed.
1490 * Size of errstr buffer needs to be MAXERROR.
1492 static ns_parse_status
1493 verify_value(ns_config_t
*cfg
, char *name
, char *value
, char *errstr
)
1495 ParamIndexType index
= 0;
1497 char *ptr
= NULL
, *strptr
= NULL
, buffer
[BUFSIZE
];
1499 ns_default_config
*def
= NULL
;
1501 if (__s_api_get_type(name
, &index
) != 0) {
1502 (void) snprintf(errstr
, MAXERROR
,
1503 gettext("Unknown keyword encountered '%s'."), name
);
1504 return (NS_PARSE_ERR
);
1507 def
= get_defconfig(cfg
, index
);
1509 /* eat up beginning quote, if any */
1510 while (value
!= NULL
&& (*value
== QUOTETOK
|| *value
== SPACETOK
))
1513 /* eat up space/quote at end of value */
1514 if (strlen(value
) > 0)
1515 ptr
= value
+ strlen(value
) - 1;
1518 for (; ptr
!= value
&& (*ptr
== SPACETOK
|| *ptr
== QUOTETOK
); ptr
--) {
1524 case NS_LDAP_CACHETTL_P
:
1525 case NS_LDAP_CERT_PATH_P
:
1526 case NS_LDAP_CERT_PASS_P
:
1527 case NS_LDAP_CERT_NICKNAME_P
:
1528 case NS_LDAP_BINDDN_P
:
1529 case NS_LDAP_BINDPASSWD_P
:
1530 case NS_LDAP_ADMIN_BINDDN_P
:
1531 case NS_LDAP_ADMIN_BINDPASSWD_P
:
1532 case NS_LDAP_DOMAIN_P
:
1533 case NS_LDAP_SEARCH_BASEDN_P
:
1534 case NS_LDAP_SEARCH_TIME_P
:
1535 case NS_LDAP_PROFILE_P
:
1536 case NS_LDAP_AUTH_P
:
1537 case NS_LDAP_SEARCH_SCOPE_P
:
1538 case NS_LDAP_CREDENTIAL_LEVEL_P
:
1539 case NS_LDAP_SERVICE_SEARCH_DESC_P
:
1540 case NS_LDAP_BIND_TIME_P
:
1541 case NS_LDAP_ATTRIBUTEMAP_P
:
1542 case NS_LDAP_OBJECTCLASSMAP_P
:
1543 case NS_LDAP_SERVICE_AUTH_METHOD_P
:
1544 case NS_LDAP_SERVICE_CRED_LEVEL_P
:
1545 case NS_LDAP_HOST_CERTPATH_P
:
1547 case NS_LDAP_SEARCH_DN_P
:
1548 /* depreciated because of service descriptors */
1549 /* Parse as appropriate at descriptor create time */
1551 case NS_LDAP_FILE_VERSION_P
:
1552 if (value
!= NULL
&&
1553 strcasecmp(value
, NS_LDAP_VERSION_1
) != 0 &&
1554 strcasecmp(value
, NS_LDAP_VERSION_2
) != 0) {
1555 (void) snprintf(errstr
, MAXERROR
,
1556 gettext("Version mismatch, expected "
1557 "cache version '%s' or '%s' but "
1558 "encountered version '%s'."),
1560 NS_LDAP_VERSION_2
, value
);
1561 return (NS_PARSE_ERR
);
1564 case NS_LDAP_SERVERS_P
:
1565 case NS_LDAP_SERVER_PREF_P
:
1566 (void) strcpy(buffer
, value
);
1567 strptr
= strtok_r(buffer
, ",", &rest
);
1568 while (strptr
!= NULL
) {
1570 tmp
= stripdup(strptr
);
1571 if (tmp
== NULL
|| (strchr(tmp
, ' ') != NULL
)) {
1572 (void) snprintf(errstr
, MAXERROR
,
1573 gettext("Invalid parameter values "
1574 "'%s' specified for keyword '%s'."),
1577 return (NS_PARSE_ERR
);
1580 strptr
= strtok_r(NULL
, ",", &rest
);
1585 while (def
->allowed
!= NULL
&&
1586 def
->allowed
[j
].name
!= NULL
&& j
< DEFMAX
) {
1587 if (strcmp(def
->allowed
[j
].name
,
1595 (void) snprintf(errstr
, MAXERROR
,
1596 gettext("Invalid option specified for "
1597 "'%s' keyword. '%s' is not a recognized "
1598 "keyword value."), name
, value
);
1599 return (NS_PARSE_ERR
);
1603 return (NS_SUCCESS
);
1607 __s_api_split_key_value(char *buffer
, char **name
, char **value
)
1612 /* split into name value pair */
1613 if ((ptr
= strchr(buffer
, TOKENSEPARATOR
)) != NULL
) {
1616 /* trim whitespace */
1617 while (*ptr
== SPACETOK
)
1624 * Set a parameter value in a generic configuration structure
1625 * Assume any necessary locks are in place. This routine would
1626 * be better named: __ns_ldap_translateString2Param
1628 * This routine translates external string format into internal
1629 * param format and saves the result in the param table.
1632 __ns_ldap_setParamValue(ns_config_t
*ptr
, const ParamIndexType type
,
1633 const void *data
, ns_ldap_error_t
**error
)
1635 ns_default_config
*def
= NULL
;
1637 ns_mapping_t
*map
, *rmap
;
1639 char *cp
, *cp2
, *end
;
1641 char errstr
[2 * MAXERROR
];
1642 char tbuf
[100], *ptbuf
;
1643 char *sid
, *origA
, **mapA
;
1646 int free_memory
, exitrc
;
1649 /* Find ParamIndexType default configuration data */
1650 def
= get_defconfig(ptr
, type
);
1652 (void) snprintf(errstr
, sizeof (errstr
),
1653 gettext("Unable to set value: "
1654 "invalid ParamIndexType (%d)"), type
);
1655 MKERROR(LOG_ERR
, *error
, NS_CONFIG_SYNTAX
, strdup(errstr
),
1657 return (NS_LDAP_CONFIG
);
1660 (void) memset(&conf
, 0, sizeof (conf
));
1662 /* data is actually const char */
1665 /* eat up beginning quote, if any */
1666 while (cp
&& (*cp
== QUOTETOK
|| *cp
== SPACETOK
))
1669 /* eat up space/quote at end of value */
1670 end
= cp2
= cp
+ strlen(cp
) - 1;
1671 for (; cp2
> cp
&& (*cp2
== SPACETOK
|| *cp2
== QUOTETOK
); cp2
--)
1673 /* data is const, must duplicate */
1675 tcp
= (char *)calloc((int)(cp2
- cp
+ 2), sizeof (char));
1677 return (NS_LDAP_MEMORY
);
1687 /* Parse data according to type */
1688 switch (def
->data_type
) {
1690 switch (def
->index
) {
1691 case NS_LDAP_PREF_ONLY_P
:
1692 case NS_LDAP_SEARCH_REF_P
:
1693 case NS_LDAP_SEARCH_SCOPE_P
:
1694 case NS_LDAP_ENABLE_SHADOW_UPDATE_P
:
1695 i
= __s_get_enum_value(ptr
, cp
, def
->index
);
1697 (void) snprintf(errstr
, sizeof (errstr
),
1698 gettext("Unable to set value: "
1699 "invalid %s (%d)"), def
->name
,
1701 MKERROR(LOG_ERR
, *error
, NS_CONFIG_SYNTAX
,
1704 return (NS_LDAP_CONFIG
);
1708 case NS_LDAP_TRANSPORT_SEC_P
: /* ignore TRANSPORT_SEC */
1712 if ((*cp2
== '+') || (*cp2
== '-'))
1714 for (/* empty */; *cp2
; cp2
++) {
1718 (void) snprintf(errstr
, sizeof (errstr
),
1719 gettext("Unable to set value: "
1720 "invalid %s (%d)"), def
->name
,
1722 MKERROR(LOG_ERR
, *error
, NS_CONFIG_SYNTAX
,
1725 return (NS_LDAP_CONFIG
);
1733 /* Do nothing with a TIMET. Initialize it below */
1736 conf
.ns_pc
= (char *)strdup(cp
);
1737 if (conf
.ns_pc
== NULL
) {
1739 return (NS_LDAP_MEMORY
);
1743 /* first check to see if colon (:) is there */
1744 if ((strchr(cp
, COLONTOK
)) == NULL
) {
1745 (void) snprintf(errstr
, sizeof (errstr
),
1746 gettext("Unable to set value: "
1747 "invalid serviceAuthenticationMethod (%s)"),
1749 MKERROR(LOG_ERR
, *error
, NS_CONFIG_SYNTAX
,
1752 return (NS_LDAP_CONFIG
);
1754 /* Appends an entry to the existing list */
1755 if (ptr
->paramList
[type
].ns_ptype
!= SAMLIST
) {
1756 conf
.ns_ppc
= (char **)calloc(2, sizeof (char *));
1757 if (conf
.ns_ppc
== NULL
) {
1759 return (NS_LDAP_MEMORY
);
1762 conf
.ns_ppc
[0] = (char *)strdup(cp
);
1763 if (conf
.ns_ppc
[0] == NULL
) {
1766 return (NS_LDAP_MEMORY
);
1772 /* Attempt to replace if possible */
1773 dpend
= strchr(cp
, COLONTOK
);
1775 dp
= (char *)malloc(len
+1);
1778 return (NS_LDAP_MEMORY
);
1780 (void) strlcpy(dp
, cp
, len
+1);
1782 for (j
= 0; j
< ptr
->paramList
[type
].ns_acnt
; j
++) {
1783 dpend
= strchr(ptr
->paramList
[type
].ns_ppc
[j
],
1787 i
= dpend
- ptr
->paramList
[type
].ns_ppc
[j
];
1790 if (strncmp(ptr
->paramList
[type
].ns_ppc
[j
],
1793 ptr
->paramList
[type
].ns_acnt
;
1795 ptr
->paramList
[type
].ns_ppc
;
1796 ptr
->paramList
[type
].ns_ppc
= NULL
;
1797 free(conf
.ns_ppc
[j
]);
1798 conf
.ns_ppc
[j
] = (char *)strdup(cp
);
1799 if (conf
.ns_ppc
[j
] == NULL
) {
1804 return (NS_LDAP_MEMORY
);
1813 break; /* Replaced completed */
1816 len
= ptr
->paramList
[type
].ns_acnt
+ 1;
1818 p
= (char **)dupParam(&ptr
->paramList
[type
]);
1821 return (NS_LDAP_MEMORY
);
1826 reallocarray(p
, len
+ 1, sizeof (char *));
1827 if (conf
.ns_ppc
== NULL
) {
1828 __s_api_free2dArray(p
);
1830 return (NS_LDAP_MEMORY
);
1833 conf
.ns_ppc
[len
-1] = (char *)strdup(cp
);
1834 if (conf
.ns_ppc
[len
-1] == NULL
) {
1835 __s_api_free2dArray(conf
.ns_ppc
);
1837 return (NS_LDAP_MEMORY
);
1839 conf
.ns_ppc
[len
] = NULL
;
1843 /* first check to see if colon (:) is there */
1844 if ((strchr(cp
, COLONTOK
)) == NULL
) {
1845 (void) snprintf(errstr
, sizeof (errstr
),
1846 gettext("Unable to set value: "
1847 "invalid serviceCredentialLevel (%s)"),
1849 MKERROR(LOG_ERR
, *error
, NS_CONFIG_SYNTAX
,
1852 return (NS_LDAP_CONFIG
);
1854 /* Appends an entry to the existing list */
1855 if (ptr
->paramList
[type
].ns_ptype
!= SCLLIST
) {
1856 conf
.ns_ppc
= (char **)calloc(2, sizeof (char *));
1857 if (conf
.ns_ppc
== NULL
) {
1859 return (NS_LDAP_MEMORY
);
1862 conf
.ns_ppc
[0] = (char *)strdup(cp
);
1863 if (conf
.ns_ppc
[0] == NULL
) {
1866 return (NS_LDAP_MEMORY
);
1872 /* Attempt to replace if possible */
1873 dpend
= strchr(cp
, COLONTOK
);
1875 dp
= (char *)malloc(len
+1);
1878 return (NS_LDAP_MEMORY
);
1880 (void) strlcpy(dp
, cp
, len
+1);
1882 for (j
= 0; j
< ptr
->paramList
[type
].ns_acnt
; j
++) {
1883 dpend
= strchr(ptr
->paramList
[type
].ns_ppc
[j
],
1887 i
= dpend
- ptr
->paramList
[type
].ns_ppc
[j
];
1890 if (strncmp(ptr
->paramList
[type
].ns_ppc
[j
],
1893 ptr
->paramList
[type
].ns_acnt
;
1895 ptr
->paramList
[type
].ns_ppc
;
1896 ptr
->paramList
[type
].ns_ppc
= NULL
;
1897 free(conf
.ns_ppc
[j
]);
1898 conf
.ns_ppc
[j
] = (char *)strdup(cp
);
1899 if (conf
.ns_ppc
[j
] == NULL
) {
1904 return (NS_LDAP_MEMORY
);
1913 break; /* Replaced completed */
1916 len
= ptr
->paramList
[type
].ns_acnt
+ 1;
1918 p
= (char **)dupParam(&ptr
->paramList
[type
]);
1921 return (NS_LDAP_MEMORY
);
1926 reallocarray(p
, len
+ 1, sizeof (char *));
1927 if (conf
.ns_ppc
== NULL
) {
1928 __s_api_free2dArray(p
);
1930 return (NS_LDAP_MEMORY
);
1933 conf
.ns_ppc
[len
-1] = (char *)strdup(cp
);
1934 if (conf
.ns_ppc
[len
-1] == NULL
) {
1935 __s_api_free2dArray(conf
.ns_ppc
);
1937 return (NS_LDAP_MEMORY
);
1939 conf
.ns_ppc
[len
] = NULL
;
1944 * first check to see if colon (:) is there,
1945 * if so, make sure the serviceId is specified,
1946 * i.e., colon is not the first character
1948 if ((strchr(cp
, COLONTOK
)) == NULL
|| *cp
== COLONTOK
) {
1949 (void) snprintf(errstr
, sizeof (errstr
),
1950 gettext("Unable to set value: "
1951 "invalid serviceSearchDescriptor (%s)"),
1953 MKERROR(LOG_ERR
, *error
, NS_CONFIG_SYNTAX
,
1956 return (NS_LDAP_CONFIG
);
1958 /* Appends an entry to the existing list */
1959 if (ptr
->paramList
[type
].ns_ptype
!= SSDLIST
) {
1960 conf
.ns_ppc
= (char **)calloc(2, sizeof (char *));
1961 if (conf
.ns_ppc
== NULL
) {
1963 return (NS_LDAP_MEMORY
);
1966 conf
.ns_ppc
[0] = (char *)strdup(cp
);
1967 if (conf
.ns_ppc
[0] == NULL
) {
1970 return (NS_LDAP_MEMORY
);
1976 /* Attempt to replace if possible */
1977 dpend
= strchr(cp
, COLONTOK
);
1979 dp
= (char *)malloc(len
+1);
1982 return (NS_LDAP_MEMORY
);
1984 (void) strlcpy(dp
, cp
, len
+1);
1986 for (j
= 0; j
< ptr
->paramList
[type
].ns_acnt
; j
++) {
1987 dpend
= strchr(ptr
->paramList
[type
].ns_ppc
[j
],
1991 i
= dpend
- ptr
->paramList
[type
].ns_ppc
[j
];
1994 if (strncmp(ptr
->paramList
[type
].ns_ppc
[j
],
1997 ptr
->paramList
[type
].ns_acnt
;
1999 ptr
->paramList
[type
].ns_ppc
;
2000 ptr
->paramList
[type
].ns_ppc
= NULL
;
2001 free(conf
.ns_ppc
[j
]);
2002 conf
.ns_ppc
[j
] = (char *)strdup(cp
);
2003 if (conf
.ns_ppc
[j
] == NULL
) {
2008 return (NS_LDAP_MEMORY
);
2017 break; /* Replaced completed */
2020 len
= ptr
->paramList
[type
].ns_acnt
+ 1;
2022 p
= (char **)dupParam(&ptr
->paramList
[type
]);
2025 return (NS_LDAP_MEMORY
);
2030 reallocarray(p
, len
+ 1, sizeof (char *));
2031 if (conf
.ns_ppc
== NULL
) {
2032 __s_api_free2dArray(p
);
2034 return (NS_LDAP_MEMORY
);
2037 conf
.ns_ppc
[len
-1] = (char *)strdup(cp
);
2038 if (conf
.ns_ppc
[len
-1] == NULL
) {
2039 __s_api_free2dArray(conf
.ns_ppc
);
2041 return (NS_LDAP_MEMORY
);
2043 conf
.ns_ppc
[len
] = NULL
;
2048 for (cp2
= cp
; *cp2
; cp2
++) {
2049 if (*cp2
== COMMATOK
)
2055 conf
.ns_ppc
= (char **)NULL
;
2059 conf
.ns_ppc
= (char **)calloc(len
+ 1, sizeof (char *));
2060 if (conf
.ns_ppc
== NULL
) {
2062 return (NS_LDAP_MEMORY
);
2066 for (cp2
= cp
; *cp2
; cp2
++) {
2067 if (*cp2
== COMMATOK
) {
2069 conf
.ns_ppc
[i
] = (char *)malloc(j
+ 1);
2070 if (conf
.ns_ppc
[i
] == NULL
) {
2071 __s_api_free2dArray(conf
.ns_ppc
);
2073 return (NS_LDAP_MEMORY
);
2075 (void) strlcpy(conf
.ns_ppc
[i
], cp
, j
);
2077 while (*cp
== SPACETOK
|| *cp
== COMMATOK
)
2084 conf
.ns_ppc
[i
] = (char *)malloc(j
+ 1);
2085 if (conf
.ns_ppc
[i
] == NULL
) {
2086 __s_api_free2dArray(conf
.ns_ppc
);
2088 return (NS_LDAP_MEMORY
);
2090 (void) strlcpy(conf
.ns_ppc
[i
], cp
, j
);
2094 for (cp2
= cp
; *cp2
; cp2
++) {
2095 if (*cp2
== SPACETOK
|| *cp2
== COMMATOK
) {
2097 for (; *(cp2
+ 1) == SPACETOK
||
2098 *(cp2
+1) == COMMATOK
; cp2
++)
2105 conf
.ns_ppc
= (char **)NULL
;
2109 conf
.ns_ppc
= (char **)calloc(len
+ 1, sizeof (char *));
2110 if (conf
.ns_ppc
== NULL
) {
2112 return (NS_LDAP_MEMORY
);
2116 for (cp2
= cp
; *cp2
; cp2
++) {
2117 if (*cp2
== SPACETOK
|| *cp2
== COMMATOK
) {
2119 conf
.ns_ppc
[i
] = (char *)malloc(j
+ 1);
2120 if (conf
.ns_ppc
[i
] == NULL
) {
2121 __s_api_free2dArray(conf
.ns_ppc
);
2123 return (NS_LDAP_MEMORY
);
2125 (void) strlcpy(conf
.ns_ppc
[i
], cp
, j
);
2127 while (*cp
== SPACETOK
|| *cp
== COMMATOK
)
2134 conf
.ns_ppc
[i
] = (char *)malloc(j
+ 1);
2135 if (conf
.ns_ppc
[i
] == NULL
) {
2136 __s_api_free2dArray(conf
.ns_ppc
);
2138 return (NS_LDAP_MEMORY
);
2140 (void) strlcpy(conf
.ns_ppc
[i
], cp
, j
);
2144 for (cp2
= cp
; *cp2
; cp2
++) {
2145 if (*cp2
== SEMITOK
|| *cp2
== COMMATOK
)
2155 conf
.ns_pi
= (int *)calloc(len
+ 1, sizeof (int));
2156 if (conf
.ns_pi
== NULL
) {
2158 return (NS_LDAP_MEMORY
);
2162 for (cp2
= cp
; *cp2
; cp2
++) {
2163 if (*cp2
== SEMITOK
|| *cp2
== COMMATOK
) {
2165 if (j
> sizeof (tbuf
)) {
2169 (void) strlcpy(tbuf
, cp
, j
);
2170 j
= __s_get_enum_value(ptr
, tbuf
,
2175 (void) snprintf(errstr
, sizeof (errstr
),
2176 gettext("Unable to set value: "
2178 "authenticationMethod (%s)"),
2180 MKERROR(LOG_ERR
, *error
,
2185 return (NS_LDAP_CONFIG
);
2193 if (j
> sizeof (tbuf
)) {
2197 (void) strlcpy(tbuf
, cp
, j
);
2198 j
= __s_get_enum_value(ptr
, tbuf
, def
->index
);
2202 (void) snprintf(errstr
, sizeof (errstr
),
2203 gettext("Unable to set value: "
2204 "invalid authenticationMethod (%s)"), ptbuf
);
2205 MKERROR(LOG_ERR
, *error
, NS_CONFIG_SYNTAX
,
2208 return (NS_LDAP_CONFIG
);
2214 for (cp2
= cp
; *cp2
; cp2
++) {
2215 if (*cp2
== SPACETOK
)
2225 conf
.ns_pi
= (int *)calloc(len
+ 1, sizeof (int));
2226 if (conf
.ns_pi
== NULL
) {
2228 return (NS_LDAP_MEMORY
);
2232 for (cp2
= cp
; *cp2
; cp2
++) {
2233 if (*cp2
== SPACETOK
) {
2235 if (j
> sizeof (tbuf
)) {
2239 (void) strlcpy(tbuf
, cp
, j
);
2240 j
= __s_get_enum_value(ptr
, tbuf
,
2245 (void) snprintf(errstr
, sizeof (errstr
),
2246 gettext("Unable to set value: "
2247 "invalid credentialLevel (%s)"),
2249 MKERROR(LOG_ERR
, *error
,
2254 return (NS_LDAP_CONFIG
);
2262 if (j
> sizeof (tbuf
)) {
2266 (void) strlcpy(tbuf
, cp
, j
);
2267 j
= __s_get_enum_value(ptr
, tbuf
, def
->index
);
2271 (void) snprintf(errstr
, sizeof (errstr
),
2272 gettext("Unable to set value: "
2273 "invalid credentialLevel (%s)"), ptbuf
);
2274 MKERROR(LOG_ERR
, *error
, NS_CONFIG_SYNTAX
,
2277 return (NS_LDAP_CONFIG
);
2283 i
= __s_api_parse_map(cp
, &sid
, &origA
, &mapA
);
2284 if (i
!= NS_HASH_RC_SUCCESS
) {
2285 if (i
== NS_HASH_RC_NO_MEMORY
) {
2286 exitrc
= NS_LDAP_MEMORY
;
2288 (void) snprintf(errstr
, sizeof (errstr
),
2289 gettext("Unable to set value: "
2290 "invalid schema mapping (%s)"), cp
);
2291 exitrc
= NS_LDAP_CONFIG
;
2292 MKERROR(LOG_ERR
, *error
, NS_CONFIG_SYNTAX
,
2300 * Add reverse map first.
2301 * There could be more than one.
2303 for (attr
= mapA
; *attr
; attr
++) {
2306 exitrc
= NS_LDAP_MEMORY
;
2308 rmap
= (ns_mapping_t
*)calloc(1,
2309 sizeof (ns_mapping_t
));
2311 rmap
->service
= strdup(sid
);
2312 if (rmap
->service
) {
2313 rmap
->orig
= strdup(*attr
);
2315 rmap
->map
= (char **)calloc(2,
2327 if (free_memory
== 0) {
2328 if (def
->data_type
== ATTRMAP
) {
2329 rmap
->type
= NS_ATTR_MAP
;
2330 i
= __s_api_add_map2hash(ptr
,
2331 NS_HASH_RAMAP
, rmap
);
2333 rmap
->type
= NS_OBJ_MAP
;
2334 i
= __s_api_add_map2hash(ptr
,
2335 NS_HASH_ROMAP
, rmap
);
2338 if (i
!= NS_HASH_RC_SUCCESS
) {
2340 case NS_HASH_RC_CONFIG_ERROR
:
2341 exitrc
= NS_LDAP_INTERNAL
;
2342 (void) snprintf(errstr
,
2345 "Unable to set value: "
2346 "no configuration info "
2348 "update (%s)"), cp
);
2349 MKERROR(LOG_ERR
, *error
,
2354 case NS_HASH_RC_EXISTED
:
2355 exitrc
= NS_LDAP_CONFIG
;
2356 (void) snprintf(errstr
,
2359 "Unable to set value: "
2361 "already existed for "
2364 MKERROR(LOG_ERR
, *error
,
2369 case NS_HASH_RC_NO_MEMORY
:
2370 exitrc
= NS_LDAP_MEMORY
;
2381 __s_api_free2dArray(mapA
);
2383 free(rmap
->service
);
2386 free((rmap
->map
)[0]);
2396 * For performance gain,
2397 * add a "schema mapping existed" indicator
2398 * for the given service if not already added.
2399 * This dummy map needs not be removed, if
2400 * the next real map add operation fails.
2401 * since the caller, e.g. ldap_cachemgr.
2402 * should exit anyway.
2405 exitrc
= NS_LDAP_MEMORY
;
2407 map
= (ns_mapping_t
*)calloc(1,
2408 sizeof (ns_mapping_t
));
2410 map
->service
= strdup(sid
);
2413 NS_HASH_SCHEMA_MAPPING_EXISTED
);
2415 map
->map
= (char **)calloc(2,
2427 if (free_memory
== 0) {
2428 map
->type
= NS_ATTR_MAP
;
2430 * add to reverse map,
2431 * so that "ldapclient list"
2434 i
= __s_api_add_map2hash(ptr
,
2435 NS_HASH_RAMAP
, map
);
2438 * ignore "map already existed" error,
2439 * just need one per service.
2440 * Need however to free memory allocated
2443 if (i
!= NS_HASH_RC_SUCCESS
&&
2444 i
!= NS_HASH_RC_EXISTED
) {
2446 case NS_HASH_RC_CONFIG_ERROR
:
2447 exitrc
= NS_LDAP_INTERNAL
;
2448 (void) snprintf(errstr
,
2451 "Unable to set value: "
2452 "no configuration info "
2454 "update (%s)"), cp
);
2455 MKERROR(LOG_ERR
, *error
,
2460 case NS_HASH_RC_NO_MEMORY
:
2461 exitrc
= NS_LDAP_MEMORY
;
2465 } else if (i
== NS_HASH_RC_EXISTED
) {
2469 free((map
->map
)[0]);
2481 __s_api_free2dArray(mapA
);
2486 free((map
->map
)[0]);
2495 * add the real schema map
2498 exitrc
= NS_LDAP_MEMORY
;
2499 map
= (ns_mapping_t
*)calloc(1, sizeof (ns_mapping_t
));
2505 if (def
->data_type
== ATTRMAP
) {
2506 map
->type
= NS_ATTR_MAP
;
2507 i
= __s_api_add_map2hash(ptr
,
2510 map
->type
= NS_OBJ_MAP
;
2511 i
= __s_api_add_map2hash(ptr
,
2515 if (i
!= NS_HASH_RC_SUCCESS
) {
2517 case NS_HASH_RC_CONFIG_ERROR
:
2518 exitrc
= NS_LDAP_INTERNAL
;
2519 (void) snprintf(errstr
,
2522 "Unable to set value: "
2523 "no configuration info "
2525 "update (%s)"), cp
);
2526 MKERROR(LOG_ERR
, *error
,
2531 case NS_HASH_RC_EXISTED
:
2532 exitrc
= NS_LDAP_CONFIG
;
2533 (void) snprintf(errstr
,
2536 "Unable to set value: "
2538 "already existed for "
2540 MKERROR(LOG_ERR
, *error
,
2545 case NS_HASH_RC_NO_MEMORY
:
2546 exitrc
= NS_LDAP_MEMORY
;
2558 __s_api_free2dArray(mapA
);
2565 /* This should never happen. */
2566 (void) snprintf(errstr
, sizeof (errstr
),
2567 gettext("Unable to set value: invalid configuration "
2568 "type (%d)"), def
->data_type
);
2569 MKERROR(LOG_ERR
, *error
, NS_CONFIG_SYNTAX
, strdup(errstr
),
2572 return (NS_LDAP_CONFIG
);
2574 conf
.ns_ptype
= def
->data_type
;
2577 /* Individually written verify routines here can replace */
2578 /* verify_value. Verify conf (data) as appropriate here */
2579 if (def
->ns_verify
!= NULL
) {
2580 if ((*def
->ns_verify
)(type
, def
, &conf
, errstr
) != NS_SUCCESS
) {
2581 ns_param_t sav_conf
;
2583 (void) snprintf(errstr
, sizeof (errstr
),
2584 gettext("%s"), errstr
);
2585 MKERROR(LOG_WARNING
, *error
, NS_CONFIG_SYNTAX
,
2588 sav_conf
= ptr
->paramList
[type
];
2589 ptr
->paramList
[type
] = conf
;
2590 destroy_param(ptr
, type
);
2591 ptr
->paramList
[type
] = sav_conf
;
2593 return (NS_LDAP_CONFIG
);
2597 /* post evaluate the data */
2600 * if this is for setting a password,
2601 * encrypt the password first.
2602 * NOTE evalue() is smart and will just return
2603 * the value passed if it is already encrypted.
2605 * Init NS_LDAP_EXP_P here when CACHETTL is updated
2607 if (type
== NS_LDAP_BINDPASSWD_P
||
2608 type
== NS_LDAP_ADMIN_BINDPASSWD_P
) {
2610 cp2
= evalue((char *)cp
);
2614 } else if (type
== NS_LDAP_FILE_VERSION_P
) {
2615 ptr
->version
= NS_LDAP_V1
;
2616 if (strcasecmp(conf
.ns_pc
, NS_LDAP_VERSION_2
) == 0) {
2617 ptr
->version
= NS_LDAP_V2
;
2619 } else if (type
== NS_LDAP_CACHETTL_P
) {
2622 ptr
->paramList
[NS_LDAP_EXP_P
].ns_ptype
= TIMET
;
2626 ptr
->paramList
[NS_LDAP_EXP_P
].ns_tm
= tm
;
2629 /* Everything checks out move new values into param */
2630 destroy_param(ptr
, type
);
2631 /* Assign new/updated value into paramList */
2632 ptr
->paramList
[type
] = conf
;
2634 return (NS_LDAP_SUCCESS
);
2639 * Set a parameter value in the 'config' configuration structure
2640 * Lock as appropriate
2644 __ns_ldap_setParam(const ParamIndexType type
,
2645 const void *data
, ns_ldap_error_t
**error
)
2647 ns_ldap_error_t
*errorp
;
2649 char errstr
[2 * MAXERROR
];
2651 ns_config_t
*cfg_g
= (ns_config_t
*)-1;
2652 ns_config_t
*new_cfg
;
2653 boolean_t reinit_connmgmt
= B_FALSE
;
2655 /* We want to refresh only one configuration at a time */
2656 (void) mutex_lock(&ns_loadrefresh_lock
);
2657 cfg
= __s_api_get_default_config();
2659 if (cache_server
== TRUE
) {
2661 __ns_ldap_default_config();
2662 cfg
= __s_api_get_default_config();
2664 (void) mutex_unlock(&ns_loadrefresh_lock
);
2665 return (NS_LDAP_MEMORY
);
2670 * This code always return error here on client side,
2671 * this needs to change once libsldap is used by more
2672 * applications that need to set parameters.
2674 (void) snprintf(errstr
, sizeof (errstr
),
2675 gettext("Unable to set parameter from a client in "
2676 "__ns_ldap_setParam()"));
2677 MKERROR(LOG_WARNING
, *error
, NS_CONFIG_SYNTAX
, strdup(errstr
),
2680 __s_api_release_config(cfg
);
2681 (void) mutex_unlock(&ns_loadrefresh_lock
);
2682 return (NS_LDAP_CONFIG
);
2685 /* (re)initialize configuration if necessary */
2686 if (!__s_api_isStandalone() &&
2687 cache_server
== FALSE
&& timetorefresh(cfg
))
2688 cfg_g
= __s_api_get_default_config_global();
2689 /* only (re)initialize the global configuration */
2692 __s_api_release_config(cfg_g
);
2693 new_cfg
= LoadCacheConfiguration(cfg
, &errorp
);
2695 __s_api_release_config(cfg
);
2696 if (new_cfg
== NULL
) {
2697 (void) snprintf(errstr
, sizeof (errstr
),
2698 gettext("Unable to load configuration '%s' "
2699 "('%s')."), NSCONFIGFILE
,
2700 errorp
!= NULL
&& errorp
->message
!= NULL
?
2701 errorp
->message
: "");
2702 MKERROR(LOG_WARNING
, *error
, NS_CONFIG_NOTLOADED
,
2705 (void) __ns_ldap_freeError(&errorp
);
2706 (void) mutex_unlock(&ns_loadrefresh_lock
);
2707 return (NS_LDAP_CONFIG
);
2709 if (new_cfg
!= cfg
) {
2710 set_curr_config_global(new_cfg
);
2712 reinit_connmgmt
= B_TRUE
;
2715 (void) mutex_unlock(&ns_loadrefresh_lock
);
2717 if (reinit_connmgmt
== B_TRUE
)
2718 __s_api_reinit_conn_mgmt_new_config(cfg
);
2720 /* translate input and save in the parameter list */
2721 ret
= __ns_ldap_setParamValue(cfg
, type
, data
, error
);
2723 __s_api_release_config(cfg
);
2730 * Make a copy of a parameter entry
2734 dupParam(ns_param_t
*ptr
)
2737 void **dupdata
, *ret
;
2739 char *cp
, tmbuf
[32];
2740 static time_t expire
= 0;
2743 switch (ptr
->ns_ptype
) {
2751 count
= ptr
->ns_acnt
;
2761 dupdata
= (void **)calloc((count
+ 1), sizeof (void *));
2762 if (dupdata
== NULL
)
2765 switch (ptr
->ns_ptype
) {
2767 for (i
= 0; i
< count
; i
++) {
2768 ap
= __s_api_AuthEnumtoStruct(
2769 (EnumAuthType_t
)ptr
->ns_pi
[i
]);
2778 for (i
= 0; i
< count
; i
++) {
2779 intptr
= (int *)malloc(sizeof (int));
2780 if (intptr
== NULL
) {
2784 dupdata
[i
] = (void *)intptr
;
2785 *intptr
= ptr
->ns_pi
[i
];
2793 for (i
= 0; i
< count
; i
++) {
2794 ret
= (void *)strdup(ptr
->ns_ppc
[i
]);
2803 if (ptr
->ns_pc
== NULL
) {
2807 ret
= (void *)strdup(ptr
->ns_pc
);
2815 intptr
= (int *)malloc(sizeof (int));
2816 if (intptr
== NULL
) {
2820 *intptr
= ptr
->ns_i
;
2821 dupdata
[0] = (void *)intptr
;
2824 expire
= ptr
->ns_tm
;
2826 cp
= lltostr((long)expire
, &tmbuf
[31]);
2827 ret
= (void *)strdup(cp
);
2839 __ns_ldap_freeParam(void ***data
)
2845 return (NS_LDAP_SUCCESS
);
2847 for (i
= 0, tmp
= *data
; tmp
[i
] != NULL
; i
++)
2854 return (NS_LDAP_SUCCESS
);
2858 * Get the internal format for a parameter value. This
2859 * routine makes a copy of an internal param value from
2860 * the currently active parameter list and returns it.
2864 __ns_ldap_getParam(const ParamIndexType Param
,
2865 void ***data
, ns_ldap_error_t
**error
)
2867 char errstr
[2 * MAXERROR
];
2868 ns_ldap_error_t
*errorp
;
2869 ns_default_config
*def
;
2871 ns_config_t
*cfg_g
= (ns_config_t
*)-1;
2872 ns_config_t
*new_cfg
;
2873 boolean_t reinit_connmgmt
= B_FALSE
;
2876 return (NS_LDAP_INVALID_PARAM
);
2880 /* We want to refresh only one configuration at a time */
2881 (void) mutex_lock(&ns_loadrefresh_lock
);
2882 cfg
= __s_api_get_default_config();
2884 /* (re)initialize configuration if necessary */
2885 if (!__s_api_isStandalone() &&
2886 cache_server
== FALSE
&& timetorefresh(cfg
))
2887 cfg_g
= __s_api_get_default_config_global();
2888 /* only (re)initialize the global configuration */
2891 __s_api_release_config(cfg_g
);
2892 new_cfg
= LoadCacheConfiguration(cfg
, &errorp
);
2894 __s_api_release_config(cfg
);
2895 if (new_cfg
== NULL
) {
2896 (void) snprintf(errstr
, sizeof (errstr
),
2897 gettext("Unable to load configuration "
2900 errorp
!= NULL
&& errorp
->message
!= NULL
?
2901 errorp
->message
: "");
2902 MKERROR(LOG_WARNING
, *error
, NS_CONFIG_NOTLOADED
,
2905 (void) __ns_ldap_freeError(&errorp
);
2906 (void) mutex_unlock(&ns_loadrefresh_lock
);
2907 return (NS_LDAP_CONFIG
);
2909 if (new_cfg
!= cfg
) {
2910 set_curr_config_global(new_cfg
);
2912 reinit_connmgmt
= B_TRUE
;
2915 (void) mutex_unlock(&ns_loadrefresh_lock
);
2917 if (reinit_connmgmt
== B_TRUE
)
2918 __s_api_reinit_conn_mgmt_new_config(cfg
);
2921 (void) snprintf(errstr
, sizeof (errstr
),
2922 gettext("No configuration information available."));
2923 MKERROR(LOG_ERR
, *error
, NS_CONFIG_NOTLOADED
,
2925 return (NS_LDAP_CONFIG
);
2928 if (Param
== NS_LDAP_DOMAIN_P
) {
2929 *data
= (void **)calloc(2, sizeof (void *));
2930 if (*data
== NULL
) {
2931 __s_api_release_config(cfg
);
2932 return (NS_LDAP_MEMORY
);
2934 (*data
)[0] = (void *)strdup(cfg
->domainName
);
2935 if ((*data
)[0] == NULL
) {
2937 __s_api_release_config(cfg
);
2938 return (NS_LDAP_MEMORY
);
2940 } else if (cfg
->paramList
[Param
].ns_ptype
== NS_UNKNOWN
) {
2942 def
= get_defconfig(cfg
, Param
);
2944 *data
= dupParam(&def
->defval
);
2946 *data
= dupParam(&(cfg
->paramList
[Param
]));
2948 __s_api_release_config(cfg
);
2950 return (NS_LDAP_SUCCESS
);
2954 * This routine takes a parameter in internal format and
2955 * translates it into a variety of string formats for various
2956 * outputs (doors/file/ldif). This routine would be better
2957 * named: __ns_ldap_translateParam2String
2961 __s_api_strValue(ns_config_t
*cfg
, ParamIndexType index
, ns_strfmt_t fmt
)
2963 ns_default_config
*def
= NULL
;
2968 char abuf
[64], **cpp
;
2970 boolean_t first
= B_TRUE
;
2972 LineBuf
*buffer
= &lbuf
;
2979 /* NS_LDAP_EXP and TRANSPORT_SEC are not exported externally */
2980 if (index
== NS_LDAP_EXP_P
|| index
== NS_LDAP_TRANSPORT_SEC_P
)
2983 /* Return nothing if the value is the default */
2984 if (cfg
->paramList
[index
].ns_ptype
== NS_UNKNOWN
)
2987 (void) memset((char *)buffer
, 0, sizeof (LineBuf
));
2989 ptr
= &(cfg
->paramList
[index
]);
2994 def
= get_defconfig(cfg
, index
);
3000 (void) strlcpy(abuf
, def
->name
, sizeof (abuf
));
3001 (void) strlcat(abuf
, EQUALSEP
, sizeof (abuf
));
3004 (void) strlcpy(abuf
, def
->name
, sizeof (abuf
));
3005 (void) strlcat(abuf
, EQUSPSEP
, sizeof (abuf
));
3008 /* If no LDIF attr exists ignore the entry */
3009 if (def
->profile_name
== NULL
)
3011 (void) strlcpy(abuf
, def
->profile_name
, sizeof (abuf
));
3012 (void) strlcat(abuf
, COLSPSEP
, sizeof (abuf
));
3018 if (__print2buf(buffer
, abuf
, NULL
))
3021 switch (ptr
->ns_ptype
) {
3023 count
= ptr
->ns_acnt
;
3024 for (i
= 0; i
< count
; i
++) {
3027 if (cfg
->version
== NS_LDAP_V1
) {
3033 if (__print2buf(buffer
, __s_get_auth_name(cfg
,
3034 (AuthType_t
)(ptr
->ns_pi
[i
])), sepstr
))
3039 count
= ptr
->ns_acnt
;
3040 for (i
= 0; i
< count
; i
++) {
3045 if (__print2buf(buffer
, __s_get_credlvl_name(cfg
,
3046 (CredLevel_t
)ptr
->ns_pi
[i
]), sepstr
))
3053 count
= ptr
->ns_acnt
;
3054 for (i
= 0; i
< count
; i
++) {
3055 if (__print2buf(buffer
, ptr
->ns_ppc
[i
], NULL
))
3061 /* Separate items */
3064 if (__print2buf(buffer
, DOORLINESEP
, NULL
) ||
3065 __print2buf(buffer
, def
->name
, EQUALSEP
))
3069 if (__print2buf(buffer
, "\n", NULL
) ||
3070 __print2buf(buffer
, def
->name
, EQUSPSEP
))
3074 if (__print2buf(buffer
, "\n", NULL
) ||
3075 __print2buf(buffer
, def
->profile_name
,
3083 count
= ptr
->ns_acnt
;
3084 for (i
= 0; i
< count
; i
++) {
3089 if (__print2buf(buffer
, ptr
->ns_ppc
[i
], sepstr
))
3094 count
= ptr
->ns_acnt
;
3095 for (i
= 0; i
< count
; i
++) {
3098 if (fmt
== NS_LDIF_FMT
) {
3104 if (__print2buf(buffer
, ptr
->ns_ppc
[i
], sepstr
))
3109 if (ptr
->ns_pc
== NULL
)
3111 if (__print2buf(buffer
, ptr
->ns_pc
, NULL
))
3115 switch (def
->index
) {
3116 case NS_LDAP_PREF_ONLY_P
:
3117 if (__print2buf(buffer
,
3118 __s_get_pref_name((PrefOnly_t
)ptr
->ns_i
), NULL
))
3121 case NS_LDAP_SEARCH_REF_P
:
3122 if (__print2buf(buffer
, __s_get_searchref_name(cfg
,
3123 (SearchRef_t
)ptr
->ns_i
), NULL
))
3126 case NS_LDAP_SEARCH_SCOPE_P
:
3127 if (__print2buf(buffer
, __s_get_scope_name(cfg
,
3128 (ScopeType_t
)ptr
->ns_i
), NULL
))
3131 case NS_LDAP_ENABLE_SHADOW_UPDATE_P
:
3132 if (__print2buf(buffer
, __s_get_shadowupdate_name(
3133 (enableShadowUpdate_t
)ptr
->ns_i
), NULL
))
3137 (void) snprintf(ibuf
, sizeof (ibuf
),
3139 if (__print2buf(buffer
, ibuf
, NULL
))
3145 for (hptr
= cfg
->llHead
; hptr
; hptr
= hptr
->h_llnext
) {
3146 if (hptr
->h_type
!= NS_HASH_AMAP
) {
3150 /* print abuf as "separator" */
3151 if (fmt
== NS_DOOR_FMT
) {
3152 if (__print2buf(buffer
, DOORLINESEP
,
3156 if (__print2buf(buffer
, "\n", abuf
))
3161 if (__print2buf(buffer
, mptr
->service
, COLONSEP
) ||
3162 __print2buf(buffer
, mptr
->orig
, EQUALSEP
))
3164 for (cpp
= mptr
->map
; cpp
&& *cpp
; cpp
++) {
3165 /* print *cpp as "separator" */
3167 if (cpp
!= mptr
->map
)
3169 if (__print2buf(buffer
, sepstr
, *cpp
))
3176 for (hptr
= cfg
->llHead
; hptr
; hptr
= hptr
->h_llnext
) {
3177 if (hptr
->h_type
!= NS_HASH_OMAP
) {
3181 /* print abuf as "separator" */
3182 if (fmt
== NS_DOOR_FMT
) {
3183 if (__print2buf(buffer
, DOORLINESEP
,
3187 if (__print2buf(buffer
, "\n", abuf
))
3192 if (__print2buf(buffer
, mptr
->service
, COLONSEP
) ||
3193 __print2buf(buffer
, mptr
->orig
, EQUALSEP
))
3195 for (cpp
= mptr
->map
; cpp
&& *cpp
; cpp
++) {
3196 /* print *cpp as "separator" */
3198 if (cpp
!= mptr
->map
)
3200 if (__print2buf(buffer
, sepstr
, *cpp
))
3208 retstring
= buffer
->str
;
3212 if (buffer
->len
> 0)
3217 /* shared by __door_getldapconfig() and __door_getadmincred() */
3219 __door_getconf(char **buffer
, int *buflen
, ns_ldap_error_t
**error
,
3224 char s_b
[DOORBUFFERSIZE
];
3231 char errstr
[MAXERROR
];
3233 ns_ldap_return_code retCode
;
3234 ldap_config_out_t
*cfghdr
;
3238 domainname
= __getdomainname();
3239 if (domainname
== NULL
|| buffer
== NULL
|| buflen
== NULL
||
3240 (strlen(domainname
) >= (sizeof (space_t
)
3241 - sizeof (space
->s_d
.ldap_call
.ldap_callnumber
)))) {
3242 return (NS_LDAP_OP_FAILED
);
3245 space
= (space_t
*)calloc(1, sizeof (space_t
));
3247 return (NS_LDAP_MEMORY
);
3249 adata
= (sizeof (ldap_call_t
) + strlen(domainname
) +1);
3250 ndata
= sizeof (space_t
);
3251 space
->s_d
.ldap_call
.ldap_callnumber
= callnumber
;
3252 (void) strcpy(space
->s_d
.ldap_call
.ldap_u
.domainname
, domainname
);
3257 switch (__ns_ldap_trydoorcall(&sptr
, &ndata
, &adata
)) {
3258 case NS_CACHE_SUCCESS
:
3260 case NS_CACHE_NOTFOUND
:
3261 (void) snprintf(errstr
, sizeof (errstr
),
3262 gettext("Door call to "
3263 "ldap_cachemgr failed - error: %d."),
3264 space
->s_d
.ldap_ret
.ldap_errno
);
3265 MKERROR(LOG_WARNING
, *error
, NS_CONFIG_CACHEMGR
,
3268 return (NS_LDAP_OP_FAILED
);
3271 return (NS_LDAP_OP_FAILED
);
3274 retCode
= NS_LDAP_SUCCESS
;
3276 /* copy info from door call to buffer here */
3277 cfghdr
= &sptr
->ldap_ret
.ldap_u
.config_str
;
3278 *buflen
= offsetof(ldap_config_out_t
, config_str
) +
3279 cfghdr
->data_size
+ 1;
3280 *buffer
= calloc(*buflen
, sizeof (char));
3281 if (*buffer
== NULL
) {
3282 retCode
= NS_LDAP_MEMORY
;
3284 (void) memcpy(*buffer
, cfghdr
, *buflen
- 1);
3286 if (sptr
!= &space
->s_d
) {
3287 (void) munmap((char *)sptr
, ndata
);
3295 __door_getldapconfig(char **buffer
, int *buflen
, ns_ldap_error_t
**error
)
3297 return (__door_getconf(buffer
, buflen
, error
, GETLDAPCONFIGV1
));
3301 * SetDoorInfoToUnixCred parses ldapcachemgr configuration information
3302 * for Admin credentials.
3305 SetDoorInfoToUnixCred(char *buffer
, ns_ldap_error_t
**errorp
,
3309 char errstr
[MAXERROR
];
3310 char *name
, *value
, valbuf
[BUFSIZE
];
3311 char *bufptr
= buffer
;
3314 ParamIndexType index
= 0;
3315 ldap_config_out_t
*cfghdr
;
3317 if (errorp
== NULL
|| cred
== NULL
|| *cred
== NULL
)
3318 return (NS_LDAP_INVALID_PARAM
);
3323 cfghdr
= (ldap_config_out_t
*)bufptr
;
3324 bufptr
= (char *)cfghdr
->config_str
;
3326 strptr
= (char *)strtok_r(bufptr
, DOORLINESEP
, &rest
);
3330 (void) strlcpy(valbuf
, strptr
, sizeof (valbuf
));
3331 __s_api_split_key_value(valbuf
, &name
, &value
);
3332 if (__ns_ldap_getParamType(name
, &index
) != 0) {
3333 (void) snprintf(errstr
, MAXERROR
,
3334 gettext("SetDoorInfoToUnixCred: "
3335 "Unknown keyword encountered '%s'."), name
);
3336 MKERROR(LOG_ERR
, *errorp
, NS_CONFIG_SYNTAX
,
3338 return (NS_LDAP_CONFIG
);
3341 case NS_LDAP_ADMIN_BINDDN_P
:
3342 ptr
->userID
= (char *)strdup(value
);
3344 case NS_LDAP_ADMIN_BINDPASSWD_P
:
3345 ptr
->passwd
= (char *)strdup(value
);
3348 (void) snprintf(errstr
, MAXERROR
,
3349 gettext("SetDoorInfoToUnixCred: "
3350 "Unknown index encountered '%d'."), index
);
3351 MKERROR(LOG_ERR
, *errorp
, NS_CONFIG_SYNTAX
,
3353 return (NS_LDAP_CONFIG
);
3355 strptr
= (char *)strtok_r(NULL
, DOORLINESEP
, &rest
);
3358 return (NS_LDAP_SUCCESS
);
3362 * SetDoorInfo parses ldapcachemgr configuration information
3363 * and verifies that the profile is version 1 or version 2 based.
3364 * version 2 profiles must have a version number as the first profile
3365 * attribute in the configuration.
3367 static ns_config_t
*
3368 SetDoorInfo(char *buffer
, ns_ldap_error_t
**errorp
)
3371 char errstr
[MAXERROR
], errbuf
[MAXERROR
];
3372 char *name
, *value
, valbuf
[BUFSIZE
];
3375 char *bufptr
= buffer
;
3380 ldap_config_out_t
*cfghdr
;
3386 ptr
= __s_api_create_config();
3391 /* get config cookie from the header */
3392 cfghdr
= (ldap_config_out_t
*)bufptr
;
3393 ptr
->config_cookie
= cfghdr
->cookie
;
3394 bufptr
= (char *)cfghdr
->config_str
;
3396 strptr
= (char *)strtok_r(bufptr
, DOORLINESEP
, &rest
);
3400 (void) strlcpy(valbuf
, strptr
, sizeof (valbuf
));
3401 __s_api_split_key_value(valbuf
, &name
, &value
);
3402 /* Use get_versiontype and check for V1 vs V2 prototypes */
3403 if (__s_api_get_versiontype(ptr
, name
, &i
) < 0) {
3404 (void) snprintf(errstr
, sizeof (errstr
),
3406 gettext("Illegal profile entry "
3407 "line in configuration."),
3410 /* Write verify routines and get rid of verify_value here */
3411 } else if (verify_value(ptr
, name
,
3412 value
, errbuf
) != NS_SUCCESS
) {
3413 (void) snprintf(errstr
, sizeof (errstr
),
3414 gettext("%s\n"), errbuf
);
3416 } else if (!first
&& i
== NS_LDAP_FILE_VERSION_P
) {
3417 (void) snprintf(errstr
, sizeof (errstr
),
3418 gettext("Illegal NS_LDAP_FILE_VERSION "
3419 "line in configuration.\n"));
3423 MKERROR(LOG_ERR
, *errorp
, NS_CONFIG_SYNTAX
,
3424 strdup(errstr
), NULL
);
3426 ret
= set_default_value(ptr
, name
, value
, errorp
);
3428 if (errfnd
|| ret
!= NS_SUCCESS
) {
3429 __s_api_destroy_config(ptr
);
3434 strptr
= (char *)strtok_r(NULL
, DOORLINESEP
, &rest
);
3437 if (__s_api_crosscheck(ptr
, errstr
, B_TRUE
) != NS_SUCCESS
) {
3438 __s_api_destroy_config(ptr
);
3439 MKERROR(LOG_WARNING
, *errorp
, NS_CONFIG_SYNTAX
, strdup(errstr
),
3447 static ns_config_t
*
3448 LoadCacheConfiguration(ns_config_t
*oldcfg
, ns_ldap_error_t
**error
)
3450 char *buffer
= NULL
;
3454 ldap_config_out_t
*cfghdr
;
3455 ldap_get_chg_cookie_t old_cookie
;
3456 ldap_get_chg_cookie_t new_cookie
;
3459 ret
= __door_getldapconfig(&buffer
, &buflen
, error
);
3461 if (ret
!= NS_LDAP_SUCCESS
) {
3462 if (*error
!= NULL
&& (*error
)->message
!= NULL
)
3463 syslog(LOG_WARNING
, "libsldap: %s", (*error
)->message
);
3467 /* No need to reload configuration if config cookie is the same */
3468 cfghdr
= (ldap_config_out_t
*)buffer
;
3469 new_cookie
= cfghdr
->cookie
;
3471 old_cookie
= oldcfg
->config_cookie
;
3473 if (oldcfg
!= NULL
&& old_cookie
.mgr_pid
== new_cookie
.mgr_pid
&&
3474 old_cookie
.seq_num
== new_cookie
.seq_num
) {
3479 /* now convert from door format */
3480 cfg
= SetDoorInfo(buffer
, error
);
3483 if (cfg
== NULL
&& *error
!= NULL
&& (*error
)->message
!= NULL
)
3484 syslog(LOG_WARNING
, "libsldap: %s", (*error
)->message
);
3489 * converts the time string into seconds. The time string can be specified
3490 * using one of the following time units:
3496 * NOTE: you can only specify one the above. No combination of the above
3497 * units is allowed. If no unit specified, it will default to "seconds".
3513 case 'w': /* weeks */
3516 case 'd': /* days */
3519 case 'h': /* hours */
3522 case 'm': /* minutes */
3525 case 's': /* seconds */
3528 /* the default case is set to "second" */
3536 if ((0 == tot
) && (EINVAL
== errno
))
3538 if (((LONG_MAX
== tot
) || (LONG_MIN
== tot
)) && (EINVAL
== errno
))
3548 __s_api_AuthEnumtoStruct(const EnumAuthType_t i
)
3552 ap
= (ns_auth_t
*)calloc(1, sizeof (ns_auth_t
));
3556 case NS_LDAP_EA_NONE
:
3558 case NS_LDAP_EA_SIMPLE
:
3559 ap
->type
= NS_LDAP_AUTH_SIMPLE
;
3561 case NS_LDAP_EA_SASL_CRAM_MD5
:
3562 ap
->type
= NS_LDAP_AUTH_SASL
;
3563 ap
->saslmech
= NS_LDAP_SASL_CRAM_MD5
;
3565 case NS_LDAP_EA_SASL_DIGEST_MD5
:
3566 ap
->type
= NS_LDAP_AUTH_SASL
;
3567 ap
->saslmech
= NS_LDAP_SASL_DIGEST_MD5
;
3569 case NS_LDAP_EA_SASL_DIGEST_MD5_INT
:
3570 ap
->type
= NS_LDAP_AUTH_SASL
;
3571 ap
->saslmech
= NS_LDAP_SASL_DIGEST_MD5
;
3572 ap
->saslopt
= NS_LDAP_SASLOPT_INT
;
3574 case NS_LDAP_EA_SASL_DIGEST_MD5_CONF
:
3575 ap
->type
= NS_LDAP_AUTH_SASL
;
3576 ap
->saslmech
= NS_LDAP_SASL_DIGEST_MD5
;
3577 ap
->saslopt
= NS_LDAP_SASLOPT_PRIV
;
3579 case NS_LDAP_EA_SASL_EXTERNAL
:
3580 ap
->type
= NS_LDAP_AUTH_SASL
;
3581 ap
->saslmech
= NS_LDAP_SASL_EXTERNAL
;
3583 case NS_LDAP_EA_SASL_GSSAPI
:
3584 ap
->type
= NS_LDAP_AUTH_SASL
;
3585 ap
->saslmech
= NS_LDAP_SASL_GSSAPI
;
3586 ap
->saslopt
= NS_LDAP_SASLOPT_INT
|
3587 NS_LDAP_SASLOPT_PRIV
;
3589 case NS_LDAP_EA_TLS_NONE
:
3590 ap
->type
= NS_LDAP_AUTH_TLS
;
3591 ap
->tlstype
= NS_LDAP_TLS_NONE
;
3593 case NS_LDAP_EA_TLS_SIMPLE
:
3594 ap
->type
= NS_LDAP_AUTH_TLS
;
3595 ap
->tlstype
= NS_LDAP_TLS_SIMPLE
;
3597 case NS_LDAP_EA_TLS_SASL_CRAM_MD5
:
3598 ap
->type
= NS_LDAP_AUTH_TLS
;
3599 ap
->tlstype
= NS_LDAP_TLS_SASL
;
3600 ap
->saslmech
= NS_LDAP_SASL_CRAM_MD5
;
3602 case NS_LDAP_EA_TLS_SASL_DIGEST_MD5
:
3603 ap
->type
= NS_LDAP_AUTH_TLS
;
3604 ap
->tlstype
= NS_LDAP_TLS_SASL
;
3605 ap
->saslmech
= NS_LDAP_SASL_DIGEST_MD5
;
3607 case NS_LDAP_EA_TLS_SASL_DIGEST_MD5_INT
:
3608 ap
->type
= NS_LDAP_AUTH_TLS
;
3609 ap
->tlstype
= NS_LDAP_TLS_SASL
;
3610 ap
->saslmech
= NS_LDAP_SASL_DIGEST_MD5
;
3611 ap
->saslopt
= NS_LDAP_SASLOPT_INT
;
3613 case NS_LDAP_EA_TLS_SASL_DIGEST_MD5_CONF
:
3614 ap
->type
= NS_LDAP_AUTH_TLS
;
3615 ap
->tlstype
= NS_LDAP_TLS_SASL
;
3616 ap
->saslmech
= NS_LDAP_SASL_DIGEST_MD5
;
3617 ap
->saslopt
= NS_LDAP_SASLOPT_PRIV
;
3619 case NS_LDAP_EA_TLS_SASL_EXTERNAL
:
3620 ap
->type
= NS_LDAP_AUTH_TLS
;
3621 ap
->tlstype
= NS_LDAP_TLS_SASL
;
3622 ap
->saslmech
= NS_LDAP_SASL_EXTERNAL
;
3625 /* should never get here */
3634 * Parameter Index Type validation routines
3637 /* Validate a positive integer */
3638 /* Size of errbuf needs to be MAXERROR */
3641 __s_val_postime(ParamIndexType i
, ns_default_config
*def
,
3642 ns_param_t
*param
, char *errbuf
)
3647 if (param
&& param
->ns_ptype
== CHARPTR
&& param
->ns_pc
) {
3648 for (cp
= param
->ns_pc
; cp
&& *cp
; cp
++) {
3649 if (*cp
>= '0' && *cp
<= '9')
3652 case 'w': /* weeks */
3653 case 'd': /* days */
3654 case 'h': /* hours */
3655 case 'm': /* minutes */
3656 case 's': /* seconds */
3657 if (*(cp
+1) == '\0') {
3661 (void) strcpy(errbuf
, "Illegal time value");
3662 return (NS_PARSE_ERR
);
3665 /* Valid form: [0-9][0-9]*[wdhms]* */
3666 tot
= atol(param
->ns_pc
); /* check overflow */
3668 return (NS_SUCCESS
);
3670 (void) snprintf(errbuf
, MAXERROR
,
3671 gettext("Illegal time value in %s"), def
->name
);
3672 return (NS_PARSE_ERR
);
3676 /* Validate the Base DN */
3677 /* It can be empty (RootDSE request) or needs to have an '=' */
3678 /* Size of errbuf needs to be MAXERROR */
3681 __s_val_basedn(ParamIndexType i
, ns_default_config
*def
,
3682 ns_param_t
*param
, char *errbuf
)
3684 if (param
&& param
->ns_ptype
== CHARPTR
&&
3685 i
== NS_LDAP_SEARCH_BASEDN_P
&&
3686 ((param
->ns_pc
== NULL
) || /* empty */
3687 (*(param
->ns_pc
) == '\0') || /* empty */
3688 (strchr(param
->ns_pc
, '=') != NULL
))) /* '=' */
3690 return (NS_SUCCESS
);
3692 (void) snprintf(errbuf
, MAXERROR
,
3693 gettext("Non-existent or invalid DN in %s"),
3695 return (NS_PARSE_ERR
);
3699 /* Validate the serverList */
3700 /* For each server in list, check if valid IP or hostname */
3701 /* Size of errbuf needs to be MAXERROR */
3704 __s_val_serverList(ParamIndexType i
, ns_default_config
*def
,
3705 ns_param_t
*param
, char *errbuf
)
3707 for (i
= 0; i
< param
->ns_acnt
; i
++) {
3708 if ((__s_api_isipv4(param
->ns_ppc
[i
])) ||
3709 (__s_api_isipv6(param
->ns_ppc
[i
])) ||
3710 (__s_api_ishost(param
->ns_ppc
[i
]))) {
3714 (void) snprintf(errbuf
, MAXERROR
,
3715 gettext("Invalid server (%s) in %s"),
3716 param
->ns_ppc
[i
], def
->name
);
3717 return (NS_PARSE_ERR
);
3720 return (NS_SUCCESS
);
3724 /* Check for a BINDDN */
3725 /* It can not be empty and needs to have an '=' */
3726 /* Size of errbuf needs to be MAXERROR */
3729 __s_val_binddn(ParamIndexType i
, ns_default_config
*def
,
3730 ns_param_t
*param
, char *errbuf
)
3734 if (param
&& param
->ns_ptype
== CHARPTR
&&
3735 (i
== NS_LDAP_BINDDN_P
|| i
== NS_LDAP_ADMIN_BINDDN_P
) &&
3736 ((param
->ns_pc
== NULL
) ||
3737 ((*(param
->ns_pc
) != '\0') &&
3738 (strchr(param
->ns_pc
, '=') != NULL
)))) {
3739 return (NS_SUCCESS
);
3741 if (i
== NS_LDAP_BINDDN_P
)
3745 (void) snprintf(errbuf
, MAXERROR
,
3746 gettext("NULL or invalid %s bind DN"), dntype
);
3747 return (NS_PARSE_ERR
);
3751 /* Check for a BINDPASSWD */
3752 /* The string can not be NULL or empty */
3753 /* Size of errbuf needs to be MAXERROR */
3756 __s_val_bindpw(ParamIndexType i
, ns_default_config
*def
,
3757 ns_param_t
*param
, char *errbuf
)
3761 if (param
&& param
->ns_ptype
== CHARPTR
&&
3762 (i
== NS_LDAP_BINDPASSWD_P
|| i
== NS_LDAP_ADMIN_BINDPASSWD_P
) &&
3763 ((param
->ns_pc
== NULL
) ||
3764 (*(param
->ns_pc
) != '\0'))) {
3765 return (NS_SUCCESS
);
3767 if (i
== NS_LDAP_BINDPASSWD_P
)
3771 (void) snprintf(errbuf
, MAXERROR
,
3772 gettext("NULL %s bind password"), pwtype
);
3773 return (NS_PARSE_ERR
);
3777 * __s_get_hostcertpath returns either the configured host certificate path
3778 * or, if none, the default host certificate path (/var/ldap). Note that this
3779 * does not use __ns_ldap_getParam because it may be called during connection
3780 * setup. This can fail due to insufficient memory.
3784 __s_get_hostcertpath(void)
3790 cfg
= __s_api_get_default_config();
3792 param
= &cfg
->paramList
[NS_LDAP_HOST_CERTPATH_P
];
3793 if (param
->ns_ptype
== CHARPTR
)
3794 ret
= strdup(param
->ns_pc
);
3795 __s_api_release_config(cfg
);
3798 ret
= strdup(NSLDAPDIRECTORY
);
3805 if (current_config
!= NULL
)
3806 destroy_config(current_config
);
3808 current_config
= NULL
;