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