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