1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* libsldap - cachemgr side configuration components */ 29 30 #include <stdio.h> 31 #include <sys/types.h> 32 #include <stdlib.h> 33 #include <libintl.h> 34 #include <string.h> 35 #include <ctype.h> 36 37 #include <sys/stat.h> 38 #include <fcntl.h> 39 #include <unistd.h> 40 #include <syslog.h> 41 #include <locale.h> 42 #include <errno.h> 43 #include <sys/time.h> 44 45 #include "ns_sldap.h" 46 #include "ns_internal.h" 47 #include "ns_cache_door.h" 48 49 #define ALWAYS 1 50 51 52 /* 53 * ************************************************************** 54 * Configuration File Routines 55 * ************************************************************** 56 */ 57 58 59 /* Size of the errstr buffer needs to be MAXERROR */ 60 static int 61 read_line(FILE *fp, char *buffer, int buflen, char *errstr) 62 { 63 int linelen; 64 char c; 65 66 *errstr = '\0'; 67 68 for (linelen = 0; linelen < buflen; ) { 69 c = getc(fp); 70 if (c == EOF) 71 break; 72 switch (c) { 73 case '\n': 74 if (linelen > 0 && buffer[linelen - 1] == '\\') { 75 /* Continuation line found */ 76 --linelen; 77 } else { 78 /* end of line found */ 79 buffer[linelen] = '\0'; 80 return (linelen); 81 } 82 break; 83 default: 84 buffer[linelen++] = c; 85 } 86 } 87 88 if (linelen >= buflen) { 89 (void) snprintf(errstr, MAXERROR, 90 gettext("Buffer overflow, line too long.")); 91 return (-2); 92 } else if (linelen > 0 && buffer[linelen - 1] == '\\') { 93 (void) snprintf(errstr, MAXERROR, 94 gettext("Unterminated continuation line.")); 95 return (-2); 96 } else { 97 /* end of file */ 98 buffer[linelen] = '\0'; 99 } 100 return (linelen > 0 ? linelen : -1); 101 } 102 103 104 static ns_parse_status 105 read_file(ns_config_t *ptr, int cred_file, ns_ldap_error_t **error) 106 { 107 ParamIndexType i = 0; 108 char errstr[MAXERROR]; 109 char buffer[BUFSIZE], *name, *value; 110 int emptyfile, lineno; 111 FILE *fp; 112 int ret; 113 int linelen; 114 char *file; 115 int first = 1; 116 117 118 if (cred_file) { 119 file = NSCREDFILE; 120 } else { 121 file = NSCONFIGFILE; 122 } 123 fp = fopen(file, "rF"); 124 if (fp == NULL) { 125 (void) snprintf(errstr, sizeof (errstr), 126 gettext("Unable to open filename '%s' " 127 "for reading (errno=%d)."), file, errno); 128 MKERROR(LOG_ERR, *error, NS_CONFIG_FILE, strdup(errstr), NULL); 129 return (NS_NOTFOUND); 130 } 131 132 emptyfile = 1; 133 lineno = 0; 134 for (; ; ) { 135 if ((linelen = read_line(fp, buffer, sizeof (buffer), 136 errstr)) < 0) 137 /* End of file */ 138 break; 139 lineno++; 140 if (linelen == 0) 141 continue; 142 /* get rid of comment lines */ 143 if (buffer[0] == '#') 144 continue; 145 emptyfile = 0; 146 name = NULL; 147 value = NULL; 148 __s_api_split_key_value(buffer, &name, &value); 149 if (name == NULL || value == NULL) { 150 (void) snprintf(errstr, sizeof (errstr), 151 gettext("Missing Name or Value on line %d."), 152 lineno); 153 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, 154 strdup(errstr), NULL); 155 (void) fclose(fp); 156 return (NS_PARSE_ERR); 157 } 158 if (__s_api_get_versiontype(ptr, name, &i) != 0) { 159 (void) snprintf(errstr, sizeof (errstr), 160 gettext("Illegal profile type on line %d."), 161 lineno); 162 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, 163 strdup(errstr), NULL); 164 (void) fclose(fp); 165 return (NS_PARSE_ERR); 166 } 167 if (!first && i == NS_LDAP_FILE_VERSION_P) { 168 (void) snprintf(errstr, sizeof (errstr), 169 gettext("Illegal NS_LDAP_FILE_VERSION " 170 "on line %d."), lineno); 171 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, 172 strdup(errstr), NULL); 173 (void) fclose(fp); 174 return (NS_PARSE_ERR); 175 } 176 first = 0; 177 switch (__s_api_get_configtype(i)) { 178 case SERVERCONFIG: 179 case CLIENTCONFIG: 180 if (cred_file == 0) { 181 ret = __ns_ldap_setParamValue(ptr, i, value, 182 error); 183 if (ret != NS_SUCCESS) { 184 (void) fclose(fp); 185 return (ret); 186 } 187 } else if (i != NS_LDAP_FILE_VERSION_P) { 188 (void) snprintf(errstr, sizeof (errstr), 189 gettext("Illegal entry in '%s' on " 190 "line %d"), file, lineno); 191 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, 192 strdup(errstr), NULL); 193 (void) fclose(fp); 194 return (NS_PARSE_ERR); 195 } 196 break; 197 case CREDCONFIG: 198 if (i == NS_LDAP_FILE_VERSION_P) 199 break; 200 if (cred_file) { 201 ret = __ns_ldap_setParamValue(ptr, i, value, 202 error); 203 if (ret != NS_SUCCESS) { 204 (void) fclose(fp); 205 return (ret); 206 } 207 } else { 208 (void) snprintf(errstr, sizeof (errstr), 209 gettext("Illegal entry in '%s' on " 210 "line %d"), file, lineno); 211 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, 212 strdup(errstr), NULL); 213 (void) fclose(fp); 214 return (NS_PARSE_ERR); 215 } 216 } 217 } 218 (void) fclose(fp); 219 if (!cred_file && emptyfile) { 220 /* Error in read_line */ 221 (void) snprintf(errstr, sizeof (errstr), 222 gettext("Empty config file: '%s'"), file); 223 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, strdup(errstr), 224 NULL); 225 return (NS_PARSE_ERR); 226 } 227 if (linelen == -2) { 228 /* Error in read_line */ 229 (void) snprintf(errstr, sizeof (errstr), 230 gettext("Line too long in '%s'"), file); 231 MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, strdup(errstr), 232 NULL); 233 return (NS_PARSE_ERR); 234 } 235 return (NS_SUCCESS); 236 } 237 238 239 /* 240 * Cache Manager side of configuration file loading 241 */ 242 243 ns_ldap_error_t * 244 __ns_ldap_LoadConfiguration() 245 { 246 ns_ldap_error_t *error = NULL; 247 ns_config_t *ptr = NULL; 248 char errstr[MAXERROR]; 249 ns_parse_status ret; 250 251 252 ptr = __s_api_create_config(); 253 if (ptr == NULL) { 254 (void) snprintf(errstr, sizeof (errstr), 255 gettext("__ns_ldap_LoadConfiguration: Out of memory.")); 256 MKERROR(LOG_ERR, error, NS_CONFIG_NOTLOADED, 257 strdup(errstr), NULL); 258 return (error); 259 } 260 261 /* Load in Configuration file */ 262 ret = read_file(ptr, 0, &error); 263 if (ret != NS_SUCCESS) { 264 __s_api_destroy_config(ptr); 265 return (error); 266 } 267 268 /* Load in Credential file */ 269 ret = read_file(ptr, 1, &error); 270 if (ret != NS_SUCCESS) { 271 __s_api_destroy_config(ptr); 272 return (error); 273 } 274 275 if (__s_api_crosscheck(ptr, errstr, B_TRUE) != NS_SUCCESS) { 276 __s_api_destroy_config(ptr); 277 MKERROR(LOG_ERR, error, NS_CONFIG_SYNTAX, strdup(errstr), NULL); 278 return (error); 279 } 280 281 __s_api_init_config(ptr); 282 return (NULL); 283 } 284 285 286 static int 287 _print2buf(LineBuf *line, char *toprint, int addsep) 288 { 289 int newsz = 0; 290 int newmax = 0; 291 char *str; 292 293 if (line == NULL) 294 return (-1); 295 296 newsz = strlen(toprint) + line->len + 1; 297 if (addsep) { 298 newsz += strlen(DOORLINESEP); 299 } 300 if (line->alloc == 0 || newsz > line->alloc) { 301 /* Round up to next buffer and add 1 */ 302 newmax = (((newsz+(BUFSIZ-1))/BUFSIZ)+1) * BUFSIZ; 303 if (line->alloc == 0) 304 line->str = (char *)calloc(newmax, 1); 305 else { 306 /* 307 * if realloc() returns NULL, 308 * the original buffer is untouched. 309 * It needs to be freed. 310 */ 311 str = (char *)realloc(line->str, newmax); 312 if (str == NULL) { 313 free(line->str); 314 line->str = NULL; 315 } 316 else 317 line->str = str; 318 } 319 line->alloc = newmax; 320 if (line->str == NULL) { 321 line->alloc = 0; 322 line->len = 0; 323 return (-1); 324 } 325 } 326 /* now add new 'toprint' data to buffer */ 327 (void) strlcat(line->str, toprint, line->alloc); 328 if (addsep) { 329 (void) strlcat(line->str, DOORLINESEP, line->alloc); 330 } 331 line->len = newsz; 332 return (0); 333 } 334 335 336 /* 337 * __ns_ldap_LoadDoorInfo is a routine used by the ldapcachemgr 338 * to create a configuration buffer to transmit back to a client 339 * domainname is transmitted to ldapcachemgr and ldapcachemgr uses 340 * it to select a configuration to transmit back. Otherwise it 341 * is essentially unused in sldap. 342 */ 343 344 ns_ldap_error_t * 345 __ns_ldap_LoadDoorInfo(LineBuf *configinfo, char *domainname) 346 { 347 ns_config_t *ptr; 348 char errstr[MAXERROR]; 349 ns_ldap_error_t *errorp; 350 char string[BUFSIZE]; 351 char *str; 352 ParamIndexType i = 0; 353 354 ptr = __s_api_get_default_config(); 355 if (ptr == NULL) { 356 (void) snprintf(errstr, sizeof (errstr), 357 gettext("No configuration information available for %s."), 358 domainname == NULL ? "<no domain specified>" : domainname); 359 MKERROR(LOG_WARNING, errorp, NS_CONFIG_NOTLOADED, 360 strdup(errstr), NULL); 361 return (errorp); 362 } 363 (void) memset((char *)configinfo, 0, sizeof (LineBuf)); 364 for (i = 0; i <= NS_LDAP_MAX_PIT_P; i++) { 365 str = __s_api_strValue(ptr, string, sizeof (string), i, 366 NS_DOOR_FMT); 367 if (str == NULL) 368 continue; 369 if (_print2buf(configinfo, str, 1) != 0) { 370 (void) snprintf(errstr, sizeof (errstr), 371 gettext("_print2buf: Out of memory.")); 372 MKERROR(LOG_WARNING, errorp, NS_CONFIG_NOTLOADED, 373 strdup(errstr), NULL); 374 __s_api_release_config(ptr); 375 if (str != (char *)&string[0]) { 376 free(str); 377 str = NULL; 378 } 379 return (errorp); 380 } 381 if (str != (char *)&string[0]) { 382 free(str); 383 str = NULL; 384 } 385 } 386 __s_api_release_config(ptr); 387 return (NULL); 388 } 389 390 391 ns_ldap_error_t * 392 __ns_ldap_DumpLdif(char *filename) 393 { 394 ns_config_t *ptr; 395 char errstr[MAXERROR]; 396 ns_ldap_error_t *errorp; 397 char string[BUFSIZE]; 398 char *str; 399 FILE *fp; 400 ParamIndexType i = 0; 401 char *profile, *container, *base; 402 403 ptr = __s_api_get_default_config(); 404 if (ptr == NULL) { 405 (void) snprintf(errstr, sizeof (errstr), 406 gettext("No configuration information available.")); 407 MKERROR(LOG_ERR, errorp, NS_CONFIG_NOTLOADED, strdup(errstr), 408 NULL); 409 return (errorp); 410 } 411 412 if (filename == NULL) { 413 fp = stdout; 414 } else { 415 fp = fopen(filename, "wF"); 416 if (fp == NULL) { 417 (void) snprintf(errstr, sizeof (errstr), 418 gettext("Unable to open filename %s for ldif " 419 "dump (errno=%d)."), filename, errno); 420 MKERROR(LOG_WARNING, errorp, NS_CONFIG_FILE, 421 strdup(errstr), NULL); 422 __s_api_release_config(ptr); 423 return (errorp); 424 } 425 (void) fchmod(fileno(fp), 0444); 426 } 427 428 if (ptr->paramList[NS_LDAP_SEARCH_BASEDN_P].ns_ptype != CHARPTR || 429 ptr->paramList[NS_LDAP_PROFILE_P].ns_ptype != CHARPTR) { 430 (void) snprintf(errstr, sizeof (errstr), 431 gettext("Required BaseDN and/or Profile name " 432 "ldif fields not present")); 433 MKERROR(LOG_WARNING, errorp, NS_CONFIG_FILE, strdup(errstr), 434 NULL); 435 __s_api_release_config(ptr); 436 return (errorp); 437 } 438 439 profile = ptr->paramList[NS_LDAP_PROFILE_P].ns_pc; 440 base = ptr->paramList[NS_LDAP_SEARCH_BASEDN_P].ns_pc; 441 container = _PROFILE_CONTAINER; 442 443 /* 444 * Construct DN, but since this is the profile, there is no need 445 * to worry about mapping. The profile itself can not be mapped 446 */ 447 (void) fprintf(fp, "dn: cn=%s,ou=%s,%s\n", profile, container, base); 448 449 /* dump objectclass names */ 450 if (ptr->version == NS_LDAP_V1) { 451 (void) fprintf(fp, "ObjectClass: top\nObjectClass: %s\n", 452 _PROFILE1_OBJECTCLASS); 453 } else { 454 (void) fprintf(fp, "ObjectClass: top\nObjectClass: %s\n", 455 _PROFILE2_OBJECTCLASS); 456 } 457 458 /* For each parameter - construct value */ 459 for (i = 0; i <= NS_LDAP_MAX_PIT_P; i++) { 460 str = __s_api_strValue(ptr, string, BUFSIZ, i, NS_LDIF_FMT); 461 if (str == NULL) 462 continue; 463 /* 464 * don't dump binddn, bind password, or cert path as they 465 * are not part of version 2 profiles 466 */ 467 if ((i != NS_LDAP_BINDDN_P) && (i != NS_LDAP_BINDPASSWD_P) && 468 (i != NS_LDAP_HOST_CERTPATH_P)) 469 (void) fprintf(fp, "%s\n", str); 470 if (str != (char *)&string[0]) { 471 free(str); 472 str = NULL; 473 } 474 } 475 476 if (filename != NULL) 477 (void) fclose(fp); 478 479 __s_api_release_config(ptr); 480 return (NULL); 481 } 482 483 /* 484 * This routine can process the configuration and/or 485 * the credential files at the same time. 486 * files is char *[3] = { "config", "cred", NULL }; 487 */ 488 489 static 490 ns_ldap_error_t * 491 __ns_ldap_DumpConfigFiles(char **files) 492 { 493 char *filename; 494 int fi; 495 int docred; 496 ns_config_t *ptr; 497 char string[BUFSIZE]; 498 char *str; 499 char errstr[MAXERROR]; 500 ParamIndexType i = 0; 501 FILE *fp; 502 int rc; 503 ns_ldap_error_t *errorp = NULL; 504 struct stat buf; 505 int cfgtype; 506 boolean_t file_export_error = B_FALSE; 507 508 ptr = __s_api_get_default_config(); 509 if (ptr == NULL) { 510 (void) snprintf(errstr, sizeof (errstr), 511 gettext("No configuration information available.")); 512 MKERROR(LOG_ERR, errorp, NS_CONFIG_NOTLOADED, strdup(errstr), 513 NULL); 514 return (errorp); 515 } 516 517 for (fi = 0; fi < 2; fi++) { 518 docred = 0; 519 filename = files[fi]; 520 if (filename == NULL) 521 continue; 522 if (fi == 1) 523 docred++; 524 rc = stat(filename, &buf); 525 fp = fopen(filename, "wF"); 526 if (fp == NULL) { 527 (void) snprintf(errstr, sizeof (errstr), 528 gettext("Unable to open filename %s" 529 " for configuration dump (%s)."), 530 filename, strerror(errno)); 531 MKERROR(LOG_ERR, errorp, NS_CONFIG_FILE, 532 strdup(errstr), NULL); 533 __s_api_release_config(ptr); 534 return (errorp); 535 } 536 if (rc == 0) { 537 if (fchmod(fileno(fp), buf.st_mode) != 0) { 538 (void) snprintf(errstr, sizeof (errstr), 539 gettext("Unable to set permissions for file" 540 " %s for configuration dump (%s)."), 541 filename, strerror(errno)); 542 (void) fclose(fp); 543 file_export_error = B_TRUE; 544 break; 545 } 546 } else { 547 if (fchmod(fileno(fp), 0400) != 0) { 548 (void) snprintf(errstr, sizeof (errstr), 549 gettext("Unable to set permissions for file" 550 " %s for configuration dump (%s)."), 551 filename, strerror(errno)); 552 (void) fclose(fp); 553 file_export_error = B_TRUE; 554 break; 555 } 556 } 557 if (fprintf(fp, "#\n# %s\n#\n", DONOTEDIT) < 0) { 558 (void) snprintf(errstr, sizeof (errstr), gettext( 559 "Writing to file %s for configuration dump failed " 560 "(%s)."), filename, strerror(errno)); 561 file_export_error = B_TRUE; 562 } 563 564 /* assume VERSION is set and it outputs first */ 565 566 /* For each parameter - construct value */ 567 for (i = 0; !file_export_error && (i <= NS_LDAP_MAX_PIT_P); 568 i++) { 569 cfgtype = __s_api_get_configtype(i); 570 if ((docred == 0 && cfgtype == CREDCONFIG) || 571 (docred == 1 && cfgtype != CREDCONFIG)) 572 continue; 573 574 str = __s_api_strValue(ptr, string, BUFSIZ, i, 575 NS_FILE_FMT); 576 if (str == NULL) 577 continue; 578 if (fprintf(fp, "%s\n", str) < 0) { 579 (void) snprintf(errstr, sizeof (errstr), 580 gettext("Writing to file %s for" 581 "configuration dump failed (%s)."), 582 filename, strerror(errno)); 583 file_export_error = B_TRUE; 584 } 585 586 if (str != (char *)&string[0]) { 587 free(str); 588 str = NULL; 589 } 590 } 591 if (fclose(fp) != 0) { 592 /* Break if error already hit */ 593 if (file_export_error) 594 break; 595 596 (void) snprintf(errstr, sizeof (errstr), gettext( 597 "Writing to file %s for configuration dump failed " 598 "during file close (%s)."), filename, 599 strerror(errno)); 600 file_export_error = B_TRUE; 601 break; 602 } 603 604 } 605 606 if (file_export_error) { 607 MKERROR(LOG_ERR, errorp, NS_CONFIG_FILE, 608 strdup(errstr), NULL); 609 (void) unlink(filename); 610 } 611 612 __s_api_release_config(ptr); 613 return (errorp); 614 } 615 616 ns_ldap_error_t * 617 __ns_ldap_DumpConfiguration(char *file) 618 { 619 ns_ldap_error_t *ret; 620 char *files[3]; 621 622 files[0] = NULL; 623 files[1] = NULL; 624 files[2] = NULL; 625 if (strcmp(file, NSCONFIGFILE) == 0) { 626 files[0] = file; 627 } else if (strcmp(file, NSCONFIGREFRESH) == 0) { 628 files[0] = file; 629 } else if (strcmp(file, NSCREDFILE) == 0) { 630 files[1] = file; 631 } else if (strcmp(file, NSCREDREFRESH) == 0) { 632 files[1] = file; 633 } 634 ret = __ns_ldap_DumpConfigFiles(files); 635 return (ret); 636 } 637 638 /* 639 * ************************************************************** 640 * Misc Routines 641 * ************************************************************** 642 */ 643 644 ns_config_t * 645 __ns_ldap_make_config(ns_ldap_result_t *result) 646 { 647 int l, m; 648 char val[BUFSIZ]; 649 char *attrname; 650 ns_ldap_entry_t *entry; 651 ns_ldap_attr_t *attr; 652 char **attrval; 653 ParamIndexType index; 654 ns_config_t *ptr; 655 ns_ldap_error_t *error = NULL; 656 int firsttime; 657 int prof_ver; 658 ns_config_t *curr_ptr = NULL; 659 char errstr[MAXERROR]; 660 ns_ldap_error_t *errorp; 661 662 if (result == NULL) 663 return (NULL); 664 665 if (result->entries_count > 1) { 666 (void) snprintf(errstr, MAXERROR, 667 gettext("Configuration Error: More than one profile " 668 "found")); 669 MKERROR(LOG_ERR, errorp, NS_PARSE_ERR, strdup(errstr), NULL); 670 (void) __ns_ldap_freeError(&errorp); 671 return (NULL); 672 } 673 674 ptr = __s_api_create_config(); 675 if (ptr == NULL) 676 return (NULL); 677 678 curr_ptr = __s_api_get_default_config(); 679 if (curr_ptr == NULL) { 680 __s_api_destroy_config(ptr); 681 return (NULL); 682 } 683 684 /* Check to see if the profile is version 1 or version 2 */ 685 prof_ver = 1; 686 entry = result->entry; 687 for (l = 0; l < entry->attr_count; l++) { 688 attr = entry->attr_pair[l]; 689 690 attrname = attr->attrname; 691 if (attrname == NULL) 692 continue; 693 if (strcasecmp(attrname, "objectclass") == 0) { 694 for (m = 0; m < attr->value_count; m++) { 695 if (strcasecmp(_PROFILE2_OBJECTCLASS, 696 attr->attrvalue[m]) == 0) { 697 prof_ver = 2; 698 break; 699 } 700 } 701 } 702 } 703 /* update the configuration to accept v1 or v2 attributes */ 704 if (prof_ver == 1) { 705 (void) strcpy(val, NS_LDAP_VERSION_1); 706 (void) __ns_ldap_setParamValue(ptr, NS_LDAP_FILE_VERSION_P, 707 val, &error); 708 } else { 709 (void) strcpy(val, NS_LDAP_VERSION_2); 710 (void) __ns_ldap_setParamValue(ptr, NS_LDAP_FILE_VERSION_P, 711 val, &error); 712 } 713 714 for (l = 0; l < entry->attr_count; l++) { 715 attr = entry->attr_pair[l]; 716 717 attrname = attr->attrname; 718 if (attrname == NULL) 719 continue; 720 if (__s_api_get_profiletype(attrname, &index) != 0) 721 continue; 722 723 attrval = attr->attrvalue; 724 switch (index) { 725 case NS_LDAP_SEARCH_DN_P: 726 case NS_LDAP_SERVICE_SEARCH_DESC_P: 727 case NS_LDAP_ATTRIBUTEMAP_P: 728 case NS_LDAP_OBJECTCLASSMAP_P: 729 case NS_LDAP_SERVICE_CRED_LEVEL_P: 730 case NS_LDAP_SERVICE_AUTH_METHOD_P: 731 /* Multiple Value - insert 1 at a time */ 732 for (m = 0; m < attr->value_count; m++) { 733 (void) __ns_ldap_setParamValue(ptr, index, 734 attrval[m], &error); 735 } 736 break; 737 default: 738 firsttime = 1; 739 /* Single or Multiple Value */ 740 val[0] = '\0'; 741 for (m = 0; m < attr->value_count; m++) { 742 if (firsttime == 1) { 743 firsttime = 0; 744 (void) strlcpy(val, attrval[m], 745 sizeof (val)); 746 } else { 747 (void) strlcat(val, " ", sizeof (val)); 748 (void) strlcat(val, attrval[m], 749 sizeof (val)); 750 } 751 } 752 (void) __ns_ldap_setParamValue(ptr, index, val, &error); 753 754 break; 755 } 756 } 757 if (ptr->version != NS_LDAP_V1) { 758 if (curr_ptr->paramList[NS_LDAP_BINDDN_P].ns_ptype == CHARPTR) { 759 (void) __ns_ldap_setParamValue(ptr, NS_LDAP_BINDDN_P, 760 curr_ptr->paramList[NS_LDAP_BINDDN_P].ns_pc, 761 &error); 762 } 763 if (curr_ptr->paramList[NS_LDAP_BINDPASSWD_P].ns_ptype == 764 CHARPTR) { 765 (void) __ns_ldap_setParamValue(ptr, 766 NS_LDAP_BINDPASSWD_P, 767 curr_ptr->paramList[NS_LDAP_BINDPASSWD_P].ns_pc, 768 &error); 769 } 770 if (curr_ptr->paramList[NS_LDAP_HOST_CERTPATH_P].ns_ptype == 771 CHARPTR) { 772 (void) __ns_ldap_setParamValue(ptr, 773 NS_LDAP_HOST_CERTPATH_P, 774 curr_ptr->paramList[NS_LDAP_HOST_CERTPATH_P].ns_pc, 775 &error); 776 } 777 } 778 __s_api_release_config(curr_ptr); 779 return (ptr); 780 } 781 782 /* 783 * Download a profile into our internal structure. The calling application 784 * needs to DumpConfig() to save the information to NSCONFIGFILE and NSCREDFILE 785 * if desired. 786 */ 787 int 788 __ns_ldap_download(const char *profile, char *addr, char *baseDN, 789 ns_ldap_error_t **errorp) 790 { 791 char filter[BUFSIZ]; 792 int rc; 793 ns_ldap_result_t *result = NULL; 794 ns_config_t *ptr = NULL; 795 ns_config_t *new_ptr = NULL; 796 char errstr[MAXERROR]; 797 798 *errorp = NULL; 799 if (baseDN == NULL) 800 return (NS_LDAP_INVALID_PARAM); 801 802 ptr = __s_api_get_default_config(); 803 if (ptr == NULL) { 804 (void) snprintf(errstr, sizeof (errstr), 805 gettext("No configuration information available.")); 806 MKERROR(LOG_ERR, *errorp, NS_CONFIG_NOTLOADED, strdup(errstr), 807 NULL); 808 return (NS_LDAP_CONFIG); 809 } 810 811 rc = __ns_ldap_setParamValue(ptr, NS_LDAP_SEARCH_BASEDN_P, baseDN, 812 errorp); 813 if (rc != NS_LDAP_SUCCESS) { 814 __s_api_release_config(ptr); 815 return (rc); 816 } 817 818 rc = __ns_ldap_setParamValue(ptr, NS_LDAP_SERVERS_P, addr, errorp); 819 __s_api_release_config(ptr); 820 if (rc != NS_LDAP_SUCCESS) 821 return (rc); 822 823 (void) snprintf(filter, sizeof (filter), _PROFILE_FILTER, 824 _PROFILE1_OBJECTCLASS, _PROFILE2_OBJECTCLASS, profile); 825 rc = __ns_ldap_list(_PROFILE_CONTAINER, (const char *)filter, 826 NULL, NULL, NULL, 0, &result, errorp, NULL, NULL); 827 828 if (rc != NS_LDAP_SUCCESS) 829 return (rc); 830 831 new_ptr = __ns_ldap_make_config(result); 832 (void) __ns_ldap_freeResult(&result); 833 834 if (new_ptr == NULL) 835 return (NS_LDAP_OP_FAILED); 836 837 rc = __s_api_crosscheck(new_ptr, errstr, B_FALSE); 838 if (rc != NS_LDAP_SUCCESS) { 839 __s_api_destroy_config(new_ptr); 840 MKERROR(LOG_ERR, *errorp, NS_CONFIG_NOTLOADED, strdup(errstr), 841 NULL); 842 return (NS_LDAP_CONFIG); 843 } 844 845 __s_api_init_config(new_ptr); 846 return (rc); 847 } 848 849 /* 850 * ************************************************************** 851 * Configuration Printing Routines 852 * ************************************************************** 853 */ 854 855 /* 856 * Yes the use of stdio is okay here because all we are doing is sending 857 * output to stdout. This would not be necessary if we could get to the 858 * configuration pointer outside this file. 859 */ 860 ns_ldap_error_t * 861 __ns_ldap_print_config(int verbose) 862 { 863 ns_config_t *ptr; 864 char errstr[MAXERROR]; 865 ns_ldap_error_t *errorp; 866 char string[BUFSIZE]; 867 char *str; 868 int i; 869 870 ptr = __s_api_get_default_config(); 871 if (ptr == NULL) { 872 errorp = __ns_ldap_LoadConfiguration(); 873 if (errorp != NULL) 874 return (errorp); 875 ptr = __s_api_get_default_config(); 876 if (ptr == NULL) { 877 (void) snprintf(errstr, sizeof (errstr), 878 gettext("No configuration information.")); 879 MKERROR(LOG_WARNING, errorp, NS_CONFIG_NOTLOADED, 880 strdup(errstr), NULL); 881 return (errorp); 882 } 883 } 884 885 if (verbose && (ptr->domainName != NULL)) { 886 (void) fputs("ptr->domainName ", stdout); 887 (void) fputs(ptr->domainName, stdout); 888 (void) putchar('\n'); 889 } 890 /* For each parameter - construct value */ 891 for (i = 0; i <= NS_LDAP_MAX_PIT_P; i++) { 892 /* 893 * Version 1 skipped this entry because: 894 * 895 * don't print default cache TTL for now since 896 * we don't store it in the ldap_client_file. 897 */ 898 if ((i == NS_LDAP_CACHETTL_P) && (ptr->version == NS_LDAP_V1)) 899 continue; 900 901 str = __s_api_strValue(ptr, string, BUFSIZ, i, NS_FILE_FMT); 902 if (str == NULL) 903 continue; 904 if (verbose) 905 (void) putchar('\t'); 906 (void) fprintf(stdout, "%s\n", str); 907 if (str != (char *)&string[0]) { 908 free(str); 909 str = NULL; 910 } 911 } 912 913 __s_api_release_config(ptr); 914 return (NULL); 915 } 916