1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * libsldap - library side configuration components
28 * Routines to manage the config structure
29 */
30
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"
58
59 #pragma fini(__s_api_shutdown_conn_mgmt, \
60 _free_config, __ns_ldap_doorfd_close)
61
62 static mutex_t ns_parse_lock = DEFAULTMUTEX;
63 static mutex_t ns_loadrefresh_lock = DEFAULTMUTEX;
64 static ns_config_t *current_config = NULL;
65
66 static int cache_server = FALSE;
67 extern thread_key_t ns_cmgkey;
68
69 /*
70 * Parameter Index Type validation routines
71 */
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);
78
79 static int
80 __s_val_binddn(ParamIndexType i, ns_default_config *def,
81 ns_param_t *param, char *errbuf);
82
83 static int
84 __s_val_bindpw(ParamIndexType i, ns_default_config *def,
85 ns_param_t *param, char *errbuf);
86
87 static int
88 __s_val_serverList(ParamIndexType i, ns_default_config *def,
89 ns_param_t *param, char *errbuf);
90
91 /*
92 * Forward declarations
93 */
94
95 static ns_parse_status
96 verify_value(ns_config_t *cfg, char *name, char *value, char *errstr);
97
98 static int
99 set_default_value(ns_config_t *configptr, char *name, char *value,
100 ns_ldap_error_t **error);
101
102 static void
103 set_curr_config(ns_config_t *ptr);
104
105 static int
106 __door_getldapconfig(char **buffer, int *buflen, ns_ldap_error_t **error);
107
108 static ns_config_t *
109 SetDoorInfo(char *buffer, ns_ldap_error_t **errorp);
110
111 static boolean_t
112 timetorefresh(ns_config_t *cfg);
113
114 static ns_config_t *
115 LoadCacheConfiguration(ns_config_t *, ns_ldap_error_t **error);
116
117 static void **
118 dupParam(ns_param_t *ptr);
119
120 static time_t
121 conv_time(char *s);
122
123 /*
124 * Structures used in enum <-> string mapping routines
125 */
126
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 },
132 };
133
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 },
155 };
156
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 },
161 };
162
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 },
169 };
170
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 },
175 };
176
177 static ns_enum_map ns_ref_enum_v2[] = {
178 { ENUM2INT(NS_LDAP_FOLLOWREF), "TRUE" },
179 { ENUM2INT(NS_LDAP_NOREF), "FALSE" },
180 { -1, NULL },
181 };
182
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 },
188 };
189
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 },
195 };
196
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 },
201 };
202
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 },
207 };
208
209 static int ns_def_auth_v1[] = {
210 ENUM2INT(NS_LDAP_EA_NONE),
211 0
212 };
213
214 static int ns_def_auth_v2[] = {
215 ENUM2INT(NS_LDAP_EA_NONE),
216 0
217 };
218
219 static int ns_def_cred_v1[] = {
220 ENUM2INT(NS_LDAP_CRED_PROXY),
221 0
222 };
223
224 static int ns_def_cred_v2[] = {
225 ENUM2INT(NS_LDAP_CRED_ANON),
226 0
227 };
228
229 /*
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.
243 *
244 * Note since amd64 is little-endian, the problem is not an issue.
245 * INT2VOIDPTR will just leave the data (i) unchanged.
246 */
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
253 /*
254 * The default configuration table
255 * Version 1 entries are first, V2 entries follow.
256 */
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 },
264
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 },
271
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 },
277
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 },
283
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 },
289
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 },
295
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 },
301
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 },
307
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 },
313
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 },
319
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 },
325
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 },
331
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 },
337
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 },
343
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 },
349
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 },
355
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 },
361
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 },
367
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 },
373
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 },
379
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 },
386
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 },
393
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 },
399
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 },
405
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 },
411
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 },
417
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 },
423
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 },
429
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 },
435
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 },
441
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 },
447
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 },
453
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 },
459
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 },
465
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 },
471
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 },
477
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 },
483
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 },
489
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 },
495
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 },
501
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 },
507
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 },
513
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 },
519
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 },
525
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 },
531
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 },
538 };
539
540 static char *
__getdomainname()541 __getdomainname()
542 {
543 /*
544 * The sysinfo man page recommends using a buffer size
545 * of 257 bytes. MAXHOSTNAMELEN is 256. So add 1 here.
546 */
547 char buf[MAXHOSTNAMELEN + 1];
548 int status;
549
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));
557 }
558
559 void
__ns_ldap_setServer(int set)560 __ns_ldap_setServer(int set)
561 {
562 cache_server = set;
563 }
564
565 static boolean_t
timetorefresh(ns_config_t * cfg)566 timetorefresh(ns_config_t *cfg)
567 {
568 struct timeval tp;
569 static time_t expire = 0;
570
571 if (cfg == NULL || gettimeofday(&tp, NULL) == -1)
572 return (B_TRUE);
573
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);
578
579 return (expire != 0 && tp.tv_sec > expire);
580 }
581
582 int
__s_get_enum_value(ns_config_t * ptr,char * value,ParamIndexType i)583 __s_get_enum_value(ns_config_t *ptr, char *value, ParamIndexType i)
584 {
585 register ns_enum_map *mapp;
586 char *pstart = value;
587 char *pend;
588 int len;
589
590 if (pstart == NULL)
591 return (-1);
592
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--)
599 ;
600 len = pend - pstart + 1;
601 if (len == 0)
602 return (-1);
603
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);
645 }
646
647 for (; mapp->name != NULL; mapp++) {
648 if (strncasecmp(pstart, mapp->name, len) == 0 &&
649 (strlen(mapp->name) == len)) {
650 return (mapp->value);
651 }
652 }
653 return (-1);
654 }
655
656 char *
__s_get_auth_name(ns_config_t * ptr,AuthType_t type)657 __s_get_auth_name(ns_config_t *ptr, AuthType_t type)
658 {
659 register ns_enum_map *mapp;
660
661 if (ptr->version == NS_LDAP_V1)
662 mapp = &ns_auth_enum_v1[0];
663 else
664 mapp = &ns_auth_enum_v2[0];
665
666 for (; mapp->name != NULL; mapp++) {
667 if (type == INT2AUTHENUM(mapp->value)) {
668 return (mapp->name);
669 }
670 }
671 return ("Unknown AuthType_t type specified");
672 }
673
674
675 char *
__s_get_security_name(ns_config_t * ptr,TlsType_t type)676 __s_get_security_name(ns_config_t *ptr, TlsType_t type)
677 {
678 register ns_enum_map *mapp;
679
680 if (ptr->version == NS_LDAP_V1) {
681 mapp = &ns_sec_enum_v1[0];
682
683 for (; mapp->name != NULL; mapp++) {
684 if (type == INT2SECENUM(mapp->value)) {
685 return (mapp->name);
686 }
687 }
688 }
689 return ("Unknown TlsType_t type specified");
690 }
691
692
693 char *
__s_get_scope_name(ns_config_t * ptr,ScopeType_t type)694 __s_get_scope_name(ns_config_t *ptr, ScopeType_t type)
695 {
696 register ns_enum_map *mapp;
697
698 if (ptr->version == NS_LDAP_V1)
699 mapp = &ns_scope_enum_v1[0];
700 else
701 mapp = &ns_scope_enum_v2[0];
702
703 for (; mapp->name != NULL; mapp++) {
704 if (type == INT2SCOPEENUM(mapp->value)) {
705 return (mapp->name);
706 }
707 }
708 return ("Unknown ScopeType_t type specified");
709 }
710
711
712 char *
__s_get_pref_name(PrefOnly_t type)713 __s_get_pref_name(PrefOnly_t type)
714 {
715 register ns_enum_map *mapp = &ns_pref_enum[0];
716
717 for (; mapp->name != NULL; mapp++) {
718 if (type == INT2PREFONLYENUM(mapp->value)) {
719 return (mapp->name);
720 }
721 }
722 return ("Unknown PrefOnly_t type specified");
723 }
724
725 char *
__s_get_searchref_name(ns_config_t * ptr,SearchRef_t type)726 __s_get_searchref_name(ns_config_t *ptr, SearchRef_t type)
727 {
728 register ns_enum_map *mapp;
729
730 if (ptr->version == NS_LDAP_V1)
731 mapp = &ns_ref_enum_v1[0];
732 else
733 mapp = &ns_ref_enum_v2[0];
734
735 for (; mapp->name != NULL; mapp++) {
736 if (type == INT2SEARCHREFENUM(mapp->value)) {
737 return (mapp->name);
738 }
739 }
740 return ("Unknown SearchRef_t type specified");
741 }
742
743 char *
__s_get_shadowupdate_name(enableShadowUpdate_t type)744 __s_get_shadowupdate_name(enableShadowUpdate_t type)
745 {
746 register ns_enum_map *mapp;
747
748 mapp = &ns_shadow_update_enum[0];
749
750 for (; mapp->name != NULL; mapp++) {
751 if (type == INT2SHADOWUPDATENUM(mapp->value)) {
752 return (mapp->name);
753 }
754 }
755 return ("Unknown enableShadowUpdate_t type specified");
756 }
757
758 static char *
__s_get_credlvl_name(ns_config_t * ptr,CredLevel_t type)759 __s_get_credlvl_name(ns_config_t *ptr, CredLevel_t type)
760 {
761 register ns_enum_map *mapp;
762
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);
768 }
769 }
770 }
771 return ("Unknown CredLevel_t type specified");
772 }
773
774 static void
destroy_param(ns_config_t * ptr,ParamIndexType type)775 destroy_param(ns_config_t *ptr, ParamIndexType type)
776 {
777 int i, j;
778 char **ppc;
779
780 if (ptr == NULL)
781 return;
782
783 /*
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.
787 */
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;
793 }
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]);
805 }
806 free((void *)ppc);
807 ptr->paramList[type].ns_ppc = NULL;
808 }
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;
815 }
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;
826 }
827 ptr->paramList[type].ns_ptype = NS_UNKNOWN;
828 }
829
830 static void
destroy_config(ns_config_t * ptr)831 destroy_config(ns_config_t *ptr)
832 {
833 ParamIndexType i;
834
835 if (ptr != NULL) {
836 if (ptr == current_config)
837 current_config = NULL;
838 if (ptr->domainName != NULL)
839 free(ptr->domainName);
840 ptr->domainName = NULL;
841 for (i = 0; i <= LAST_VALUE; i++) {
842 destroy_param(ptr, i);
843 }
844 __s_api_destroy_hash(ptr);
845 free(ptr);
846 }
847 }
848
849 /*
850 * Marks the ns_config_t to be deleted and then releases it. (If no other
851 * caller is using, then __s_api_release_config will destroy it.)
852 *
853 * Note that __s_api_destroy_config should only be called if the caller has
854 * created the ns_config_t with __s_api_create_config (with the exception
855 * of set_curr_config). The ns_config_t should be private to the caller.
856 *
857 * This function should not be called with the current_config except by
858 * set_curr_config which locks ns_parse_lock to ensure that no thread
859 * will be waiting on current_config->config_mutex. This ensures that
860 * no caller with be waiting on cfg->config_mutex while it is being
861 * destroyed by __s_api_release_config.
862 */
863
864 void
__s_api_destroy_config(ns_config_t * cfg)865 __s_api_destroy_config(ns_config_t *cfg)
866 {
867 if (cfg != NULL) {
868 (void) mutex_lock(&cfg->config_mutex);
869 cfg->delete = TRUE;
870 (void) mutex_unlock(&cfg->config_mutex);
871 __s_api_release_config(cfg);
872 }
873 }
874
875
876 /*
877 * Increment the configuration use count by one - assumes ns_parse_lock has
878 * been obtained.
879 */
880
881 static ns_config_t *
get_curr_config_unlocked(ns_config_t * cfg,boolean_t global)882 get_curr_config_unlocked(ns_config_t *cfg, boolean_t global)
883 {
884 ns_config_t *ret;
885
886 ret = cfg;
887 if (cfg != NULL) {
888 (void) mutex_lock(&cfg->config_mutex);
889 /*
890 * allow access to per connection management (non-global)
891 * config so operations on connection being closed can still
892 * be completed
893 */
894 if (cfg->delete && global == B_TRUE)
895 ret = NULL;
896 else
897 cfg->nUse++;
898 (void) mutex_unlock(&cfg->config_mutex);
899 }
900 return (ret);
901 }
902
903 /*
904 * set_curr_config_global sets the current global config to the
905 * specified ns_config_t. Note that this function is similar
906 * to the project private function __s_api_init_config_global
907 * except that it does not release the new ns_config_t.
908 */
909 static void
set_curr_config_global(ns_config_t * ptr)910 set_curr_config_global(ns_config_t *ptr)
911 {
912 ns_config_t *cfg;
913 ns_config_t *cur_cfg;
914
915 (void) mutex_lock(&ns_parse_lock);
916 cur_cfg = current_config;
917 cfg = get_curr_config_unlocked(cur_cfg, B_TRUE);
918 if (cfg != ptr) {
919 __s_api_destroy_config(cfg);
920 current_config = ptr;
921 }
922 (void) mutex_unlock(&ns_parse_lock);
923 }
924
925
926 /*
927 * set_curr_config sets the current config or the per connection
928 * management one to the specified ns_config_t. Note that this function
929 * is similar to the project private function __s_api_init_config
930 * except that it does not release the new ns_config_t. Also note
931 * that if there's no per connection management one to set, the
932 * global current config will be set.
933 */
934
935 static void
set_curr_config(ns_config_t * ptr)936 set_curr_config(ns_config_t *ptr)
937 {
938 ns_config_t *cfg;
939 ns_config_t *cur_cfg;
940 ns_conn_mgmt_t *cmg;
941 int rc;
942
943 rc = thr_getspecific(ns_cmgkey, (void **)&cmg);
944
945 /* set the per connection management config if possible */
946 if (rc == 0 && cmg != NULL && cmg->config != NULL) {
947 (void) mutex_lock(&cmg->cfg_lock);
948 cur_cfg = cmg->config;
949 cfg = get_curr_config_unlocked(cur_cfg, B_FALSE);
950 if (cfg != ptr) {
951 __s_api_destroy_config(cfg);
952 cmg->config = ptr;
953 }
954 (void) mutex_unlock(&cmg->cfg_lock);
955 return;
956 }
957
958 /* else set the global current config */
959 set_curr_config_global(ptr);
960 }
961
962 /*
963 * Decrements the ns_config_t usage count by one. Delete if delete flag
964 * is set and no other callers are using.
965 */
966
967 void
__s_api_release_config(ns_config_t * cfg)968 __s_api_release_config(ns_config_t *cfg)
969 {
970 if (cfg != NULL) {
971 (void) mutex_lock(&cfg->config_mutex);
972 cfg->nUse--;
973 if (cfg->nUse == 0 && cfg->delete) {
974 destroy_config(cfg);
975 } else
976 (void) mutex_unlock(&cfg->config_mutex);
977 }
978 }
979
980 /*
981 * __s_api_init_config function destroys the previous global configuration
982 * sets the new global configuration and then releases it
983 */
984 void
__s_api_init_config_global(ns_config_t * ptr)985 __s_api_init_config_global(ns_config_t *ptr)
986 {
987 set_curr_config_global(ptr);
988 __s_api_release_config(ptr);
989 }
990
991 /*
992 * __s_api_init_config function destroys the previous configuration
993 * sets the new configuration and then releases it. The configuration
994 * may be the global one or the per connection management one.
995 */
996 void
__s_api_init_config(ns_config_t * ptr)997 __s_api_init_config(ns_config_t *ptr)
998 {
999 set_curr_config(ptr);
1000 __s_api_release_config(ptr);
1001 }
1002
1003
1004 /*
1005 * Create an ns_config_t, set the usage count to one
1006 */
1007
1008 ns_config_t *
__s_api_create_config(void)1009 __s_api_create_config(void)
1010 {
1011 ns_config_t *ret;
1012 ret = (ns_config_t *)calloc(1, sizeof (ns_config_t));
1013 if (ret == NULL)
1014 return (NULL);
1015
1016 ret->domainName = __getdomainname();
1017 if (ret->domainName == NULL) {
1018 free(ret);
1019 return (NULL);
1020 }
1021 ret->version = NS_LDAP_V1;
1022 (void) mutex_init(&ret->config_mutex, USYNC_THREAD, NULL);
1023 ret->nUse = 1;
1024 ret->delete = B_FALSE;
1025 return (ret);
1026 }
1027
1028 /*
1029 * __s_api_get_default_config_global returns the current global config
1030 */
1031 ns_config_t *
__s_api_get_default_config_global(void)1032 __s_api_get_default_config_global(void)
1033 {
1034 ns_config_t *cfg;
1035 ns_config_t *cur_cfg;
1036
1037 (void) mutex_lock(&ns_parse_lock);
1038 cur_cfg = current_config;
1039 cfg = get_curr_config_unlocked(cur_cfg, B_TRUE);
1040 (void) mutex_unlock(&ns_parse_lock);
1041
1042 return (cfg);
1043 }
1044
1045 /*
1046 * __s_api_get_default_config returns the current global config or the
1047 * per connection management one.
1048 */
1049 ns_config_t *
__s_api_get_default_config(void)1050 __s_api_get_default_config(void)
1051 {
1052 ns_config_t *cfg;
1053 ns_config_t *cur_cfg;
1054 ns_conn_mgmt_t *cmg;
1055 int rc;
1056
1057 rc = thr_getspecific(ns_cmgkey, (void **)&cmg);
1058
1059 /* get the per connection management config if available */
1060 if (rc == 0 && cmg != NULL && cmg->config != NULL) {
1061 (void) mutex_lock(&cmg->cfg_lock);
1062 cur_cfg = cmg->config;
1063 cfg = get_curr_config_unlocked(cur_cfg, B_FALSE);
1064 (void) mutex_unlock(&cmg->cfg_lock);
1065 return (cfg);
1066 }
1067
1068 /* else get the global current config */
1069 return (__s_api_get_default_config_global());
1070 }
1071
1072 static char *
stripdup(const char * instr)1073 stripdup(const char *instr)
1074 {
1075 char *pstart = (char *)instr;
1076 char *pend, *ret;
1077 int len;
1078
1079 if (pstart == NULL)
1080 return (NULL);
1081 /* remove leading spaces */
1082 while (*pstart == SPACETOK)
1083 pstart++;
1084 /* remove trailing spaces */
1085 pend = pstart + strlen(pstart) - 1;
1086 for (; pend >= pstart && *pend == SPACETOK; pend--)
1087 ;
1088 len = pend - pstart + 1;
1089 if ((ret = malloc(len + 1)) == NULL)
1090 return (NULL);
1091 if (len != 0) {
1092 (void) strncpy(ret, pstart, len);
1093 }
1094 ret[len] = '\0';
1095 return (ret);
1096 }
1097
1098 /*
1099 * Note that __s_api_crosscheck is assumed to be called with an ns_config_t
1100 * that is properly protected - so that it will not change during the
1101 * duration of the call
1102 */
1103
1104 /* Size of errstr needs to be MAXERROR */
1105 ns_parse_status
__s_api_crosscheck(ns_config_t * ptr,char * errstr,int check_dn)1106 __s_api_crosscheck(ns_config_t *ptr, char *errstr, int check_dn)
1107 {
1108 int value, j;
1109 time_t tm;
1110 const char *str, *str1;
1111 int i, cnt;
1112 int self, gssapi;
1113
1114 if (ptr == NULL)
1115 return (NS_SUCCESS);
1116
1117 /* check for no server specified */
1118 if (ptr->paramList[NS_LDAP_SERVERS_P].ns_ppc == NULL) {
1119 if (ptr->version == NS_LDAP_V1) {
1120 str = NULL_OR_STR(__s_api_get_configname(
1121 NS_LDAP_SERVERS_P));
1122 (void) snprintf(errstr, MAXERROR,
1123 gettext("Configuration Error: No entry for "
1124 "'%s' found"), str);
1125 return (NS_PARSE_ERR);
1126 } else if (ptr->paramList[NS_LDAP_SERVER_PREF_P].ns_ppc ==
1127 NULL) {
1128 str = NULL_OR_STR(__s_api_get_configname(
1129 NS_LDAP_SERVERS_P));
1130 str1 = NULL_OR_STR(__s_api_get_configname(
1131 NS_LDAP_SERVER_PREF_P));
1132 (void) snprintf(errstr, MAXERROR,
1133 gettext("Configuration Error: "
1134 "Neither '%s' nor '%s' is defined"), str, str1);
1135 return (NS_PARSE_ERR);
1136 }
1137 }
1138 if (ptr->paramList[NS_LDAP_CERT_PASS_P].ns_pc != NULL &&
1139 ptr->paramList[NS_LDAP_CERT_PATH_P].ns_pc == NULL) {
1140 str = NULL_OR_STR(__s_api_get_configname(
1141 NS_LDAP_CERT_PASS_P));
1142 str1 = NULL_OR_STR(__s_api_get_configname(
1143 NS_LDAP_CERT_PATH_P));
1144 (void) snprintf(errstr, MAXERROR,
1145 gettext("Configuration Error: %s specified "
1146 "but no value for '%s' found"), str, str1);
1147 return (NS_PARSE_ERR);
1148 }
1149 if (ptr->paramList[NS_LDAP_CERT_PASS_P].ns_pc == NULL &&
1150 ptr->paramList[NS_LDAP_CERT_PATH_P].ns_pc != NULL) {
1151 str = NULL_OR_STR(__s_api_get_configname(
1152 NS_LDAP_CERT_PATH_P));
1153 str1 = NULL_OR_STR(__s_api_get_configname(
1154 NS_LDAP_CERT_PASS_P));
1155 (void) snprintf(errstr, MAXERROR,
1156 gettext("Configuration Error: %s specified "
1157 "but no value for '%s' found"), str, str1);
1158 return (NS_PARSE_ERR);
1159 }
1160 /* check if search basedn has been specified */
1161 if (ptr->paramList[NS_LDAP_SEARCH_BASEDN_P].ns_ppc == NULL) {
1162 str = NULL_OR_STR(__s_api_get_configname(
1163 NS_LDAP_SEARCH_BASEDN_P));
1164 (void) snprintf(errstr, MAXERROR,
1165 gettext("Configuration Error: No entry for "
1166 "'%s' found"), str);
1167 return (NS_PARSE_ERR);
1168 }
1169
1170 if (check_dn) {
1171 /* check for auth value....passwd/bindn if necessary */
1172
1173 for (j = 0; ptr->paramList[NS_LDAP_AUTH_P].ns_pi != NULL &&
1174 ptr->paramList[NS_LDAP_AUTH_P].ns_pi[j] != NULL; j++) {
1175 value = ptr->paramList[NS_LDAP_AUTH_P].ns_pi[j];
1176 switch (value) {
1177 case NS_LDAP_EA_SIMPLE:
1178 case NS_LDAP_EA_SASL_CRAM_MD5:
1179 case NS_LDAP_EA_SASL_DIGEST_MD5:
1180 case NS_LDAP_EA_SASL_DIGEST_MD5_INT:
1181 case NS_LDAP_EA_SASL_DIGEST_MD5_CONF:
1182 case NS_LDAP_EA_TLS_SIMPLE:
1183 case NS_LDAP_EA_TLS_SASL_CRAM_MD5:
1184 case NS_LDAP_EA_TLS_SASL_DIGEST_MD5:
1185 case NS_LDAP_EA_TLS_SASL_DIGEST_MD5_INT:
1186 case NS_LDAP_EA_TLS_SASL_DIGEST_MD5_CONF:
1187 if (ptr->paramList[NS_LDAP_BINDDN_P].ns_ppc == NULL) {
1188 str = NULL_OR_STR(__s_api_get_configname(
1189 NS_LDAP_BINDDN_P));
1190 (void) snprintf(errstr, MAXERROR,
1191 gettext("Configuration Error: No entry for "
1192 "'%s' found"), str);
1193 return (NS_PARSE_ERR);
1194 }
1195 if (ptr->paramList[NS_LDAP_BINDPASSWD_P].ns_ppc
1196 == NULL) {
1197 str = NULL_OR_STR(__s_api_get_configname(
1198 NS_LDAP_BINDPASSWD_P));
1199 (void) snprintf(errstr, MAXERROR,
1200 gettext("Configuration Error: No entry for "
1201 "'%s' found"), str);
1202 return (NS_PARSE_ERR);
1203 }
1204 break;
1205 }
1206 }
1207 }
1208
1209 /*
1210 * If NS_LDAP_CACHETTL is not specified,
1211 * init NS_LDAP_EXP_P here. Otherwise,
1212 * ldap_cachemgr will never refresh the profile.
1213 * Set it to current time + default
1214 * NS_LDAP_CACHETTL
1215 */
1216 if (ptr->paramList[NS_LDAP_CACHETTL_P].ns_pc == NULL) {
1217 tm = conv_time(
1218 defconfig[NS_LDAP_CACHETTL_P].defval.ns_pc);
1219 ptr->paramList[NS_LDAP_EXP_P].ns_ptype = TIMET;
1220 if (tm != 0) {
1221 tm += time(NULL);
1222 }
1223 ptr->paramList[NS_LDAP_EXP_P].ns_tm = tm;
1224 }
1225 /*
1226 * If credential level self is defined, there should be
1227 * at least an auth method sasl/GSSAPI and vice versa.
1228 */
1229 self = 0;
1230 cnt = ptr->paramList[NS_LDAP_CREDENTIAL_LEVEL_P].ns_acnt;
1231 for (i = 0; i < cnt; i++) {
1232 if (ptr->paramList[NS_LDAP_CREDENTIAL_LEVEL_P].ns_pi[i] ==
1233 NS_LDAP_CRED_SELF)
1234 self++;
1235 }
1236 gssapi = 0;
1237 cnt = ptr->paramList[NS_LDAP_AUTH_P].ns_acnt;
1238 for (i = 0; i < cnt; i++) {
1239 if (ptr->paramList[NS_LDAP_AUTH_P].ns_pi[i] ==
1240 NS_LDAP_EA_SASL_GSSAPI)
1241 gssapi++;
1242 }
1243 if (gssapi == 0 && self > 0) {
1244 (void) snprintf(errstr, MAXERROR,
1245 gettext("Configuration Error: "
1246 "Credential level self requires "
1247 "authentication method sasl/GSSAPI"));
1248 return (NS_PARSE_ERR);
1249 }
1250 if (gssapi > 0 && self == 0) {
1251 (void) snprintf(errstr, MAXERROR,
1252 gettext("Configuration Error: "
1253 "Authentication method sasl/GSSAPI "
1254 "requires credential level self"));
1255 return (NS_PARSE_ERR);
1256 }
1257 return (NS_SUCCESS);
1258 }
1259
1260
1261 int
__s_api_get_type(const char * value,ParamIndexType * type)1262 __s_api_get_type(const char *value, ParamIndexType *type)
1263 {
1264 int i;
1265
1266 for (i = 0; defconfig[i].name != NULL; i++) {
1267 if (strcasecmp(defconfig[i].name, value) == 0) {
1268 *type = defconfig[i].index;
1269 return (0);
1270 }
1271 }
1272 return (-1);
1273 }
1274
1275 /*
1276 * Externally defined version of get_type.
1277 * Includes extra error checking
1278 */
1279
1280 int
__ns_ldap_getParamType(const char * value,ParamIndexType * type)1281 __ns_ldap_getParamType(const char *value, ParamIndexType *type)
1282 {
1283 if (value == NULL || type == NULL)
1284 return (-1);
1285 return (__s_api_get_type(value, type));
1286 }
1287
1288 int
__s_api_get_versiontype(ns_config_t * ptr,char * value,ParamIndexType * type)1289 __s_api_get_versiontype(ns_config_t *ptr, char *value, ParamIndexType *type)
1290 {
1291 ns_version_t ver;
1292 int i;
1293
1294 if (ptr == NULL)
1295 return (-1);
1296
1297 ver = ptr->version;
1298
1299 for (i = 0; defconfig[i].name != NULL; i++) {
1300 if (strcasecmp(defconfig[i].name, value) == 0) {
1301 if (defconfig[i].version == ver) {
1302 *type = defconfig[i].index;
1303 return (0);
1304 }
1305 }
1306 }
1307 return (-1);
1308 }
1309
1310 int
__s_api_get_profiletype(char * value,ParamIndexType * type)1311 __s_api_get_profiletype(char *value, ParamIndexType *type)
1312 {
1313 int i;
1314
1315 for (i = 0; defconfig[i].name != NULL; i++) {
1316 if (defconfig[i].profile_name == NULL)
1317 continue;
1318 if (strcasecmp(defconfig[i].profile_name, value) == 0) {
1319 *type = defconfig[i].index;
1320 return (0);
1321 }
1322 }
1323 return (-1);
1324 }
1325
1326 int
__s_api_get_configtype(ParamIndexType type)1327 __s_api_get_configtype(ParamIndexType type)
1328 {
1329 int i;
1330
1331 for (i = 0; defconfig[i].name != NULL; i++) {
1332 if (defconfig[i].index == type) {
1333 return (defconfig[i].config_type);
1334 }
1335 }
1336 return (-1);
1337 }
1338
1339 const char *
__s_api_get_configname(ParamIndexType type)1340 __s_api_get_configname(ParamIndexType type)
1341 {
1342 int i;
1343
1344 for (i = 0; defconfig[i].name != NULL; i++) {
1345 if (defconfig[i].index == type) {
1346 if (defconfig[i].name[0] == '\0')
1347 return (NULL);
1348 else
1349 return (defconfig[i].name);
1350 }
1351 }
1352 return (NULL);
1353 }
1354
1355 static ns_default_config *
get_defconfig(ns_config_t * ptr,ParamIndexType type)1356 get_defconfig(ns_config_t *ptr, ParamIndexType type)
1357 {
1358 ns_version_t ver;
1359 int i;
1360
1361 ver = ptr->version;
1362
1363 for (i = 0; defconfig[i].name != NULL; i++) {
1364 if (defconfig[i].index == type &&
1365 defconfig[i].version == ver) {
1366 return (&defconfig[i]);
1367 }
1368 }
1369 return (NULL);
1370 }
1371
1372 static int
set_default_value(ns_config_t * configptr,char * name,char * value,ns_ldap_error_t ** error)1373 set_default_value(ns_config_t *configptr, char *name,
1374 char *value, ns_ldap_error_t **error)
1375 {
1376 ParamIndexType i;
1377 int ret;
1378 char errstr[MAXERROR];
1379
1380 if (__s_api_get_type(name, &i) < 0) {
1381 (void) snprintf(errstr, sizeof (errstr), gettext(
1382 "Illegal type name (%s).\n"), name);
1383 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, strdup(errstr),
1384 NULL);
1385 return (NS_LDAP_CONFIG);
1386 }
1387
1388 if (i != NS_LDAP_SERVERS_P &&
1389 i != NS_LDAP_SERVICE_AUTH_METHOD_P &&
1390 i != NS_LDAP_SERVICE_CRED_LEVEL_P &&
1391 i != NS_LDAP_SERVICE_SEARCH_DESC_P &&
1392 i != NS_LDAP_SERVER_PREF_P &&
1393 i != NS_LDAP_SEARCH_DN_P) {
1394 if (configptr->paramList[i].ns_ptype != NS_UNKNOWN) {
1395 destroy_param(configptr, i);
1396 }
1397 }
1398
1399 ret = __ns_ldap_setParamValue(configptr, i, value, error);
1400 return (ret);
1401 }
1402
1403
1404 /*
1405 * Initialize config to a default state
1406 * By default leave configuration empty
1407 * getParam will automatically get the
1408 * appropriate default value if none exists
1409 */
1410
1411 void
__ns_ldap_default_config()1412 __ns_ldap_default_config()
1413 {
1414 ns_config_t *ptr;
1415
1416 ptr = __s_api_create_config();
1417 if (ptr == NULL)
1418 return;
1419
1420 set_curr_config(ptr);
1421 __s_api_release_config(ptr);
1422 }
1423
1424 /*
1425 * Get the current configuration pointer and return it.
1426 * If necessary initialize or refresh the current
1427 * configuration as applicable. If global is set, returns
1428 * the global one.
1429 */
1430
1431 static ns_config_t *
loadrefresh_config(boolean_t global)1432 loadrefresh_config(boolean_t global)
1433 {
1434 ns_config_t *cfg;
1435 ns_config_t *new_cfg;
1436 ns_ldap_error_t *errorp;
1437
1438 /* We want to refresh only one configuration at a time */
1439 (void) mutex_lock(&ns_loadrefresh_lock);
1440 if (global == B_TRUE)
1441 cfg = __s_api_get_default_config_global();
1442 else
1443 cfg = __s_api_get_default_config();
1444
1445 /* (re)initialize configuration if necessary */
1446 if (!__s_api_isStandalone() && timetorefresh(cfg)) {
1447 new_cfg = LoadCacheConfiguration(cfg, &errorp);
1448 if (new_cfg != NULL && new_cfg != cfg) {
1449 __s_api_release_config(cfg);
1450 if (global == B_TRUE)
1451 set_curr_config_global(new_cfg);
1452 else
1453 set_curr_config(new_cfg);
1454 cfg = new_cfg;
1455 }
1456 if (errorp != NULL)
1457 (void) __ns_ldap_freeError(&errorp);
1458 }
1459 (void) mutex_unlock(&ns_loadrefresh_lock);
1460 return (cfg);
1461 }
1462
1463 /*
1464 * Get the current global configuration pointer and return it.
1465 * If necessary initialize or refresh the current
1466 * configuration as applicable.
1467 */
1468
1469 ns_config_t *
__s_api_loadrefresh_config_global()1470 __s_api_loadrefresh_config_global()
1471 {
1472 return (loadrefresh_config(B_TRUE));
1473 }
1474
1475 /*
1476 * Get the current configuration pointer and return it.
1477 * If necessary initialize or refresh the current
1478 * configuration as applicable. The configuration may
1479 * be the global one or the per connection management one.
1480 */
1481
1482 ns_config_t *
__s_api_loadrefresh_config()1483 __s_api_loadrefresh_config()
1484 {
1485 return (loadrefresh_config(B_FALSE));
1486 }
1487
1488 /*
1489 * In general this routine is not very usefull. Individual routines can be
1490 * created to do this job. Once that is done, this function can be removed.
1491 * Size of errstr buffer needs to be MAXERROR.
1492 */
1493 static ns_parse_status
verify_value(ns_config_t * cfg,char * name,char * value,char * errstr)1494 verify_value(ns_config_t *cfg, char *name, char *value, char *errstr)
1495 {
1496 ParamIndexType index = 0;
1497 int found = 0, j;
1498 char *ptr = NULL, *strptr = NULL, buffer[BUFSIZE];
1499 char *rest;
1500 ns_default_config *def = NULL;
1501
1502 if (__s_api_get_type(name, &index) != 0) {
1503 (void) snprintf(errstr, MAXERROR,
1504 gettext("Unknown keyword encountered '%s'."), name);
1505 return (NS_PARSE_ERR);
1506 }
1507
1508 def = get_defconfig(cfg, index);
1509
1510 /* eat up beginning quote, if any */
1511 while (value != NULL && (*value == QUOTETOK || *value == SPACETOK))
1512 value++;
1513
1514 /* eat up space/quote at end of value */
1515 if (strlen(value) > 0)
1516 ptr = value + strlen(value) - 1;
1517 else
1518 ptr = value;
1519 for (; ptr != value && (*ptr == SPACETOK || *ptr == QUOTETOK); ptr--) {
1520 *ptr = '\0';
1521 }
1522
1523 switch (index) {
1524 case NS_LDAP_EXP_P:
1525 case NS_LDAP_CACHETTL_P:
1526 case NS_LDAP_CERT_PATH_P:
1527 case NS_LDAP_CERT_PASS_P:
1528 case NS_LDAP_CERT_NICKNAME_P:
1529 case NS_LDAP_BINDDN_P:
1530 case NS_LDAP_BINDPASSWD_P:
1531 case NS_LDAP_ADMIN_BINDDN_P:
1532 case NS_LDAP_ADMIN_BINDPASSWD_P:
1533 case NS_LDAP_DOMAIN_P:
1534 case NS_LDAP_SEARCH_BASEDN_P:
1535 case NS_LDAP_SEARCH_TIME_P:
1536 case NS_LDAP_PROFILE_P:
1537 case NS_LDAP_AUTH_P:
1538 case NS_LDAP_SEARCH_SCOPE_P:
1539 case NS_LDAP_CREDENTIAL_LEVEL_P:
1540 case NS_LDAP_SERVICE_SEARCH_DESC_P:
1541 case NS_LDAP_BIND_TIME_P:
1542 case NS_LDAP_ATTRIBUTEMAP_P:
1543 case NS_LDAP_OBJECTCLASSMAP_P:
1544 case NS_LDAP_SERVICE_AUTH_METHOD_P:
1545 case NS_LDAP_SERVICE_CRED_LEVEL_P:
1546 case NS_LDAP_HOST_CERTPATH_P:
1547 break;
1548 case NS_LDAP_SEARCH_DN_P:
1549 /* depreciated because of service descriptors */
1550 /* Parse as appropriate at descriptor create time */
1551 break;
1552 case NS_LDAP_FILE_VERSION_P:
1553 if (value != NULL &&
1554 strcasecmp(value, NS_LDAP_VERSION_1) != 0 &&
1555 strcasecmp(value, NS_LDAP_VERSION_2) != 0) {
1556 (void) snprintf(errstr, MAXERROR,
1557 gettext("Version mismatch, expected "
1558 "cache version '%s' or '%s' but "
1559 "encountered version '%s'."),
1560 NS_LDAP_VERSION_1,
1561 NS_LDAP_VERSION_2, value);
1562 return (NS_PARSE_ERR);
1563 }
1564 break;
1565 case NS_LDAP_SERVERS_P:
1566 case NS_LDAP_SERVER_PREF_P:
1567 (void) strcpy(buffer, value);
1568 strptr = strtok_r(buffer, ",", &rest);
1569 while (strptr != NULL) {
1570 char *tmp = NULL;
1571 tmp = stripdup(strptr);
1572 if (tmp == NULL || (strchr(tmp, ' ') != NULL)) {
1573 (void) snprintf(errstr, MAXERROR,
1574 gettext("Invalid parameter values "
1575 "'%s' specified for keyword '%s'."),
1576 tmp, name);
1577 free(tmp);
1578 return (NS_PARSE_ERR);
1579 }
1580 free(tmp);
1581 strptr = strtok_r(NULL, ",", &rest);
1582 }
1583 break;
1584 default:
1585 found = 0; j = 0;
1586 while (def->allowed != NULL &&
1587 def->allowed[j].name != NULL && j < DEFMAX) {
1588 if (strcmp(def->allowed[j].name,
1589 value) == 0) {
1590 found = 1;
1591 break;
1592 }
1593 j++;
1594 }
1595 if (!found) {
1596 (void) snprintf(errstr, MAXERROR,
1597 gettext("Invalid option specified for "
1598 "'%s' keyword. '%s' is not a recognized "
1599 "keyword value."), name, value);
1600 return (NS_PARSE_ERR);
1601 }
1602 }
1603
1604 return (NS_SUCCESS);
1605 }
1606
1607 void
__s_api_split_key_value(char * buffer,char ** name,char ** value)1608 __s_api_split_key_value(char *buffer, char **name, char **value)
1609 {
1610 char *ptr;
1611
1612 *name = buffer;
1613 /* split into name value pair */
1614 if ((ptr = strchr(buffer, TOKENSEPARATOR)) != NULL) {
1615 *ptr = '\0';
1616 ptr++;
1617 /* trim whitespace */
1618 while (*ptr == SPACETOK)
1619 ptr++;
1620 *value = ptr;
1621 }
1622 }
1623
1624 /*
1625 * Set a parameter value in a generic configuration structure
1626 * Assume any necessary locks are in place. This routine would
1627 * be better named: __ns_ldap_translateString2Param
1628 *
1629 * This routine translates external string format into internal
1630 * param format and saves the result in the param table.
1631 */
1632 int
__ns_ldap_setParamValue(ns_config_t * ptr,const ParamIndexType type,const void * data,ns_ldap_error_t ** error)1633 __ns_ldap_setParamValue(ns_config_t *ptr, const ParamIndexType type,
1634 const void *data, ns_ldap_error_t **error)
1635 {
1636 ns_default_config *def = NULL;
1637 ns_param_t conf;
1638 ns_mapping_t *map, *rmap;
1639 int i, j, len;
1640 char *cp, *cp2, *end;
1641 char *tcp = NULL;
1642 char errstr[2 * MAXERROR];
1643 char tbuf[100], *ptbuf;
1644 char *sid, *origA, **mapA;
1645 char **attr;
1646 time_t tm;
1647 int free_memory, exitrc;
1648 char **p;
1649
1650 /* Find ParamIndexType default configuration data */
1651 def = get_defconfig(ptr, type);
1652 if (def == NULL) {
1653 (void) snprintf(errstr, sizeof (errstr),
1654 gettext("Unable to set value: "
1655 "invalid ParamIndexType (%d)"), type);
1656 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, strdup(errstr),
1657 NULL);
1658 return (NS_LDAP_CONFIG);
1659 }
1660
1661 (void) memset(&conf, 0, sizeof (conf));
1662
1663 /* data is actually const char */
1664 cp = (char *)data;
1665
1666 /* eat up beginning quote, if any */
1667 while (cp && (*cp == QUOTETOK || *cp == SPACETOK))
1668 cp++;
1669
1670 /* eat up space/quote at end of value */
1671 end = cp2 = cp + strlen(cp) - 1;
1672 for (; cp2 > cp && (*cp2 == SPACETOK || *cp2 == QUOTETOK); cp2--)
1673 ;
1674 /* data is const, must duplicate */
1675 if (cp2 != end) {
1676 tcp = (char *)calloc((int)(cp2 - cp + 2), sizeof (char));
1677 if (tcp == NULL)
1678 return (NS_LDAP_MEMORY);
1679 end = cp2;
1680 cp2 = tcp;
1681 while (cp <= end) {
1682 *cp2++ = *cp++;
1683 }
1684 *cp2 = '\0';
1685 cp = tcp;
1686 }
1687
1688 /* Parse data according to type */
1689 switch (def->data_type) {
1690 case INT:
1691 switch (def->index) {
1692 case NS_LDAP_PREF_ONLY_P:
1693 case NS_LDAP_SEARCH_REF_P:
1694 case NS_LDAP_SEARCH_SCOPE_P:
1695 case NS_LDAP_ENABLE_SHADOW_UPDATE_P:
1696 i = __s_get_enum_value(ptr, cp, def->index);
1697 if (i < 0) {
1698 (void) snprintf(errstr, sizeof (errstr),
1699 gettext("Unable to set value: "
1700 "invalid %s (%d)"), def->name,
1701 def->index);
1702 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
1703 strdup(errstr), NULL);
1704 if (tcp != NULL)
1705 free(tcp);
1706 return (NS_LDAP_CONFIG);
1707 }
1708 conf.ns_i = i;
1709 break;
1710 case NS_LDAP_TRANSPORT_SEC_P: /* ignore TRANSPORT_SEC */
1711 break;
1712 default:
1713 cp2 = cp;
1714 if ((*cp2 == '+') || (*cp2 == '-'))
1715 cp2++;
1716 for (/* empty */; *cp2; cp2++) {
1717 if (isdigit(*cp2))
1718 continue;
1719
1720 (void) snprintf(errstr, sizeof (errstr),
1721 gettext("Unable to set value: "
1722 "invalid %s (%d)"), def->name,
1723 def->index);
1724 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
1725 strdup(errstr), NULL);
1726 if (tcp != NULL)
1727 free(tcp);
1728 return (NS_LDAP_CONFIG);
1729 }
1730 i = atoi(cp);
1731 conf.ns_i = i;
1732 break;
1733 }
1734 break;
1735 case TIMET:
1736 /* Do nothing with a TIMET. Initialize it below */
1737 break;
1738 case CHARPTR:
1739 conf.ns_pc = (char *)strdup(cp);
1740 if (conf.ns_pc == NULL) {
1741 if (tcp != NULL)
1742 free(tcp);
1743 return (NS_LDAP_MEMORY);
1744 }
1745 break;
1746 case SAMLIST:
1747 /* first check to see if colon (:) is there */
1748 if ((strchr(cp, COLONTOK)) == NULL) {
1749 (void) snprintf(errstr, sizeof (errstr),
1750 gettext("Unable to set value: "
1751 "invalid serviceAuthenticationMethod (%s)"),
1752 cp);
1753 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
1754 strdup(errstr), NULL);
1755 if (tcp != NULL)
1756 free(tcp);
1757 return (NS_LDAP_CONFIG);
1758 }
1759 /* Appends an entry to the existing list */
1760 if (ptr->paramList[type].ns_ptype != SAMLIST) {
1761 conf.ns_ppc = (char **)calloc(2, sizeof (char *));
1762 if (conf.ns_ppc == NULL) {
1763 if (tcp != NULL)
1764 free(tcp);
1765 return (NS_LDAP_MEMORY);
1766 }
1767 conf.ns_acnt = 1;
1768 conf.ns_ppc[0] = (char *)strdup(cp);
1769 if (conf.ns_ppc[0] == NULL) {
1770 free(conf.ns_ppc);
1771 if (tcp != NULL)
1772 free(tcp);
1773 return (NS_LDAP_MEMORY);
1774 }
1775 } else {
1776 char *dp, *dpend;
1777 int fnd = 0;
1778
1779 /* Attempt to replace if possible */
1780 dpend = strchr(cp, COLONTOK);
1781 len = dpend - cp;
1782 dp = (char *)malloc(len+1);
1783 if (dp == NULL) {
1784 if (tcp != NULL)
1785 free(tcp);
1786 return (NS_LDAP_MEMORY);
1787 }
1788 (void) strlcpy(dp, cp, len+1);
1789 fnd = 0;
1790 for (j = 0; j < ptr->paramList[type].ns_acnt; j++) {
1791 dpend = strchr(ptr->paramList[type].ns_ppc[j],
1792 COLONTOK);
1793 if (dpend == NULL)
1794 continue;
1795 i = dpend - ptr->paramList[type].ns_ppc[j];
1796 if (i != len)
1797 continue;
1798 if (strncmp(ptr->paramList[type].ns_ppc[j],
1799 dp, len) == 0) {
1800 conf.ns_acnt =
1801 ptr->paramList[type].ns_acnt;
1802 conf.ns_ppc =
1803 ptr->paramList[type].ns_ppc;
1804 ptr->paramList[type].ns_ppc = NULL;
1805 free(conf.ns_ppc[j]);
1806 conf.ns_ppc[j] = (char *)strdup(cp);
1807 if (conf.ns_ppc[j] == NULL) {
1808 free(dp);
1809 __s_api_free2dArray
1810 (conf.ns_ppc);
1811 if (tcp != NULL)
1812 free(tcp);
1813 return (NS_LDAP_MEMORY);
1814 }
1815 fnd = 1;
1816 break;
1817 }
1818 }
1819 free(dp);
1820
1821 if (fnd)
1822 break; /* Replaced completed */
1823
1824 /* Append */
1825 len = ptr->paramList[type].ns_acnt + 1;
1826 if (len > 1) {
1827 p = (char **)dupParam(&ptr->paramList[type]);
1828 if (p == NULL) {
1829 if (tcp != NULL)
1830 free(tcp);
1831 return (NS_LDAP_MEMORY);
1832 }
1833 } else
1834 p = NULL;
1835 conf.ns_ppc =
1836 (char **)realloc(p, (len+1) * sizeof (char *));
1837 if (conf.ns_ppc == NULL) {
1838 __s_api_free2dArray(p);
1839 if (tcp != NULL)
1840 free(tcp);
1841 return (NS_LDAP_MEMORY);
1842 }
1843 conf.ns_acnt = len;
1844 conf.ns_ppc[len-1] = (char *)strdup(cp);
1845 if (conf.ns_ppc[len-1] == NULL) {
1846 __s_api_free2dArray(conf.ns_ppc);
1847 if (tcp != NULL)
1848 free(tcp);
1849 return (NS_LDAP_MEMORY);
1850 }
1851 conf.ns_ppc[len] = NULL;
1852 }
1853 break;
1854 case SCLLIST:
1855 /* first check to see if colon (:) is there */
1856 if ((strchr(cp, COLONTOK)) == NULL) {
1857 (void) snprintf(errstr, sizeof (errstr),
1858 gettext("Unable to set value: "
1859 "invalid serviceCredentialLevel (%s)"),
1860 cp);
1861 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
1862 strdup(errstr), NULL);
1863 if (tcp != NULL)
1864 free(tcp);
1865 return (NS_LDAP_CONFIG);
1866 }
1867 /* Appends an entry to the existing list */
1868 if (ptr->paramList[type].ns_ptype != SCLLIST) {
1869 conf.ns_ppc = (char **)calloc(2, sizeof (char *));
1870 if (conf.ns_ppc == NULL) {
1871 if (tcp != NULL)
1872 free(tcp);
1873 return (NS_LDAP_MEMORY);
1874 }
1875 conf.ns_acnt = 1;
1876 conf.ns_ppc[0] = (char *)strdup(cp);
1877 if (conf.ns_ppc[0] == NULL) {
1878 free(conf.ns_ppc);
1879 if (tcp != NULL)
1880 free(tcp);
1881 return (NS_LDAP_MEMORY);
1882 }
1883 } else {
1884 char *dp, *dpend;
1885 int fnd = 0;
1886
1887 /* Attempt to replace if possible */
1888 dpend = strchr(cp, COLONTOK);
1889 len = dpend - cp;
1890 dp = (char *)malloc(len+1);
1891 if (dp == NULL) {
1892 if (tcp != NULL)
1893 free(tcp);
1894 return (NS_LDAP_MEMORY);
1895 }
1896 (void) strlcpy(dp, cp, len+1);
1897 fnd = 0;
1898 for (j = 0; j < ptr->paramList[type].ns_acnt; j++) {
1899 dpend = strchr(ptr->paramList[type].ns_ppc[j],
1900 COLONTOK);
1901 if (dpend == NULL)
1902 continue;
1903 i = dpend - ptr->paramList[type].ns_ppc[j];
1904 if (i != len)
1905 continue;
1906 if (strncmp(ptr->paramList[type].ns_ppc[j],
1907 dp, len) == 0) {
1908 conf.ns_acnt =
1909 ptr->paramList[type].ns_acnt;
1910 conf.ns_ppc =
1911 ptr->paramList[type].ns_ppc;
1912 ptr->paramList[type].ns_ppc = NULL;
1913 free(conf.ns_ppc[j]);
1914 conf.ns_ppc[j] = (char *)strdup(cp);
1915 if (conf.ns_ppc[j] == NULL) {
1916 free(dp);
1917 __s_api_free2dArray
1918 (conf.ns_ppc);
1919 if (tcp != NULL)
1920 free(tcp);
1921 return (NS_LDAP_MEMORY);
1922 }
1923 fnd = 1;
1924 break;
1925 }
1926 }
1927 free(dp);
1928
1929 if (fnd)
1930 break; /* Replaced completed */
1931
1932 /* Append */
1933 len = ptr->paramList[type].ns_acnt + 1;
1934 if (len > 1) {
1935 p = (char **)dupParam(&ptr->paramList[type]);
1936 if (p == NULL) {
1937 if (tcp != NULL)
1938 free(tcp);
1939 return (NS_LDAP_MEMORY);
1940 }
1941 } else
1942 p = NULL;
1943 conf.ns_ppc =
1944 (char **)realloc(p, (len+1) * sizeof (char *));
1945 if (conf.ns_ppc == NULL) {
1946 __s_api_free2dArray(p);
1947 if (tcp != NULL)
1948 free(tcp);
1949 return (NS_LDAP_MEMORY);
1950 }
1951 conf.ns_acnt = len;
1952 conf.ns_ppc[len-1] = (char *)strdup(cp);
1953 if (conf.ns_ppc[len-1] == NULL) {
1954 __s_api_free2dArray(conf.ns_ppc);
1955 if (tcp != NULL)
1956 free(tcp);
1957 return (NS_LDAP_MEMORY);
1958 }
1959 conf.ns_ppc[len] = NULL;
1960 }
1961 break;
1962 case SSDLIST:
1963 /*
1964 * first check to see if colon (:) is there,
1965 * if so, make sure the serviceId is specified,
1966 * i.e., colon is not the first character
1967 */
1968 if ((strchr(cp, COLONTOK)) == NULL || *cp == COLONTOK) {
1969 (void) snprintf(errstr, sizeof (errstr),
1970 gettext("Unable to set value: "
1971 "invalid serviceSearchDescriptor (%s)"),
1972 cp);
1973 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
1974 strdup(errstr), NULL);
1975 if (tcp != NULL)
1976 free(tcp);
1977 return (NS_LDAP_CONFIG);
1978 }
1979 /* Appends an entry to the existing list */
1980 if (ptr->paramList[type].ns_ptype != SSDLIST) {
1981 conf.ns_ppc = (char **)calloc(2, sizeof (char *));
1982 if (conf.ns_ppc == NULL) {
1983 if (tcp != NULL)
1984 free(tcp);
1985 return (NS_LDAP_MEMORY);
1986 }
1987 conf.ns_acnt = 1;
1988 conf.ns_ppc[0] = (char *)strdup(cp);
1989 if (conf.ns_ppc[0] == NULL) {
1990 free(conf.ns_ppc);
1991 if (tcp != NULL)
1992 free(tcp);
1993 return (NS_LDAP_MEMORY);
1994 }
1995 } else {
1996 char *dp, *dpend;
1997 int fnd = 0;
1998
1999 /* Attempt to replace if possible */
2000 dpend = strchr(cp, COLONTOK);
2001 len = dpend - cp;
2002 dp = (char *)malloc(len+1);
2003 if (dp == NULL) {
2004 if (tcp != NULL)
2005 free(tcp);
2006 return (NS_LDAP_MEMORY);
2007 }
2008 (void) strlcpy(dp, cp, len+1);
2009 fnd = 0;
2010 for (j = 0; j < ptr->paramList[type].ns_acnt; j++) {
2011 dpend = strchr(ptr->paramList[type].ns_ppc[j],
2012 COLONTOK);
2013 if (dpend == NULL)
2014 continue;
2015 i = dpend - ptr->paramList[type].ns_ppc[j];
2016 if (i != len)
2017 continue;
2018 if (strncmp(ptr->paramList[type].ns_ppc[j],
2019 dp, len) == 0) {
2020 conf.ns_acnt =
2021 ptr->paramList[type].ns_acnt;
2022 conf.ns_ppc =
2023 ptr->paramList[type].ns_ppc;
2024 ptr->paramList[type].ns_ppc = NULL;
2025 free(conf.ns_ppc[j]);
2026 conf.ns_ppc[j] = (char *)strdup(cp);
2027 if (conf.ns_ppc[j] == NULL) {
2028 free(dp);
2029 __s_api_free2dArray
2030 (conf.ns_ppc);
2031 if (tcp != NULL)
2032 free(tcp);
2033 return (NS_LDAP_MEMORY);
2034 }
2035 fnd = 1;
2036 break;
2037 }
2038 }
2039 free(dp);
2040
2041 if (fnd)
2042 break; /* Replaced completed */
2043
2044 /* Append */
2045 len = ptr->paramList[type].ns_acnt + 1;
2046 if (len > 1) {
2047 p = (char **)dupParam(&ptr->paramList[type]);
2048 if (p == NULL) {
2049 if (tcp != NULL)
2050 free(tcp);
2051 return (NS_LDAP_MEMORY);
2052 }
2053 } else
2054 p = NULL;
2055 conf.ns_ppc =
2056 (char **)realloc(p, (len+1) * sizeof (char *));
2057 if (conf.ns_ppc == NULL) {
2058 __s_api_free2dArray(p);
2059 if (tcp != NULL)
2060 free(tcp);
2061 return (NS_LDAP_MEMORY);
2062 }
2063 conf.ns_acnt = len;
2064 conf.ns_ppc[len-1] = (char *)strdup(cp);
2065 if (conf.ns_ppc[len-1] == NULL) {
2066 __s_api_free2dArray(conf.ns_ppc);
2067 if (tcp != NULL)
2068 free(tcp);
2069 return (NS_LDAP_MEMORY);
2070 }
2071 conf.ns_ppc[len] = NULL;
2072 }
2073 break;
2074 case ARRAYCP:
2075 len = 0;
2076 for (cp2 = cp; *cp2; cp2++) {
2077 if (*cp2 == COMMATOK)
2078 len++;
2079 }
2080 if (cp != cp2)
2081 len++;
2082 if (len == 0) {
2083 conf.ns_ppc = (char **)NULL;
2084 conf.ns_acnt = 0;
2085 break;
2086 }
2087 conf.ns_ppc = (char **)calloc(len + 1, sizeof (char *));
2088 if (conf.ns_ppc == NULL) {
2089 if (tcp != NULL)
2090 free(tcp);
2091 return (NS_LDAP_MEMORY);
2092 }
2093 conf.ns_acnt = len;
2094 i = 0;
2095 for (cp2 = cp; *cp2; cp2++) {
2096 if (*cp2 == COMMATOK) {
2097 j = cp2 - cp + 1;
2098 conf.ns_ppc[i] = (char *)malloc(j + 1);
2099 if (conf.ns_ppc[i] == NULL) {
2100 __s_api_free2dArray(conf.ns_ppc);
2101 if (tcp != NULL)
2102 free(tcp);
2103 return (NS_LDAP_MEMORY);
2104 }
2105 (void) strlcpy(conf.ns_ppc[i], cp, j);
2106 cp = cp2+1;
2107 while (*cp == SPACETOK || *cp == COMMATOK)
2108 cp++;
2109 cp2 = cp - 1;
2110 i++;
2111 }
2112 }
2113 j = cp2 - cp + 1;
2114 conf.ns_ppc[i] = (char *)malloc(j + 1);
2115 if (conf.ns_ppc[i] == NULL) {
2116 __s_api_free2dArray(conf.ns_ppc);
2117 if (tcp != NULL)
2118 free(tcp);
2119 return (NS_LDAP_MEMORY);
2120 }
2121 (void) strlcpy(conf.ns_ppc[i], cp, j);
2122 break;
2123 case SERVLIST:
2124 len = 0;
2125 for (cp2 = cp; *cp2; cp2++) {
2126 if (*cp2 == SPACETOK || *cp2 == COMMATOK) {
2127 len++;
2128 for (; *(cp2 + 1) == SPACETOK ||
2129 *(cp2 +1) == COMMATOK; cp2++)
2130 ;
2131 }
2132 }
2133 if (cp != cp2)
2134 len++;
2135 if (len == 0) {
2136 conf.ns_ppc = (char **)NULL;
2137 conf.ns_acnt = 0;
2138 break;
2139 }
2140 conf.ns_ppc = (char **)calloc(len + 1, sizeof (char *));
2141 if (conf.ns_ppc == NULL) {
2142 if (tcp != NULL)
2143 free(tcp);
2144 return (NS_LDAP_MEMORY);
2145 }
2146 conf.ns_acnt = len;
2147 i = 0;
2148 for (cp2 = cp; *cp2; cp2++) {
2149 if (*cp2 == SPACETOK || *cp2 == COMMATOK) {
2150 j = cp2 - cp + 1;
2151 conf.ns_ppc[i] = (char *)malloc(j + 1);
2152 if (conf.ns_ppc[i] == NULL) {
2153 __s_api_free2dArray(conf.ns_ppc);
2154 if (tcp != NULL)
2155 free(tcp);
2156 return (NS_LDAP_MEMORY);
2157 }
2158 (void) strlcpy(conf.ns_ppc[i], cp, j);
2159 cp = cp2+1;
2160 while (*cp == SPACETOK || *cp == COMMATOK)
2161 cp++;
2162 cp2 = cp - 1;
2163 i++;
2164 }
2165 }
2166 j = cp2 - cp + 1;
2167 conf.ns_ppc[i] = (char *)malloc(j + 1);
2168 if (conf.ns_ppc[i] == NULL) {
2169 __s_api_free2dArray(conf.ns_ppc);
2170 if (tcp != NULL)
2171 free(tcp);
2172 return (NS_LDAP_MEMORY);
2173 }
2174 (void) strlcpy(conf.ns_ppc[i], cp, j);
2175 break;
2176 case ARRAYAUTH:
2177 len = 0;
2178 for (cp2 = cp; *cp2; cp2++) {
2179 if (*cp2 == SEMITOK || *cp2 == COMMATOK)
2180 len++;
2181 }
2182 if (cp != cp2)
2183 len++;
2184 if (len == 0) {
2185 conf.ns_pi = (int *)NULL;
2186 conf.ns_acnt = 0;
2187 break;
2188 }
2189 conf.ns_pi = (int *)calloc(len + 1, sizeof (int));
2190 if (conf.ns_pi == NULL) {
2191 if (tcp != NULL)
2192 free(tcp);
2193 return (NS_LDAP_MEMORY);
2194 }
2195 conf.ns_acnt = len;
2196 i = 0;
2197 for (cp2 = cp; *cp2; cp2++) {
2198 if (*cp2 == SEMITOK || *cp2 == COMMATOK) {
2199 j = cp2 - cp + 1;
2200 if (j > sizeof (tbuf)) {
2201 j = -1;
2202 ptbuf = cp;
2203 } else {
2204 (void) strlcpy(tbuf, cp, j);
2205 j = __s_get_enum_value(ptr, tbuf,
2206 def->index);
2207 ptbuf = tbuf;
2208 }
2209 if (j < 0) {
2210 (void) snprintf(errstr, sizeof (errstr),
2211 gettext("Unable to set value: "
2212 "invalid "
2213 "authenticationMethod (%s)"),
2214 ptbuf);
2215 MKERROR(LOG_ERR, *error,
2216 NS_CONFIG_SYNTAX,
2217 strdup(errstr), NULL);
2218 free(conf.ns_pi);
2219 if (tcp != NULL)
2220 free(tcp);
2221 return (NS_LDAP_CONFIG);
2222 }
2223 conf.ns_pi[i] = j;
2224 cp = cp2+1;
2225 i++;
2226 }
2227 }
2228 j = cp2 - cp + 1;
2229 if (j > sizeof (tbuf)) {
2230 j = -1;
2231 ptbuf = cp;
2232 } else {
2233 (void) strlcpy(tbuf, cp, j);
2234 j = __s_get_enum_value(ptr, tbuf, def->index);
2235 ptbuf = tbuf;
2236 }
2237 if (j < 0) {
2238 (void) snprintf(errstr, sizeof (errstr),
2239 gettext("Unable to set value: "
2240 "invalid authenticationMethod (%s)"), ptbuf);
2241 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
2242 strdup(errstr), NULL);
2243 if (tcp != NULL)
2244 free(tcp);
2245 return (NS_LDAP_CONFIG);
2246 }
2247 conf.ns_pi[i] = j;
2248 break;
2249 case ARRAYCRED:
2250 len = 0;
2251 for (cp2 = cp; *cp2; cp2++) {
2252 if (*cp2 == SPACETOK)
2253 len++;
2254 }
2255 if (cp != cp2)
2256 len++;
2257 if (len == 0) {
2258 conf.ns_pi = (int *)NULL;
2259 conf.ns_acnt = 0;
2260 break;
2261 }
2262 conf.ns_pi = (int *)calloc(len + 1, sizeof (int));
2263 if (conf.ns_pi == NULL) {
2264 if (tcp != NULL)
2265 free(tcp);
2266 return (NS_LDAP_MEMORY);
2267 }
2268 conf.ns_acnt = len;
2269 i = 0;
2270 for (cp2 = cp; *cp2; cp2++) {
2271 if (*cp2 == SPACETOK) {
2272 j = cp2 - cp + 1;
2273 if (j > sizeof (tbuf)) {
2274 j = -1;
2275 ptbuf = cp;
2276 } else {
2277 (void) strlcpy(tbuf, cp, j);
2278 j = __s_get_enum_value(ptr, tbuf,
2279 def->index);
2280 ptbuf = tbuf;
2281 }
2282 if (j < 0) {
2283 (void) snprintf(errstr, sizeof (errstr),
2284 gettext("Unable to set value: "
2285 "invalid credentialLevel (%s)"),
2286 ptbuf);
2287 MKERROR(LOG_ERR, *error,
2288 NS_CONFIG_SYNTAX,
2289 strdup(errstr), NULL);
2290 free(conf.ns_pi);
2291 if (tcp != NULL)
2292 free(tcp);
2293 return (NS_LDAP_CONFIG);
2294 }
2295 conf.ns_pi[i] = j;
2296 cp = cp2+1;
2297 i++;
2298 }
2299 }
2300 j = cp2 - cp + 1;
2301 if (j > sizeof (tbuf)) {
2302 j = -1;
2303 ptbuf = cp;
2304 } else {
2305 (void) strlcpy(tbuf, cp, j);
2306 j = __s_get_enum_value(ptr, tbuf, def->index);
2307 ptbuf = tbuf;
2308 }
2309 if (j < 0) {
2310 (void) snprintf(errstr, sizeof (errstr),
2311 gettext("Unable to set value: "
2312 "invalid credentialLevel (%s)"), ptbuf);
2313 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
2314 strdup(errstr), NULL);
2315 if (tcp != NULL)
2316 free(tcp);
2317 return (NS_LDAP_CONFIG);
2318 }
2319 conf.ns_pi[i] = j;
2320 break;
2321 case ATTRMAP:
2322 case OBJMAP:
2323 i = __s_api_parse_map(cp, &sid, &origA, &mapA);
2324 if (i != NS_HASH_RC_SUCCESS) {
2325 if (i == NS_HASH_RC_NO_MEMORY) {
2326 exitrc = NS_LDAP_MEMORY;
2327 } else {
2328 (void) snprintf(errstr, sizeof (errstr),
2329 gettext("Unable to set value: "
2330 "invalid schema mapping (%s)"), cp);
2331 exitrc = NS_LDAP_CONFIG;
2332 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
2333 strdup(errstr), NULL);
2334 }
2335 if (tcp)
2336 free(tcp);
2337 return (exitrc);
2338 }
2339
2340 /*
2341 * Add reverse map first.
2342 * There could be more than one.
2343 */
2344 for (attr = mapA; *attr; attr++) {
2345
2346 free_memory = 1;
2347 exitrc = NS_LDAP_MEMORY;
2348
2349 rmap = (ns_mapping_t *)calloc(1,
2350 sizeof (ns_mapping_t));
2351 if (rmap) {
2352 rmap->service = strdup(sid);
2353 if (rmap->service) {
2354 rmap->orig = strdup(*attr);
2355 if (rmap->orig) {
2356 rmap->map = (char **)calloc(2,
2357 sizeof (char *));
2358 if (rmap->map) {
2359 (rmap->map)[0] =
2360 strdup(origA);
2361 if ((rmap->map)[0])
2362 free_memory = 0;
2363 }
2364 }
2365 }
2366 }
2367
2368 if (free_memory == 0) {
2369 if (def->data_type == ATTRMAP) {
2370 rmap->type = NS_ATTR_MAP;
2371 i = __s_api_add_map2hash(ptr,
2372 NS_HASH_RAMAP, rmap);
2373 } else {
2374 rmap->type = NS_OBJ_MAP;
2375 i = __s_api_add_map2hash(ptr,
2376 NS_HASH_ROMAP, rmap);
2377 }
2378
2379 if (i != NS_HASH_RC_SUCCESS) {
2380 switch (i) {
2381 case NS_HASH_RC_CONFIG_ERROR:
2382 exitrc = NS_LDAP_INTERNAL;
2383 (void) snprintf(errstr,
2384 sizeof (errstr),
2385 gettext(
2386 "Unable to set value: "
2387 "no configuration info "
2388 "for schema map "
2389 "update (%s)"), cp);
2390 MKERROR(LOG_ERR, *error,
2391 NS_LDAP_INTERNAL,
2392 strdup(errstr),
2393 NULL);
2394 break;
2395 case NS_HASH_RC_EXISTED:
2396 exitrc = NS_LDAP_CONFIG;
2397 (void) snprintf(errstr,
2398 sizeof (errstr),
2399 gettext(
2400 "Unable to set value: "
2401 "schema map "
2402 "already existed for "
2403 "(%s, %s)."),
2404 *attr, origA);
2405 MKERROR(LOG_ERR, *error,
2406 NS_CONFIG_SYNTAX,
2407 strdup(errstr),
2408 NULL);
2409 break;
2410 case NS_HASH_RC_NO_MEMORY:
2411 exitrc = NS_LDAP_MEMORY;
2412 break;
2413 }
2414 free_memory = 1;
2415 }
2416 }
2417
2418 if (free_memory) {
2419 if (tcp)
2420 free(tcp);
2421 free(sid);
2422 free(origA);
2423 __s_api_free2dArray(mapA);
2424 if (rmap) {
2425 if (rmap->service)
2426 free(rmap->service);
2427 if (rmap->orig)
2428 free(rmap->orig);
2429 if (rmap->map) {
2430 if ((rmap->map)[0])
2431 free((rmap->map)[0]);
2432 free(rmap->map);
2433 }
2434 free(rmap);
2435 }
2436 return (exitrc);
2437 }
2438 }
2439
2440 /*
2441 * For performance gain,
2442 * add a "schema mapping existed" indicator
2443 * for the given service if not already added.
2444 * This dummy map needs not be removed, if
2445 * the next real map add operation fails.
2446 * since the caller, e.g. ldap_cachemgr.
2447 * should exit anyway.
2448 */
2449 free_memory = 1;
2450 exitrc = NS_LDAP_MEMORY;
2451
2452 map = (ns_mapping_t *)calloc(1,
2453 sizeof (ns_mapping_t));
2454 if (map) {
2455 map->service = strdup(sid);
2456 if (map->service) {
2457 map->orig = strdup(
2458 NS_HASH_SCHEMA_MAPPING_EXISTED);
2459 if (map->orig) {
2460 map->map = (char **)calloc(2,
2461 sizeof (char *));
2462 if (map->map) {
2463 (map->map)[0] =
2464 strdup(sid);
2465 if ((map->map)[0])
2466 free_memory = 0;
2467 }
2468 }
2469 }
2470 }
2471
2472 if (free_memory == 0) {
2473 map->type = NS_ATTR_MAP;
2474 /*
2475 * add to reverse map,
2476 * so that "ldapclient list"
2477 * would not show it
2478 */
2479 i = __s_api_add_map2hash(ptr,
2480 NS_HASH_RAMAP, map);
2481
2482 /*
2483 * ignore "map already existed" error,
2484 * just need one per service.
2485 * Need however to free memory allocated
2486 * for map.
2487 */
2488 if (i != NS_HASH_RC_SUCCESS &&
2489 i != NS_HASH_RC_EXISTED) {
2490 switch (i) {
2491 case NS_HASH_RC_CONFIG_ERROR:
2492 exitrc = NS_LDAP_INTERNAL;
2493 (void) snprintf(errstr,
2494 sizeof (errstr),
2495 gettext(
2496 "Unable to set value: "
2497 "no configuration info "
2498 "for schema map "
2499 "update (%s)"), cp);
2500 MKERROR(LOG_ERR, *error,
2501 NS_LDAP_INTERNAL,
2502 strdup(errstr),
2503 NULL);
2504 break;
2505 case NS_HASH_RC_NO_MEMORY:
2506 exitrc = NS_LDAP_MEMORY;
2507 break;
2508 }
2509 free_memory = 1;
2510 } else if (i == NS_HASH_RC_EXISTED) {
2511 if (map->service)
2512 free(map->service);
2513 if (map->orig)
2514 free(map->orig);
2515 if (map->map) {
2516 if ((map->map)[0])
2517 free((map->map)[0]);
2518 free(map->map);
2519 }
2520 free(map);
2521 map = NULL;
2522 }
2523 }
2524
2525 if (free_memory) {
2526 if (tcp)
2527 free(tcp);
2528 free(sid);
2529 free(origA);
2530 __s_api_free2dArray(mapA);
2531 if (map) {
2532 if (map->service)
2533 free(map->service);
2534 if (map->orig)
2535 free(map->orig);
2536 if (map->map) {
2537 if ((map->map)[0])
2538 free((map->map)[0]);
2539 free(map->map);
2540 }
2541 free(map);
2542 }
2543 return (exitrc);
2544 }
2545
2546 /*
2547 * add the real schema map
2548 */
2549 free_memory = 1;
2550 exitrc = NS_LDAP_MEMORY;
2551 map = (ns_mapping_t *)calloc(1, sizeof (ns_mapping_t));
2552 if (map) {
2553 map->service = sid;
2554 map->orig = origA;
2555 map->map = mapA;
2556
2557 if (def->data_type == ATTRMAP) {
2558 map->type = NS_ATTR_MAP;
2559 i = __s_api_add_map2hash(ptr,
2560 NS_HASH_AMAP, map);
2561 } else {
2562 map->type = NS_OBJ_MAP;
2563 i = __s_api_add_map2hash(ptr,
2564 NS_HASH_OMAP, map);
2565 }
2566
2567 if (i != NS_HASH_RC_SUCCESS) {
2568 switch (i) {
2569 case NS_HASH_RC_CONFIG_ERROR:
2570 exitrc = NS_LDAP_INTERNAL;
2571 (void) snprintf(errstr,
2572 sizeof (errstr),
2573 gettext(
2574 "Unable to set value: "
2575 "no configuration info "
2576 "for schema map "
2577 "update (%s)"), cp);
2578 MKERROR(LOG_ERR, *error,
2579 NS_LDAP_INTERNAL,
2580 strdup(errstr),
2581 NULL);
2582 break;
2583 case NS_HASH_RC_EXISTED:
2584 exitrc = NS_LDAP_CONFIG;
2585 (void) snprintf(errstr,
2586 sizeof (errstr),
2587 gettext(
2588 "Unable to set value: "
2589 "schema map "
2590 "already existed for "
2591 "'%s'."), origA);
2592 MKERROR(LOG_ERR, *error,
2593 NS_CONFIG_SYNTAX,
2594 strdup(errstr),
2595 NULL);
2596 break;
2597 case NS_HASH_RC_NO_MEMORY:
2598 exitrc = NS_LDAP_MEMORY;
2599 break;
2600 }
2601 free_memory = 1;
2602 } else
2603 free_memory = 0;
2604 }
2605
2606 if (free_memory) {
2607 if (tcp)
2608 free(tcp);
2609 free(sid);
2610 free(origA);
2611 __s_api_free2dArray(mapA);
2612 if (map)
2613 free(map);
2614 return (exitrc);
2615 }
2616
2617 break;
2618 default:
2619 /* This should never happen. */
2620 (void) snprintf(errstr, sizeof (errstr),
2621 gettext("Unable to set value: invalid configuration "
2622 "type (%d)"), def->data_type);
2623 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, strdup(errstr),
2624 NULL);
2625 if (tcp != NULL)
2626 free(tcp);
2627 return (NS_LDAP_CONFIG);
2628 }
2629 conf.ns_ptype = def->data_type;
2630 if (tcp != NULL)
2631 free(tcp);
2632
2633 /* Individually written verify routines here can replace */
2634 /* verify_value. Verify conf (data) as appropriate here */
2635 if (def->ns_verify != NULL) {
2636 if ((*def->ns_verify)(type, def, &conf, errstr) != NS_SUCCESS) {
2637 ns_param_t sav_conf;
2638
2639 (void) snprintf(errstr, sizeof (errstr),
2640 gettext("%s"), errstr);
2641 MKERROR(LOG_WARNING, *error, NS_CONFIG_SYNTAX,
2642 strdup(errstr), NULL);
2643
2644 sav_conf = ptr->paramList[type];
2645 ptr->paramList[type] = conf;
2646 destroy_param(ptr, type);
2647 ptr->paramList[type] = sav_conf;
2648
2649 return (NS_LDAP_CONFIG);
2650 }
2651 }
2652
2653 /* post evaluate the data */
2654
2655 /*
2656 * if this is for setting a password,
2657 * encrypt the password first.
2658 * NOTE evalue() is smart and will just return
2659 * the value passed if it is already encrypted.
2660 *
2661 * Init NS_LDAP_EXP_P here when CACHETTL is updated
2662 */
2663 if (type == NS_LDAP_BINDPASSWD_P ||
2664 type == NS_LDAP_ADMIN_BINDPASSWD_P) {
2665 cp = conf.ns_pc;
2666 cp2 = evalue((char *)cp);
2667 conf.ns_pc = cp2;
2668 free(cp);
2669 cp = NULL;
2670 } else if (type == NS_LDAP_FILE_VERSION_P) {
2671 ptr->version = NS_LDAP_V1;
2672 if (strcasecmp(conf.ns_pc, NS_LDAP_VERSION_2) == 0) {
2673 ptr->version = NS_LDAP_V2;
2674 }
2675 } else if (type == NS_LDAP_CACHETTL_P) {
2676 cp = conf.ns_pc;
2677 tm = conv_time(cp);
2678 ptr->paramList[NS_LDAP_EXP_P].ns_ptype = TIMET;
2679 if (tm != 0) {
2680 tm += time(NULL);
2681 }
2682 ptr->paramList[NS_LDAP_EXP_P].ns_tm = tm;
2683 }
2684
2685 /* Everything checks out move new values into param */
2686 destroy_param(ptr, type);
2687 /* Assign new/updated value into paramList */
2688 ptr->paramList[type] = conf;
2689
2690 return (NS_LDAP_SUCCESS);
2691 }
2692
2693
2694 /*
2695 * Set a parameter value in the 'config' configuration structure
2696 * Lock as appropriate
2697 */
2698
2699 int
__ns_ldap_setParam(const ParamIndexType type,const void * data,ns_ldap_error_t ** error)2700 __ns_ldap_setParam(const ParamIndexType type,
2701 const void *data, ns_ldap_error_t **error)
2702 {
2703 ns_ldap_error_t *errorp;
2704 int ret;
2705 char errstr[2 * MAXERROR];
2706 ns_config_t *cfg;
2707 ns_config_t *cfg_g = (ns_config_t *)-1;
2708 ns_config_t *new_cfg;
2709 boolean_t reinit_connmgmt = B_FALSE;
2710
2711 /* We want to refresh only one configuration at a time */
2712 (void) mutex_lock(&ns_loadrefresh_lock);
2713 cfg = __s_api_get_default_config();
2714
2715 if (cache_server == TRUE) {
2716 if (cfg == NULL) {
2717 __ns_ldap_default_config();
2718 cfg = __s_api_get_default_config();
2719 if (cfg == NULL) {
2720 (void) mutex_unlock(&ns_loadrefresh_lock);
2721 return (NS_LDAP_MEMORY);
2722 }
2723 }
2724 } else {
2725 /*
2726 * This code always return error here on client side,
2727 * this needs to change once libsldap is used by more
2728 * applications that need to set parameters.
2729 */
2730 (void) snprintf(errstr, sizeof (errstr),
2731 gettext("Unable to set parameter from a client in "
2732 "__ns_ldap_setParam()"));
2733 MKERROR(LOG_WARNING, *error, NS_CONFIG_SYNTAX, strdup(errstr),
2734 NULL);
2735 if (cfg != NULL)
2736 __s_api_release_config(cfg);
2737 (void) mutex_unlock(&ns_loadrefresh_lock);
2738 return (NS_LDAP_CONFIG);
2739 }
2740
2741 /* (re)initialize configuration if necessary */
2742 if (!__s_api_isStandalone() &&
2743 cache_server == FALSE && timetorefresh(cfg))
2744 cfg_g = __s_api_get_default_config_global();
2745 /* only (re)initialize the global configuration */
2746 if (cfg == cfg_g) {
2747 if (cfg_g != NULL)
2748 __s_api_release_config(cfg_g);
2749 new_cfg = LoadCacheConfiguration(cfg, &errorp);
2750 if (new_cfg != cfg)
2751 __s_api_release_config(cfg);
2752 if (new_cfg == NULL) {
2753 (void) snprintf(errstr, sizeof (errstr),
2754 gettext("Unable to load configuration '%s' "
2755 "('%s')."), NSCONFIGFILE,
2756 errorp != NULL && errorp->message != NULL ?
2757 errorp->message : "");
2758 MKERROR(LOG_WARNING, *error, NS_CONFIG_NOTLOADED,
2759 strdup(errstr), NULL);
2760 if (errorp != NULL)
2761 (void) __ns_ldap_freeError(&errorp);
2762 (void) mutex_unlock(&ns_loadrefresh_lock);
2763 return (NS_LDAP_CONFIG);
2764 }
2765 if (new_cfg != cfg) {
2766 set_curr_config_global(new_cfg);
2767 cfg = new_cfg;
2768 reinit_connmgmt = B_TRUE;
2769 }
2770 }
2771 (void) mutex_unlock(&ns_loadrefresh_lock);
2772
2773 if (reinit_connmgmt == B_TRUE)
2774 __s_api_reinit_conn_mgmt_new_config(cfg);
2775
2776 /* translate input and save in the parameter list */
2777 ret = __ns_ldap_setParamValue(cfg, type, data, error);
2778
2779 __s_api_release_config(cfg);
2780
2781 return (ret);
2782 }
2783
2784
2785 /*
2786 * Make a copy of a parameter entry
2787 */
2788
2789 static void **
dupParam(ns_param_t * ptr)2790 dupParam(ns_param_t *ptr)
2791 {
2792 int count, i;
2793 void **dupdata, *ret;
2794 int *intptr;
2795 char *cp, tmbuf[32];
2796 static time_t expire = 0;
2797 ns_auth_t *ap;
2798
2799 switch (ptr->ns_ptype) {
2800 case ARRAYAUTH:
2801 case ARRAYCRED:
2802 case SAMLIST:
2803 case SCLLIST:
2804 case SSDLIST:
2805 case SERVLIST:
2806 case ARRAYCP:
2807 count = ptr->ns_acnt;
2808 if (count == 0)
2809 return (NULL);
2810 break;
2811 case CHARPTR:
2812 case INT:
2813 case TIMET:
2814 count = 1;
2815 }
2816
2817 dupdata = (void **)calloc((count + 1), sizeof (void *));
2818 if (dupdata == NULL)
2819 return (NULL);
2820
2821 switch (ptr->ns_ptype) {
2822 case ARRAYAUTH:
2823 for (i = 0; i < count; i++) {
2824 ap = __s_api_AuthEnumtoStruct(
2825 (EnumAuthType_t)ptr->ns_pi[i]);
2826 if (ap == NULL) {
2827 free(dupdata);
2828 return (NULL);
2829 }
2830 dupdata[i] = ap;
2831 }
2832 break;
2833 case ARRAYCRED:
2834 for (i = 0; i < count; i++) {
2835 intptr = (int *)malloc(sizeof (int));
2836 if (intptr == NULL) {
2837 free(dupdata);
2838 return (NULL);
2839 }
2840 dupdata[i] = (void *)intptr;
2841 *intptr = ptr->ns_pi[i];
2842 }
2843 break;
2844 case SAMLIST:
2845 case SCLLIST:
2846 case SSDLIST:
2847 case SERVLIST:
2848 case ARRAYCP:
2849 for (i = 0; i < count; i++) {
2850 ret = (void *)strdup(ptr->ns_ppc[i]);
2851 if (ret == NULL) {
2852 free(dupdata);
2853 return (NULL);
2854 }
2855 dupdata[i] = ret;
2856 }
2857 break;
2858 case CHARPTR:
2859 if (ptr->ns_pc == NULL) {
2860 free(dupdata);
2861 return (NULL);
2862 }
2863 ret = (void *)strdup(ptr->ns_pc);
2864 if (ret == NULL) {
2865 free(dupdata);
2866 return (NULL);
2867 }
2868 dupdata[0] = ret;
2869 break;
2870 case INT:
2871 intptr = (int *)malloc(sizeof (int));
2872 if (intptr == NULL) {
2873 free(dupdata);
2874 return (NULL);
2875 }
2876 *intptr = ptr->ns_i;
2877 dupdata[0] = (void *)intptr;
2878 break;
2879 case TIMET:
2880 expire = ptr->ns_tm;
2881 tmbuf[31] = '\0';
2882 cp = lltostr((long)expire, &tmbuf[31]);
2883 ret = (void *)strdup(cp);
2884 if (ret == NULL) {
2885 free(dupdata);
2886 return (NULL);
2887 }
2888 dupdata[0] = ret;
2889 break;
2890 }
2891 return (dupdata);
2892 }
2893
2894 int
__ns_ldap_freeParam(void *** data)2895 __ns_ldap_freeParam(void ***data)
2896 {
2897 void **tmp;
2898 int i = 0;
2899
2900 if (*data == NULL)
2901 return (NS_LDAP_SUCCESS);
2902
2903 for (i = 0, tmp = *data; tmp[i] != NULL; i++)
2904 free(tmp[i]);
2905
2906 free(*data);
2907
2908 *data = NULL;
2909
2910 return (NS_LDAP_SUCCESS);
2911 }
2912
2913 /*
2914 * Get the internal format for a parameter value. This
2915 * routine makes a copy of an internal param value from
2916 * the currently active parameter list and returns it.
2917 */
2918
2919 int
__ns_ldap_getParam(const ParamIndexType Param,void *** data,ns_ldap_error_t ** error)2920 __ns_ldap_getParam(const ParamIndexType Param,
2921 void ***data, ns_ldap_error_t **error)
2922 {
2923 char errstr[2 * MAXERROR];
2924 ns_ldap_error_t *errorp;
2925 ns_default_config *def;
2926 ns_config_t *cfg;
2927 ns_config_t *cfg_g = (ns_config_t *)-1;
2928 ns_config_t *new_cfg;
2929 boolean_t reinit_connmgmt = B_FALSE;
2930
2931 if (data == NULL)
2932 return (NS_LDAP_INVALID_PARAM);
2933
2934 *data = NULL;
2935
2936 /* We want to refresh only one configuration at a time */
2937 (void) mutex_lock(&ns_loadrefresh_lock);
2938 cfg = __s_api_get_default_config();
2939
2940 /* (re)initialize configuration if necessary */
2941 if (!__s_api_isStandalone() &&
2942 cache_server == FALSE && timetorefresh(cfg))
2943 cfg_g = __s_api_get_default_config_global();
2944 /* only (re)initialize the global configuration */
2945 if (cfg == cfg_g) {
2946 if (cfg_g != NULL)
2947 __s_api_release_config(cfg_g);
2948 new_cfg = LoadCacheConfiguration(cfg, &errorp);
2949 if (new_cfg != cfg)
2950 __s_api_release_config(cfg);
2951 if (new_cfg == NULL) {
2952 (void) snprintf(errstr, sizeof (errstr),
2953 gettext("Unable to load configuration "
2954 "'%s' ('%s')."),
2955 NSCONFIGFILE,
2956 errorp != NULL && errorp->message != NULL ?
2957 errorp->message : "");
2958 MKERROR(LOG_WARNING, *error, NS_CONFIG_NOTLOADED,
2959 strdup(errstr), NULL);
2960 if (errorp != NULL)
2961 (void) __ns_ldap_freeError(&errorp);
2962 (void) mutex_unlock(&ns_loadrefresh_lock);
2963 return (NS_LDAP_CONFIG);
2964 }
2965 if (new_cfg != cfg) {
2966 set_curr_config_global(new_cfg);
2967 cfg = new_cfg;
2968 reinit_connmgmt = B_TRUE;
2969 }
2970 }
2971 (void) mutex_unlock(&ns_loadrefresh_lock);
2972
2973 if (reinit_connmgmt == B_TRUE)
2974 __s_api_reinit_conn_mgmt_new_config(cfg);
2975
2976 if (cfg == NULL) {
2977 (void) snprintf(errstr, sizeof (errstr),
2978 gettext("No configuration information available."));
2979 MKERROR(LOG_ERR, *error, NS_CONFIG_NOTLOADED,
2980 strdup(errstr), NULL);
2981 return (NS_LDAP_CONFIG);
2982 }
2983
2984 if (Param == NS_LDAP_DOMAIN_P) {
2985 *data = (void **)calloc(2, sizeof (void *));
2986 if (*data == NULL) {
2987 __s_api_release_config(cfg);
2988 return (NS_LDAP_MEMORY);
2989 }
2990 (*data)[0] = (void *)strdup(cfg->domainName);
2991 if ((*data)[0] == NULL) {
2992 free(*data);
2993 __s_api_release_config(cfg);
2994 return (NS_LDAP_MEMORY);
2995 }
2996 } else if (cfg->paramList[Param].ns_ptype == NS_UNKNOWN) {
2997 /* get default */
2998 def = get_defconfig(cfg, Param);
2999 if (def != NULL)
3000 *data = dupParam(&def->defval);
3001 } else {
3002 *data = dupParam(&(cfg->paramList[Param]));
3003 }
3004 __s_api_release_config(cfg);
3005
3006 return (NS_LDAP_SUCCESS);
3007 }
3008
3009 /*
3010 * This routine takes a parameter in internal format and
3011 * translates it into a variety of string formats for various
3012 * outputs (doors/file/ldif). This routine would be better
3013 * named: __ns_ldap_translateParam2String
3014 */
3015
3016 char *
__s_api_strValue(ns_config_t * cfg,ParamIndexType index,ns_strfmt_t fmt)3017 __s_api_strValue(ns_config_t *cfg, ParamIndexType index, ns_strfmt_t fmt)
3018 {
3019 ns_default_config *def = NULL;
3020 ns_param_t *ptr;
3021 ns_hash_t *hptr;
3022 ns_mapping_t *mptr;
3023 char ibuf[14];
3024 char abuf[64], **cpp;
3025 int count, i;
3026 boolean_t first = B_TRUE;
3027 LineBuf lbuf;
3028 LineBuf *buffer = &lbuf;
3029 char *retstring;
3030 char *sepstr;
3031
3032 if (cfg == NULL)
3033 return (NULL);
3034
3035 /* NS_LDAP_EXP and TRANSPORT_SEC are not exported externally */
3036 if (index == NS_LDAP_EXP_P || index == NS_LDAP_TRANSPORT_SEC_P)
3037 return (NULL);
3038
3039 /* Return nothing if the value is the default */
3040 if (cfg->paramList[index].ns_ptype == NS_UNKNOWN)
3041 return (NULL);
3042
3043 (void) memset((char *)buffer, 0, sizeof (LineBuf));
3044
3045 ptr = &(cfg->paramList[index]);
3046
3047 abuf[0] = '\0';
3048
3049 /* get default */
3050 def = get_defconfig(cfg, index);
3051 if (def == NULL)
3052 return (NULL);
3053
3054 switch (fmt) {
3055 case NS_DOOR_FMT:
3056 (void) strlcpy(abuf, def->name, sizeof (abuf));
3057 (void) strlcat(abuf, EQUALSEP, sizeof (abuf));
3058 break;
3059 case NS_FILE_FMT:
3060 (void) strlcpy(abuf, def->name, sizeof (abuf));
3061 (void) strlcat(abuf, EQUSPSEP, sizeof (abuf));
3062 break;
3063 case NS_LDIF_FMT:
3064 /* If no LDIF attr exists ignore the entry */
3065 if (def->profile_name == NULL)
3066 return (NULL);
3067 (void) strlcpy(abuf, def->profile_name, sizeof (abuf));
3068 (void) strlcat(abuf, COLSPSEP, sizeof (abuf));
3069 break;
3070 default:
3071 break;
3072 }
3073
3074 if (__print2buf(buffer, abuf, NULL))
3075 goto strValueError;
3076
3077 switch (ptr->ns_ptype) {
3078 case ARRAYAUTH:
3079 count = ptr->ns_acnt;
3080 for (i = 0; i < count; i++) {
3081 sepstr = NULL;
3082 if (i != count-1) {
3083 if (cfg->version == NS_LDAP_V1) {
3084 sepstr = COMMASEP;
3085 } else {
3086 sepstr = SEMISEP;
3087 }
3088 }
3089 if (__print2buf(buffer, __s_get_auth_name(cfg,
3090 (AuthType_t)(ptr->ns_pi[i])), sepstr))
3091 goto strValueError;
3092 }
3093 break;
3094 case ARRAYCRED:
3095 count = ptr->ns_acnt;
3096 for (i = 0; i < count; i++) {
3097 sepstr = NULL;
3098 if (i != count-1) {
3099 sepstr = SPACESEP;
3100 }
3101 if (__print2buf(buffer, __s_get_credlvl_name(cfg,
3102 (CredLevel_t)ptr->ns_pi[i]), sepstr))
3103 goto strValueError;
3104 }
3105 break;
3106 case SAMLIST:
3107 case SCLLIST:
3108 case SSDLIST:
3109 count = ptr->ns_acnt;
3110 for (i = 0; i < count; i++) {
3111 if (__print2buf(buffer, ptr->ns_ppc[i], NULL))
3112 goto strValueError;
3113
3114 if (i == count-1)
3115 continue;
3116
3117 /* Separate items */
3118 switch (fmt) {
3119 case NS_DOOR_FMT:
3120 if (__print2buf(buffer, DOORLINESEP, NULL) ||
3121 __print2buf(buffer, def->name, EQUALSEP))
3122 goto strValueError;
3123 break;
3124 case NS_FILE_FMT:
3125 if (__print2buf(buffer, "\n", NULL) ||
3126 __print2buf(buffer, def->name, EQUSPSEP))
3127 goto strValueError;
3128 break;
3129 case NS_LDIF_FMT:
3130 if (__print2buf(buffer, "\n", NULL) ||
3131 __print2buf(buffer, def->profile_name,
3132 COLSPSEP))
3133 goto strValueError;
3134 break;
3135 }
3136 }
3137 break;
3138 case ARRAYCP:
3139 count = ptr->ns_acnt;
3140 for (i = 0; i < count; i++) {
3141 sepstr = NULL;
3142 if (i != count-1) {
3143 sepstr = COMMASEP;
3144 }
3145 if (__print2buf(buffer, ptr->ns_ppc[i], sepstr))
3146 goto strValueError;
3147 }
3148 break;
3149 case SERVLIST:
3150 count = ptr->ns_acnt;
3151 for (i = 0; i < count; i++) {
3152 sepstr = NULL;
3153 if (i != count-1) {
3154 if (fmt == NS_LDIF_FMT) {
3155 sepstr = SPACESEP;
3156 } else {
3157 sepstr = COMMASEP;
3158 }
3159 }
3160 if (__print2buf(buffer, ptr->ns_ppc[i], sepstr))
3161 goto strValueError;
3162 }
3163 break;
3164 case CHARPTR:
3165 if (ptr->ns_pc == NULL)
3166 break;
3167 if (__print2buf(buffer, ptr->ns_pc, NULL))
3168 goto strValueError;
3169 break;
3170 case INT:
3171 switch (def->index) {
3172 case NS_LDAP_PREF_ONLY_P:
3173 if (__print2buf(buffer,
3174 __s_get_pref_name((PrefOnly_t)ptr->ns_i), NULL))
3175 goto strValueError;
3176 break;
3177 case NS_LDAP_SEARCH_REF_P:
3178 if (__print2buf(buffer, __s_get_searchref_name(cfg,
3179 (SearchRef_t)ptr->ns_i), NULL))
3180 goto strValueError;
3181 break;
3182 case NS_LDAP_SEARCH_SCOPE_P:
3183 if (__print2buf(buffer, __s_get_scope_name(cfg,
3184 (ScopeType_t)ptr->ns_i), NULL))
3185 goto strValueError;
3186 break;
3187 case NS_LDAP_ENABLE_SHADOW_UPDATE_P:
3188 if (__print2buf(buffer, __s_get_shadowupdate_name(
3189 (enableShadowUpdate_t)ptr->ns_i), NULL))
3190 goto strValueError;
3191 break;
3192 default:
3193 (void) snprintf(ibuf, sizeof (ibuf),
3194 "%d", ptr->ns_i);
3195 if (__print2buf(buffer, ibuf, NULL))
3196 goto strValueError;
3197 break;
3198 }
3199 break;
3200 case ATTRMAP:
3201 for (hptr = cfg->llHead; hptr; hptr = hptr->h_llnext) {
3202 if (hptr->h_type != NS_HASH_AMAP) {
3203 continue;
3204 }
3205 if (!first) {
3206 /* print abuf as "separator" */
3207 if (fmt == NS_DOOR_FMT) {
3208 if (__print2buf(buffer, DOORLINESEP,
3209 abuf))
3210 goto strValueError;
3211 } else {
3212 if (__print2buf(buffer, "\n", abuf))
3213 goto strValueError;
3214 }
3215 }
3216 mptr = hptr->h_map;
3217 if (__print2buf(buffer, mptr->service, COLONSEP) ||
3218 __print2buf(buffer, mptr->orig, EQUALSEP))
3219 goto strValueError;
3220 for (cpp = mptr->map; cpp && *cpp; cpp++) {
3221 /* print *cpp as "separator" */
3222 sepstr = "";
3223 if (cpp != mptr->map)
3224 sepstr = SPACESEP;
3225 if (__print2buf(buffer, sepstr, *cpp))
3226 goto strValueError;
3227 }
3228 first = B_FALSE;
3229 }
3230 break;
3231 case OBJMAP:
3232 for (hptr = cfg->llHead; hptr; hptr = hptr->h_llnext) {
3233 if (hptr->h_type != NS_HASH_OMAP) {
3234 continue;
3235 }
3236 if (!first) {
3237 /* print abuf as "separator" */
3238 if (fmt == NS_DOOR_FMT) {
3239 if (__print2buf(buffer, DOORLINESEP,
3240 abuf))
3241 goto strValueError;
3242 } else {
3243 if (__print2buf(buffer, "\n", abuf))
3244 goto strValueError;
3245 }
3246 }
3247 mptr = hptr->h_map;
3248 if (__print2buf(buffer, mptr->service, COLONSEP) ||
3249 __print2buf(buffer, mptr->orig, EQUALSEP))
3250 goto strValueError;
3251 for (cpp = mptr->map; cpp && *cpp; cpp++) {
3252 /* print *cpp as "separator" */
3253 sepstr = "";
3254 if (cpp != mptr->map)
3255 sepstr = SPACESEP;
3256 if (__print2buf(buffer, sepstr, *cpp))
3257 goto strValueError;
3258 }
3259 first = B_FALSE;
3260 }
3261 break;
3262 }
3263
3264 retstring = buffer->str;
3265 return (retstring);
3266
3267 strValueError:
3268 if (buffer->len > 0)
3269 free(buffer->str);
3270 return (NULL);
3271 }
3272
3273 /* shared by __door_getldapconfig() and __door_getadmincred() */
3274 int
__door_getconf(char ** buffer,int * buflen,ns_ldap_error_t ** error,int callnumber)3275 __door_getconf(char **buffer, int *buflen, ns_ldap_error_t **error,
3276 int callnumber)
3277 {
3278 typedef union {
3279 ldap_data_t s_d;
3280 char s_b[DOORBUFFERSIZE];
3281 } space_t;
3282 space_t *space;
3283
3284 ldap_data_t *sptr;
3285 int ndata;
3286 int adata;
3287 char errstr[MAXERROR];
3288 char *domainname;
3289 ns_ldap_return_code retCode;
3290 ldap_config_out_t *cfghdr;
3291
3292 *error = NULL;
3293
3294 domainname = __getdomainname();
3295 if (domainname == NULL || buffer == NULL || buflen == NULL ||
3296 (strlen(domainname) >= (sizeof (space_t)
3297 - sizeof (space->s_d.ldap_call.ldap_callnumber)))) {
3298 return (NS_LDAP_OP_FAILED);
3299 }
3300
3301 space = (space_t *)calloc(1, sizeof (space_t));
3302 if (space == NULL)
3303 return (NS_LDAP_MEMORY);
3304
3305 adata = (sizeof (ldap_call_t) + strlen(domainname) +1);
3306 ndata = sizeof (space_t);
3307 space->s_d.ldap_call.ldap_callnumber = callnumber;
3308 (void) strcpy(space->s_d.ldap_call.ldap_u.domainname, domainname);
3309 free(domainname);
3310 domainname = NULL;
3311 sptr = &space->s_d;
3312
3313 switch (__ns_ldap_trydoorcall(&sptr, &ndata, &adata)) {
3314 case NS_CACHE_SUCCESS:
3315 break;
3316 case NS_CACHE_NOTFOUND:
3317 (void) snprintf(errstr, sizeof (errstr),
3318 gettext("Door call to "
3319 "ldap_cachemgr failed - error: %d."),
3320 space->s_d.ldap_ret.ldap_errno);
3321 MKERROR(LOG_WARNING, *error, NS_CONFIG_CACHEMGR,
3322 strdup(errstr), NULL);
3323 free(space);
3324 return (NS_LDAP_OP_FAILED);
3325 default:
3326 free(space);
3327 return (NS_LDAP_OP_FAILED);
3328 }
3329
3330 retCode = NS_LDAP_SUCCESS;
3331
3332 /* copy info from door call to buffer here */
3333 cfghdr = &sptr->ldap_ret.ldap_u.config_str;
3334 *buflen = offsetof(ldap_config_out_t, config_str) +
3335 cfghdr->data_size + 1;
3336 *buffer = calloc(*buflen, sizeof (char));
3337 if (*buffer == NULL) {
3338 retCode = NS_LDAP_MEMORY;
3339 } else
3340 (void) memcpy(*buffer, cfghdr, *buflen - 1);
3341
3342 if (sptr != &space->s_d) {
3343 (void) munmap((char *)sptr, ndata);
3344 }
3345 free(space);
3346
3347 return (retCode);
3348 }
3349
3350 static int
__door_getldapconfig(char ** buffer,int * buflen,ns_ldap_error_t ** error)3351 __door_getldapconfig(char **buffer, int *buflen, ns_ldap_error_t **error)
3352 {
3353 return (__door_getconf(buffer, buflen, error, GETLDAPCONFIGV1));
3354 }
3355
3356 /*
3357 * SetDoorInfoToUnixCred parses ldapcachemgr configuration information
3358 * for Admin credentials.
3359 */
3360 int
SetDoorInfoToUnixCred(char * buffer,ns_ldap_error_t ** errorp,UnixCred_t ** cred)3361 SetDoorInfoToUnixCred(char *buffer, ns_ldap_error_t **errorp,
3362 UnixCred_t **cred)
3363 {
3364 UnixCred_t *ptr;
3365 char errstr[MAXERROR];
3366 char *name, *value, valbuf[BUFSIZE];
3367 char *bufptr = buffer;
3368 char *strptr;
3369 char *rest;
3370 ParamIndexType index = 0;
3371 ldap_config_out_t *cfghdr;
3372
3373 if (errorp == NULL || cred == NULL || *cred == NULL)
3374 return (NS_LDAP_INVALID_PARAM);
3375 *errorp = NULL;
3376
3377 ptr = *cred;
3378
3379 cfghdr = (ldap_config_out_t *)bufptr;
3380 bufptr = (char *)cfghdr->config_str;
3381
3382 strptr = (char *)strtok_r(bufptr, DOORLINESEP, &rest);
3383 for (; ; ) {
3384 if (strptr == NULL)
3385 break;
3386 (void) strlcpy(valbuf, strptr, sizeof (valbuf));
3387 __s_api_split_key_value(valbuf, &name, &value);
3388 if (__ns_ldap_getParamType(name, &index) != 0) {
3389 (void) snprintf(errstr, MAXERROR,
3390 gettext("SetDoorInfoToUnixCred: "
3391 "Unknown keyword encountered '%s'."), name);
3392 MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX,
3393 strdup(errstr), NULL);
3394 return (NS_LDAP_CONFIG);
3395 }
3396 switch (index) {
3397 case NS_LDAP_ADMIN_BINDDN_P:
3398 ptr->userID = (char *)strdup(value);
3399 break;
3400 case NS_LDAP_ADMIN_BINDPASSWD_P:
3401 ptr->passwd = (char *)strdup(value);
3402 break;
3403 default:
3404 (void) snprintf(errstr, MAXERROR,
3405 gettext("SetDoorInfoToUnixCred: "
3406 "Unknown index encountered '%d'."), index);
3407 MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX,
3408 strdup(errstr), NULL);
3409 return (NS_LDAP_CONFIG);
3410 }
3411 strptr = (char *)strtok_r(NULL, DOORLINESEP, &rest);
3412 }
3413
3414 return (NS_LDAP_SUCCESS);
3415 }
3416
3417 /*
3418 * SetDoorInfo parses ldapcachemgr configuration information
3419 * and verifies that the profile is version 1 or version 2 based.
3420 * version 2 profiles must have a version number as the first profile
3421 * attribute in the configuration.
3422 */
3423 static ns_config_t *
SetDoorInfo(char * buffer,ns_ldap_error_t ** errorp)3424 SetDoorInfo(char *buffer, ns_ldap_error_t **errorp)
3425 {
3426 ns_config_t *ptr;
3427 char errstr[MAXERROR], errbuf[MAXERROR];
3428 char *name, *value, valbuf[BUFSIZE];
3429 char *strptr;
3430 char *rest;
3431 char *bufptr = buffer;
3432 ParamIndexType i;
3433 int ret;
3434 int first = 1;
3435 int errfnd = 0;
3436 ldap_config_out_t *cfghdr;
3437
3438 if (errorp == NULL)
3439 return (NULL);
3440 *errorp = NULL;
3441
3442 ptr = __s_api_create_config();
3443 if (ptr == NULL) {
3444 return (NULL);
3445 }
3446
3447 /* get config cookie from the header */
3448 cfghdr = (ldap_config_out_t *)bufptr;
3449 ptr->config_cookie = cfghdr->cookie;
3450 bufptr = (char *)cfghdr->config_str;
3451
3452 strptr = (char *)strtok_r(bufptr, DOORLINESEP, &rest);
3453 for (; ; ) {
3454 if (strptr == NULL)
3455 break;
3456 (void) strlcpy(valbuf, strptr, sizeof (valbuf));
3457 __s_api_split_key_value(valbuf, &name, &value);
3458 /* Use get_versiontype and check for V1 vs V2 prototypes */
3459 if (__s_api_get_versiontype(ptr, name, &i) < 0) {
3460 (void) snprintf(errstr, sizeof (errstr),
3461 "%s (%s)\n",
3462 gettext("Illegal profile entry "
3463 "line in configuration."),
3464 name);
3465 errfnd++;
3466 /* Write verify routines and get rid of verify_value here */
3467 } else if (verify_value(ptr, name,
3468 value, errbuf) != NS_SUCCESS) {
3469 (void) snprintf(errstr, sizeof (errstr),
3470 gettext("%s\n"), errbuf);
3471 errfnd++;
3472 } else if (!first && i == NS_LDAP_FILE_VERSION_P) {
3473 (void) snprintf(errstr, sizeof (errstr),
3474 gettext("Illegal NS_LDAP_FILE_VERSION "
3475 "line in configuration.\n"));
3476 errfnd++;
3477 }
3478 if (errfnd) {
3479 MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX,
3480 strdup(errstr), NULL);
3481 } else {
3482 ret = set_default_value(ptr, name, value, errorp);
3483 }
3484 if (errfnd || ret != NS_SUCCESS) {
3485 __s_api_destroy_config(ptr);
3486 return (NULL);
3487 }
3488 first = 0;
3489
3490 strptr = (char *)strtok_r(NULL, DOORLINESEP, &rest);
3491 }
3492
3493 if (__s_api_crosscheck(ptr, errstr, B_TRUE) != NS_SUCCESS) {
3494 __s_api_destroy_config(ptr);
3495 MKERROR(LOG_WARNING, *errorp, NS_CONFIG_SYNTAX, strdup(errstr),
3496 NULL);
3497 return (NULL);
3498 }
3499
3500 return (ptr);
3501 }
3502
3503 static ns_config_t *
LoadCacheConfiguration(ns_config_t * oldcfg,ns_ldap_error_t ** error)3504 LoadCacheConfiguration(ns_config_t *oldcfg, ns_ldap_error_t **error)
3505 {
3506 char *buffer = NULL;
3507 int buflen = 0;
3508 int ret;
3509 ns_config_t *cfg;
3510 ldap_config_out_t *cfghdr;
3511 ldap_get_chg_cookie_t old_cookie;
3512 ldap_get_chg_cookie_t new_cookie;
3513
3514 *error = NULL;
3515 ret = __door_getldapconfig(&buffer, &buflen, error);
3516
3517 if (ret != NS_LDAP_SUCCESS) {
3518 if (*error != NULL && (*error)->message != NULL)
3519 syslog(LOG_WARNING, "libsldap: %s", (*error)->message);
3520 return (NULL);
3521 }
3522
3523 /* No need to reload configuration if config cookie is the same */
3524 cfghdr = (ldap_config_out_t *)buffer;
3525 new_cookie = cfghdr->cookie;
3526 if (oldcfg != NULL)
3527 old_cookie = oldcfg->config_cookie;
3528
3529 if (oldcfg != NULL && old_cookie.mgr_pid == new_cookie.mgr_pid &&
3530 old_cookie.seq_num == new_cookie.seq_num) {
3531 free(buffer);
3532 return (oldcfg);
3533 }
3534
3535 /* now convert from door format */
3536 cfg = SetDoorInfo(buffer, error);
3537 free(buffer);
3538
3539 if (cfg == NULL && *error != NULL && (*error)->message != NULL)
3540 syslog(LOG_WARNING, "libsldap: %s", (*error)->message);
3541 return (cfg);
3542 }
3543
3544 /*
3545 * converts the time string into seconds. The time string can be specified
3546 * using one of the following time units:
3547 * #s (# of seconds)
3548 * #m (# of minutes)
3549 * #h (# of hours)
3550 * #d (# of days)
3551 * #w (# of weeks)
3552 * NOTE: you can only specify one the above. No combination of the above
3553 * units is allowed. If no unit specified, it will default to "seconds".
3554 */
3555 static time_t
conv_time(char * s)3556 conv_time(char *s)
3557 {
3558 time_t t;
3559 char c;
3560 int l, m;
3561 long tot;
3562
3563 l = strlen(s);
3564 if (l == 0)
3565 return (0);
3566 c = s[--l];
3567 m = 0;
3568 switch (c) {
3569 case 'w': /* weeks */
3570 m = 604800;
3571 break;
3572 case 'd': /* days */
3573 m = 86400;
3574 break;
3575 case 'h': /* hours */
3576 m = 3600;
3577 break;
3578 case 'm': /* minutes */
3579 m = 60;
3580 break;
3581 case 's': /* seconds */
3582 m = 1;
3583 break;
3584 /* the default case is set to "second" */
3585 }
3586 if (m != 0)
3587 s[l] = '\0';
3588 else
3589 m = 1;
3590 errno = 0;
3591 tot = atol(s);
3592 if ((0 == tot) && (EINVAL == errno))
3593 return (0);
3594 if (((LONG_MAX == tot) || (LONG_MIN == tot)) && (EINVAL == errno))
3595 return (0);
3596
3597 tot = tot * m;
3598 t = (time_t)tot;
3599 return (t);
3600 }
3601
3602
3603 ns_auth_t *
__s_api_AuthEnumtoStruct(const EnumAuthType_t i)3604 __s_api_AuthEnumtoStruct(const EnumAuthType_t i)
3605 {
3606 ns_auth_t *ap;
3607
3608 ap = (ns_auth_t *)calloc(1, sizeof (ns_auth_t));
3609 if (ap == NULL)
3610 return (NULL);
3611 switch (i) {
3612 case NS_LDAP_EA_NONE:
3613 break;
3614 case NS_LDAP_EA_SIMPLE:
3615 ap->type = NS_LDAP_AUTH_SIMPLE;
3616 break;
3617 case NS_LDAP_EA_SASL_CRAM_MD5:
3618 ap->type = NS_LDAP_AUTH_SASL;
3619 ap->saslmech = NS_LDAP_SASL_CRAM_MD5;
3620 break;
3621 case NS_LDAP_EA_SASL_DIGEST_MD5:
3622 ap->type = NS_LDAP_AUTH_SASL;
3623 ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
3624 break;
3625 case NS_LDAP_EA_SASL_DIGEST_MD5_INT:
3626 ap->type = NS_LDAP_AUTH_SASL;
3627 ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
3628 ap->saslopt = NS_LDAP_SASLOPT_INT;
3629 break;
3630 case NS_LDAP_EA_SASL_DIGEST_MD5_CONF:
3631 ap->type = NS_LDAP_AUTH_SASL;
3632 ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
3633 ap->saslopt = NS_LDAP_SASLOPT_PRIV;
3634 break;
3635 case NS_LDAP_EA_SASL_EXTERNAL:
3636 ap->type = NS_LDAP_AUTH_SASL;
3637 ap->saslmech = NS_LDAP_SASL_EXTERNAL;
3638 break;
3639 case NS_LDAP_EA_SASL_GSSAPI:
3640 ap->type = NS_LDAP_AUTH_SASL;
3641 ap->saslmech = NS_LDAP_SASL_GSSAPI;
3642 ap->saslopt = NS_LDAP_SASLOPT_INT |
3643 NS_LDAP_SASLOPT_PRIV;
3644 break;
3645 case NS_LDAP_EA_TLS_NONE:
3646 ap->type = NS_LDAP_AUTH_TLS;
3647 ap->tlstype = NS_LDAP_TLS_NONE;
3648 break;
3649 case NS_LDAP_EA_TLS_SIMPLE:
3650 ap->type = NS_LDAP_AUTH_TLS;
3651 ap->tlstype = NS_LDAP_TLS_SIMPLE;
3652 break;
3653 case NS_LDAP_EA_TLS_SASL_CRAM_MD5:
3654 ap->type = NS_LDAP_AUTH_TLS;
3655 ap->tlstype = NS_LDAP_TLS_SASL;
3656 ap->saslmech = NS_LDAP_SASL_CRAM_MD5;
3657 break;
3658 case NS_LDAP_EA_TLS_SASL_DIGEST_MD5:
3659 ap->type = NS_LDAP_AUTH_TLS;
3660 ap->tlstype = NS_LDAP_TLS_SASL;
3661 ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
3662 break;
3663 case NS_LDAP_EA_TLS_SASL_DIGEST_MD5_INT:
3664 ap->type = NS_LDAP_AUTH_TLS;
3665 ap->tlstype = NS_LDAP_TLS_SASL;
3666 ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
3667 ap->saslopt = NS_LDAP_SASLOPT_INT;
3668 break;
3669 case NS_LDAP_EA_TLS_SASL_DIGEST_MD5_CONF:
3670 ap->type = NS_LDAP_AUTH_TLS;
3671 ap->tlstype = NS_LDAP_TLS_SASL;
3672 ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
3673 ap->saslopt = NS_LDAP_SASLOPT_PRIV;
3674 break;
3675 case NS_LDAP_EA_TLS_SASL_EXTERNAL:
3676 ap->type = NS_LDAP_AUTH_TLS;
3677 ap->tlstype = NS_LDAP_TLS_SASL;
3678 ap->saslmech = NS_LDAP_SASL_EXTERNAL;
3679 break;
3680 default:
3681 /* should never get here */
3682 free(ap);
3683 return (NULL);
3684 }
3685 return (ap);
3686 }
3687
3688
3689 /*
3690 * Parameter Index Type validation routines
3691 */
3692
3693 /* Validate a positive integer */
3694 /* Size of errbuf needs to be MAXERROR */
3695 /* ARGSUSED */
3696 static int
__s_val_postime(ParamIndexType i,ns_default_config * def,ns_param_t * param,char * errbuf)3697 __s_val_postime(ParamIndexType i, ns_default_config *def,
3698 ns_param_t *param, char *errbuf)
3699 {
3700 char *cp;
3701 long tot;
3702
3703 if (param && param->ns_ptype == CHARPTR && param->ns_pc) {
3704 for (cp = param->ns_pc; cp && *cp; cp++) {
3705 if (*cp >= '0' && *cp <= '9')
3706 continue;
3707 switch (*cp) {
3708 case 'w': /* weeks */
3709 case 'd': /* days */
3710 case 'h': /* hours */
3711 case 'm': /* minutes */
3712 case 's': /* seconds */
3713 if (*(cp+1) == '\0') {
3714 break;
3715 }
3716 default:
3717 (void) strcpy(errbuf, "Illegal time value");
3718 return (NS_PARSE_ERR);
3719 }
3720 }
3721 /* Valid form: [0-9][0-9]*[wdhms]* */
3722 tot = atol(param->ns_pc); /* check overflow */
3723 if (tot >= 0)
3724 return (NS_SUCCESS);
3725 }
3726 (void) snprintf(errbuf, MAXERROR,
3727 gettext("Illegal time value in %s"), def->name);
3728 return (NS_PARSE_ERR);
3729 }
3730
3731
3732 /* Validate the Base DN */
3733 /* It can be empty (RootDSE request) or needs to have an '=' */
3734 /* Size of errbuf needs to be MAXERROR */
3735 /* ARGSUSED */
3736 static int
__s_val_basedn(ParamIndexType i,ns_default_config * def,ns_param_t * param,char * errbuf)3737 __s_val_basedn(ParamIndexType i, ns_default_config *def,
3738 ns_param_t *param, char *errbuf)
3739 {
3740 if (param && param->ns_ptype == CHARPTR &&
3741 i == NS_LDAP_SEARCH_BASEDN_P &&
3742 ((param->ns_pc == NULL) || /* empty */
3743 (*(param->ns_pc) == '\0') || /* empty */
3744 (strchr(param->ns_pc, '=') != NULL))) /* '=' */
3745 {
3746 return (NS_SUCCESS);
3747 }
3748 (void) snprintf(errbuf, MAXERROR,
3749 gettext("Non-existent or invalid DN in %s"),
3750 def->name);
3751 return (NS_PARSE_ERR);
3752 }
3753
3754
3755 /* Validate the serverList */
3756 /* For each server in list, check if valid IP or hostname */
3757 /* Size of errbuf needs to be MAXERROR */
3758 /* ARGSUSED */
3759 static int
__s_val_serverList(ParamIndexType i,ns_default_config * def,ns_param_t * param,char * errbuf)3760 __s_val_serverList(ParamIndexType i, ns_default_config *def,
3761 ns_param_t *param, char *errbuf)
3762 {
3763 for (i = 0; i < param->ns_acnt; i++) {
3764 if ((__s_api_isipv4(param->ns_ppc[i])) ||
3765 (__s_api_isipv6(param->ns_ppc[i])) ||
3766 (__s_api_ishost(param->ns_ppc[i]))) {
3767 continue;
3768 }
3769 /* err */
3770 (void) snprintf(errbuf, MAXERROR,
3771 gettext("Invalid server (%s) in %s"),
3772 param->ns_ppc[i], def->name);
3773 return (NS_PARSE_ERR);
3774 }
3775
3776 return (NS_SUCCESS);
3777 }
3778
3779
3780 /* Check for a BINDDN */
3781 /* It can not be empty and needs to have an '=' */
3782 /* Size of errbuf needs to be MAXERROR */
3783 /* ARGSUSED */
3784 static int
__s_val_binddn(ParamIndexType i,ns_default_config * def,ns_param_t * param,char * errbuf)3785 __s_val_binddn(ParamIndexType i, ns_default_config *def,
3786 ns_param_t *param, char *errbuf)
3787 {
3788 char *dntype;
3789
3790 if (param && param->ns_ptype == CHARPTR &&
3791 (i == NS_LDAP_BINDDN_P || i == NS_LDAP_ADMIN_BINDDN_P) &&
3792 ((param->ns_pc == NULL) ||
3793 ((*(param->ns_pc) != '\0') &&
3794 (strchr(param->ns_pc, '=') != NULL)))) {
3795 return (NS_SUCCESS);
3796 }
3797 if (i == NS_LDAP_BINDDN_P)
3798 dntype = "proxy";
3799 else
3800 dntype = "update";
3801 (void) snprintf(errbuf, MAXERROR,
3802 gettext("NULL or invalid %s bind DN"), dntype);
3803 return (NS_PARSE_ERR);
3804 }
3805
3806
3807 /* Check for a BINDPASSWD */
3808 /* The string can not be NULL or empty */
3809 /* Size of errbuf needs to be MAXERROR */
3810 /* ARGSUSED */
3811 static int
__s_val_bindpw(ParamIndexType i,ns_default_config * def,ns_param_t * param,char * errbuf)3812 __s_val_bindpw(ParamIndexType i, ns_default_config *def,
3813 ns_param_t *param, char *errbuf)
3814 {
3815 char *pwtype;
3816
3817 if (param && param->ns_ptype == CHARPTR &&
3818 (i == NS_LDAP_BINDPASSWD_P || i == NS_LDAP_ADMIN_BINDPASSWD_P) &&
3819 ((param->ns_pc == NULL) ||
3820 (*(param->ns_pc) != '\0'))) {
3821 return (NS_SUCCESS);
3822 }
3823 if (i == NS_LDAP_BINDPASSWD_P)
3824 pwtype = "proxy";
3825 else
3826 pwtype = "admin";
3827 (void) snprintf(errbuf, MAXERROR,
3828 gettext("NULL %s bind password"), pwtype);
3829 return (NS_PARSE_ERR);
3830 }
3831
3832 /*
3833 * __s_get_hostcertpath returns either the configured host certificate path
3834 * or, if none, the default host certificate path (/var/ldap). Note that this
3835 * does not use __ns_ldap_getParam because it may be called during connection
3836 * setup. This can fail due to insufficient memory.
3837 */
3838
3839 char *
__s_get_hostcertpath(void)3840 __s_get_hostcertpath(void)
3841 {
3842 ns_config_t *cfg;
3843 ns_param_t *param;
3844 char *ret = NULL;
3845
3846 cfg = __s_api_get_default_config();
3847 if (cfg != NULL) {
3848 param = &cfg->paramList[NS_LDAP_HOST_CERTPATH_P];
3849 if (param->ns_ptype == CHARPTR)
3850 ret = strdup(param->ns_pc);
3851 __s_api_release_config(cfg);
3852 }
3853 if (ret == NULL)
3854 ret = strdup(NSLDAPDIRECTORY);
3855 return (ret);
3856 }
3857
3858 static void
_free_config()3859 _free_config()
3860 {
3861 if (current_config != NULL)
3862 destroy_config(current_config);
3863
3864 current_config = NULL;
3865 }
3866