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