8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libsldap / common / ns_config.c
blobb4b5b700b54ca073c0523bb4f58579379a9e773c
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
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
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <stddef.h>
34 #include <string.h>
35 #include <strings.h>
36 #include <libintl.h>
37 #include <locale.h>
38 #include <thread.h>
39 #include <synch.h>
40 #include <errno.h>
41 #include <unistd.h>
42 #include <fcntl.h>
43 #include <ctype.h>
44 #include <crypt.h>
45 #include <arpa/inet.h>
46 #include <sys/types.h>
47 #include <sys/stat.h>
48 #include <syslog.h>
49 #include <netdb.h>
50 #include <sys/systeminfo.h>
51 #include <sys/mman.h>
52 #include <sys/time.h>
53 #include <limits.h>
54 #include "ns_sldap.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
72 static int
73 __s_val_postime(ParamIndexType i, ns_default_config *def,
74 ns_param_t *param, char *errbuf);
75 static int
76 __s_val_basedn(ParamIndexType i, ns_default_config *def,
77 ns_param_t *param, char *errbuf);
79 static int
80 __s_val_binddn(ParamIndexType i, ns_default_config *def,
81 ns_param_t *param, char *errbuf);
83 static int
84 __s_val_bindpw(ParamIndexType i, ns_default_config *def,
85 ns_param_t *param, char *errbuf);
87 static int
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);
98 static int
99 set_default_value(ns_config_t *configptr, char *name, char *value,
100 ns_ldap_error_t **error);
102 static void
103 set_curr_config(ns_config_t *ptr);
105 static int
106 __door_getldapconfig(char **buffer, int *buflen, ns_ldap_error_t **error);
108 static ns_config_t *
109 SetDoorInfo(char *buffer, ns_ldap_error_t **errorp);
111 static boolean_t
112 timetorefresh(ns_config_t *cfg);
114 static ns_config_t *
115 LoadCacheConfiguration(ns_config_t *, ns_ldap_error_t **error);
117 static void **
118 dupParam(ns_param_t *ptr);
120 static time_t
121 conv_time(char *s);
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" },
131 { -1, NULL },
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" },
154 { -1, NULL },
157 /* V1 ONLY */
158 static ns_enum_map ns_sec_enum_v1[] = {
159 { ENUM2INT(NS_LDAP_TLS_NONE), "NS_LDAP_SEC_NONE" },
160 { -1, NULL },
163 /* V2 ONLY */
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" },
168 { -1, NULL },
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" },
174 { -1, NULL },
177 static ns_enum_map ns_ref_enum_v2[] = {
178 { ENUM2INT(NS_LDAP_FOLLOWREF), "TRUE" },
179 { ENUM2INT(NS_LDAP_NOREF), "FALSE" },
180 { -1, NULL },
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" },
187 { -1, NULL },
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" },
194 { -1, NULL },
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" },
200 { -1, NULL },
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" },
206 { -1, NULL },
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
242 * defined one.
244 * Note since amd64 is little-endian, the problem is not an issue.
245 * INT2VOIDPTR will just leave the data (i) unchanged.
247 #if defined(__amd64)
248 #define INT2VOIDPTR(i) (void *)i
249 #else
250 #define INT2VOIDPTR(i) \
251 (void *)(((long)(i))<<(8*(sizeof (void *) - sizeof (int))))
252 #endif
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 },
263 NULL, NULL },
265 /* ---------- V1 profile ---------- */
266 {"NS_LDAP_BINDDN", NS_LDAP_BINDDN_P,
267 CREDCONFIG, CHARPTR, TRUE, NS_LDAP_V1,
268 _P1_BINDDN,
269 { CHARPTR, 0, NULL },
270 __s_val_binddn, NULL },
272 {"NS_LDAP_BINDPASSWD", NS_LDAP_BINDPASSWD_P,
273 CREDCONFIG, CHARPTR, TRUE, NS_LDAP_V1,
274 _P1_BINDPASSWORD,
275 { CHARPTR, 0, NULL },
276 __s_val_bindpw, NULL },
278 {"NS_LDAP_SERVERS", NS_LDAP_SERVERS_P,
279 SERVERCONFIG, ARRAYCP, FALSE, NS_LDAP_V1,
280 _P1_SERVERS,
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,
286 _P1_SEARCHBASEDN,
287 { CHARPTR, 0, NULL },
288 __s_val_basedn, NULL },
290 {"NS_LDAP_AUTH", NS_LDAP_AUTH_P,
291 CLIENTCONFIG, ARRAYAUTH, FALSE, NS_LDAP_V1,
292 _P1_AUTHMETHOD,
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,
304 _P1_SEARCHREFERRAL,
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 },
312 NULL, 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 */
317 { INT, 0, 0 },
318 NULL, NULL },
320 {"NS_LDAP_CERT_PATH", NS_LDAP_CERT_PATH_P,
321 CREDCONFIG, CHARPTR, TRUE, NS_LDAP_V1,
322 _P1_CERTIFICATEPATH,
323 { CHARPTR, 0, NULL },
324 NULL, 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 },
330 NULL, NULL },
332 {"NS_LDAP_SEARCH_DN", NS_LDAP_SEARCH_DN_P,
333 CLIENTCONFIG, SSDLIST, FALSE, NS_LDAP_V1,
334 _P1_DATASEARCHDN,
335 { SSDLIST, 0, NULL },
336 NULL, NULL },
338 {"NS_LDAP_SEARCH_SCOPE", NS_LDAP_SEARCH_SCOPE_P,
339 CLIENTCONFIG, INT, TRUE, NS_LDAP_V1,
340 _P1_SEARCHSCOPE,
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,
346 _P1_SEARCHTIMELIMIT,
347 { INT, 0, INT2VOIDPTR(NS_DEFAULT_SEARCH_TIMEOUT) },
348 NULL, NULL },
350 {"NS_LDAP_SERVER_PREF", NS_LDAP_SERVER_PREF_P,
351 CLIENTCONFIG, ARRAYCP, FALSE, NS_LDAP_V1,
352 _P1_PREFERREDSERVER,
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,
364 _P1_CACHETTL,
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,
370 _P_CN,
371 { CHARPTR, 0, (void *)DEFAULTCONFIGNAME },
372 NULL, NULL },
374 {"NS_LDAP_BIND_TIME", NS_LDAP_BIND_TIME_P,
375 CLIENTCONFIG, INT, TRUE, NS_LDAP_V1,
376 _P1_BINDTIMELIMIT,
377 { INT, 0, INT2VOIDPTR(NS_DEFAULT_BIND_TIMEOUT) },
378 NULL, NULL },
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] },
385 NULL, NULL },
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 },
392 NULL, NULL },
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 */
427 { INT, 0, 0 },
428 NULL, NULL },
430 {"NS_LDAP_SERVER_PREF", NS_LDAP_SERVER_PREF_P,
431 CLIENTCONFIG, SERVLIST, FALSE, NS_LDAP_V2,
432 _P2_PREFERREDSERVER,
433 { SERVLIST, 0, NULL },
434 __s_val_serverList, NULL },
436 {"NS_LDAP_SERVERS", NS_LDAP_SERVERS_P,
437 SERVERCONFIG, SERVLIST, FALSE, NS_LDAP_V2,
438 _P2_DEFAULTSERVER,
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,
444 _P2_SEARCHBASEDN,
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,
450 _P2_SEARCHSCOPE,
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,
456 _P2_AUTHMETHOD,
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,
462 _P2_CREDENTIALLEVEL,
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 },
470 NULL, NULL },
472 {"NS_LDAP_SEARCH_TIME", NS_LDAP_SEARCH_TIME_P,
473 CLIENTCONFIG, INT, TRUE, NS_LDAP_V2,
474 _P2_SEARCHTIMELIMIT,
475 { INT, 0, INT2VOIDPTR(NS_DEFAULT_SEARCH_TIMEOUT) },
476 NULL, NULL },
478 {"NS_LDAP_BIND_TIME", NS_LDAP_BIND_TIME_P,
479 CLIENTCONFIG, INT, TRUE, NS_LDAP_V2,
480 _P2_BINDTIMELIMIT,
481 { INT, 0, INT2VOIDPTR(NS_DEFAULT_BIND_TIMEOUT) },
482 NULL, NULL },
484 {"NS_LDAP_SEARCH_REF", NS_LDAP_SEARCH_REF_P,
485 CLIENTCONFIG, INT, TRUE, NS_LDAP_V2,
486 _P2_FOLLOWREFERRALS,
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,
492 _P2_PROFILETTL,
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,
498 _P2_ATTRIBUTEMAP,
499 { ATTRMAP, 0, NULL },
500 NULL, NULL },
502 {"NS_LDAP_OBJECTCLASSMAP", NS_LDAP_OBJECTCLASSMAP_P,
503 CLIENTCONFIG, OBJMAP, FALSE, NS_LDAP_V2,
504 _P2_OBJECTCLASSMAP,
505 { OBJMAP, 0, NULL },
506 NULL, NULL },
508 {"NS_LDAP_PROFILE", NS_LDAP_PROFILE_P,
509 CLIENTCONFIG, CHARPTR, TRUE, NS_LDAP_V2,
510 _P_CN,
511 { CHARPTR, 0, (void *)DEFAULTCONFIGNAME },
512 NULL, NULL },
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 },
518 NULL, 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 },
524 NULL, 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 },
530 NULL, NULL },
532 /* array terminator [not an entry] */
533 {NULL, NS_LDAP_FILE_VERSION_P,
534 CLIENTCONFIG, NS_UNKNOWN, TRUE, NULL,
535 NULL,
536 { NS_UNKNOWN, 0, NULL },
537 NULL, NULL },
540 static char *
541 __getdomainname()
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];
548 int status;
550 status = sysinfo(SI_SRPC_DOMAIN, buf, MAXHOSTNAMELEN);
551 if (status < 0)
552 return (NULL);
553 /* error: not enough space to hold returned value */
554 if (status > sizeof (buf))
555 return (NULL);
556 return (strdup(buf));
559 void
560 __ns_ldap_setServer(int set)
562 cache_server = set;
565 static boolean_t
566 timetorefresh(ns_config_t *cfg)
568 struct timeval tp;
569 static time_t expire = 0;
571 if (cfg == NULL || gettimeofday(&tp, NULL) == -1)
572 return (B_TRUE);
574 if (cfg->paramList[NS_LDAP_EXP_P].ns_ptype == TIMET)
575 expire = cfg->paramList[NS_LDAP_EXP_P].ns_tm;
576 else
577 return (B_TRUE);
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;
587 char *pend;
588 int len;
590 if (pstart == NULL)
591 return (-1);
593 /* skip leading spaces */
594 while (*pstart == SPACETOK)
595 pstart++;
596 /* skip trailing spaces */
597 pend = pstart + strlen(pstart) - 1;
598 for (; pend >= pstart && *pend == SPACETOK; pend--)
600 len = pend - pstart + 1;
601 if (len == 0)
602 return (-1);
604 switch (i) {
605 case NS_LDAP_AUTH_P:
606 if (ptr->version == NS_LDAP_V1)
607 mapp = &ns_auth_enum_v1[0];
608 else
609 mapp = &ns_auth_enum_v2[0];
610 break;
611 case NS_LDAP_TRANSPORT_SEC_P:
612 return (-1);
613 case NS_LDAP_SEARCH_SCOPE_P:
614 if (ptr->version == NS_LDAP_V1)
615 mapp = &ns_scope_enum_v1[0];
616 else
617 mapp = &ns_scope_enum_v2[0];
618 break;
619 case NS_LDAP_SEARCH_REF_P:
620 if (ptr->version == NS_LDAP_V1)
621 mapp = &ns_ref_enum_v1[0];
622 else
623 mapp = &ns_ref_enum_v2[0];
624 break;
625 case NS_LDAP_PREF_ONLY_P:
626 mapp = &ns_pref_enum[0];
627 break;
628 case NS_LDAP_ENABLE_SHADOW_UPDATE_P:
629 mapp = &ns_shadow_update_enum[0];
630 break;
631 case NS_LDAP_CREDENTIAL_LEVEL_P:
632 if (ptr->version == NS_LDAP_V1)
633 return (-1);
634 else
635 mapp = &ns_cred_enum_v2[0];
636 break;
637 case NS_LDAP_SERVICE_AUTH_METHOD_P:
638 mapp = &ns_auth_enum_v2[0];
639 break;
640 case NS_LDAP_SERVICE_CRED_LEVEL_P:
641 mapp = &ns_cred_enum_v2[0];
642 break;
643 default:
644 return (-1);
647 for (; mapp->name != NULL; mapp++) {
648 if (strncasecmp(pstart, mapp->name, len) == 0 &&
649 (strlen(mapp->name) == len)) {
650 return (mapp->value);
653 return (-1);
656 char *
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];
663 else
664 mapp = &ns_auth_enum_v2[0];
666 for (; mapp->name != NULL; mapp++) {
667 if (type == INT2AUTHENUM(mapp->value)) {
668 return (mapp->name);
671 return ("Unknown AuthType_t type specified");
675 char *
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)) {
685 return (mapp->name);
689 return ("Unknown TlsType_t type specified");
693 char *
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];
700 else
701 mapp = &ns_scope_enum_v2[0];
703 for (; mapp->name != NULL; mapp++) {
704 if (type == INT2SCOPEENUM(mapp->value)) {
705 return (mapp->name);
708 return ("Unknown ScopeType_t type specified");
712 char *
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)) {
719 return (mapp->name);
722 return ("Unknown PrefOnly_t type specified");
725 char *
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];
732 else
733 mapp = &ns_ref_enum_v2[0];
735 for (; mapp->name != NULL; mapp++) {
736 if (type == INT2SEARCHREFENUM(mapp->value)) {
737 return (mapp->name);
740 return ("Unknown SearchRef_t type specified");
743 char *
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)) {
752 return (mapp->name);
755 return ("Unknown enableShadowUpdate_t type specified");
758 static char *
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)) {
767 return (mapp->name);
771 return ("Unknown CredLevel_t type specified");
774 static void
775 destroy_param(ns_config_t *ptr, ParamIndexType type)
777 int i, j;
778 char **ppc;
780 if (ptr == NULL)
781 return;
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) {
789 case CHARPTR:
790 if (ptr->paramList[type].ns_pc) {
791 free(ptr->paramList[type].ns_pc);
792 ptr->paramList[type].ns_pc = NULL;
794 break;
795 case SAMLIST:
796 case SCLLIST:
797 case SSDLIST:
798 case ARRAYCP:
799 case SERVLIST:
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]);
806 free((void *)ppc);
807 ptr->paramList[type].ns_ppc = NULL;
809 break;
810 case ARRAYAUTH:
811 case ARRAYCRED:
812 if (ptr->paramList[type].ns_pi) {
813 free(ptr->paramList[type].ns_pi);
814 ptr->paramList[type].ns_pi = NULL;
816 break;
817 case INT:
818 ptr->paramList[type].ns_i = 0;
819 break;
820 case ATTRMAP:
821 break;
822 case OBJMAP:
823 break;
824 default:
825 break;
827 ptr->paramList[type].ns_ptype = NS_UNKNOWN;
830 static void
831 destroy_config(ns_config_t *ptr)
833 ParamIndexType i;
835 if (ptr != NULL) {
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);
844 free(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.
863 void
864 __s_api_destroy_config(ns_config_t *cfg)
866 if (cfg != NULL) {
867 (void) mutex_lock(&cfg->config_mutex);
868 cfg->delete = TRUE;
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
877 * been obtained.
880 static ns_config_t *
881 get_curr_config_unlocked(ns_config_t *cfg, boolean_t global)
883 ns_config_t *ret;
885 ret = cfg;
886 if (cfg != NULL) {
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
891 * be completed
893 if (cfg->delete && global == B_TRUE)
894 ret = NULL;
895 else
896 cfg->nUse++;
897 (void) mutex_unlock(&cfg->config_mutex);
899 return (ret);
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.
908 static void
909 set_curr_config_global(ns_config_t *ptr)
911 ns_config_t *cfg;
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);
917 if (cfg != ptr) {
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.
934 static void
935 set_curr_config(ns_config_t *ptr)
937 ns_config_t *cfg;
938 ns_config_t *cur_cfg;
939 ns_conn_mgmt_t *cmg;
940 int rc;
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);
949 if (cfg != ptr) {
950 __s_api_destroy_config(cfg);
951 cmg->config = ptr;
953 (void) mutex_unlock(&cmg->cfg_lock);
954 return;
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.
966 void
967 __s_api_release_config(ns_config_t *cfg)
969 if (cfg != NULL) {
970 (void) mutex_lock(&cfg->config_mutex);
971 cfg->nUse--;
972 if (cfg->nUse == 0 && cfg->delete) {
973 destroy_config(cfg);
974 } else
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
983 void
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.
995 void
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
1007 ns_config_t *
1008 __s_api_create_config(void)
1010 ns_config_t *ret;
1011 ret = (ns_config_t *)calloc(1, sizeof (ns_config_t));
1012 if (ret == NULL)
1013 return (NULL);
1015 ret->domainName = __getdomainname();
1016 if (ret->domainName == NULL) {
1017 free(ret);
1018 return (NULL);
1020 ret->version = NS_LDAP_V1;
1021 (void) mutex_init(&ret->config_mutex, USYNC_THREAD, NULL);
1022 ret->nUse = 1;
1023 ret->delete = B_FALSE;
1024 return (ret);
1028 * __s_api_get_default_config_global returns the current global config
1030 ns_config_t *
1031 __s_api_get_default_config_global(void)
1033 ns_config_t *cfg;
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);
1041 return (cfg);
1045 * __s_api_get_default_config returns the current global config or the
1046 * per connection management one.
1048 ns_config_t *
1049 __s_api_get_default_config(void)
1051 ns_config_t *cfg;
1052 ns_config_t *cur_cfg;
1053 ns_conn_mgmt_t *cmg;
1054 int rc;
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);
1064 return (cfg);
1067 /* else get the global current config */
1068 return (__s_api_get_default_config_global());
1071 static char *
1072 stripdup(const char *instr)
1074 char *pstart = (char *)instr;
1075 char *pend, *ret;
1076 int len;
1078 if (pstart == NULL)
1079 return (NULL);
1080 /* remove leading spaces */
1081 while (*pstart == SPACETOK)
1082 pstart++;
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)
1089 return (NULL);
1090 if (len != 0) {
1091 (void) strncpy(ret, pstart, len);
1093 ret[len] = '\0';
1094 return (ret);
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 */
1104 ns_parse_status
1105 __s_api_crosscheck(ns_config_t *ptr, char *errstr, int check_dn)
1107 int value, j;
1108 time_t tm;
1109 const char *str, *str1;
1110 int i, cnt;
1111 int self, gssapi;
1113 if (ptr == NULL)
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 ==
1126 NULL) {
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);
1169 if (check_dn) {
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] != NULL; j++) {
1174 value = ptr->paramList[NS_LDAP_AUTH_P].ns_pi[j];
1175 switch (value) {
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(
1188 NS_LDAP_BINDDN_P));
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
1195 == NULL) {
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);
1203 break;
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
1213 * NS_LDAP_CACHETTL
1215 if (ptr->paramList[NS_LDAP_CACHETTL_P].ns_pc == NULL) {
1216 tm = conv_time(
1217 defconfig[NS_LDAP_CACHETTL_P].defval.ns_pc);
1218 ptr->paramList[NS_LDAP_EXP_P].ns_ptype = TIMET;
1219 if (tm != 0) {
1220 tm += time(NULL);
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.
1228 self = 0;
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] ==
1232 NS_LDAP_CRED_SELF)
1233 self++;
1235 gssapi = 0;
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)
1240 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)
1263 int i;
1265 for (i = 0; defconfig[i].name != NULL; i++) {
1266 if (strcasecmp(defconfig[i].name, value) == 0) {
1267 *type = defconfig[i].index;
1268 return (0);
1271 return (-1);
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)
1283 return (-1);
1284 return (__s_api_get_type(value, type));
1288 __s_api_get_versiontype(ns_config_t *ptr, char *value, ParamIndexType *type)
1290 ns_version_t ver;
1291 int i;
1293 if (ptr == NULL)
1294 return (-1);
1296 ver = ptr->version;
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;
1302 return (0);
1306 return (-1);
1310 __s_api_get_profiletype(char *value, ParamIndexType *type)
1312 int i;
1314 for (i = 0; defconfig[i].name != NULL; i++) {
1315 if (defconfig[i].profile_name == NULL)
1316 continue;
1317 if (strcasecmp(defconfig[i].profile_name, value) == 0) {
1318 *type = defconfig[i].index;
1319 return (0);
1322 return (-1);
1326 __s_api_get_configtype(ParamIndexType type)
1328 int i;
1330 for (i = 0; defconfig[i].name != NULL; i++) {
1331 if (defconfig[i].index == type) {
1332 return (defconfig[i].config_type);
1335 return (-1);
1338 const char *
1339 __s_api_get_configname(ParamIndexType type)
1341 int i;
1343 for (i = 0; defconfig[i].name != NULL; i++) {
1344 if (defconfig[i].index == type) {
1345 if (defconfig[i].name[0] == '\0')
1346 return (NULL);
1347 else
1348 return (defconfig[i].name);
1351 return (NULL);
1354 static ns_default_config *
1355 get_defconfig(ns_config_t *ptr, ParamIndexType type)
1357 ns_version_t ver;
1358 int i;
1360 ver = ptr->version;
1362 for (i = 0; defconfig[i].name != NULL; i++) {
1363 if (defconfig[i].index == type &&
1364 defconfig[i].version == ver) {
1365 return (&defconfig[i]);
1368 return (NULL);
1371 static int
1372 set_default_value(ns_config_t *configptr, char *name,
1373 char *value, ns_ldap_error_t **error)
1375 ParamIndexType i;
1376 int ret;
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),
1383 NULL);
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);
1399 return (ret);
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
1410 void
1411 __ns_ldap_default_config()
1413 ns_config_t *ptr;
1415 ptr = __s_api_create_config();
1416 if (ptr == NULL)
1417 return;
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
1427 * the global one.
1430 static ns_config_t *
1431 loadrefresh_config(boolean_t global)
1433 ns_config_t *cfg;
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();
1441 else
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);
1451 else
1452 set_curr_config(new_cfg);
1453 cfg = new_cfg;
1455 if (errorp != NULL)
1456 (void) __ns_ldap_freeError(&errorp);
1458 (void) mutex_unlock(&ns_loadrefresh_lock);
1459 return (cfg);
1463 * Get the current global configuration pointer and return it.
1464 * If necessary initialize or refresh the current
1465 * configuration as applicable.
1468 ns_config_t *
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.
1481 ns_config_t *
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;
1496 int found = 0, j;
1497 char *ptr = NULL, *strptr = NULL, buffer[BUFSIZE];
1498 char *rest;
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))
1511 value++;
1513 /* eat up space/quote at end of value */
1514 if (strlen(value) > 0)
1515 ptr = value + strlen(value) - 1;
1516 else
1517 ptr = value;
1518 for (; ptr != value && (*ptr == SPACETOK || *ptr == QUOTETOK); ptr--) {
1519 *ptr = '\0';
1522 switch (index) {
1523 case NS_LDAP_EXP_P:
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:
1546 break;
1547 case NS_LDAP_SEARCH_DN_P:
1548 /* depreciated because of service descriptors */
1549 /* Parse as appropriate at descriptor create time */
1550 break;
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'."),
1559 NS_LDAP_VERSION_1,
1560 NS_LDAP_VERSION_2, value);
1561 return (NS_PARSE_ERR);
1563 break;
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) {
1569 char *tmp = 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'."),
1575 tmp, name);
1576 free(tmp);
1577 return (NS_PARSE_ERR);
1579 free(tmp);
1580 strptr = strtok_r(NULL, ",", &rest);
1582 break;
1583 default:
1584 found = 0; j = 0;
1585 while (def->allowed != NULL &&
1586 def->allowed[j].name != NULL && j < DEFMAX) {
1587 if (strcmp(def->allowed[j].name,
1588 value) == 0) {
1589 found = 1;
1590 break;
1592 j++;
1594 if (!found) {
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);
1606 void
1607 __s_api_split_key_value(char *buffer, char **name, char **value)
1609 char *ptr;
1611 *name = buffer;
1612 /* split into name value pair */
1613 if ((ptr = strchr(buffer, TOKENSEPARATOR)) != NULL) {
1614 *ptr = '\0';
1615 ptr++;
1616 /* trim whitespace */
1617 while (*ptr == SPACETOK)
1618 ptr++;
1619 *value = ptr;
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;
1636 ns_param_t conf;
1637 ns_mapping_t *map, *rmap;
1638 int i, j, len;
1639 char *cp, *cp2, *end;
1640 char *tcp = NULL;
1641 char errstr[2 * MAXERROR];
1642 char tbuf[100], *ptbuf;
1643 char *sid, *origA, **mapA;
1644 char **attr;
1645 time_t tm;
1646 int free_memory, exitrc;
1647 char **p;
1649 /* Find ParamIndexType default configuration data */
1650 def = get_defconfig(ptr, type);
1651 if (def == NULL) {
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),
1656 NULL);
1657 return (NS_LDAP_CONFIG);
1660 (void) memset(&conf, 0, sizeof (conf));
1662 /* data is actually const char */
1663 cp = (char *)data;
1665 /* eat up beginning quote, if any */
1666 while (cp && (*cp == QUOTETOK || *cp == SPACETOK))
1667 cp++;
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 */
1674 if (cp2 != end) {
1675 tcp = (char *)calloc((int)(cp2 - cp + 2), sizeof (char));
1676 if (tcp == NULL)
1677 return (NS_LDAP_MEMORY);
1678 end = cp2;
1679 cp2 = tcp;
1680 while (cp <= end) {
1681 *cp2++ = *cp++;
1683 *cp2 = '\0';
1684 cp = tcp;
1687 /* Parse data according to type */
1688 switch (def->data_type) {
1689 case INT:
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);
1696 if (i < 0) {
1697 (void) snprintf(errstr, sizeof (errstr),
1698 gettext("Unable to set value: "
1699 "invalid %s (%d)"), def->name,
1700 def->index);
1701 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
1702 strdup(errstr), NULL);
1703 if (tcp != NULL)
1704 free(tcp);
1705 return (NS_LDAP_CONFIG);
1707 conf.ns_i = i;
1708 break;
1709 case NS_LDAP_TRANSPORT_SEC_P: /* ignore TRANSPORT_SEC */
1710 break;
1711 default:
1712 cp2 = cp;
1713 if ((*cp2 == '+') || (*cp2 == '-'))
1714 cp2++;
1715 for (/* empty */; *cp2; cp2++) {
1716 if (isdigit(*cp2))
1717 continue;
1719 (void) snprintf(errstr, sizeof (errstr),
1720 gettext("Unable to set value: "
1721 "invalid %s (%d)"), def->name,
1722 def->index);
1723 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
1724 strdup(errstr), NULL);
1725 if (tcp != NULL)
1726 free(tcp);
1727 return (NS_LDAP_CONFIG);
1729 i = atoi(cp);
1730 conf.ns_i = i;
1731 break;
1733 break;
1734 case TIMET:
1735 /* Do nothing with a TIMET. Initialize it below */
1736 break;
1737 case CHARPTR:
1738 conf.ns_pc = (char *)strdup(cp);
1739 if (conf.ns_pc == NULL) {
1740 if (tcp != NULL)
1741 free(tcp);
1742 return (NS_LDAP_MEMORY);
1744 break;
1745 case SAMLIST:
1746 /* first check to see if colon (:) is there */
1747 if ((strchr(cp, COLONTOK)) == NULL) {
1748 (void) snprintf(errstr, sizeof (errstr),
1749 gettext("Unable to set value: "
1750 "invalid serviceAuthenticationMethod (%s)"),
1751 cp);
1752 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
1753 strdup(errstr), NULL);
1754 if (tcp != NULL)
1755 free(tcp);
1756 return (NS_LDAP_CONFIG);
1758 /* Appends an entry to the existing list */
1759 if (ptr->paramList[type].ns_ptype != SAMLIST) {
1760 conf.ns_ppc = (char **)calloc(2, sizeof (char *));
1761 if (conf.ns_ppc == NULL) {
1762 if (tcp != NULL)
1763 free(tcp);
1764 return (NS_LDAP_MEMORY);
1766 conf.ns_acnt = 1;
1767 conf.ns_ppc[0] = (char *)strdup(cp);
1768 if (conf.ns_ppc[0] == NULL) {
1769 free(conf.ns_ppc);
1770 if (tcp != NULL)
1771 free(tcp);
1772 return (NS_LDAP_MEMORY);
1774 } else {
1775 char *dp, *dpend;
1776 int fnd = 0;
1778 /* Attempt to replace if possible */
1779 dpend = strchr(cp, COLONTOK);
1780 len = dpend - cp;
1781 dp = (char *)malloc(len+1);
1782 if (dp == NULL) {
1783 if (tcp != NULL)
1784 free(tcp);
1785 return (NS_LDAP_MEMORY);
1787 (void) strlcpy(dp, cp, len+1);
1788 fnd = 0;
1789 for (j = 0; j < ptr->paramList[type].ns_acnt; j++) {
1790 dpend = strchr(ptr->paramList[type].ns_ppc[j],
1791 COLONTOK);
1792 if (dpend == NULL)
1793 continue;
1794 i = dpend - ptr->paramList[type].ns_ppc[j];
1795 if (i != len)
1796 continue;
1797 if (strncmp(ptr->paramList[type].ns_ppc[j],
1798 dp, len) == 0) {
1799 conf.ns_acnt =
1800 ptr->paramList[type].ns_acnt;
1801 conf.ns_ppc =
1802 ptr->paramList[type].ns_ppc;
1803 ptr->paramList[type].ns_ppc = NULL;
1804 free(conf.ns_ppc[j]);
1805 conf.ns_ppc[j] = (char *)strdup(cp);
1806 if (conf.ns_ppc[j] == NULL) {
1807 free(dp);
1808 __s_api_free2dArray
1809 (conf.ns_ppc);
1810 if (tcp != NULL)
1811 free(tcp);
1812 return (NS_LDAP_MEMORY);
1814 fnd = 1;
1815 break;
1818 free(dp);
1820 if (fnd)
1821 break; /* Replaced completed */
1823 /* Append */
1824 len = ptr->paramList[type].ns_acnt + 1;
1825 if (len > 1) {
1826 p = (char **)dupParam(&ptr->paramList[type]);
1827 if (p == NULL) {
1828 if (tcp != NULL)
1829 free(tcp);
1830 return (NS_LDAP_MEMORY);
1832 } else
1833 p = NULL;
1834 conf.ns_ppc =
1835 (char **)realloc(p, (len+1) * sizeof (char *));
1836 if (conf.ns_ppc == NULL) {
1837 __s_api_free2dArray(p);
1838 if (tcp != NULL)
1839 free(tcp);
1840 return (NS_LDAP_MEMORY);
1842 conf.ns_acnt = len;
1843 conf.ns_ppc[len-1] = (char *)strdup(cp);
1844 if (conf.ns_ppc[len-1] == NULL) {
1845 __s_api_free2dArray(conf.ns_ppc);
1846 if (tcp != NULL)
1847 free(tcp);
1848 return (NS_LDAP_MEMORY);
1850 conf.ns_ppc[len] = NULL;
1852 break;
1853 case SCLLIST:
1854 /* first check to see if colon (:) is there */
1855 if ((strchr(cp, COLONTOK)) == NULL) {
1856 (void) snprintf(errstr, sizeof (errstr),
1857 gettext("Unable to set value: "
1858 "invalid serviceCredentialLevel (%s)"),
1859 cp);
1860 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
1861 strdup(errstr), NULL);
1862 if (tcp != NULL)
1863 free(tcp);
1864 return (NS_LDAP_CONFIG);
1866 /* Appends an entry to the existing list */
1867 if (ptr->paramList[type].ns_ptype != SCLLIST) {
1868 conf.ns_ppc = (char **)calloc(2, sizeof (char *));
1869 if (conf.ns_ppc == NULL) {
1870 if (tcp != NULL)
1871 free(tcp);
1872 return (NS_LDAP_MEMORY);
1874 conf.ns_acnt = 1;
1875 conf.ns_ppc[0] = (char *)strdup(cp);
1876 if (conf.ns_ppc[0] == NULL) {
1877 free(conf.ns_ppc);
1878 if (tcp != NULL)
1879 free(tcp);
1880 return (NS_LDAP_MEMORY);
1882 } else {
1883 char *dp, *dpend;
1884 int fnd = 0;
1886 /* Attempt to replace if possible */
1887 dpend = strchr(cp, COLONTOK);
1888 len = dpend - cp;
1889 dp = (char *)malloc(len+1);
1890 if (dp == NULL) {
1891 if (tcp != NULL)
1892 free(tcp);
1893 return (NS_LDAP_MEMORY);
1895 (void) strlcpy(dp, cp, len+1);
1896 fnd = 0;
1897 for (j = 0; j < ptr->paramList[type].ns_acnt; j++) {
1898 dpend = strchr(ptr->paramList[type].ns_ppc[j],
1899 COLONTOK);
1900 if (dpend == NULL)
1901 continue;
1902 i = dpend - ptr->paramList[type].ns_ppc[j];
1903 if (i != len)
1904 continue;
1905 if (strncmp(ptr->paramList[type].ns_ppc[j],
1906 dp, len) == 0) {
1907 conf.ns_acnt =
1908 ptr->paramList[type].ns_acnt;
1909 conf.ns_ppc =
1910 ptr->paramList[type].ns_ppc;
1911 ptr->paramList[type].ns_ppc = NULL;
1912 free(conf.ns_ppc[j]);
1913 conf.ns_ppc[j] = (char *)strdup(cp);
1914 if (conf.ns_ppc[j] == NULL) {
1915 free(dp);
1916 __s_api_free2dArray
1917 (conf.ns_ppc);
1918 if (tcp != NULL)
1919 free(tcp);
1920 return (NS_LDAP_MEMORY);
1922 fnd = 1;
1923 break;
1926 free(dp);
1928 if (fnd)
1929 break; /* Replaced completed */
1931 /* Append */
1932 len = ptr->paramList[type].ns_acnt + 1;
1933 if (len > 1) {
1934 p = (char **)dupParam(&ptr->paramList[type]);
1935 if (p == NULL) {
1936 if (tcp != NULL)
1937 free(tcp);
1938 return (NS_LDAP_MEMORY);
1940 } else
1941 p = NULL;
1942 conf.ns_ppc =
1943 (char **)realloc(p, (len+1) * sizeof (char *));
1944 if (conf.ns_ppc == NULL) {
1945 __s_api_free2dArray(p);
1946 if (tcp != NULL)
1947 free(tcp);
1948 return (NS_LDAP_MEMORY);
1950 conf.ns_acnt = len;
1951 conf.ns_ppc[len-1] = (char *)strdup(cp);
1952 if (conf.ns_ppc[len-1] == NULL) {
1953 __s_api_free2dArray(conf.ns_ppc);
1954 if (tcp != NULL)
1955 free(tcp);
1956 return (NS_LDAP_MEMORY);
1958 conf.ns_ppc[len] = NULL;
1960 break;
1961 case SSDLIST:
1963 * first check to see if colon (:) is there,
1964 * if so, make sure the serviceId is specified,
1965 * i.e., colon is not the first character
1967 if ((strchr(cp, COLONTOK)) == NULL || *cp == COLONTOK) {
1968 (void) snprintf(errstr, sizeof (errstr),
1969 gettext("Unable to set value: "
1970 "invalid serviceSearchDescriptor (%s)"),
1971 cp);
1972 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
1973 strdup(errstr), NULL);
1974 if (tcp != NULL)
1975 free(tcp);
1976 return (NS_LDAP_CONFIG);
1978 /* Appends an entry to the existing list */
1979 if (ptr->paramList[type].ns_ptype != SSDLIST) {
1980 conf.ns_ppc = (char **)calloc(2, sizeof (char *));
1981 if (conf.ns_ppc == NULL) {
1982 if (tcp != NULL)
1983 free(tcp);
1984 return (NS_LDAP_MEMORY);
1986 conf.ns_acnt = 1;
1987 conf.ns_ppc[0] = (char *)strdup(cp);
1988 if (conf.ns_ppc[0] == NULL) {
1989 free(conf.ns_ppc);
1990 if (tcp != NULL)
1991 free(tcp);
1992 return (NS_LDAP_MEMORY);
1994 } else {
1995 char *dp, *dpend;
1996 int fnd = 0;
1998 /* Attempt to replace if possible */
1999 dpend = strchr(cp, COLONTOK);
2000 len = dpend - cp;
2001 dp = (char *)malloc(len+1);
2002 if (dp == NULL) {
2003 if (tcp != NULL)
2004 free(tcp);
2005 return (NS_LDAP_MEMORY);
2007 (void) strlcpy(dp, cp, len+1);
2008 fnd = 0;
2009 for (j = 0; j < ptr->paramList[type].ns_acnt; j++) {
2010 dpend = strchr(ptr->paramList[type].ns_ppc[j],
2011 COLONTOK);
2012 if (dpend == NULL)
2013 continue;
2014 i = dpend - ptr->paramList[type].ns_ppc[j];
2015 if (i != len)
2016 continue;
2017 if (strncmp(ptr->paramList[type].ns_ppc[j],
2018 dp, len) == 0) {
2019 conf.ns_acnt =
2020 ptr->paramList[type].ns_acnt;
2021 conf.ns_ppc =
2022 ptr->paramList[type].ns_ppc;
2023 ptr->paramList[type].ns_ppc = NULL;
2024 free(conf.ns_ppc[j]);
2025 conf.ns_ppc[j] = (char *)strdup(cp);
2026 if (conf.ns_ppc[j] == NULL) {
2027 free(dp);
2028 __s_api_free2dArray
2029 (conf.ns_ppc);
2030 if (tcp != NULL)
2031 free(tcp);
2032 return (NS_LDAP_MEMORY);
2034 fnd = 1;
2035 break;
2038 free(dp);
2040 if (fnd)
2041 break; /* Replaced completed */
2043 /* Append */
2044 len = ptr->paramList[type].ns_acnt + 1;
2045 if (len > 1) {
2046 p = (char **)dupParam(&ptr->paramList[type]);
2047 if (p == NULL) {
2048 if (tcp != NULL)
2049 free(tcp);
2050 return (NS_LDAP_MEMORY);
2052 } else
2053 p = NULL;
2054 conf.ns_ppc =
2055 (char **)realloc(p, (len+1) * sizeof (char *));
2056 if (conf.ns_ppc == NULL) {
2057 __s_api_free2dArray(p);
2058 if (tcp != NULL)
2059 free(tcp);
2060 return (NS_LDAP_MEMORY);
2062 conf.ns_acnt = len;
2063 conf.ns_ppc[len-1] = (char *)strdup(cp);
2064 if (conf.ns_ppc[len-1] == NULL) {
2065 __s_api_free2dArray(conf.ns_ppc);
2066 if (tcp != NULL)
2067 free(tcp);
2068 return (NS_LDAP_MEMORY);
2070 conf.ns_ppc[len] = NULL;
2072 break;
2073 case ARRAYCP:
2074 len = 0;
2075 for (cp2 = cp; *cp2; cp2++) {
2076 if (*cp2 == COMMATOK)
2077 len++;
2079 if (cp != cp2)
2080 len++;
2081 if (len == 0) {
2082 conf.ns_ppc = (char **)NULL;
2083 conf.ns_acnt = 0;
2084 break;
2086 conf.ns_ppc = (char **)calloc(len + 1, sizeof (char *));
2087 if (conf.ns_ppc == NULL) {
2088 if (tcp != NULL)
2089 free(tcp);
2090 return (NS_LDAP_MEMORY);
2092 conf.ns_acnt = len;
2093 i = 0;
2094 for (cp2 = cp; *cp2; cp2++) {
2095 if (*cp2 == COMMATOK) {
2096 j = cp2 - cp + 1;
2097 conf.ns_ppc[i] = (char *)malloc(j + 1);
2098 if (conf.ns_ppc[i] == NULL) {
2099 __s_api_free2dArray(conf.ns_ppc);
2100 if (tcp != NULL)
2101 free(tcp);
2102 return (NS_LDAP_MEMORY);
2104 (void) strlcpy(conf.ns_ppc[i], cp, j);
2105 cp = cp2+1;
2106 while (*cp == SPACETOK || *cp == COMMATOK)
2107 cp++;
2108 cp2 = cp - 1;
2109 i++;
2112 j = cp2 - cp + 1;
2113 conf.ns_ppc[i] = (char *)malloc(j + 1);
2114 if (conf.ns_ppc[i] == NULL) {
2115 __s_api_free2dArray(conf.ns_ppc);
2116 if (tcp != NULL)
2117 free(tcp);
2118 return (NS_LDAP_MEMORY);
2120 (void) strlcpy(conf.ns_ppc[i], cp, j);
2121 break;
2122 case SERVLIST:
2123 len = 0;
2124 for (cp2 = cp; *cp2; cp2++) {
2125 if (*cp2 == SPACETOK || *cp2 == COMMATOK) {
2126 len++;
2127 for (; *(cp2 + 1) == SPACETOK ||
2128 *(cp2 +1) == COMMATOK; cp2++)
2132 if (cp != cp2)
2133 len++;
2134 if (len == 0) {
2135 conf.ns_ppc = (char **)NULL;
2136 conf.ns_acnt = 0;
2137 break;
2139 conf.ns_ppc = (char **)calloc(len + 1, sizeof (char *));
2140 if (conf.ns_ppc == NULL) {
2141 if (tcp != NULL)
2142 free(tcp);
2143 return (NS_LDAP_MEMORY);
2145 conf.ns_acnt = len;
2146 i = 0;
2147 for (cp2 = cp; *cp2; cp2++) {
2148 if (*cp2 == SPACETOK || *cp2 == COMMATOK) {
2149 j = cp2 - cp + 1;
2150 conf.ns_ppc[i] = (char *)malloc(j + 1);
2151 if (conf.ns_ppc[i] == NULL) {
2152 __s_api_free2dArray(conf.ns_ppc);
2153 if (tcp != NULL)
2154 free(tcp);
2155 return (NS_LDAP_MEMORY);
2157 (void) strlcpy(conf.ns_ppc[i], cp, j);
2158 cp = cp2+1;
2159 while (*cp == SPACETOK || *cp == COMMATOK)
2160 cp++;
2161 cp2 = cp - 1;
2162 i++;
2165 j = cp2 - cp + 1;
2166 conf.ns_ppc[i] = (char *)malloc(j + 1);
2167 if (conf.ns_ppc[i] == NULL) {
2168 __s_api_free2dArray(conf.ns_ppc);
2169 if (tcp != NULL)
2170 free(tcp);
2171 return (NS_LDAP_MEMORY);
2173 (void) strlcpy(conf.ns_ppc[i], cp, j);
2174 break;
2175 case ARRAYAUTH:
2176 len = 0;
2177 for (cp2 = cp; *cp2; cp2++) {
2178 if (*cp2 == SEMITOK || *cp2 == COMMATOK)
2179 len++;
2181 if (cp != cp2)
2182 len++;
2183 if (len == 0) {
2184 conf.ns_pi = (int *)NULL;
2185 conf.ns_acnt = 0;
2186 break;
2188 conf.ns_pi = (int *)calloc(len + 1, sizeof (int));
2189 if (conf.ns_pi == NULL) {
2190 if (tcp != NULL)
2191 free(tcp);
2192 return (NS_LDAP_MEMORY);
2194 conf.ns_acnt = len;
2195 i = 0;
2196 for (cp2 = cp; *cp2; cp2++) {
2197 if (*cp2 == SEMITOK || *cp2 == COMMATOK) {
2198 j = cp2 - cp + 1;
2199 if (j > sizeof (tbuf)) {
2200 j = -1;
2201 ptbuf = cp;
2202 } else {
2203 (void) strlcpy(tbuf, cp, j);
2204 j = __s_get_enum_value(ptr, tbuf,
2205 def->index);
2206 ptbuf = tbuf;
2208 if (j < 0) {
2209 (void) snprintf(errstr, sizeof (errstr),
2210 gettext("Unable to set value: "
2211 "invalid "
2212 "authenticationMethod (%s)"),
2213 ptbuf);
2214 MKERROR(LOG_ERR, *error,
2215 NS_CONFIG_SYNTAX,
2216 strdup(errstr), NULL);
2217 free(conf.ns_pi);
2218 if (tcp != NULL)
2219 free(tcp);
2220 return (NS_LDAP_CONFIG);
2222 conf.ns_pi[i] = j;
2223 cp = cp2+1;
2224 i++;
2227 j = cp2 - cp + 1;
2228 if (j > sizeof (tbuf)) {
2229 j = -1;
2230 ptbuf = cp;
2231 } else {
2232 (void) strlcpy(tbuf, cp, j);
2233 j = __s_get_enum_value(ptr, tbuf, def->index);
2234 ptbuf = tbuf;
2236 if (j < 0) {
2237 (void) snprintf(errstr, sizeof (errstr),
2238 gettext("Unable to set value: "
2239 "invalid authenticationMethod (%s)"), ptbuf);
2240 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
2241 strdup(errstr), NULL);
2242 if (tcp != NULL)
2243 free(tcp);
2244 return (NS_LDAP_CONFIG);
2246 conf.ns_pi[i] = j;
2247 break;
2248 case ARRAYCRED:
2249 len = 0;
2250 for (cp2 = cp; *cp2; cp2++) {
2251 if (*cp2 == SPACETOK)
2252 len++;
2254 if (cp != cp2)
2255 len++;
2256 if (len == 0) {
2257 conf.ns_pi = (int *)NULL;
2258 conf.ns_acnt = 0;
2259 break;
2261 conf.ns_pi = (int *)calloc(len + 1, sizeof (int));
2262 if (conf.ns_pi == NULL) {
2263 if (tcp != NULL)
2264 free(tcp);
2265 return (NS_LDAP_MEMORY);
2267 conf.ns_acnt = len;
2268 i = 0;
2269 for (cp2 = cp; *cp2; cp2++) {
2270 if (*cp2 == SPACETOK) {
2271 j = cp2 - cp + 1;
2272 if (j > sizeof (tbuf)) {
2273 j = -1;
2274 ptbuf = cp;
2275 } else {
2276 (void) strlcpy(tbuf, cp, j);
2277 j = __s_get_enum_value(ptr, tbuf,
2278 def->index);
2279 ptbuf = tbuf;
2281 if (j < 0) {
2282 (void) snprintf(errstr, sizeof (errstr),
2283 gettext("Unable to set value: "
2284 "invalid credentialLevel (%s)"),
2285 ptbuf);
2286 MKERROR(LOG_ERR, *error,
2287 NS_CONFIG_SYNTAX,
2288 strdup(errstr), NULL);
2289 free(conf.ns_pi);
2290 if (tcp != NULL)
2291 free(tcp);
2292 return (NS_LDAP_CONFIG);
2294 conf.ns_pi[i] = j;
2295 cp = cp2+1;
2296 i++;
2299 j = cp2 - cp + 1;
2300 if (j > sizeof (tbuf)) {
2301 j = -1;
2302 ptbuf = cp;
2303 } else {
2304 (void) strlcpy(tbuf, cp, j);
2305 j = __s_get_enum_value(ptr, tbuf, def->index);
2306 ptbuf = tbuf;
2308 if (j < 0) {
2309 (void) snprintf(errstr, sizeof (errstr),
2310 gettext("Unable to set value: "
2311 "invalid credentialLevel (%s)"), ptbuf);
2312 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
2313 strdup(errstr), NULL);
2314 if (tcp != NULL)
2315 free(tcp);
2316 return (NS_LDAP_CONFIG);
2318 conf.ns_pi[i] = j;
2319 break;
2320 case ATTRMAP:
2321 case OBJMAP:
2322 i = __s_api_parse_map(cp, &sid, &origA, &mapA);
2323 if (i != NS_HASH_RC_SUCCESS) {
2324 if (i == NS_HASH_RC_NO_MEMORY) {
2325 exitrc = NS_LDAP_MEMORY;
2326 } else {
2327 (void) snprintf(errstr, sizeof (errstr),
2328 gettext("Unable to set value: "
2329 "invalid schema mapping (%s)"), cp);
2330 exitrc = NS_LDAP_CONFIG;
2331 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
2332 strdup(errstr), NULL);
2334 if (tcp)
2335 free(tcp);
2336 return (exitrc);
2340 * Add reverse map first.
2341 * There could be more than one.
2343 for (attr = mapA; *attr; attr++) {
2345 free_memory = 1;
2346 exitrc = NS_LDAP_MEMORY;
2348 rmap = (ns_mapping_t *)calloc(1,
2349 sizeof (ns_mapping_t));
2350 if (rmap) {
2351 rmap->service = strdup(sid);
2352 if (rmap->service) {
2353 rmap->orig = strdup(*attr);
2354 if (rmap->orig) {
2355 rmap->map = (char **)calloc(2,
2356 sizeof (char *));
2357 if (rmap->map) {
2358 (rmap->map)[0] =
2359 strdup(origA);
2360 if ((rmap->map)[0])
2361 free_memory = 0;
2367 if (free_memory == 0) {
2368 if (def->data_type == ATTRMAP) {
2369 rmap->type = NS_ATTR_MAP;
2370 i = __s_api_add_map2hash(ptr,
2371 NS_HASH_RAMAP, rmap);
2372 } else {
2373 rmap->type = NS_OBJ_MAP;
2374 i = __s_api_add_map2hash(ptr,
2375 NS_HASH_ROMAP, rmap);
2378 if (i != NS_HASH_RC_SUCCESS) {
2379 switch (i) {
2380 case NS_HASH_RC_CONFIG_ERROR:
2381 exitrc = NS_LDAP_INTERNAL;
2382 (void) snprintf(errstr,
2383 sizeof (errstr),
2384 gettext(
2385 "Unable to set value: "
2386 "no configuration info "
2387 "for schema map "
2388 "update (%s)"), cp);
2389 MKERROR(LOG_ERR, *error,
2390 NS_LDAP_INTERNAL,
2391 strdup(errstr),
2392 NULL);
2393 break;
2394 case NS_HASH_RC_EXISTED:
2395 exitrc = NS_LDAP_CONFIG;
2396 (void) snprintf(errstr,
2397 sizeof (errstr),
2398 gettext(
2399 "Unable to set value: "
2400 "schema map "
2401 "already existed for "
2402 "(%s, %s)."),
2403 *attr, origA);
2404 MKERROR(LOG_ERR, *error,
2405 NS_CONFIG_SYNTAX,
2406 strdup(errstr),
2407 NULL);
2408 break;
2409 case NS_HASH_RC_NO_MEMORY:
2410 exitrc = NS_LDAP_MEMORY;
2411 break;
2413 free_memory = 1;
2417 if (free_memory) {
2418 if (tcp)
2419 free(tcp);
2420 free(sid);
2421 free(origA);
2422 __s_api_free2dArray(mapA);
2423 if (rmap) {
2424 if (rmap->service)
2425 free(rmap->service);
2426 if (rmap->orig)
2427 free(rmap->orig);
2428 if (rmap->map) {
2429 if ((rmap->map)[0])
2430 free((rmap->map)[0]);
2431 free(rmap->map);
2433 free(rmap);
2435 return (exitrc);
2440 * For performance gain,
2441 * add a "schema mapping existed" indicator
2442 * for the given service if not already added.
2443 * This dummy map needs not be removed, if
2444 * the next real map add operation fails.
2445 * since the caller, e.g. ldap_cachemgr.
2446 * should exit anyway.
2448 free_memory = 1;
2449 exitrc = NS_LDAP_MEMORY;
2451 map = (ns_mapping_t *)calloc(1,
2452 sizeof (ns_mapping_t));
2453 if (map) {
2454 map->service = strdup(sid);
2455 if (map->service) {
2456 map->orig = strdup(
2457 NS_HASH_SCHEMA_MAPPING_EXISTED);
2458 if (map->orig) {
2459 map->map = (char **)calloc(2,
2460 sizeof (char *));
2461 if (map->map) {
2462 (map->map)[0] =
2463 strdup(sid);
2464 if ((map->map)[0])
2465 free_memory = 0;
2471 if (free_memory == 0) {
2472 map->type = NS_ATTR_MAP;
2474 * add to reverse map,
2475 * so that "ldapclient list"
2476 * would not show it
2478 i = __s_api_add_map2hash(ptr,
2479 NS_HASH_RAMAP, map);
2482 * ignore "map already existed" error,
2483 * just need one per service.
2484 * Need however to free memory allocated
2485 * for map.
2487 if (i != NS_HASH_RC_SUCCESS &&
2488 i != NS_HASH_RC_EXISTED) {
2489 switch (i) {
2490 case NS_HASH_RC_CONFIG_ERROR:
2491 exitrc = NS_LDAP_INTERNAL;
2492 (void) snprintf(errstr,
2493 sizeof (errstr),
2494 gettext(
2495 "Unable to set value: "
2496 "no configuration info "
2497 "for schema map "
2498 "update (%s)"), cp);
2499 MKERROR(LOG_ERR, *error,
2500 NS_LDAP_INTERNAL,
2501 strdup(errstr),
2502 NULL);
2503 break;
2504 case NS_HASH_RC_NO_MEMORY:
2505 exitrc = NS_LDAP_MEMORY;
2506 break;
2508 free_memory = 1;
2509 } else if (i == NS_HASH_RC_EXISTED) {
2510 if (map->service)
2511 free(map->service);
2512 if (map->orig)
2513 free(map->orig);
2514 if (map->map) {
2515 if ((map->map)[0])
2516 free((map->map)[0]);
2517 free(map->map);
2519 free(map);
2520 map = NULL;
2524 if (free_memory) {
2525 if (tcp)
2526 free(tcp);
2527 free(sid);
2528 free(origA);
2529 __s_api_free2dArray(mapA);
2530 if (map) {
2531 if (map->service)
2532 free(map->service);
2533 if (map->orig)
2534 free(map->orig);
2535 if (map->map) {
2536 if ((map->map)[0])
2537 free((map->map)[0]);
2538 free(map->map);
2540 free(map);
2542 return (exitrc);
2546 * add the real schema map
2548 free_memory = 1;
2549 exitrc = NS_LDAP_MEMORY;
2550 map = (ns_mapping_t *)calloc(1, sizeof (ns_mapping_t));
2551 if (map) {
2552 map->service = sid;
2553 map->orig = origA;
2554 map->map = mapA;
2556 if (def->data_type == ATTRMAP) {
2557 map->type = NS_ATTR_MAP;
2558 i = __s_api_add_map2hash(ptr,
2559 NS_HASH_AMAP, map);
2560 } else {
2561 map->type = NS_OBJ_MAP;
2562 i = __s_api_add_map2hash(ptr,
2563 NS_HASH_OMAP, map);
2566 if (i != NS_HASH_RC_SUCCESS) {
2567 switch (i) {
2568 case NS_HASH_RC_CONFIG_ERROR:
2569 exitrc = NS_LDAP_INTERNAL;
2570 (void) snprintf(errstr,
2571 sizeof (errstr),
2572 gettext(
2573 "Unable to set value: "
2574 "no configuration info "
2575 "for schema map "
2576 "update (%s)"), cp);
2577 MKERROR(LOG_ERR, *error,
2578 NS_LDAP_INTERNAL,
2579 strdup(errstr),
2580 NULL);
2581 break;
2582 case NS_HASH_RC_EXISTED:
2583 exitrc = NS_LDAP_CONFIG;
2584 (void) snprintf(errstr,
2585 sizeof (errstr),
2586 gettext(
2587 "Unable to set value: "
2588 "schema map "
2589 "already existed for "
2590 "'%s'."), origA);
2591 MKERROR(LOG_ERR, *error,
2592 NS_CONFIG_SYNTAX,
2593 strdup(errstr),
2594 NULL);
2595 break;
2596 case NS_HASH_RC_NO_MEMORY:
2597 exitrc = NS_LDAP_MEMORY;
2598 break;
2600 free_memory = 1;
2601 } else
2602 free_memory = 0;
2605 if (free_memory) {
2606 if (tcp)
2607 free(tcp);
2608 free(sid);
2609 free(origA);
2610 __s_api_free2dArray(mapA);
2611 if (map)
2612 free(map);
2613 return (exitrc);
2616 break;
2617 default:
2618 /* This should never happen. */
2619 (void) snprintf(errstr, sizeof (errstr),
2620 gettext("Unable to set value: invalid configuration "
2621 "type (%d)"), def->data_type);
2622 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, strdup(errstr),
2623 NULL);
2624 if (tcp != NULL)
2625 free(tcp);
2626 return (NS_LDAP_CONFIG);
2628 conf.ns_ptype = def->data_type;
2629 if (tcp != NULL)
2630 free(tcp);
2632 /* Individually written verify routines here can replace */
2633 /* verify_value. Verify conf (data) as appropriate here */
2634 if (def->ns_verify != NULL) {
2635 if ((*def->ns_verify)(type, def, &conf, errstr) != NS_SUCCESS) {
2636 ns_param_t sav_conf;
2638 (void) snprintf(errstr, sizeof (errstr),
2639 gettext("%s"), errstr);
2640 MKERROR(LOG_WARNING, *error, NS_CONFIG_SYNTAX,
2641 strdup(errstr), NULL);
2643 sav_conf = ptr->paramList[type];
2644 ptr->paramList[type] = conf;
2645 destroy_param(ptr, type);
2646 ptr->paramList[type] = sav_conf;
2648 return (NS_LDAP_CONFIG);
2652 /* post evaluate the data */
2655 * if this is for setting a password,
2656 * encrypt the password first.
2657 * NOTE evalue() is smart and will just return
2658 * the value passed if it is already encrypted.
2660 * Init NS_LDAP_EXP_P here when CACHETTL is updated
2662 if (type == NS_LDAP_BINDPASSWD_P ||
2663 type == NS_LDAP_ADMIN_BINDPASSWD_P) {
2664 cp = conf.ns_pc;
2665 cp2 = evalue((char *)cp);
2666 conf.ns_pc = cp2;
2667 free(cp);
2668 cp = NULL;
2669 } else if (type == NS_LDAP_FILE_VERSION_P) {
2670 ptr->version = NS_LDAP_V1;
2671 if (strcasecmp(conf.ns_pc, NS_LDAP_VERSION_2) == 0) {
2672 ptr->version = NS_LDAP_V2;
2674 } else if (type == NS_LDAP_CACHETTL_P) {
2675 cp = conf.ns_pc;
2676 tm = conv_time(cp);
2677 ptr->paramList[NS_LDAP_EXP_P].ns_ptype = TIMET;
2678 if (tm != 0) {
2679 tm += time(NULL);
2681 ptr->paramList[NS_LDAP_EXP_P].ns_tm = tm;
2684 /* Everything checks out move new values into param */
2685 destroy_param(ptr, type);
2686 /* Assign new/updated value into paramList */
2687 ptr->paramList[type] = conf;
2689 return (NS_LDAP_SUCCESS);
2694 * Set a parameter value in the 'config' configuration structure
2695 * Lock as appropriate
2699 __ns_ldap_setParam(const ParamIndexType type,
2700 const void *data, ns_ldap_error_t **error)
2702 ns_ldap_error_t *errorp;
2703 int ret;
2704 char errstr[2 * MAXERROR];
2705 ns_config_t *cfg;
2706 ns_config_t *cfg_g = (ns_config_t *)-1;
2707 ns_config_t *new_cfg;
2708 boolean_t reinit_connmgmt = B_FALSE;
2710 /* We want to refresh only one configuration at a time */
2711 (void) mutex_lock(&ns_loadrefresh_lock);
2712 cfg = __s_api_get_default_config();
2714 if (cache_server == TRUE) {
2715 if (cfg == NULL) {
2716 __ns_ldap_default_config();
2717 cfg = __s_api_get_default_config();
2718 if (cfg == NULL) {
2719 (void) mutex_unlock(&ns_loadrefresh_lock);
2720 return (NS_LDAP_MEMORY);
2723 } else {
2725 * This code always return error here on client side,
2726 * this needs to change once libsldap is used by more
2727 * applications that need to set parameters.
2729 (void) snprintf(errstr, sizeof (errstr),
2730 gettext("Unable to set parameter from a client in "
2731 "__ns_ldap_setParam()"));
2732 MKERROR(LOG_WARNING, *error, NS_CONFIG_SYNTAX, strdup(errstr),
2733 NULL);
2734 if (cfg != NULL)
2735 __s_api_release_config(cfg);
2736 (void) mutex_unlock(&ns_loadrefresh_lock);
2737 return (NS_LDAP_CONFIG);
2740 /* (re)initialize configuration if necessary */
2741 if (!__s_api_isStandalone() &&
2742 cache_server == FALSE && timetorefresh(cfg))
2743 cfg_g = __s_api_get_default_config_global();
2744 /* only (re)initialize the global configuration */
2745 if (cfg == cfg_g) {
2746 if (cfg_g != NULL)
2747 __s_api_release_config(cfg_g);
2748 new_cfg = LoadCacheConfiguration(cfg, &errorp);
2749 if (new_cfg != cfg)
2750 __s_api_release_config(cfg);
2751 if (new_cfg == NULL) {
2752 (void) snprintf(errstr, sizeof (errstr),
2753 gettext("Unable to load configuration '%s' "
2754 "('%s')."), NSCONFIGFILE,
2755 errorp != NULL && errorp->message != NULL ?
2756 errorp->message : "");
2757 MKERROR(LOG_WARNING, *error, NS_CONFIG_NOTLOADED,
2758 strdup(errstr), NULL);
2759 if (errorp != NULL)
2760 (void) __ns_ldap_freeError(&errorp);
2761 (void) mutex_unlock(&ns_loadrefresh_lock);
2762 return (NS_LDAP_CONFIG);
2764 if (new_cfg != cfg) {
2765 set_curr_config_global(new_cfg);
2766 cfg = new_cfg;
2767 reinit_connmgmt = B_TRUE;
2770 (void) mutex_unlock(&ns_loadrefresh_lock);
2772 if (reinit_connmgmt == B_TRUE)
2773 __s_api_reinit_conn_mgmt_new_config(cfg);
2775 /* translate input and save in the parameter list */
2776 ret = __ns_ldap_setParamValue(cfg, type, data, error);
2778 __s_api_release_config(cfg);
2780 return (ret);
2785 * Make a copy of a parameter entry
2788 static void **
2789 dupParam(ns_param_t *ptr)
2791 int count, i;
2792 void **dupdata, *ret;
2793 int *intptr;
2794 char *cp, tmbuf[32];
2795 static time_t expire = 0;
2796 ns_auth_t *ap;
2798 switch (ptr->ns_ptype) {
2799 case ARRAYAUTH:
2800 case ARRAYCRED:
2801 case SAMLIST:
2802 case SCLLIST:
2803 case SSDLIST:
2804 case SERVLIST:
2805 case ARRAYCP:
2806 count = ptr->ns_acnt;
2807 if (count == 0)
2808 return (NULL);
2809 break;
2810 case CHARPTR:
2811 case INT:
2812 case TIMET:
2813 count = 1;
2816 dupdata = (void **)calloc((count + 1), sizeof (void *));
2817 if (dupdata == NULL)
2818 return (NULL);
2820 switch (ptr->ns_ptype) {
2821 case ARRAYAUTH:
2822 for (i = 0; i < count; i++) {
2823 ap = __s_api_AuthEnumtoStruct(
2824 (EnumAuthType_t)ptr->ns_pi[i]);
2825 if (ap == NULL) {
2826 free(dupdata);
2827 return (NULL);
2829 dupdata[i] = ap;
2831 break;
2832 case ARRAYCRED:
2833 for (i = 0; i < count; i++) {
2834 intptr = (int *)malloc(sizeof (int));
2835 if (intptr == NULL) {
2836 free(dupdata);
2837 return (NULL);
2839 dupdata[i] = (void *)intptr;
2840 *intptr = ptr->ns_pi[i];
2842 break;
2843 case SAMLIST:
2844 case SCLLIST:
2845 case SSDLIST:
2846 case SERVLIST:
2847 case ARRAYCP:
2848 for (i = 0; i < count; i++) {
2849 ret = (void *)strdup(ptr->ns_ppc[i]);
2850 if (ret == NULL) {
2851 free(dupdata);
2852 return (NULL);
2854 dupdata[i] = ret;
2856 break;
2857 case CHARPTR:
2858 if (ptr->ns_pc == NULL) {
2859 free(dupdata);
2860 return (NULL);
2862 ret = (void *)strdup(ptr->ns_pc);
2863 if (ret == NULL) {
2864 free(dupdata);
2865 return (NULL);
2867 dupdata[0] = ret;
2868 break;
2869 case INT:
2870 intptr = (int *)malloc(sizeof (int));
2871 if (intptr == NULL) {
2872 free(dupdata);
2873 return (NULL);
2875 *intptr = ptr->ns_i;
2876 dupdata[0] = (void *)intptr;
2877 break;
2878 case TIMET:
2879 expire = ptr->ns_tm;
2880 tmbuf[31] = '\0';
2881 cp = lltostr((long)expire, &tmbuf[31]);
2882 ret = (void *)strdup(cp);
2883 if (ret == NULL) {
2884 free(dupdata);
2885 return (NULL);
2887 dupdata[0] = ret;
2888 break;
2890 return (dupdata);
2894 __ns_ldap_freeParam(void ***data)
2896 void **tmp;
2897 int i = 0;
2899 if (*data == NULL)
2900 return (NS_LDAP_SUCCESS);
2902 for (i = 0, tmp = *data; tmp[i] != NULL; i++)
2903 free(tmp[i]);
2905 free(*data);
2907 *data = NULL;
2909 return (NS_LDAP_SUCCESS);
2913 * Get the internal format for a parameter value. This
2914 * routine makes a copy of an internal param value from
2915 * the currently active parameter list and returns it.
2919 __ns_ldap_getParam(const ParamIndexType Param,
2920 void ***data, ns_ldap_error_t **error)
2922 char errstr[2 * MAXERROR];
2923 ns_ldap_error_t *errorp;
2924 ns_default_config *def;
2925 ns_config_t *cfg;
2926 ns_config_t *cfg_g = (ns_config_t *)-1;
2927 ns_config_t *new_cfg;
2928 boolean_t reinit_connmgmt = B_FALSE;
2930 if (data == NULL)
2931 return (NS_LDAP_INVALID_PARAM);
2933 *data = NULL;
2935 /* We want to refresh only one configuration at a time */
2936 (void) mutex_lock(&ns_loadrefresh_lock);
2937 cfg = __s_api_get_default_config();
2939 /* (re)initialize configuration if necessary */
2940 if (!__s_api_isStandalone() &&
2941 cache_server == FALSE && timetorefresh(cfg))
2942 cfg_g = __s_api_get_default_config_global();
2943 /* only (re)initialize the global configuration */
2944 if (cfg == cfg_g) {
2945 if (cfg_g != NULL)
2946 __s_api_release_config(cfg_g);
2947 new_cfg = LoadCacheConfiguration(cfg, &errorp);
2948 if (new_cfg != cfg)
2949 __s_api_release_config(cfg);
2950 if (new_cfg == NULL) {
2951 (void) snprintf(errstr, sizeof (errstr),
2952 gettext("Unable to load configuration "
2953 "'%s' ('%s')."),
2954 NSCONFIGFILE,
2955 errorp != NULL && errorp->message != NULL ?
2956 errorp->message : "");
2957 MKERROR(LOG_WARNING, *error, NS_CONFIG_NOTLOADED,
2958 strdup(errstr), NULL);
2959 if (errorp != NULL)
2960 (void) __ns_ldap_freeError(&errorp);
2961 (void) mutex_unlock(&ns_loadrefresh_lock);
2962 return (NS_LDAP_CONFIG);
2964 if (new_cfg != cfg) {
2965 set_curr_config_global(new_cfg);
2966 cfg = new_cfg;
2967 reinit_connmgmt = B_TRUE;
2970 (void) mutex_unlock(&ns_loadrefresh_lock);
2972 if (reinit_connmgmt == B_TRUE)
2973 __s_api_reinit_conn_mgmt_new_config(cfg);
2975 if (cfg == NULL) {
2976 (void) snprintf(errstr, sizeof (errstr),
2977 gettext("No configuration information available."));
2978 MKERROR(LOG_ERR, *error, NS_CONFIG_NOTLOADED,
2979 strdup(errstr), NULL);
2980 return (NS_LDAP_CONFIG);
2983 if (Param == NS_LDAP_DOMAIN_P) {
2984 *data = (void **)calloc(2, sizeof (void *));
2985 if (*data == NULL) {
2986 __s_api_release_config(cfg);
2987 return (NS_LDAP_MEMORY);
2989 (*data)[0] = (void *)strdup(cfg->domainName);
2990 if ((*data)[0] == NULL) {
2991 free(*data);
2992 __s_api_release_config(cfg);
2993 return (NS_LDAP_MEMORY);
2995 } else if (cfg->paramList[Param].ns_ptype == NS_UNKNOWN) {
2996 /* get default */
2997 def = get_defconfig(cfg, Param);
2998 if (def != NULL)
2999 *data = dupParam(&def->defval);
3000 } else {
3001 *data = dupParam(&(cfg->paramList[Param]));
3003 __s_api_release_config(cfg);
3005 return (NS_LDAP_SUCCESS);
3009 * This routine takes a parameter in internal format and
3010 * translates it into a variety of string formats for various
3011 * outputs (doors/file/ldif). This routine would be better
3012 * named: __ns_ldap_translateParam2String
3015 char *
3016 __s_api_strValue(ns_config_t *cfg, ParamIndexType index, ns_strfmt_t fmt)
3018 ns_default_config *def = NULL;
3019 ns_param_t *ptr;
3020 ns_hash_t *hptr;
3021 ns_mapping_t *mptr;
3022 char ibuf[14];
3023 char abuf[64], **cpp;
3024 int count, i;
3025 boolean_t first = B_TRUE;
3026 LineBuf lbuf;
3027 LineBuf *buffer = &lbuf;
3028 char *retstring;
3029 char *sepstr;
3031 if (cfg == NULL)
3032 return (NULL);
3034 /* NS_LDAP_EXP and TRANSPORT_SEC are not exported externally */
3035 if (index == NS_LDAP_EXP_P || index == NS_LDAP_TRANSPORT_SEC_P)
3036 return (NULL);
3038 /* Return nothing if the value is the default */
3039 if (cfg->paramList[index].ns_ptype == NS_UNKNOWN)
3040 return (NULL);
3042 (void) memset((char *)buffer, 0, sizeof (LineBuf));
3044 ptr = &(cfg->paramList[index]);
3046 abuf[0] = '\0';
3048 /* get default */
3049 def = get_defconfig(cfg, index);
3050 if (def == NULL)
3051 return (NULL);
3053 switch (fmt) {
3054 case NS_DOOR_FMT:
3055 (void) strlcpy(abuf, def->name, sizeof (abuf));
3056 (void) strlcat(abuf, EQUALSEP, sizeof (abuf));
3057 break;
3058 case NS_FILE_FMT:
3059 (void) strlcpy(abuf, def->name, sizeof (abuf));
3060 (void) strlcat(abuf, EQUSPSEP, sizeof (abuf));
3061 break;
3062 case NS_LDIF_FMT:
3063 /* If no LDIF attr exists ignore the entry */
3064 if (def->profile_name == NULL)
3065 return (NULL);
3066 (void) strlcpy(abuf, def->profile_name, sizeof (abuf));
3067 (void) strlcat(abuf, COLSPSEP, sizeof (abuf));
3068 break;
3069 default:
3070 break;
3073 if (__print2buf(buffer, abuf, NULL))
3074 goto strValueError;
3076 switch (ptr->ns_ptype) {
3077 case ARRAYAUTH:
3078 count = ptr->ns_acnt;
3079 for (i = 0; i < count; i++) {
3080 sepstr = NULL;
3081 if (i != count-1) {
3082 if (cfg->version == NS_LDAP_V1) {
3083 sepstr = COMMASEP;
3084 } else {
3085 sepstr = SEMISEP;
3088 if (__print2buf(buffer, __s_get_auth_name(cfg,
3089 (AuthType_t)(ptr->ns_pi[i])), sepstr))
3090 goto strValueError;
3092 break;
3093 case ARRAYCRED:
3094 count = ptr->ns_acnt;
3095 for (i = 0; i < count; i++) {
3096 sepstr = NULL;
3097 if (i != count-1) {
3098 sepstr = SPACESEP;
3100 if (__print2buf(buffer, __s_get_credlvl_name(cfg,
3101 (CredLevel_t)ptr->ns_pi[i]), sepstr))
3102 goto strValueError;
3104 break;
3105 case SAMLIST:
3106 case SCLLIST:
3107 case SSDLIST:
3108 count = ptr->ns_acnt;
3109 for (i = 0; i < count; i++) {
3110 if (__print2buf(buffer, ptr->ns_ppc[i], NULL))
3111 goto strValueError;
3113 if (i == count-1)
3114 continue;
3116 /* Separate items */
3117 switch (fmt) {
3118 case NS_DOOR_FMT:
3119 if (__print2buf(buffer, DOORLINESEP, NULL) ||
3120 __print2buf(buffer, def->name, EQUALSEP))
3121 goto strValueError;
3122 break;
3123 case NS_FILE_FMT:
3124 if (__print2buf(buffer, "\n", NULL) ||
3125 __print2buf(buffer, def->name, EQUSPSEP))
3126 goto strValueError;
3127 break;
3128 case NS_LDIF_FMT:
3129 if (__print2buf(buffer, "\n", NULL) ||
3130 __print2buf(buffer, def->profile_name,
3131 COLSPSEP))
3132 goto strValueError;
3133 break;
3136 break;
3137 case ARRAYCP:
3138 count = ptr->ns_acnt;
3139 for (i = 0; i < count; i++) {
3140 sepstr = NULL;
3141 if (i != count-1) {
3142 sepstr = COMMASEP;
3144 if (__print2buf(buffer, ptr->ns_ppc[i], sepstr))
3145 goto strValueError;
3147 break;
3148 case SERVLIST:
3149 count = ptr->ns_acnt;
3150 for (i = 0; i < count; i++) {
3151 sepstr = NULL;
3152 if (i != count-1) {
3153 if (fmt == NS_LDIF_FMT) {
3154 sepstr = SPACESEP;
3155 } else {
3156 sepstr = COMMASEP;
3159 if (__print2buf(buffer, ptr->ns_ppc[i], sepstr))
3160 goto strValueError;
3162 break;
3163 case CHARPTR:
3164 if (ptr->ns_pc == NULL)
3165 break;
3166 if (__print2buf(buffer, ptr->ns_pc, NULL))
3167 goto strValueError;
3168 break;
3169 case INT:
3170 switch (def->index) {
3171 case NS_LDAP_PREF_ONLY_P:
3172 if (__print2buf(buffer,
3173 __s_get_pref_name((PrefOnly_t)ptr->ns_i), NULL))
3174 goto strValueError;
3175 break;
3176 case NS_LDAP_SEARCH_REF_P:
3177 if (__print2buf(buffer, __s_get_searchref_name(cfg,
3178 (SearchRef_t)ptr->ns_i), NULL))
3179 goto strValueError;
3180 break;
3181 case NS_LDAP_SEARCH_SCOPE_P:
3182 if (__print2buf(buffer, __s_get_scope_name(cfg,
3183 (ScopeType_t)ptr->ns_i), NULL))
3184 goto strValueError;
3185 break;
3186 case NS_LDAP_ENABLE_SHADOW_UPDATE_P:
3187 if (__print2buf(buffer, __s_get_shadowupdate_name(
3188 (enableShadowUpdate_t)ptr->ns_i), NULL))
3189 goto strValueError;
3190 break;
3191 default:
3192 (void) snprintf(ibuf, sizeof (ibuf),
3193 "%d", ptr->ns_i);
3194 if (__print2buf(buffer, ibuf, NULL))
3195 goto strValueError;
3196 break;
3198 break;
3199 case ATTRMAP:
3200 for (hptr = cfg->llHead; hptr; hptr = hptr->h_llnext) {
3201 if (hptr->h_type != NS_HASH_AMAP) {
3202 continue;
3204 if (!first) {
3205 /* print abuf as "separator" */
3206 if (fmt == NS_DOOR_FMT) {
3207 if (__print2buf(buffer, DOORLINESEP,
3208 abuf))
3209 goto strValueError;
3210 } else {
3211 if (__print2buf(buffer, "\n", abuf))
3212 goto strValueError;
3215 mptr = hptr->h_map;
3216 if (__print2buf(buffer, mptr->service, COLONSEP) ||
3217 __print2buf(buffer, mptr->orig, EQUALSEP))
3218 goto strValueError;
3219 for (cpp = mptr->map; cpp && *cpp; cpp++) {
3220 /* print *cpp as "separator" */
3221 sepstr = "";
3222 if (cpp != mptr->map)
3223 sepstr = SPACESEP;
3224 if (__print2buf(buffer, sepstr, *cpp))
3225 goto strValueError;
3227 first = B_FALSE;
3229 break;
3230 case OBJMAP:
3231 for (hptr = cfg->llHead; hptr; hptr = hptr->h_llnext) {
3232 if (hptr->h_type != NS_HASH_OMAP) {
3233 continue;
3235 if (!first) {
3236 /* print abuf as "separator" */
3237 if (fmt == NS_DOOR_FMT) {
3238 if (__print2buf(buffer, DOORLINESEP,
3239 abuf))
3240 goto strValueError;
3241 } else {
3242 if (__print2buf(buffer, "\n", abuf))
3243 goto strValueError;
3246 mptr = hptr->h_map;
3247 if (__print2buf(buffer, mptr->service, COLONSEP) ||
3248 __print2buf(buffer, mptr->orig, EQUALSEP))
3249 goto strValueError;
3250 for (cpp = mptr->map; cpp && *cpp; cpp++) {
3251 /* print *cpp as "separator" */
3252 sepstr = "";
3253 if (cpp != mptr->map)
3254 sepstr = SPACESEP;
3255 if (__print2buf(buffer, sepstr, *cpp))
3256 goto strValueError;
3258 first = B_FALSE;
3260 break;
3263 retstring = buffer->str;
3264 return (retstring);
3266 strValueError:
3267 if (buffer->len > 0)
3268 free(buffer->str);
3269 return (NULL);
3272 /* shared by __door_getldapconfig() and __door_getadmincred() */
3274 __door_getconf(char **buffer, int *buflen, ns_ldap_error_t **error,
3275 int callnumber)
3277 typedef union {
3278 ldap_data_t s_d;
3279 char s_b[DOORBUFFERSIZE];
3280 } space_t;
3281 space_t *space;
3283 ldap_data_t *sptr;
3284 int ndata;
3285 int adata;
3286 char errstr[MAXERROR];
3287 char *domainname;
3288 ns_ldap_return_code retCode;
3289 ldap_config_out_t *cfghdr;
3291 *error = NULL;
3293 domainname = __getdomainname();
3294 if (domainname == NULL || buffer == NULL || buflen == NULL ||
3295 (strlen(domainname) >= (sizeof (space_t)
3296 - sizeof (space->s_d.ldap_call.ldap_callnumber)))) {
3297 return (NS_LDAP_OP_FAILED);
3300 space = (space_t *)calloc(1, sizeof (space_t));
3301 if (space == NULL)
3302 return (NS_LDAP_MEMORY);
3304 adata = (sizeof (ldap_call_t) + strlen(domainname) +1);
3305 ndata = sizeof (space_t);
3306 space->s_d.ldap_call.ldap_callnumber = callnumber;
3307 (void) strcpy(space->s_d.ldap_call.ldap_u.domainname, domainname);
3308 free(domainname);
3309 domainname = NULL;
3310 sptr = &space->s_d;
3312 switch (__ns_ldap_trydoorcall(&sptr, &ndata, &adata)) {
3313 case NS_CACHE_SUCCESS:
3314 break;
3315 case NS_CACHE_NOTFOUND:
3316 (void) snprintf(errstr, sizeof (errstr),
3317 gettext("Door call to "
3318 "ldap_cachemgr failed - error: %d."),
3319 space->s_d.ldap_ret.ldap_errno);
3320 MKERROR(LOG_WARNING, *error, NS_CONFIG_CACHEMGR,
3321 strdup(errstr), NULL);
3322 free(space);
3323 return (NS_LDAP_OP_FAILED);
3324 default:
3325 free(space);
3326 return (NS_LDAP_OP_FAILED);
3329 retCode = NS_LDAP_SUCCESS;
3331 /* copy info from door call to buffer here */
3332 cfghdr = &sptr->ldap_ret.ldap_u.config_str;
3333 *buflen = offsetof(ldap_config_out_t, config_str) +
3334 cfghdr->data_size + 1;
3335 *buffer = calloc(*buflen, sizeof (char));
3336 if (*buffer == NULL) {
3337 retCode = NS_LDAP_MEMORY;
3338 } else
3339 (void) memcpy(*buffer, cfghdr, *buflen - 1);
3341 if (sptr != &space->s_d) {
3342 (void) munmap((char *)sptr, ndata);
3344 free(space);
3346 return (retCode);
3349 static int
3350 __door_getldapconfig(char **buffer, int *buflen, ns_ldap_error_t **error)
3352 return (__door_getconf(buffer, buflen, error, GETLDAPCONFIGV1));
3356 * SetDoorInfoToUnixCred parses ldapcachemgr configuration information
3357 * for Admin credentials.
3360 SetDoorInfoToUnixCred(char *buffer, ns_ldap_error_t **errorp,
3361 UnixCred_t **cred)
3363 UnixCred_t *ptr;
3364 char errstr[MAXERROR];
3365 char *name, *value, valbuf[BUFSIZE];
3366 char *bufptr = buffer;
3367 char *strptr;
3368 char *rest;
3369 ParamIndexType index = 0;
3370 ldap_config_out_t *cfghdr;
3372 if (errorp == NULL || cred == NULL || *cred == NULL)
3373 return (NS_LDAP_INVALID_PARAM);
3374 *errorp = NULL;
3376 ptr = *cred;
3378 cfghdr = (ldap_config_out_t *)bufptr;
3379 bufptr = (char *)cfghdr->config_str;
3381 strptr = (char *)strtok_r(bufptr, DOORLINESEP, &rest);
3382 for (; ; ) {
3383 if (strptr == NULL)
3384 break;
3385 (void) strlcpy(valbuf, strptr, sizeof (valbuf));
3386 __s_api_split_key_value(valbuf, &name, &value);
3387 if (__ns_ldap_getParamType(name, &index) != 0) {
3388 (void) snprintf(errstr, MAXERROR,
3389 gettext("SetDoorInfoToUnixCred: "
3390 "Unknown keyword encountered '%s'."), name);
3391 MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX,
3392 strdup(errstr), NULL);
3393 return (NS_LDAP_CONFIG);
3395 switch (index) {
3396 case NS_LDAP_ADMIN_BINDDN_P:
3397 ptr->userID = (char *)strdup(value);
3398 break;
3399 case NS_LDAP_ADMIN_BINDPASSWD_P:
3400 ptr->passwd = (char *)strdup(value);
3401 break;
3402 default:
3403 (void) snprintf(errstr, MAXERROR,
3404 gettext("SetDoorInfoToUnixCred: "
3405 "Unknown index encountered '%d'."), index);
3406 MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX,
3407 strdup(errstr), NULL);
3408 return (NS_LDAP_CONFIG);
3410 strptr = (char *)strtok_r(NULL, DOORLINESEP, &rest);
3413 return (NS_LDAP_SUCCESS);
3417 * SetDoorInfo parses ldapcachemgr configuration information
3418 * and verifies that the profile is version 1 or version 2 based.
3419 * version 2 profiles must have a version number as the first profile
3420 * attribute in the configuration.
3422 static ns_config_t *
3423 SetDoorInfo(char *buffer, ns_ldap_error_t **errorp)
3425 ns_config_t *ptr;
3426 char errstr[MAXERROR], errbuf[MAXERROR];
3427 char *name, *value, valbuf[BUFSIZE];
3428 char *strptr;
3429 char *rest;
3430 char *bufptr = buffer;
3431 ParamIndexType i;
3432 int ret;
3433 int first = 1;
3434 int errfnd = 0;
3435 ldap_config_out_t *cfghdr;
3437 if (errorp == NULL)
3438 return (NULL);
3439 *errorp = NULL;
3441 ptr = __s_api_create_config();
3442 if (ptr == NULL) {
3443 return (NULL);
3446 /* get config cookie from the header */
3447 cfghdr = (ldap_config_out_t *)bufptr;
3448 ptr->config_cookie = cfghdr->cookie;
3449 bufptr = (char *)cfghdr->config_str;
3451 strptr = (char *)strtok_r(bufptr, DOORLINESEP, &rest);
3452 for (; ; ) {
3453 if (strptr == NULL)
3454 break;
3455 (void) strlcpy(valbuf, strptr, sizeof (valbuf));
3456 __s_api_split_key_value(valbuf, &name, &value);
3457 /* Use get_versiontype and check for V1 vs V2 prototypes */
3458 if (__s_api_get_versiontype(ptr, name, &i) < 0) {
3459 (void) snprintf(errstr, sizeof (errstr),
3460 "%s (%s)\n",
3461 gettext("Illegal profile entry "
3462 "line in configuration."),
3463 name);
3464 errfnd++;
3465 /* Write verify routines and get rid of verify_value here */
3466 } else if (verify_value(ptr, name,
3467 value, errbuf) != NS_SUCCESS) {
3468 (void) snprintf(errstr, sizeof (errstr),
3469 gettext("%s\n"), errbuf);
3470 errfnd++;
3471 } else if (!first && i == NS_LDAP_FILE_VERSION_P) {
3472 (void) snprintf(errstr, sizeof (errstr),
3473 gettext("Illegal NS_LDAP_FILE_VERSION "
3474 "line in configuration.\n"));
3475 errfnd++;
3477 if (errfnd) {
3478 MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX,
3479 strdup(errstr), NULL);
3480 } else {
3481 ret = set_default_value(ptr, name, value, errorp);
3483 if (errfnd || ret != NS_SUCCESS) {
3484 __s_api_destroy_config(ptr);
3485 return (NULL);
3487 first = 0;
3489 strptr = (char *)strtok_r(NULL, DOORLINESEP, &rest);
3492 if (__s_api_crosscheck(ptr, errstr, B_TRUE) != NS_SUCCESS) {
3493 __s_api_destroy_config(ptr);
3494 MKERROR(LOG_WARNING, *errorp, NS_CONFIG_SYNTAX, strdup(errstr),
3495 NULL);
3496 return (NULL);
3499 return (ptr);
3502 static ns_config_t *
3503 LoadCacheConfiguration(ns_config_t *oldcfg, ns_ldap_error_t **error)
3505 char *buffer = NULL;
3506 int buflen = 0;
3507 int ret;
3508 ns_config_t *cfg;
3509 ldap_config_out_t *cfghdr;
3510 ldap_get_chg_cookie_t old_cookie;
3511 ldap_get_chg_cookie_t new_cookie;
3513 *error = NULL;
3514 ret = __door_getldapconfig(&buffer, &buflen, error);
3516 if (ret != NS_LDAP_SUCCESS) {
3517 if (*error != NULL && (*error)->message != NULL)
3518 syslog(LOG_WARNING, "libsldap: %s", (*error)->message);
3519 return (NULL);
3522 /* No need to reload configuration if config cookie is the same */
3523 cfghdr = (ldap_config_out_t *)buffer;
3524 new_cookie = cfghdr->cookie;
3525 if (oldcfg != NULL)
3526 old_cookie = oldcfg->config_cookie;
3528 if (oldcfg != NULL && old_cookie.mgr_pid == new_cookie.mgr_pid &&
3529 old_cookie.seq_num == new_cookie.seq_num) {
3530 free(buffer);
3531 return (oldcfg);
3534 /* now convert from door format */
3535 cfg = SetDoorInfo(buffer, error);
3536 free(buffer);
3538 if (cfg == NULL && *error != NULL && (*error)->message != NULL)
3539 syslog(LOG_WARNING, "libsldap: %s", (*error)->message);
3540 return (cfg);
3544 * converts the time string into seconds. The time string can be specified
3545 * using one of the following time units:
3546 * #s (# of seconds)
3547 * #m (# of minutes)
3548 * #h (# of hours)
3549 * #d (# of days)
3550 * #w (# of weeks)
3551 * NOTE: you can only specify one the above. No combination of the above
3552 * units is allowed. If no unit specified, it will default to "seconds".
3554 static time_t
3555 conv_time(char *s)
3557 time_t t;
3558 char c;
3559 int l, m;
3560 long tot;
3562 l = strlen(s);
3563 if (l == 0)
3564 return (0);
3565 c = s[--l];
3566 m = 0;
3567 switch (c) {
3568 case 'w': /* weeks */
3569 m = 604800;
3570 break;
3571 case 'd': /* days */
3572 m = 86400;
3573 break;
3574 case 'h': /* hours */
3575 m = 3600;
3576 break;
3577 case 'm': /* minutes */
3578 m = 60;
3579 break;
3580 case 's': /* seconds */
3581 m = 1;
3582 break;
3583 /* the default case is set to "second" */
3585 if (m != 0)
3586 s[l] = '\0';
3587 else
3588 m = 1;
3589 errno = 0;
3590 tot = atol(s);
3591 if ((0 == tot) && (EINVAL == errno))
3592 return (0);
3593 if (((LONG_MAX == tot) || (LONG_MIN == tot)) && (EINVAL == errno))
3594 return (0);
3596 tot = tot * m;
3597 t = (time_t)tot;
3598 return (t);
3602 ns_auth_t *
3603 __s_api_AuthEnumtoStruct(const EnumAuthType_t i)
3605 ns_auth_t *ap;
3607 ap = (ns_auth_t *)calloc(1, sizeof (ns_auth_t));
3608 if (ap == NULL)
3609 return (NULL);
3610 switch (i) {
3611 case NS_LDAP_EA_NONE:
3612 break;
3613 case NS_LDAP_EA_SIMPLE:
3614 ap->type = NS_LDAP_AUTH_SIMPLE;
3615 break;
3616 case NS_LDAP_EA_SASL_CRAM_MD5:
3617 ap->type = NS_LDAP_AUTH_SASL;
3618 ap->saslmech = NS_LDAP_SASL_CRAM_MD5;
3619 break;
3620 case NS_LDAP_EA_SASL_DIGEST_MD5:
3621 ap->type = NS_LDAP_AUTH_SASL;
3622 ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
3623 break;
3624 case NS_LDAP_EA_SASL_DIGEST_MD5_INT:
3625 ap->type = NS_LDAP_AUTH_SASL;
3626 ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
3627 ap->saslopt = NS_LDAP_SASLOPT_INT;
3628 break;
3629 case NS_LDAP_EA_SASL_DIGEST_MD5_CONF:
3630 ap->type = NS_LDAP_AUTH_SASL;
3631 ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
3632 ap->saslopt = NS_LDAP_SASLOPT_PRIV;
3633 break;
3634 case NS_LDAP_EA_SASL_EXTERNAL:
3635 ap->type = NS_LDAP_AUTH_SASL;
3636 ap->saslmech = NS_LDAP_SASL_EXTERNAL;
3637 break;
3638 case NS_LDAP_EA_SASL_GSSAPI:
3639 ap->type = NS_LDAP_AUTH_SASL;
3640 ap->saslmech = NS_LDAP_SASL_GSSAPI;
3641 ap->saslopt = NS_LDAP_SASLOPT_INT |
3642 NS_LDAP_SASLOPT_PRIV;
3643 break;
3644 case NS_LDAP_EA_TLS_NONE:
3645 ap->type = NS_LDAP_AUTH_TLS;
3646 ap->tlstype = NS_LDAP_TLS_NONE;
3647 break;
3648 case NS_LDAP_EA_TLS_SIMPLE:
3649 ap->type = NS_LDAP_AUTH_TLS;
3650 ap->tlstype = NS_LDAP_TLS_SIMPLE;
3651 break;
3652 case NS_LDAP_EA_TLS_SASL_CRAM_MD5:
3653 ap->type = NS_LDAP_AUTH_TLS;
3654 ap->tlstype = NS_LDAP_TLS_SASL;
3655 ap->saslmech = NS_LDAP_SASL_CRAM_MD5;
3656 break;
3657 case NS_LDAP_EA_TLS_SASL_DIGEST_MD5:
3658 ap->type = NS_LDAP_AUTH_TLS;
3659 ap->tlstype = NS_LDAP_TLS_SASL;
3660 ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
3661 break;
3662 case NS_LDAP_EA_TLS_SASL_DIGEST_MD5_INT:
3663 ap->type = NS_LDAP_AUTH_TLS;
3664 ap->tlstype = NS_LDAP_TLS_SASL;
3665 ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
3666 ap->saslopt = NS_LDAP_SASLOPT_INT;
3667 break;
3668 case NS_LDAP_EA_TLS_SASL_DIGEST_MD5_CONF:
3669 ap->type = NS_LDAP_AUTH_TLS;
3670 ap->tlstype = NS_LDAP_TLS_SASL;
3671 ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
3672 ap->saslopt = NS_LDAP_SASLOPT_PRIV;
3673 break;
3674 case NS_LDAP_EA_TLS_SASL_EXTERNAL:
3675 ap->type = NS_LDAP_AUTH_TLS;
3676 ap->tlstype = NS_LDAP_TLS_SASL;
3677 ap->saslmech = NS_LDAP_SASL_EXTERNAL;
3678 break;
3679 default:
3680 /* should never get here */
3681 free(ap);
3682 return (NULL);
3684 return (ap);
3689 * Parameter Index Type validation routines
3692 /* Validate a positive integer */
3693 /* Size of errbuf needs to be MAXERROR */
3694 /* ARGSUSED */
3695 static int
3696 __s_val_postime(ParamIndexType i, ns_default_config *def,
3697 ns_param_t *param, char *errbuf)
3699 char *cp;
3700 long tot;
3702 if (param && param->ns_ptype == CHARPTR && param->ns_pc) {
3703 for (cp = param->ns_pc; cp && *cp; cp++) {
3704 if (*cp >= '0' && *cp <= '9')
3705 continue;
3706 switch (*cp) {
3707 case 'w': /* weeks */
3708 case 'd': /* days */
3709 case 'h': /* hours */
3710 case 'm': /* minutes */
3711 case 's': /* seconds */
3712 if (*(cp+1) == '\0') {
3713 break;
3715 default:
3716 (void) strcpy(errbuf, "Illegal time value");
3717 return (NS_PARSE_ERR);
3720 /* Valid form: [0-9][0-9]*[wdhms]* */
3721 tot = atol(param->ns_pc); /* check overflow */
3722 if (tot >= 0)
3723 return (NS_SUCCESS);
3725 (void) snprintf(errbuf, MAXERROR,
3726 gettext("Illegal time value in %s"), def->name);
3727 return (NS_PARSE_ERR);
3731 /* Validate the Base DN */
3732 /* It can be empty (RootDSE request) or needs to have an '=' */
3733 /* Size of errbuf needs to be MAXERROR */
3734 /* ARGSUSED */
3735 static int
3736 __s_val_basedn(ParamIndexType i, ns_default_config *def,
3737 ns_param_t *param, char *errbuf)
3739 if (param && param->ns_ptype == CHARPTR &&
3740 i == NS_LDAP_SEARCH_BASEDN_P &&
3741 ((param->ns_pc == NULL) || /* empty */
3742 (*(param->ns_pc) == '\0') || /* empty */
3743 (strchr(param->ns_pc, '=') != NULL))) /* '=' */
3745 return (NS_SUCCESS);
3747 (void) snprintf(errbuf, MAXERROR,
3748 gettext("Non-existent or invalid DN in %s"),
3749 def->name);
3750 return (NS_PARSE_ERR);
3754 /* Validate the serverList */
3755 /* For each server in list, check if valid IP or hostname */
3756 /* Size of errbuf needs to be MAXERROR */
3757 /* ARGSUSED */
3758 static int
3759 __s_val_serverList(ParamIndexType i, ns_default_config *def,
3760 ns_param_t *param, char *errbuf)
3762 for (i = 0; i < param->ns_acnt; i++) {
3763 if ((__s_api_isipv4(param->ns_ppc[i])) ||
3764 (__s_api_isipv6(param->ns_ppc[i])) ||
3765 (__s_api_ishost(param->ns_ppc[i]))) {
3766 continue;
3768 /* err */
3769 (void) snprintf(errbuf, MAXERROR,
3770 gettext("Invalid server (%s) in %s"),
3771 param->ns_ppc[i], def->name);
3772 return (NS_PARSE_ERR);
3775 return (NS_SUCCESS);
3779 /* Check for a BINDDN */
3780 /* It can not be empty and needs to have an '=' */
3781 /* Size of errbuf needs to be MAXERROR */
3782 /* ARGSUSED */
3783 static int
3784 __s_val_binddn(ParamIndexType i, ns_default_config *def,
3785 ns_param_t *param, char *errbuf)
3787 char *dntype;
3789 if (param && param->ns_ptype == CHARPTR &&
3790 (i == NS_LDAP_BINDDN_P || i == NS_LDAP_ADMIN_BINDDN_P) &&
3791 ((param->ns_pc == NULL) ||
3792 ((*(param->ns_pc) != '\0') &&
3793 (strchr(param->ns_pc, '=') != NULL)))) {
3794 return (NS_SUCCESS);
3796 if (i == NS_LDAP_BINDDN_P)
3797 dntype = "proxy";
3798 else
3799 dntype = "update";
3800 (void) snprintf(errbuf, MAXERROR,
3801 gettext("NULL or invalid %s bind DN"), dntype);
3802 return (NS_PARSE_ERR);
3806 /* Check for a BINDPASSWD */
3807 /* The string can not be NULL or empty */
3808 /* Size of errbuf needs to be MAXERROR */
3809 /* ARGSUSED */
3810 static int
3811 __s_val_bindpw(ParamIndexType i, ns_default_config *def,
3812 ns_param_t *param, char *errbuf)
3814 char *pwtype;
3816 if (param && param->ns_ptype == CHARPTR &&
3817 (i == NS_LDAP_BINDPASSWD_P || i == NS_LDAP_ADMIN_BINDPASSWD_P) &&
3818 ((param->ns_pc == NULL) ||
3819 (*(param->ns_pc) != '\0'))) {
3820 return (NS_SUCCESS);
3822 if (i == NS_LDAP_BINDPASSWD_P)
3823 pwtype = "proxy";
3824 else
3825 pwtype = "admin";
3826 (void) snprintf(errbuf, MAXERROR,
3827 gettext("NULL %s bind password"), pwtype);
3828 return (NS_PARSE_ERR);
3832 * __s_get_hostcertpath returns either the configured host certificate path
3833 * or, if none, the default host certificate path (/var/ldap). Note that this
3834 * does not use __ns_ldap_getParam because it may be called during connection
3835 * setup. This can fail due to insufficient memory.
3838 char *
3839 __s_get_hostcertpath(void)
3841 ns_config_t *cfg;
3842 ns_param_t *param;
3843 char *ret = NULL;
3845 cfg = __s_api_get_default_config();
3846 if (cfg != NULL) {
3847 param = &cfg->paramList[NS_LDAP_HOST_CERTPATH_P];
3848 if (param->ns_ptype == CHARPTR)
3849 ret = strdup(param->ns_pc);
3850 __s_api_release_config(cfg);
3852 if (ret == NULL)
3853 ret = strdup(NSLDAPDIRECTORY);
3854 return (ret);
3857 static void
3858 _free_config()
3860 if (current_config != NULL)
3861 destroy_config(current_config);
3863 current_config = NULL;