1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <stdio.h> 27 #include <sys/types.h> 28 #include <stdlib.h> 29 #include <libintl.h> 30 31 #include <sys/stat.h> 32 #include <fcntl.h> 33 #include <unistd.h> 34 #include <string.h> 35 #include <strings.h> 36 #include <lber.h> 37 #include <ldap.h> 38 #include <syslog.h> 39 #include <stddef.h> 40 #include <sys/mman.h> 41 42 #include "ns_sldap.h" 43 #include "ns_internal.h" 44 #include "ns_connmgmt.h" 45 #include "ns_cache_door.h" 46 47 /* Additional headers for addTypedEntry Conversion routines */ 48 #include <pwd.h> 49 #include <project.h> 50 #include <shadow.h> 51 #include <grp.h> 52 #include <netinet/in.h> 53 #include <arpa/inet.h> 54 #include <netdb.h> 55 #include <rpc/rpcent.h> 56 #include <auth_attr.h> 57 #include <exec_attr.h> 58 #include <prof_attr.h> 59 #include <user_attr.h> 60 #include <bsm/libbsm.h> 61 #include <sys/tsol/tndb.h> 62 #include <tsol/label.h> 63 64 static int send_to_cachemgr(const char *, 65 ns_ldap_attr_t **, ns_ldap_error_t **); 66 /* 67 * If the rdn is a mapped attr: 68 * return NS_LDAP_SUCCESS and a new_dn. 69 * If no mapped attr is found in the rdn: 70 * return NS_LDAP_SUCCESS and *new_dn == NULL 71 * For example: 72 * service = abc 73 * dn = cn=foo,dc=bar,dc=com 74 * attributeMapping: abc:cn=sn 75 * Then: 76 * new_dn = sn=foo,dc=bar,dc=com 77 * 78 */ 79 static int 80 replace_mapped_attr_in_dn( 81 const char *service, const char *dn, char **new_dn) 82 { 83 char **mappedattr; 84 char **dnArray = NULL; 85 char *rservice; 86 char *cur = NULL; 87 int len = 0, orig_len = 0, mapped_len = 0; 88 int dn_len = 0; 89 90 *new_dn = NULL; 91 92 /* 93 * separate dn into individual componets 94 * e.g. 95 * "automountKey=user_01" , "automountMapName_test=auto_home", ... 96 */ 97 dnArray = ldap_explode_dn(dn, 0); 98 if (!dnArray || !*dnArray) 99 return (NS_LDAP_INVALID_PARAM); 100 101 cur = strchr(dnArray[0], '='); 102 if (!cur) { 103 __s_api_free2dArray(dnArray); 104 return (NS_LDAP_INVALID_PARAM); 105 } 106 *cur = '\0'; 107 108 /* we only check schema mapping for automount, not for auto_* */ 109 if (strncasecmp(service, NS_LDAP_TYPE_AUTOMOUNT, 110 sizeof (NS_LDAP_TYPE_AUTOMOUNT) - 1) == 0) 111 rservice = "automount"; 112 else 113 rservice = (char *)service; 114 115 mappedattr = __ns_ldap_getMappedAttributes(rservice, dnArray[0]); 116 if (!mappedattr || !mappedattr[0]) { 117 __s_api_free2dArray(dnArray); 118 if (mappedattr) 119 __s_api_free2dArray(mappedattr); 120 return (NS_LDAP_SUCCESS); 121 } 122 orig_len = strlen(dnArray[0]); 123 124 /* 125 * The new length is *dn length + (difference between 126 * orig attr and mapped attr) + 1 ; 127 * e.g. 128 * automountKey=aa,automountMapName=auto_home,dc=foo,dc=com 129 * ==> 130 * cn=aa,automountMapName=auto_home,dc=foo,dc=com 131 */ 132 mapped_len = strlen(mappedattr[0]); 133 dn_len = strlen(dn); 134 len = dn_len - orig_len + mapped_len + 1; 135 *new_dn = (char *)calloc(1, len); 136 if (*new_dn == NULL) { 137 __s_api_free2dArray(dnArray); 138 __s_api_free2dArray(mappedattr); 139 return (NS_LDAP_MEMORY); 140 } 141 142 (void) snprintf(*new_dn, len, "%s=%s", mappedattr[0], dn + orig_len +1); 143 __s_api_free2dArray(dnArray); 144 __s_api_free2dArray(mappedattr); 145 146 return (NS_LDAP_SUCCESS); 147 } 148 149 150 /* 151 * The following function is only used by the 152 * "gecos" 1 to N attribute mapping code. It expects 153 * and handle only one data/length pair. 154 */ 155 static int 156 init_bval_mod( 157 LDAPMod *mod, 158 int mop, 159 char *mtype, 160 char *mvptr, 161 int mvlen) 162 { 163 164 struct berval **bmodval; 165 166 /* dup attribute name */ 167 mod->mod_type = strdup(mtype); 168 if (mod->mod_type == NULL) 169 return (-1); 170 171 /* 172 * assume single value, 173 * since only one value/length pair passed in 174 */ 175 bmodval = (struct berval **)calloc(2, sizeof (struct berval *)); 176 if (bmodval == NULL) { 177 free(mod->mod_type); 178 mod->mod_type = NULL; 179 return (-1); 180 } 181 bmodval[0] = (struct berval *)calloc(1, sizeof (struct berval)); 182 if (bmodval[0] == NULL) { 183 free(mod->mod_type); 184 mod->mod_type = NULL; 185 free(bmodval); 186 return (-1); 187 } 188 189 /* set pointer to data */ 190 bmodval[0]->bv_val = mvptr; 191 192 /* set length */ 193 bmodval[0]->bv_len = mvlen; 194 195 /* 196 * turn on the BVALUE bit to indicate 197 * that the length of data is supplied 198 */ 199 mod->mod_op = mop | LDAP_MOD_BVALUES; 200 201 mod->mod_bvalues = bmodval; 202 203 return (0); 204 } 205 206 static void 207 freeModList(LDAPMod **mods) 208 { 209 int i, j; 210 int name_is_oc; 211 212 if (mods == NULL) 213 return; 214 215 for (i = 0; mods[i]; i++) { 216 217 /* free attribute name */ 218 name_is_oc = FALSE; 219 if (mods[i]->mod_type) { 220 if (strcasecmp(mods[i]->mod_type, "objectclass") == 0) 221 name_is_oc = TRUE; 222 free(mods[i]->mod_type); 223 } 224 225 if (mods[i]->mod_bvalues == NULL) 226 continue; 227 /* 228 * LDAP_MOD_BVALUES is only set by 229 * the "gecos" 1 to N attribute mapping 230 * code, and the attribute is single valued. 231 */ 232 if (mods[i]->mod_op & LDAP_MOD_BVALUES) { 233 if (mods[i]->mod_bvalues[0]) 234 free(mods[i]->mod_bvalues[0]); 235 } else { 236 if (name_is_oc) { 237 /* 238 * only values for the "objectclass" 239 * were dupped using strdup. 240 * other attribute values were 241 * not dupped, but via pointer 242 * assignment. So here the 243 * values for "objectclass" 244 * is freed one by one, 245 * but the values for other 246 * attributes need not be freed. 247 */ 248 for (j = 0; mods[i]->mod_values[j]; j++) 249 free(mods[i]->mod_values[j]); 250 } 251 252 } 253 free(mods[i]->mod_bvalues); 254 } 255 256 /* modlist */ 257 free((char *)(mods[0])); 258 free(mods); 259 } 260 261 static LDAPMod ** 262 __s_api_makeModListCount( 263 const char *service, 264 const ns_ldap_attr_t * const *attr, 265 const int mod_op, 266 const int count, 267 const int flags) 268 { 269 LDAPMod **mods, *modlist; 270 char **modval; 271 char **mapping; 272 int i; 273 int j; 274 int k, rc, vlen; 275 char *c, *comma1 = NULL, *comma2 = NULL; 276 int schema_mapping_existed = FALSE; 277 int auto_service = FALSE; 278 279 280 /* 281 * add 2 for "gecos" 1 to up to 3 attribute mapping 282 */ 283 mods = (LDAPMod **)calloc((count + 3), sizeof (LDAPMod *)); 284 if (mods == NULL) { 285 return (NULL); 286 } 287 /* 288 * add 2 for "gecos" 1 to up to 3 attribute mapping 289 */ 290 modlist = (LDAPMod *)calloc(count + 2, sizeof (LDAPMod)); 291 if (modlist == NULL) { 292 free(mods); 293 return (NULL); 294 } 295 296 if (service != NULL && strncasecmp(service, NS_LDAP_TYPE_AUTOMOUNT, 297 sizeof (NS_LDAP_TYPE_AUTOMOUNT) - 1) == 0) 298 auto_service = TRUE; 299 300 /* 301 * see if schema mapping existed for the given service 302 */ 303 mapping = __ns_ldap_getOrigAttribute(service, 304 NS_HASH_SCHEMA_MAPPING_EXISTED); 305 if (mapping) { 306 schema_mapping_existed = TRUE; 307 __s_api_free2dArray(mapping); 308 mapping = NULL; 309 } 310 311 for (i = 0, k = 0; k < count && attr[k] != NULL; i++, k++) { 312 mods[i] = &modlist[i]; 313 mods[i]->mod_op = mod_op; 314 /* 315 * Perform attribute mapping if necessary. 316 */ 317 if (schema_mapping_existed && (flags & NS_LDAP_NOMAP) == 0) { 318 mapping = __ns_ldap_getMappedAttributes(service, 319 attr[k]->attrname); 320 } else 321 mapping = NULL; 322 323 if (mapping == NULL && auto_service && 324 (flags & NS_LDAP_NOMAP) == 0) { 325 /* 326 * if service == auto_xxx and 327 * no mapped attribute is found 328 * and NS_LDAP_NOMAP is not set 329 * then try automount's mapped attribute 330 */ 331 mapping = __ns_ldap_getMappedAttributes("automount", 332 attr[k]->attrname); 333 } 334 335 if (mapping == NULL) { 336 mods[i]->mod_type = strdup(attr[k]->attrname); 337 if (mods[i]->mod_type == NULL) 338 goto free_memory; 339 } else { 340 /* 341 * 1 to N attribute mapping is only done for "gecos", 342 * and only 1 to 3 mapping. 343 * nine cases here: 344 * 345 * A. attrMap=passwd:gecos=a 346 * 1. gecos="xx,yy,zz" -> a="xx,yy,zz" 347 * 2. gecos="xx,yy" -> a="xx,yy" 348 * 3. gecos="xx" -> a="xx" 349 * 350 * B. attrMap=passwd:gecos=a b 351 * 4. gecos="xx,yy,zz" -> a="xx" b="yy,zz" 352 * 5. gecos="xx,yy" -> a="xx" b="yy" 353 * 6. gecos="xx" -> a="xx" 354 * 355 * C. attrMap=passwd:gecos=a b c 356 * 7. gecos="xx,yy,zz" -> a="xx" b="yy" c="zz" 357 * 8. gecos="xx,yy" -> a="xx" b="yy" 358 * 9. gecos="xx" -> a="xx" 359 * 360 * This can be grouped as: 361 * 362 * c1 cases: 1,2,3,6,9 363 * if ((attrMap=passwd:gecos=a) || 364 * (no "," in gecos value)) 365 * same as other no-mapping attributes, 366 * no special processing needed 367 * else 368 * 369 * c2 cases: 4,5,8 370 * if ((attrMap=passwd:gecos=a b) || 371 * (only one "," in gecos value)) 372 * a=xx b=yy[,...] 373 * else 374 * 375 * c3 case: 7 376 * a=xx b=yy c=... 377 * 378 * notes: in case c2 and c3, ... could still contain "," 379 */ 380 if (strcasecmp(service, "passwd") == 0 && 381 strcasecmp(attr[k]->attrname, "gecos") == 0 && 382 mapping[1] && attr[k]->attrvalue[0] && 383 (comma1 = strchr(attr[k]->attrvalue[0], 384 COMMATOK)) != NULL) { 385 386 /* is there a second comma? */ 387 if (*(comma1 + 1) != '\0') 388 comma2 = strchr(comma1 + 1, COMMATOK); 389 390 /* 391 * Process case c2 or c3. 392 * case c2: mapped to two attributes or just 393 * one comma 394 */ 395 if (mapping[2] == NULL || comma2 == NULL) { 396 /* case c2 */ 397 398 /* 399 * int mod structure for the first attribute 400 */ 401 vlen = comma1 - attr[k]->attrvalue[0]; 402 c = attr[k]->attrvalue[0]; 403 404 if (vlen > 0 && c) { 405 rc = init_bval_mod(mods[i], mod_op, 406 mapping[0], c, vlen); 407 if (rc != 0) 408 goto free_memory; 409 } else { 410 /* don't leave a hole in mods array */ 411 mods[i] = NULL; 412 i--; 413 } 414 415 416 /* 417 * init mod structure for the 2nd attribute 418 */ 419 if (*(comma1 + 1) == '\0') { 420 __s_api_free2dArray(mapping); 421 mapping = NULL; 422 continue; 423 } 424 425 i++; 426 mods[i] = &modlist[i]; 427 428 /* 429 * get pointer to data. 430 * Skip leading spaces. 431 */ 432 for (c = comma1 + 1; *c == SPACETOK; c++) { 433 /* empty */ 434 } 435 436 /* get data length */ 437 vlen = strlen(attr[k]->attrvalue[0]) - 438 (c - attr[k]->attrvalue[0]); 439 440 if (vlen > 0 && c) { 441 rc = init_bval_mod(mods[i], mod_op, 442 mapping[1], c, vlen); 443 if (rc != 0) 444 goto free_memory; 445 } else { 446 /* don't leave a hole in mods array */ 447 mods[i] = NULL; 448 i--; 449 } 450 451 /* done with the mapping array */ 452 __s_api_free2dArray(mapping); 453 mapping = NULL; 454 455 continue; 456 } else { 457 /* case c3 */ 458 459 /* 460 * int mod structure for the first attribute 461 */ 462 vlen = comma1 - attr[k]->attrvalue[0]; 463 c = attr[k]->attrvalue[0]; 464 465 if (vlen > 0 && c) { 466 rc = init_bval_mod(mods[i], mod_op, 467 mapping[0], c, vlen); 468 if (rc != 0) 469 goto free_memory; 470 } else { 471 /* don't leave a hole in mods array */ 472 mods[i] = NULL; 473 i--; 474 } 475 476 /* 477 * init mod structure for the 2nd attribute 478 */ 479 i++; 480 mods[i] = &modlist[i]; 481 482 /* 483 * get pointer to data. 484 * Skip leading spaces. 485 */ 486 for (c = comma1 + 1; *c == SPACETOK; c++) { 487 /* empty */ 488 }; 489 490 /* get data length */ 491 vlen = comma2 - c; 492 493 if (vlen > 0 && c) { 494 rc = init_bval_mod(mods[i], mod_op, 495 mapping[1], c, vlen); 496 if (rc != 0) 497 goto free_memory; 498 } else { 499 /* don't leave a hole in mods array */ 500 mods[i] = NULL; 501 i--; 502 } 503 504 /* 505 * init mod structure for the 3rd attribute 506 */ 507 if (*(comma2 + 1) == '\0') { 508 __s_api_free2dArray(mapping); 509 mapping = NULL; 510 continue; 511 } 512 513 i++; 514 mods[i] = &modlist[i]; 515 /* 516 * get pointer to data. 517 * Skip leading spaces. 518 */ 519 for (c = comma2 + 1; *c == SPACETOK; c++) { 520 /* empty */ 521 } 522 523 /* get data length */ 524 vlen = strlen(attr[k]->attrvalue[0]) - 525 (c - attr[k]->attrvalue[0]); 526 527 if (vlen > 0 && c) { 528 rc = init_bval_mod(mods[i], mod_op, 529 mapping[2], c, vlen); 530 if (rc != 0) 531 goto free_memory; 532 } else { 533 /* don't leave a hole in mods array */ 534 mods[i] = NULL; 535 i--; 536 } 537 538 /* done with the mapping array */ 539 __s_api_free2dArray(mapping); 540 mapping = NULL; 541 542 continue; 543 } 544 } 545 546 /* case c1 */ 547 mods[i]->mod_type = strdup(mapping[0]); 548 if (mods[i]->mod_type == NULL) { 549 goto free_memory; 550 } 551 __s_api_free2dArray(mapping); 552 mapping = NULL; 553 } 554 555 modval = (char **)calloc(attr[k]->value_count+1, 556 sizeof (char *)); 557 if (modval == NULL) 558 goto free_memory; 559 /* 560 * Perform objectclass mapping. 561 * Note that the values for the "objectclass" attribute 562 * will be dupped using strdup. Values for other 563 * attributes will be referenced via pointer 564 * assignments. 565 */ 566 if (strcasecmp(mods[i]->mod_type, "objectclass") == 0) { 567 for (j = 0; j < attr[k]->value_count; j++) { 568 if (schema_mapping_existed && 569 (flags & NS_LDAP_NOMAP) == 0) 570 mapping = 571 __ns_ldap_getMappedObjectClass( 572 service, attr[k]->attrvalue[j]); 573 else 574 mapping = NULL; 575 576 if (mapping == NULL && auto_service && 577 (flags & NS_LDAP_NOMAP) == 0) 578 /* 579 * if service == auto_xxx and 580 * no mapped objectclass is found 581 * then try automount 582 */ 583 mapping = 584 __ns_ldap_getMappedObjectClass( 585 "automount", attr[k]->attrvalue[j]); 586 587 if (mapping && mapping[0]) { 588 /* assume single mapping */ 589 modval[j] = strdup(mapping[0]); 590 } else { 591 modval[j] = strdup(attr[k]-> 592 attrvalue[j]); 593 } 594 if (modval[j] == NULL) 595 goto free_memory; 596 } 597 } else { 598 for (j = 0; j < attr[k]->value_count; j++) { 599 /* ASSIGN NOT COPY */ 600 modval[j] = attr[k]->attrvalue[j]; 601 } 602 } 603 mods[i]->mod_values = modval; 604 } 605 606 return (mods); 607 608 free_memory: 609 freeModList(mods); 610 if (mapping) 611 __s_api_free2dArray(mapping); 612 613 return (NULL); 614 615 } 616 617 static LDAPMod ** 618 __s_api_makeModList( 619 const char *service, 620 const ns_ldap_attr_t * const *attr, 621 const int mod_op, 622 const int flags) 623 { 624 ns_ldap_attr_t **aptr = (ns_ldap_attr_t **)attr; 625 int count = 0; 626 627 if (aptr == NULL) 628 return (NULL); 629 630 /* count number of attributes */ 631 while (*aptr++) 632 count++; 633 634 return (__s_api_makeModListCount(service, attr, mod_op, count, flags)); 635 } 636 637 static void 638 __s_cvt_freeEntryRdn(ns_ldap_entry_t **entry, char **rdn) 639 { 640 if (*entry != NULL) { 641 __ns_ldap_freeEntry(*entry); 642 *entry = NULL; 643 } 644 if (*rdn != NULL) { 645 free(*rdn); 646 *rdn = NULL; 647 } 648 } 649 650 /* 651 * This state machine performs one or more LDAP add/delete/modify 652 * operations to configured LDAP servers. 653 */ 654 static int 655 write_state_machine( 656 int ldap_op, 657 char *dn, 658 LDAPMod **mods, 659 const ns_cred_t *cred, 660 const int flags, 661 ns_ldap_error_t ** errorp) 662 { 663 ConnectionID connectionId = -1; 664 Connection *conp = NULL; 665 LDAPMessage *res; 666 char *target_dn = NULL; 667 char errstr[MAXERROR]; 668 int rc = NS_LDAP_SUCCESS; 669 int return_rc = NS_LDAP_SUCCESS; 670 int followRef = FALSE; 671 int target_dn_allocated = FALSE; 672 int len; 673 int msgid; 674 int Errno; 675 int always = 1; 676 char *err, *errmsg = NULL; 677 /* referrals returned by the LDAP operation */ 678 char **referrals = NULL; 679 /* 680 * list of referrals used by the state machine, built from 681 * the referrals variable above 682 */ 683 ns_referral_info_t *ref_list = NULL; 684 /* current referral */ 685 ns_referral_info_t *current_ref = NULL; 686 ns_write_state_t state = W_INIT, new_state, err_state = W_INIT; 687 int do_not_fail_if_new_pwd_reqd = 0; 688 ns_ldap_passwd_status_t pwd_status = NS_PASSWD_GOOD; 689 int passwd_mgmt = 0; 690 int i = 0; 691 int ldap_error; 692 int nopasswd_acct_mgmt = 0; 693 ns_conn_user_t *conn_user = NULL; 694 695 while (always) { 696 switch (state) { 697 case W_EXIT: 698 /* return the MT connection and free the conn user */ 699 if (conn_user != NULL) { 700 if (conn_user->use_mt_conn == B_TRUE) { 701 if (conn_user->ns_error != NULL) { 702 *errorp = conn_user->ns_error; 703 conn_user->ns_error = NULL; 704 return_rc = conn_user->ns_rc; 705 } 706 if (conn_user->conn_mt != NULL) 707 __s_api_conn_mt_return( 708 conn_user); 709 } 710 __s_api_conn_user_free(conn_user); 711 } 712 713 if (connectionId > -1) 714 DropConnection(connectionId, NS_LDAP_NEW_CONN); 715 if (ref_list) 716 __s_api_deleteRefInfo(ref_list); 717 if (target_dn && target_dn_allocated) 718 free(target_dn); 719 return (return_rc); 720 case W_INIT: 721 /* see if need to follow referrals */ 722 rc = __s_api_toFollowReferrals(flags, 723 &followRef, errorp); 724 if (rc != NS_LDAP_SUCCESS) { 725 return_rc = rc; 726 new_state = W_ERROR; 727 break; 728 } 729 len = strlen(dn); 730 if (dn[len-1] == COMMATOK) 731 rc = __s_api_append_default_basedn( 732 dn, &target_dn, &target_dn_allocated, 733 errorp); 734 else 735 target_dn = dn; 736 if (rc != NS_LDAP_SUCCESS) { 737 return_rc = rc; 738 new_state = W_ERROR; 739 } 740 else 741 new_state = GET_CONNECTION; 742 break; 743 case GET_CONNECTION: 744 /* identify self as a write user */ 745 conn_user = __s_api_conn_user_init(NS_CONN_USER_WRITE, 746 NULL, B_FALSE); 747 rc = __s_api_getConnection(NULL, 748 flags, cred, &connectionId, &conp, errorp, 749 do_not_fail_if_new_pwd_reqd, nopasswd_acct_mgmt, 750 conn_user); 751 752 /* 753 * If password control attached 754 * in *errorp, 755 * e.g. rc == NS_LDAP_SUCCESS_WITH_INFO, 756 * free the error structure (we do not need 757 * the password management info). 758 * Reset rc to NS_LDAP_SUCCESS. 759 */ 760 if (rc == NS_LDAP_SUCCESS_WITH_INFO) { 761 (void) __ns_ldap_freeError(errorp); 762 *errorp = NULL; 763 rc = NS_LDAP_SUCCESS; 764 } 765 766 if (rc != NS_LDAP_SUCCESS) { 767 return_rc = rc; 768 new_state = W_ERROR; 769 break; 770 } 771 if (followRef) 772 new_state = SELECT_OPERATION_ASYNC; 773 else 774 new_state = SELECT_OPERATION_SYNC; 775 break; 776 case SELECT_OPERATION_SYNC: 777 if (ldap_op == LDAP_REQ_ADD) 778 new_state = DO_ADD_SYNC; 779 else if (ldap_op == LDAP_REQ_DELETE) 780 new_state = DO_DELETE_SYNC; 781 else if (ldap_op == LDAP_REQ_MODIFY) 782 new_state = DO_MODIFY_SYNC; 783 break; 784 case SELECT_OPERATION_ASYNC: 785 if (ldap_op == LDAP_REQ_ADD) 786 new_state = DO_ADD_ASYNC; 787 else if (ldap_op == LDAP_REQ_DELETE) 788 new_state = DO_DELETE_ASYNC; 789 else if (ldap_op == LDAP_REQ_MODIFY) 790 new_state = DO_MODIFY_ASYNC; 791 break; 792 case DO_ADD_SYNC: 793 rc = ldap_add_ext_s(conp->ld, target_dn, 794 mods, NULL, NULL); 795 new_state = GET_RESULT_SYNC; 796 break; 797 case DO_DELETE_SYNC: 798 rc = ldap_delete_ext_s(conp->ld, target_dn, 799 NULL, NULL); 800 new_state = GET_RESULT_SYNC; 801 break; 802 case DO_MODIFY_SYNC: 803 rc = ldap_modify_ext_s(conp->ld, target_dn, 804 mods, NULL, NULL); 805 new_state = GET_RESULT_SYNC; 806 break; 807 case DO_ADD_ASYNC: 808 rc = ldap_add_ext(conp->ld, target_dn, 809 mods, NULL, NULL, &msgid); 810 new_state = GET_RESULT_ASYNC; 811 break; 812 case DO_DELETE_ASYNC: 813 rc = ldap_delete_ext(conp->ld, target_dn, 814 NULL, NULL, &msgid); 815 new_state = GET_RESULT_ASYNC; 816 break; 817 case DO_MODIFY_ASYNC: 818 rc = ldap_modify_ext(conp->ld, target_dn, 819 mods, NULL, NULL, &msgid); 820 new_state = GET_RESULT_ASYNC; 821 break; 822 case GET_RESULT_SYNC: 823 if (rc != LDAP_SUCCESS) { 824 Errno = rc; 825 (void) ldap_get_lderrno(conp->ld, 826 NULL, &errmsg); 827 /* 828 * free errmsg if it is an empty string 829 */ 830 if (errmsg && *errmsg == '\0') { 831 ldap_memfree(errmsg); 832 errmsg = NULL; 833 } 834 new_state = W_LDAP_ERROR; 835 } else { 836 return_rc = NS_LDAP_SUCCESS; 837 new_state = W_EXIT; 838 } 839 break; 840 case GET_RESULT_ASYNC: 841 rc = ldap_result(conp->ld, msgid, 1, 842 (struct timeval *)NULL, &res); 843 /* if no server response, set Errno */ 844 if (rc == -1) { 845 (void) ldap_get_option(conp->ld, 846 LDAP_OPT_ERROR_NUMBER, &Errno); 847 new_state = W_LDAP_ERROR; 848 break; 849 } 850 if (rc == LDAP_RES_ADD || rc == LDAP_RES_MODIFY || 851 rc == LDAP_RES_DELETE) { 852 new_state = PARSE_RESULT; 853 break; 854 } else { 855 return_rc = rc; 856 new_state = W_ERROR; 857 } 858 break; 859 case PARSE_RESULT: 860 /* 861 * need Errno, referrals, error msg, 862 * and the last "1" is to free 863 * the result (res) 864 */ 865 rc = ldap_parse_result(conp->ld, res, &Errno, 866 NULL, &errmsg, &referrals, NULL, 1); 867 /* 868 * free errmsg if it is an empty string 869 */ 870 if (errmsg && *errmsg == '\0') { 871 ldap_memfree(errmsg); 872 errmsg = NULL; 873 } 874 /* 875 * If we received referral data, process 876 * it if: 877 * - we are configured to follow referrals 878 * - and not already in referral mode (to keep 879 * consistency with search_state_machine() 880 * which follows 1 level of referrals only; 881 * see proc_result_referrals() and 882 * proc_search_references(). 883 */ 884 if (Errno == LDAP_REFERRAL && followRef && !ref_list) { 885 for (i = 0; referrals[i] != NULL; i++) { 886 /* add to referral list */ 887 rc = __s_api_addRefInfo(&ref_list, 888 referrals[i], NULL, NULL, NULL, 889 conp->ld); 890 if (rc != NS_LDAP_SUCCESS) { 891 __s_api_deleteRefInfo(ref_list); 892 ref_list = NULL; 893 break; 894 } 895 } 896 ldap_value_free(referrals); 897 if (ref_list == NULL) { 898 if (rc != NS_LDAP_MEMORY) 899 rc = NS_LDAP_INTERNAL; 900 return_rc = rc; 901 new_state = W_ERROR; 902 } else { 903 new_state = GET_REFERRAL_CONNECTION; 904 current_ref = ref_list; 905 } 906 if (errmsg) { 907 ldap_memfree(errmsg); 908 errmsg = NULL; 909 } 910 break; 911 } 912 if (Errno != LDAP_SUCCESS) { 913 new_state = W_LDAP_ERROR; 914 } else { 915 return_rc = NS_LDAP_SUCCESS; 916 new_state = W_EXIT; 917 } 918 break; 919 case GET_REFERRAL_CONNECTION: 920 /* 921 * since we are starting over, 922 * discard the old error info 923 */ 924 return_rc = NS_LDAP_SUCCESS; 925 if (*errorp) 926 (void) __ns_ldap_freeError(errorp); 927 if (connectionId > -1) 928 DropConnection(connectionId, NS_LDAP_NEW_CONN); 929 930 /* set it up to use a referral connection */ 931 if (conn_user != NULL) { 932 /* 933 * If an MT connection is being used, 934 * return it to the pool. 935 */ 936 if (conn_user->conn_mt != NULL) 937 __s_api_conn_mt_return(conn_user); 938 939 conn_user->referral = B_TRUE; 940 } 941 rc = __s_api_getConnection(current_ref->refHost, 942 0, cred, &connectionId, &conp, errorp, 943 do_not_fail_if_new_pwd_reqd, 944 nopasswd_acct_mgmt, conn_user); 945 946 /* 947 * If password control attached 948 * in errorp, 949 * e.g. rc == NS_LDAP_SUCCESS_WITH_INFO, 950 * free the error structure (we do not need 951 * the password management info). 952 * Reset rc to NS_LDAP_SUCCESS. 953 */ 954 if (rc == NS_LDAP_SUCCESS_WITH_INFO) { 955 (void) __ns_ldap_freeError(errorp); 956 *errorp = NULL; 957 rc = NS_LDAP_SUCCESS; 958 } 959 960 if (rc != NS_LDAP_SUCCESS) { 961 return_rc = rc; 962 /* 963 * If current referral is not 964 * available for some reason, 965 * try next referral in the list. 966 * Get LDAP error code from errorp. 967 */ 968 if (*errorp != NULL) { 969 ns_write_state_t get_ref = 970 GET_REFERRAL_CONNECTION; 971 972 ldap_error = (*errorp)->status; 973 if (ldap_error == LDAP_BUSY || 974 ldap_error == LDAP_UNAVAILABLE || 975 ldap_error == 976 LDAP_UNWILLING_TO_PERFORM || 977 ldap_error == LDAP_CONNECT_ERROR || 978 ldap_error == LDAP_SERVER_DOWN) { 979 current_ref = current_ref->next; 980 if (current_ref == NULL) { 981 /* no more referral to follow */ 982 new_state = W_ERROR; 983 } else 984 new_state = get_ref; 985 /* 986 * free errorp before going to 987 * next referral 988 */ 989 (void) __ns_ldap_freeError( 990 errorp); 991 *errorp = NULL; 992 break; 993 } 994 /* 995 * free errorp before going to W_ERROR 996 */ 997 (void) __ns_ldap_freeError(errorp); 998 *errorp = NULL; 999 } 1000 /* else, exit */ 1001 __s_api_deleteRefInfo(ref_list); 1002 ref_list = NULL; 1003 new_state = W_ERROR; 1004 if (conn_user != NULL) 1005 conn_user->referral = B_FALSE; 1006 break; 1007 } 1008 /* target DN may changed due to referrals */ 1009 if (current_ref->refDN) { 1010 if (target_dn && target_dn_allocated) { 1011 free(target_dn); 1012 target_dn = NULL; 1013 target_dn_allocated = FALSE; 1014 } 1015 target_dn = current_ref->refDN; 1016 } 1017 new_state = SELECT_OPERATION_SYNC; 1018 break; 1019 case W_LDAP_ERROR: 1020 /* 1021 * map error code and error message 1022 * to password status if necessary. 1023 * This is to see if password updates 1024 * failed due to password policy or 1025 * password syntax checking. 1026 */ 1027 if (errmsg) { 1028 /* 1029 * check if server supports 1030 * password management 1031 */ 1032 passwd_mgmt = 1033 __s_api_contain_passwd_control_oid( 1034 conp->controls); 1035 if (passwd_mgmt) 1036 pwd_status = 1037 __s_api_set_passwd_status( 1038 Errno, errmsg); 1039 ldap_memfree(errmsg); 1040 errmsg = NULL; 1041 } 1042 1043 (void) snprintf(errstr, sizeof (errstr), 1044 "%s", ldap_err2string(Errno)); 1045 err = strdup(errstr); 1046 if (pwd_status != NS_PASSWD_GOOD) { 1047 MKERROR_PWD_MGMT(*errorp, Errno, err, 1048 pwd_status, 0, NULL); 1049 } else { 1050 MKERROR(LOG_INFO, *errorp, Errno, err, NULL); 1051 } 1052 if (conn_user != NULL && 1053 (Errno == LDAP_SERVER_DOWN || 1054 Errno == LDAP_CONNECT_ERROR)) { 1055 __s_api_conn_mt_close(conn_user, Errno, errorp); 1056 } 1057 return_rc = NS_LDAP_INTERNAL; 1058 new_state = W_EXIT; 1059 break; 1060 case W_ERROR: 1061 default: 1062 (void) sprintf(errstr, 1063 gettext("Internal write State machine exit" 1064 " (state = %d, rc = %d)."), 1065 err_state, return_rc); 1066 err = strdup(errstr); 1067 MKERROR(LOG_WARNING, *errorp, return_rc, err, NULL); 1068 new_state = W_EXIT; 1069 break; 1070 } 1071 1072 if (new_state == W_ERROR) 1073 err_state = state; 1074 1075 if (conn_user != NULL && conn_user->bad_mt_conn == B_TRUE) { 1076 __s_api_conn_mt_close(conn_user, 0, NULL); 1077 new_state = W_EXIT; 1078 } 1079 1080 state = new_state; 1081 } 1082 1083 /* 1084 * should never be here, the next line is to eliminating 1085 * lint message 1086 */ 1087 return (NS_LDAP_INTERNAL); 1088 } 1089 1090 1091 /*ARGSUSED*/ 1092 int 1093 __ns_ldap_addAttr( 1094 const char *service, 1095 const char *dn, 1096 const ns_ldap_attr_t * const *attr, 1097 const ns_cred_t *cred, 1098 const int flags, 1099 ns_ldap_error_t ** errorp) 1100 { 1101 LDAPMod **mods; 1102 int rc = 0; 1103 1104 #ifdef DEBUG 1105 (void) fprintf(stderr, "__ns_ldap_addAttr START\n"); 1106 #endif 1107 *errorp = NULL; 1108 1109 /* Sanity check */ 1110 if ((attr == NULL) || (*attr == NULL) || 1111 (dn == NULL) || (cred == NULL)) 1112 return (NS_LDAP_INVALID_PARAM); 1113 1114 mods = __s_api_makeModList(service, attr, LDAP_MOD_ADD, flags); 1115 if (mods == NULL) { 1116 return (NS_LDAP_MEMORY); 1117 } 1118 1119 rc = write_state_machine(LDAP_REQ_MODIFY, 1120 (char *)dn, mods, cred, flags, errorp); 1121 freeModList(mods); 1122 1123 return (rc); 1124 } 1125 1126 1127 /*ARGSUSED*/ 1128 int 1129 __ns_ldap_delAttr( 1130 const char *service, 1131 const char *dn, 1132 const ns_ldap_attr_t * const *attr, 1133 const ns_cred_t *cred, 1134 const int flags, 1135 ns_ldap_error_t ** errorp) 1136 { 1137 LDAPMod **mods; 1138 int rc = 0; 1139 1140 #ifdef DEBUG 1141 (void) fprintf(stderr, "__ns_ldap_delAttr START\n"); 1142 #endif 1143 *errorp = NULL; 1144 1145 /* Sanity check */ 1146 if ((attr == NULL) || (*attr == NULL) || 1147 (dn == NULL) || (cred == NULL)) 1148 return (NS_LDAP_INVALID_PARAM); 1149 1150 mods = __s_api_makeModList(service, attr, LDAP_MOD_DELETE, flags); 1151 if (mods == NULL) { 1152 return (NS_LDAP_MEMORY); 1153 } 1154 1155 rc = write_state_machine(LDAP_REQ_MODIFY, 1156 (char *)dn, mods, cred, flags, errorp); 1157 1158 freeModList(mods); 1159 return (rc); 1160 } 1161 1162 /* Retrieve the admin bind password from the configuration, if allowed. */ 1163 static int 1164 get_admin_passwd(ns_cred_t *cred, ns_ldap_error_t **errorp) 1165 { 1166 void **paramVal = NULL; 1167 int rc, ldaprc; 1168 char *modparamVal = NULL; 1169 1170 /* 1171 * For GSSAPI/Kerberos, host credential is used, no need to get 1172 * admin bind password 1173 */ 1174 if (cred->auth.saslmech == NS_LDAP_SASL_GSSAPI) 1175 return (NS_LDAP_SUCCESS); 1176 1177 /* 1178 * Retrieve admin bind password. 1179 * The admin bind password is available 1180 * only in the ldap_cachemgr process as 1181 * they are not exposed outside of that 1182 * process. 1183 */ 1184 paramVal = NULL; 1185 if ((ldaprc = __ns_ldap_getParam(NS_LDAP_ADMIN_BINDPASSWD_P, 1186 ¶mVal, errorp)) != NS_LDAP_SUCCESS) 1187 return (ldaprc); 1188 if (paramVal == NULL || *paramVal == NULL) { 1189 rc = NS_LDAP_CONFIG; 1190 *errorp = __s_api_make_error(NS_CONFIG_NODEFAULT, 1191 gettext("Admin bind password not configured")); 1192 if (*errorp == NULL) 1193 rc = NS_LDAP_MEMORY; 1194 return (rc); 1195 } 1196 modparamVal = dvalue((char *)*paramVal); 1197 (void) memset(*paramVal, 0, strlen((char *)*paramVal)); 1198 (void) __ns_ldap_freeParam(¶mVal); 1199 if (modparamVal == NULL || *((char *)modparamVal) == '\0') { 1200 if (modparamVal != NULL) 1201 free(modparamVal); 1202 rc = NS_LDAP_CONFIG; 1203 *errorp = __s_api_make_error(NS_CONFIG_SYNTAX, 1204 gettext("bind password not valid")); 1205 if (*errorp == NULL) 1206 rc = NS_LDAP_MEMORY; 1207 return (rc); 1208 } 1209 1210 cred->cred.unix_cred.passwd = modparamVal; 1211 return (NS_LDAP_SUCCESS); 1212 } 1213 1214 boolean_t 1215 __ns_ldap_is_shadow_update_enabled() { 1216 1217 int **enable_shadow = NULL; 1218 1219 if (__ns_ldap_getParam(NS_LDAP_ENABLE_SHADOW_UPDATE_P, 1220 (void ***)&enable_shadow, NULL) != NS_LDAP_SUCCESS) { 1221 return (B_FALSE); 1222 } 1223 if ((enable_shadow != NULL && *enable_shadow != NULL) && 1224 (*enable_shadow[0] == NS_LDAP_ENABLE_SHADOW_UPDATE_TRUE)) { 1225 (void) __ns_ldap_freeParam((void ***)&enable_shadow); 1226 return (B_TRUE); 1227 } 1228 if (enable_shadow != NULL) 1229 (void) __ns_ldap_freeParam((void ***)&enable_shadow); 1230 return (B_FALSE); 1231 } 1232 1233 /* 1234 * __ns_ldap_repAttr modifies ldap attributes of the 'dn' entry stored 1235 * on the LDAP server. 'service' indicates the type of database entries 1236 * to modify. When the Native LDAP client is configured with 'shadow update 1237 * enabled', Shadowshadow(4) entries can only be modified by privileged users. 1238 * Such users use the NS_LDAP_UPDATE_SHADOW flag to indicate the call is 1239 * for such a shadow(4) update, which would be forwarded to ldap_cachemgr 1240 * for performing the LDAP modify operation. ldap_cachemgr would call 1241 * this function again and use the special service NS_ADMIN_SHADOW_UPDATE 1242 * to identify itself, so that admin credential would be obtained and 1243 * the actual LDAP modify operation be done. 1244 */ 1245 /*ARGSUSED*/ 1246 int 1247 __ns_ldap_repAttr( 1248 const char *service, 1249 const char *dn, 1250 const ns_ldap_attr_t * const *attr, 1251 const ns_cred_t *cred, 1252 const int flags, 1253 ns_ldap_error_t ** errorp) 1254 { 1255 LDAPMod **mods; 1256 int rc = 0; 1257 boolean_t priv; 1258 boolean_t shadow_update_enabled = B_FALSE; 1259 1260 #ifdef DEBUG 1261 (void) fprintf(stderr, "__ns_ldap_repAttr START\n"); 1262 #endif 1263 *errorp = NULL; 1264 1265 /* Sanity check */ 1266 if (attr == NULL || *attr == NULL || dn == NULL) 1267 return (NS_LDAP_INVALID_PARAM); 1268 1269 /* Privileged shadow modify? */ 1270 if ((flags & NS_LDAP_UPDATE_SHADOW) != 0 && 1271 strcmp(service, "shadow") == 0) { 1272 1273 /* Shadow update enabled ? If not, error out */ 1274 shadow_update_enabled = __ns_ldap_is_shadow_update_enabled(); 1275 if (!shadow_update_enabled) { 1276 *errorp = __s_api_make_error(NS_CONFIG_NOTALLOW, 1277 gettext("Shadow Update is not enabled")); 1278 return (NS_LDAP_CONFIG); 1279 } 1280 1281 /* privileged shadow modify requires euid 0 or all zone privs */ 1282 priv = (geteuid() == 0); 1283 if (!priv) { 1284 priv_set_t *ps = priv_allocset(); /* caller */ 1285 priv_set_t *zs; /* zone */ 1286 1287 (void) getppriv(PRIV_EFFECTIVE, ps); 1288 zs = priv_str_to_set("zone", ",", NULL); 1289 priv = priv_isequalset(ps, zs); 1290 priv_freeset(ps); 1291 priv_freeset(zs); 1292 } 1293 if (!priv) 1294 return (NS_LDAP_OP_FAILED); 1295 1296 rc = send_to_cachemgr(dn, (ns_ldap_attr_t **)attr, errorp); 1297 return (rc); 1298 } 1299 1300 if (cred == NULL) 1301 return (NS_LDAP_INVALID_PARAM); 1302 1303 /* 1304 * If service is NS_ADMIN_SHADOW_UPDATE, the caller should be 1305 * ldap_cachemgr. We need to get the admin cred to do work. 1306 * If the caller is not ldap_cachemgr, but use the service 1307 * NS_ADMIN_SHADOW_UPDATE, get_admin_passwd() will fail, 1308 * as the admin cred is not available to the caller. 1309 */ 1310 if (strcmp(service, NS_ADMIN_SHADOW_UPDATE) == 0) { 1311 if ((rc = get_admin_passwd((ns_cred_t *)cred, errorp)) != 1312 NS_LDAP_SUCCESS) 1313 return (rc); 1314 } 1315 1316 mods = __s_api_makeModList(service, attr, LDAP_MOD_REPLACE, flags); 1317 if (mods == NULL) 1318 return (NS_LDAP_MEMORY); 1319 1320 rc = write_state_machine(LDAP_REQ_MODIFY, 1321 (char *)dn, mods, cred, flags, errorp); 1322 1323 freeModList(mods); 1324 return (rc); 1325 } 1326 1327 /*ARGSUSED*/ 1328 int 1329 __ns_ldap_addEntry( 1330 const char *service, 1331 const char *dn, 1332 const ns_ldap_entry_t *entry, 1333 const ns_cred_t *cred, 1334 const int flags, 1335 ns_ldap_error_t ** errorp) 1336 { 1337 char *new_dn = NULL; 1338 LDAPMod **mods = NULL; 1339 const ns_ldap_attr_t * const *attr; 1340 int nAttr = 0; 1341 int rc = 0; 1342 1343 #ifdef DEBUG 1344 (void) fprintf(stderr, "__ns_ldap_addEntry START\n"); 1345 #endif 1346 1347 if ((entry == NULL) || (dn == NULL) || (cred == NULL)) 1348 return (NS_LDAP_INVALID_PARAM); 1349 *errorp = NULL; 1350 1351 /* Construct array of LDAPMod representing attributes of new entry. */ 1352 1353 nAttr = entry->attr_count; 1354 attr = (const ns_ldap_attr_t * const *)(entry->attr_pair); 1355 mods = __s_api_makeModListCount(service, attr, LDAP_MOD_ADD, 1356 nAttr, flags); 1357 if (mods == NULL) { 1358 return (NS_LDAP_MEMORY); 1359 } 1360 1361 rc = replace_mapped_attr_in_dn(service, dn, &new_dn); 1362 if (rc != NS_LDAP_SUCCESS) { 1363 freeModList(mods); 1364 return (rc); 1365 } 1366 1367 rc = write_state_machine(LDAP_REQ_ADD, 1368 new_dn ? new_dn : (char *)dn, mods, cred, flags, errorp); 1369 1370 if (new_dn) 1371 free(new_dn); 1372 freeModList(mods); 1373 return (rc); 1374 } 1375 1376 1377 /*ARGSUSED*/ 1378 int 1379 __ns_ldap_delEntry( 1380 const char *service, 1381 const char *dn, 1382 const ns_cred_t *cred, 1383 const int flags, 1384 ns_ldap_error_t ** errorp) 1385 { 1386 int rc; 1387 1388 #ifdef DEBUG 1389 (void) fprintf(stderr, "__ns_ldap_delEntry START\n"); 1390 #endif 1391 if ((dn == NULL) || (cred == NULL)) 1392 return (NS_LDAP_INVALID_PARAM); 1393 1394 *errorp = NULL; 1395 1396 rc = write_state_machine(LDAP_REQ_DELETE, 1397 (char *)dn, NULL, cred, flags, errorp); 1398 1399 return (rc); 1400 } 1401 1402 /* 1403 * Add Typed Entry Helper routines 1404 */ 1405 1406 /* 1407 * Add Typed Entry Conversion routines 1408 */ 1409 1410 static int 1411 __s_add_attr(ns_ldap_entry_t *e, char *attrname, char *value) 1412 { 1413 ns_ldap_attr_t *a; 1414 char *v; 1415 1416 a = (ns_ldap_attr_t *)calloc(1, sizeof (ns_ldap_attr_t)); 1417 if (a == NULL) 1418 return (NS_LDAP_MEMORY); 1419 a->attrname = strdup(attrname); 1420 if (a->attrname == NULL) 1421 return (NS_LDAP_MEMORY); 1422 a->attrvalue = (char **)calloc(1, sizeof (char **)); 1423 if (a->attrvalue == NULL) 1424 return (NS_LDAP_MEMORY); 1425 a->value_count = 1; 1426 a->attrvalue[0] = NULL; 1427 v = strdup(value); 1428 if (v == NULL) 1429 return (NS_LDAP_MEMORY); 1430 a->attrvalue[0] = v; 1431 e->attr_pair[e->attr_count] = a; 1432 e->attr_count++; 1433 return (NS_LDAP_SUCCESS); 1434 } 1435 1436 static int 1437 __s_add_attrlist(ns_ldap_entry_t *e, char *attrname, char **argv) 1438 { 1439 ns_ldap_attr_t *a; 1440 char *v; 1441 char **av; 1442 int i, j; 1443 1444 a = (ns_ldap_attr_t *)calloc(1, sizeof (ns_ldap_attr_t)); 1445 if (a == NULL) 1446 return (NS_LDAP_MEMORY); 1447 a->attrname = strdup(attrname); 1448 if (a->attrname == NULL) 1449 return (NS_LDAP_MEMORY); 1450 1451 for (i = 0, av = argv; *av != NULL; av++, i++) 1452 ; 1453 1454 a->attrvalue = (char **)calloc(i, sizeof (char *)); 1455 1456 if (a->attrvalue == NULL) 1457 return (NS_LDAP_MEMORY); 1458 1459 a->value_count = i; 1460 for (j = 0; j < i; j++) { 1461 v = strdup(argv[j]); 1462 if (v == NULL) 1463 return (NS_LDAP_MEMORY); 1464 a->attrvalue[j] = v; 1465 } 1466 e->attr_pair[e->attr_count] = a; 1467 e->attr_count++; 1468 return (NS_LDAP_SUCCESS); 1469 } 1470 1471 static ns_ldap_entry_t * 1472 __s_mk_entry(char **objclass, int max_attr) 1473 { 1474 ns_ldap_entry_t *e; 1475 e = (ns_ldap_entry_t *)calloc(1, sizeof (ns_ldap_entry_t)); 1476 if (e == NULL) 1477 return (NULL); 1478 /* allocate attributes, +1 for objectclass, +1 for NULL terminator */ 1479 e->attr_pair = (ns_ldap_attr_t **) 1480 calloc(max_attr + 2, sizeof (ns_ldap_attr_t *)); 1481 if (e->attr_pair == NULL) { 1482 free(e); 1483 return (NULL); 1484 } 1485 e->attr_count = 0; 1486 if (__s_add_attrlist(e, "objectClass", objclass) != NS_LDAP_SUCCESS) { 1487 free(e->attr_pair); 1488 free(e); 1489 return (NULL); 1490 } 1491 return (e); 1492 } 1493 1494 1495 /* 1496 * Conversion: passwd 1497 * Input format: struct passwd 1498 * Exported objectclass: posixAccount 1499 */ 1500 static int 1501 __s_cvt_passwd(const void *data, char **rdn, 1502 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 1503 { 1504 ns_ldap_entry_t *e; 1505 int rc; 1506 char trdn[RDNSIZE]; 1507 /* routine specific */ 1508 struct passwd *ptr; 1509 int max_attr = 9; 1510 char ibuf[10]; 1511 static char *oclist[] = { 1512 "posixAccount", 1513 "shadowAccount", 1514 "account", 1515 "top", 1516 NULL 1517 }; 1518 1519 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 1520 return (NS_LDAP_OP_FAILED); 1521 *entry = e = __s_mk_entry(oclist, max_attr); 1522 if (e == NULL) 1523 return (NS_LDAP_MEMORY); 1524 1525 /* Convert the structure */ 1526 ptr = (struct passwd *)data; 1527 1528 if (ptr->pw_name == NULL || ptr->pw_uid > MAXUID || 1529 ptr->pw_gid > MAXUID || ptr->pw_dir == NULL) { 1530 __ns_ldap_freeEntry(e); 1531 *entry = NULL; 1532 return (NS_LDAP_INVALID_PARAM); 1533 } 1534 1535 /* Create an appropriate rdn */ 1536 (void) snprintf(trdn, RDNSIZE, "uid=%s", ptr->pw_name); 1537 *rdn = strdup(trdn); 1538 if (*rdn == NULL) { 1539 __ns_ldap_freeEntry(e); 1540 *entry = NULL; 1541 return (NS_LDAP_MEMORY); 1542 } 1543 1544 /* Error check the data and add the attributes */ 1545 rc = __s_add_attr(e, "uid", ptr->pw_name); 1546 if (rc != NS_LDAP_SUCCESS) { 1547 __s_cvt_freeEntryRdn(entry, rdn); 1548 return (rc); 1549 } 1550 rc = __s_add_attr(e, "cn", ptr->pw_name); 1551 if (rc != NS_LDAP_SUCCESS) { 1552 __s_cvt_freeEntryRdn(entry, rdn); 1553 return (rc); 1554 } 1555 1556 if (ptr->pw_passwd != NULL && 1557 ptr->pw_passwd[0] != '\0') { 1558 rc = __s_add_attr(e, "userPassword", ptr->pw_passwd); 1559 if (rc != NS_LDAP_SUCCESS) { 1560 __s_cvt_freeEntryRdn(entry, rdn); 1561 return (rc); 1562 } 1563 } 1564 1565 (void) sprintf(ibuf, "%u", ptr->pw_uid); 1566 rc = __s_add_attr(e, "uidNumber", ibuf); 1567 if (rc != NS_LDAP_SUCCESS) { 1568 __s_cvt_freeEntryRdn(entry, rdn); 1569 return (rc); 1570 } 1571 1572 (void) sprintf(ibuf, "%u", ptr->pw_gid); 1573 rc = __s_add_attr(e, "gidNumber", ibuf); 1574 if (rc != NS_LDAP_SUCCESS) { 1575 __s_cvt_freeEntryRdn(entry, rdn); 1576 return (rc); 1577 } 1578 if (ptr->pw_gecos != NULL && 1579 ptr->pw_gecos[0] != '\0') { 1580 rc = __s_add_attr(e, "gecos", ptr->pw_gecos); 1581 if (rc != NS_LDAP_SUCCESS) { 1582 __s_cvt_freeEntryRdn(entry, rdn); 1583 return (rc); 1584 } 1585 } 1586 1587 rc = __s_add_attr(e, "homeDirectory", ptr->pw_dir); 1588 if (rc != NS_LDAP_SUCCESS) { 1589 __s_cvt_freeEntryRdn(entry, rdn); 1590 return (rc); 1591 } 1592 if (ptr->pw_shell != NULL && 1593 ptr->pw_shell[0] != '\0') { 1594 rc = __s_add_attr(e, "loginShell", ptr->pw_shell); 1595 if (rc != NS_LDAP_SUCCESS) { 1596 __s_cvt_freeEntryRdn(entry, rdn); 1597 return (rc); 1598 } 1599 } 1600 1601 return (NS_LDAP_SUCCESS); 1602 } 1603 1604 /* 1605 * Conversion: project 1606 * Input format: struct project 1607 * Exported objectclass: SolarisProject 1608 */ 1609 static int 1610 __s_cvt_project(const void *data, char **rdn, 1611 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 1612 { 1613 ns_ldap_entry_t *e; 1614 int rc; 1615 char trdn[RDNSIZE]; 1616 1617 /* routine specific */ 1618 struct project *ptr; 1619 int max_attr = 9; 1620 char ibuf[11]; 1621 static char *oclist[] = { 1622 "SolarisProject", 1623 "top", 1624 NULL 1625 }; 1626 1627 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 1628 return (NS_LDAP_OP_FAILED); 1629 1630 *entry = e = __s_mk_entry(oclist, max_attr); 1631 if (e == NULL) 1632 return (NS_LDAP_MEMORY); 1633 1634 /* Convert the structure */ 1635 ptr = (struct project *)data; 1636 1637 if (ptr->pj_name == NULL || ptr->pj_projid > MAXUID) { 1638 __ns_ldap_freeEntry(e); 1639 *entry = NULL; 1640 return (NS_LDAP_INVALID_PARAM); 1641 } 1642 1643 /* Create an appropriate rdn */ 1644 (void) snprintf(trdn, RDNSIZE, "SolarisProjectName=%s", ptr->pj_name); 1645 *rdn = strdup(trdn); 1646 if (*rdn == NULL) { 1647 __ns_ldap_freeEntry(e); 1648 *entry = NULL; 1649 return (NS_LDAP_MEMORY); 1650 } 1651 1652 /* Error check the data and add the attributes */ 1653 1654 /* Project name */ 1655 rc = __s_add_attr(e, "SolarisProjectName", ptr->pj_name); 1656 if (rc != NS_LDAP_SUCCESS) { 1657 __s_cvt_freeEntryRdn(entry, rdn); 1658 return (rc); 1659 } 1660 1661 /* 1662 * Project ID: 1663 * ibuf is 11 chars big, which should be enough for string 1664 * representation of 32bit number + nul-car 1665 */ 1666 if (snprintf(ibuf, sizeof (ibuf), "%u", ptr->pj_projid) < 0) { 1667 __s_cvt_freeEntryRdn(entry, rdn); 1668 return (NS_LDAP_INVALID_PARAM); 1669 } 1670 rc = __s_add_attr(e, "SolarisProjectID", ibuf); 1671 if (rc != NS_LDAP_SUCCESS) { 1672 __s_cvt_freeEntryRdn(entry, rdn); 1673 return (rc); 1674 } 1675 1676 /* Comment/Description */ 1677 if (ptr->pj_comment != NULL && ptr->pj_comment[0] != '\0') { 1678 rc = __s_add_attr(e, "description", ptr->pj_comment); 1679 if (rc != NS_LDAP_SUCCESS) { 1680 __s_cvt_freeEntryRdn(entry, rdn); 1681 return (rc); 1682 } 1683 } 1684 1685 /* Attributes */ 1686 if (ptr->pj_attr != NULL && ptr->pj_attr[0] != '\0') { 1687 rc = __s_add_attr(e, "SolarisProjectAttr", ptr->pj_attr); 1688 if (rc != NS_LDAP_SUCCESS) { 1689 __s_cvt_freeEntryRdn(entry, rdn); 1690 return (rc); 1691 } 1692 } 1693 1694 /* Users */ 1695 if (ptr->pj_users != NULL) { 1696 rc = __s_add_attrlist(e, "memberUid", ptr->pj_users); 1697 if (rc != NS_LDAP_SUCCESS) { 1698 __s_cvt_freeEntryRdn(entry, rdn); 1699 return (rc); 1700 } 1701 } 1702 1703 /* Groups */ 1704 if (ptr->pj_groups != NULL) { 1705 rc = __s_add_attrlist(e, "memberGid", ptr->pj_groups); 1706 if (rc != NS_LDAP_SUCCESS) { 1707 __s_cvt_freeEntryRdn(entry, rdn); 1708 return (rc); 1709 } 1710 } 1711 1712 1713 1714 return (NS_LDAP_SUCCESS); 1715 } 1716 /* 1717 * Conversion: shadow 1718 * Input format: struct shadow 1719 * Exported objectclass: shadowAccount 1720 */ 1721 static int 1722 __s_cvt_shadow(const void *data, char **rdn, 1723 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 1724 { 1725 ns_ldap_entry_t *e; 1726 int rc; 1727 char trdn[RDNSIZE]; 1728 /* routine specific */ 1729 struct spwd *ptr; 1730 int max_attr = 10; 1731 char ibuf[10]; 1732 static char *oclist[] = { 1733 "posixAccount", 1734 "shadowAccount", 1735 "account", 1736 "top", 1737 NULL 1738 }; 1739 1740 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 1741 return (NS_LDAP_OP_FAILED); 1742 *entry = e = __s_mk_entry(oclist, max_attr); 1743 if (e == NULL) 1744 return (NS_LDAP_MEMORY); 1745 1746 /* Convert the structure */ 1747 ptr = (struct spwd *)data; 1748 1749 if (ptr->sp_namp == NULL) { 1750 __ns_ldap_freeEntry(e); 1751 *entry = NULL; 1752 return (NS_LDAP_INVALID_PARAM); 1753 } 1754 1755 /* Create an appropriate rdn */ 1756 (void) snprintf(trdn, RDNSIZE, "uid=%s", ptr->sp_namp); 1757 *rdn = strdup(trdn); 1758 if (*rdn == NULL) { 1759 __ns_ldap_freeEntry(e); 1760 *entry = NULL; 1761 return (NS_LDAP_MEMORY); 1762 } 1763 1764 /* Error check the data and add the attributes */ 1765 rc = __s_add_attr(e, "uid", ptr->sp_namp); 1766 if (rc != NS_LDAP_SUCCESS) { 1767 __s_cvt_freeEntryRdn(entry, rdn); 1768 return (rc); 1769 } 1770 1771 if (ptr->sp_pwdp == NULL) { 1772 __s_cvt_freeEntryRdn(entry, rdn); 1773 return (NS_LDAP_INVALID_PARAM); 1774 } else { 1775 rc = __s_add_attr(e, "userPassword", ptr->sp_pwdp); 1776 if (rc != NS_LDAP_SUCCESS) { 1777 __s_cvt_freeEntryRdn(entry, rdn); 1778 return (rc); 1779 } 1780 } 1781 if (ptr->sp_lstchg >= 0) { 1782 (void) sprintf(ibuf, "%d", ptr->sp_lstchg); 1783 rc = __s_add_attr(e, "shadowLastChange", ibuf); 1784 if (rc != NS_LDAP_SUCCESS) { 1785 __s_cvt_freeEntryRdn(entry, rdn); 1786 return (rc); 1787 } 1788 } 1789 if (ptr->sp_min >= 0) { 1790 (void) sprintf(ibuf, "%d", ptr->sp_min); 1791 rc = __s_add_attr(e, "shadowMin", ibuf); 1792 if (rc != NS_LDAP_SUCCESS) { 1793 __s_cvt_freeEntryRdn(entry, rdn); 1794 return (rc); 1795 } 1796 } 1797 if (ptr->sp_max >= 0) { 1798 (void) sprintf(ibuf, "%d", ptr->sp_max); 1799 rc = __s_add_attr(e, "shadowMax", ibuf); 1800 if (rc != NS_LDAP_SUCCESS) { 1801 __s_cvt_freeEntryRdn(entry, rdn); 1802 return (rc); 1803 } 1804 } 1805 if (ptr->sp_warn >= 0) { 1806 (void) sprintf(ibuf, "%d", ptr->sp_warn); 1807 rc = __s_add_attr(e, "shadowWarning", ibuf); 1808 if (rc != NS_LDAP_SUCCESS) { 1809 __s_cvt_freeEntryRdn(entry, rdn); 1810 return (rc); 1811 } 1812 } 1813 if (ptr->sp_inact >= 0) { 1814 (void) sprintf(ibuf, "%d", ptr->sp_inact); 1815 rc = __s_add_attr(e, "shadowInactive", ibuf); 1816 if (rc != NS_LDAP_SUCCESS) { 1817 __s_cvt_freeEntryRdn(entry, rdn); 1818 return (rc); 1819 } 1820 } 1821 if (ptr->sp_expire >= 0) { 1822 (void) sprintf(ibuf, "%d", ptr->sp_expire); 1823 rc = __s_add_attr(e, "shadowExpire", ibuf); 1824 if (rc != NS_LDAP_SUCCESS) { 1825 __s_cvt_freeEntryRdn(entry, rdn); 1826 return (rc); 1827 } 1828 } 1829 (void) sprintf(ibuf, "%d", ptr->sp_flag); 1830 rc = __s_add_attr(e, "shadowFlag", ibuf); 1831 if (rc != NS_LDAP_SUCCESS) { 1832 __s_cvt_freeEntryRdn(entry, rdn); 1833 return (rc); 1834 } 1835 1836 return (NS_LDAP_SUCCESS); 1837 } 1838 1839 1840 /* 1841 * Conversion: group 1842 * Input format: struct group 1843 * Exported objectclass: posixGroup 1844 */ 1845 static int 1846 __s_cvt_group(const void *data, char **rdn, 1847 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 1848 { 1849 ns_ldap_entry_t *e; 1850 int rc; 1851 char trdn[RDNSIZE]; 1852 /* routine specific */ 1853 struct group *ptr; 1854 int i, j, k; 1855 char **nm, **lm; 1856 int max_attr = 4; 1857 char ibuf[10]; 1858 static char *oclist[] = { 1859 "posixGroup", 1860 "top", 1861 NULL 1862 }; 1863 1864 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 1865 return (NS_LDAP_OP_FAILED); 1866 *entry = e = __s_mk_entry(oclist, max_attr); 1867 if (e == NULL) 1868 return (NS_LDAP_MEMORY); 1869 1870 /* Convert the structure */ 1871 ptr = (struct group *)data; 1872 1873 if (ptr->gr_name == NULL || ptr->gr_gid > MAXUID) { 1874 __ns_ldap_freeEntry(e); 1875 *entry = NULL; 1876 return (NS_LDAP_INVALID_PARAM); 1877 } 1878 1879 /* Create an appropriate rdn */ 1880 (void) snprintf(trdn, RDNSIZE, "cn=%s", ptr->gr_name); 1881 *rdn = strdup(trdn); 1882 if (*rdn == NULL) { 1883 __ns_ldap_freeEntry(e); 1884 *entry = NULL; 1885 return (NS_LDAP_MEMORY); 1886 } 1887 1888 /* Error check the data and add the attributes */ 1889 rc = __s_add_attr(e, "cn", ptr->gr_name); 1890 if (rc != NS_LDAP_SUCCESS) { 1891 __s_cvt_freeEntryRdn(entry, rdn); 1892 return (rc); 1893 } 1894 1895 (void) sprintf(ibuf, "%u", ptr->gr_gid); 1896 rc = __s_add_attr(e, "gidNumber", ibuf); 1897 if (rc != NS_LDAP_SUCCESS) { 1898 __s_cvt_freeEntryRdn(entry, rdn); 1899 return (rc); 1900 } 1901 if (ptr->gr_passwd && ptr->gr_passwd[0] != '\0') { 1902 rc = __s_add_attr(e, "userPassword", ptr->gr_passwd); 1903 if (rc != NS_LDAP_SUCCESS) { 1904 __s_cvt_freeEntryRdn(entry, rdn); 1905 return (rc); 1906 } 1907 } 1908 1909 if (ptr->gr_mem && ptr->gr_mem[0]) { 1910 lm = ptr->gr_mem; 1911 for (i = 0; *lm; i++, lm++) 1912 ; 1913 lm = ptr->gr_mem; 1914 nm = (char **)calloc(i+2, sizeof (char *)); 1915 if (nm == NULL) { 1916 __s_cvt_freeEntryRdn(entry, rdn); 1917 return (NS_LDAP_MEMORY); 1918 } 1919 for (j = 0; j < i; j++) { 1920 nm[j] = strdup(lm[j]); 1921 if (nm[j] == NULL) { 1922 for (k = 0; k < j; k++) 1923 free(nm[k]); 1924 free(nm); 1925 __s_cvt_freeEntryRdn(entry, rdn); 1926 return (NS_LDAP_MEMORY); 1927 } 1928 } 1929 rc = __s_add_attrlist(e, "memberUid", nm); 1930 for (j = 0; j < i; j++) { 1931 free(nm[j]); 1932 } 1933 free(nm); 1934 nm = NULL; 1935 if (rc != NS_LDAP_SUCCESS) { 1936 __s_cvt_freeEntryRdn(entry, rdn); 1937 return (rc); 1938 } 1939 } 1940 1941 return (NS_LDAP_SUCCESS); 1942 } 1943 1944 /* 1945 * Conversion: hosts 1946 * Input format: struct hostent 1947 * Exported objectclass: ipHost 1948 */ 1949 static int 1950 __s_cvt_hosts(const void *data, char **rdn, 1951 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 1952 { 1953 ns_ldap_entry_t *e; 1954 int rc; 1955 char trdn[RDNSIZE]; 1956 /* routine specific */ 1957 struct hostent *ptr; 1958 int max_attr = 6; 1959 int i, j, k; 1960 char **nm, **lm; 1961 static char *oclist[] = { 1962 "ipHost", 1963 "device", 1964 "top", 1965 NULL 1966 }; 1967 1968 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 1969 return (NS_LDAP_OP_FAILED); 1970 *entry = e = __s_mk_entry(oclist, max_attr); 1971 if (e == NULL) 1972 return (NS_LDAP_MEMORY); 1973 1974 /* Convert the structure */ 1975 ptr = (struct hostent *)data; 1976 1977 if (ptr->h_name == NULL || 1978 ptr->h_addr_list == NULL || ptr->h_addr_list[0] == '\0') { 1979 __ns_ldap_freeEntry(e); 1980 *entry = NULL; 1981 return (NS_LDAP_INVALID_PARAM); 1982 } 1983 1984 /* Create an appropriate rdn */ 1985 (void) snprintf(trdn, RDNSIZE, "cn=%s+ipHostNumber=%s", 1986 ptr->h_name, ptr->h_addr_list[0]); 1987 *rdn = strdup(trdn); 1988 if (*rdn == NULL) { 1989 __ns_ldap_freeEntry(e); 1990 *entry = NULL; 1991 return (NS_LDAP_MEMORY); 1992 } 1993 1994 /* Error check the data and add the attributes */ 1995 if (ptr->h_aliases && ptr->h_aliases[0]) { 1996 lm = ptr->h_aliases; 1997 /* 1998 * If there is a description, 'i' will contain 1999 * the index of the description in the aliases list 2000 */ 2001 for (i = 0; *lm && (*lm)[0] != '#'; i++, lm++) 2002 ; 2003 lm = ptr->h_aliases; 2004 nm = (char **)calloc(i+2, sizeof (char *)); 2005 if (nm == NULL) { 2006 __s_cvt_freeEntryRdn(entry, rdn); 2007 return (NS_LDAP_MEMORY); 2008 } 2009 nm[0] = ptr->h_name; 2010 for (j = 0; j < i; j++) 2011 nm[j+1] = ptr->h_aliases[j]; 2012 2013 rc = __s_add_attrlist(e, "cn", nm); 2014 2015 if (rc != NS_LDAP_SUCCESS) { 2016 __s_cvt_freeEntryRdn(entry, rdn); 2017 free(nm); 2018 return (rc); 2019 } 2020 2021 if (lm[i] && lm[i][0] == '#') { 2022 nm[0] = &(lm[i][1]); 2023 nm[1] = NULL; 2024 rc = __s_add_attrlist(e, "description", nm); 2025 } 2026 free(nm); 2027 nm = NULL; 2028 if (rc != NS_LDAP_SUCCESS) { 2029 __s_cvt_freeEntryRdn(entry, rdn); 2030 return (rc); 2031 } 2032 } else { 2033 rc = __s_add_attr(e, "cn", ptr->h_name); 2034 if (rc != NS_LDAP_SUCCESS) { 2035 __s_cvt_freeEntryRdn(entry, rdn); 2036 return (rc); 2037 } 2038 } 2039 2040 if (ptr->h_addr_list && ptr->h_addr_list[0]) { 2041 lm = ptr->h_addr_list; 2042 for (i = 0; *lm; i++, lm++) 2043 ; 2044 lm = ptr->h_addr_list; 2045 nm = (char **)calloc(i+2, sizeof (char *)); 2046 if (nm == NULL) { 2047 __s_cvt_freeEntryRdn(entry, rdn); 2048 return (NS_LDAP_MEMORY); 2049 } 2050 for (j = 0; j < i; j++) { 2051 nm[j] = strdup(lm[j]); 2052 if (nm[j] == NULL) { 2053 for (k = 0; k < j; k++) 2054 free(nm[k]); 2055 free(nm); 2056 __s_cvt_freeEntryRdn(entry, rdn); 2057 return (NS_LDAP_MEMORY); 2058 } 2059 } 2060 rc = __s_add_attrlist(e, "ipHostNumber", nm); 2061 for (j = 0; j < i; j++) { 2062 free(nm[j]); 2063 } 2064 free(nm); 2065 nm = NULL; 2066 if (rc != NS_LDAP_SUCCESS) { 2067 __s_cvt_freeEntryRdn(entry, rdn); 2068 return (rc); 2069 } 2070 } else { 2071 __s_cvt_freeEntryRdn(entry, rdn); 2072 return (NS_LDAP_INVALID_PARAM); 2073 } 2074 2075 return (NS_LDAP_SUCCESS); 2076 } 2077 2078 /* 2079 * Conversion: rpc 2080 * Input format: struct rpcent 2081 * Exported objectclass: oncRpc 2082 */ 2083 static int 2084 __s_cvt_rpc(const void *data, char **rdn, 2085 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 2086 { 2087 ns_ldap_entry_t *e; 2088 int rc; 2089 char trdn[RDNSIZE]; 2090 /* routine specific */ 2091 struct rpcent *ptr; 2092 int max_attr = 3; 2093 int i, j; 2094 char **nm; 2095 char ibuf[10]; 2096 static char *oclist[] = { 2097 "oncRpc", 2098 "top", 2099 NULL 2100 }; 2101 2102 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 2103 return (NS_LDAP_OP_FAILED); 2104 *entry = e = __s_mk_entry(oclist, max_attr); 2105 if (e == NULL) 2106 return (NS_LDAP_MEMORY); 2107 2108 /* Convert the structure */ 2109 ptr = (struct rpcent *)data; 2110 2111 if (ptr->r_name == NULL || ptr->r_number < 0) { 2112 __ns_ldap_freeEntry(e); 2113 *entry = NULL; 2114 return (NS_LDAP_INVALID_PARAM); 2115 } 2116 2117 /* Create an appropriate rdn */ 2118 (void) snprintf(trdn, RDNSIZE, "cn=%s", ptr->r_name); 2119 *rdn = strdup(trdn); 2120 if (*rdn == NULL) { 2121 __ns_ldap_freeEntry(e); 2122 *entry = NULL; 2123 return (NS_LDAP_MEMORY); 2124 } 2125 2126 /* Error check the data and add the attributes */ 2127 if (ptr->r_aliases && ptr->r_aliases[0]) { 2128 nm = ptr->r_aliases; 2129 for (i = 0; *nm; i++, nm++) 2130 ; 2131 nm = (char **)calloc(i+2, sizeof (char *)); 2132 if (nm == NULL) { 2133 __s_cvt_freeEntryRdn(entry, rdn); 2134 return (NS_LDAP_MEMORY); 2135 } 2136 nm[0] = ptr->r_name; 2137 for (j = 0; j < i; j++) 2138 nm[j+1] = ptr->r_aliases[j]; 2139 2140 rc = __s_add_attrlist(e, "cn", nm); 2141 free(nm); 2142 nm = NULL; 2143 if (rc != NS_LDAP_SUCCESS) { 2144 __s_cvt_freeEntryRdn(entry, rdn); 2145 return (rc); 2146 } 2147 } else { 2148 rc = __s_add_attr(e, "cn", ptr->r_name); 2149 if (rc != NS_LDAP_SUCCESS) { 2150 __s_cvt_freeEntryRdn(entry, rdn); 2151 return (rc); 2152 } 2153 } 2154 2155 if (ptr->r_number >= 0) { 2156 (void) sprintf(ibuf, "%d", ptr->r_number); 2157 rc = __s_add_attr(e, "oncRpcNumber", ibuf); 2158 if (rc != NS_LDAP_SUCCESS) { 2159 __s_cvt_freeEntryRdn(entry, rdn); 2160 return (rc); 2161 } 2162 } 2163 2164 return (NS_LDAP_SUCCESS); 2165 2166 } 2167 2168 /* 2169 * Conversion: protocols 2170 * Input format: struct protoent 2171 * Exported objectclass: ipProtocol 2172 */ 2173 static int 2174 __s_cvt_protocols(const void *data, char **rdn, 2175 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 2176 { 2177 ns_ldap_entry_t *e; 2178 int rc; 2179 char trdn[RDNSIZE]; 2180 /* routine specific */ 2181 struct protoent *ptr; 2182 int max_attr = 3; 2183 int i, j; 2184 char ibuf[10]; 2185 char **nm; 2186 static char *oclist[] = { 2187 "ipProtocol", 2188 "top", 2189 NULL 2190 }; 2191 2192 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 2193 return (NS_LDAP_OP_FAILED); 2194 *entry = e = __s_mk_entry(oclist, max_attr); 2195 if (e == NULL) 2196 return (NS_LDAP_MEMORY); 2197 2198 /* Convert the structure */ 2199 ptr = (struct protoent *)data; 2200 2201 if (ptr->p_name == NULL || ptr->p_proto < 0) { 2202 __ns_ldap_freeEntry(e); 2203 *entry = NULL; 2204 return (NS_LDAP_INVALID_PARAM); 2205 } 2206 2207 /* Create an appropriate rdn */ 2208 (void) snprintf(trdn, RDNSIZE, "cn=%s", ptr->p_name); 2209 *rdn = strdup(trdn); 2210 if (*rdn == NULL) { 2211 __ns_ldap_freeEntry(e); 2212 *entry = NULL; 2213 return (NS_LDAP_MEMORY); 2214 } 2215 2216 /* Error check the data and add the attributes */ 2217 if (ptr->p_aliases && ptr->p_aliases[0]) { 2218 nm = ptr->p_aliases; 2219 for (i = 0; *nm; i++, nm++) 2220 ; 2221 nm = (char **)calloc(i+2, sizeof (char *)); 2222 if (nm == NULL) { 2223 __s_cvt_freeEntryRdn(entry, rdn); 2224 return (NS_LDAP_MEMORY); 2225 } 2226 nm[0] = ptr->p_name; 2227 for (j = 0; j < i; j++) 2228 nm[j+1] = ptr->p_aliases[j]; 2229 2230 rc = __s_add_attrlist(e, "cn", nm); 2231 free(nm); 2232 nm = NULL; 2233 if (rc != NS_LDAP_SUCCESS) { 2234 __s_cvt_freeEntryRdn(entry, rdn); 2235 return (rc); 2236 } 2237 } else { 2238 rc = __s_add_attr(e, "cn", ptr->p_name); 2239 if (rc != NS_LDAP_SUCCESS) { 2240 __s_cvt_freeEntryRdn(entry, rdn); 2241 return (rc); 2242 } 2243 } 2244 2245 (void) sprintf(ibuf, "%d", ptr->p_proto); 2246 rc = __s_add_attr(e, "ipProtocolNumber", ibuf); 2247 if (rc != NS_LDAP_SUCCESS) { 2248 __s_cvt_freeEntryRdn(entry, rdn); 2249 return (rc); 2250 } 2251 2252 return (NS_LDAP_SUCCESS); 2253 2254 } 2255 2256 /* 2257 * Conversion: services 2258 * Input format: struct servent 2259 * Exported objectclass: ipService 2260 */ 2261 static int 2262 __s_cvt_services(const void *data, char **rdn, 2263 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 2264 { 2265 ns_ldap_entry_t *e; 2266 int rc; 2267 char trdn[RDNSIZE]; 2268 /* routine specific */ 2269 struct servent *ptr; 2270 int max_attr = 4; 2271 int i, j; 2272 char ibuf[10]; 2273 char **nm; 2274 static char *oclist[] = { 2275 "ipService", 2276 "top", 2277 NULL 2278 }; 2279 2280 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 2281 return (NS_LDAP_OP_FAILED); 2282 *entry = e = __s_mk_entry(oclist, max_attr); 2283 if (e == NULL) 2284 return (NS_LDAP_MEMORY); 2285 2286 /* Convert the structure */ 2287 ptr = (struct servent *)data; 2288 2289 if (ptr->s_name == NULL || ptr->s_port < 0 || ptr->s_proto == '\0') { 2290 __ns_ldap_freeEntry(e); 2291 *entry = NULL; 2292 return (NS_LDAP_INVALID_PARAM); 2293 } 2294 2295 /* Create an appropriate rdn */ 2296 (void) snprintf(trdn, RDNSIZE, "cn=%s+ipServiceProtocol=%s", 2297 ptr->s_name, ptr->s_proto); 2298 *rdn = strdup(trdn); 2299 if (*rdn == NULL) { 2300 __ns_ldap_freeEntry(e); 2301 *entry = NULL; 2302 return (NS_LDAP_MEMORY); 2303 } 2304 2305 /* Error check the data and add the attributes */ 2306 if (ptr->s_aliases && ptr->s_aliases[0]) { 2307 nm = ptr->s_aliases; 2308 for (i = 0; *nm; i++, nm++) 2309 ; 2310 nm = (char **)calloc(i+2, sizeof (char *)); 2311 if (nm == NULL) { 2312 __s_cvt_freeEntryRdn(entry, rdn); 2313 return (NS_LDAP_MEMORY); 2314 } 2315 nm[0] = ptr->s_name; 2316 for (j = 0; j < i; j++) 2317 nm[j+1] = ptr->s_aliases[j]; 2318 2319 rc = __s_add_attrlist(e, "cn", nm); 2320 free(nm); 2321 nm = NULL; 2322 if (rc != NS_LDAP_SUCCESS) { 2323 __s_cvt_freeEntryRdn(entry, rdn); 2324 return (rc); 2325 } 2326 } else { 2327 rc = __s_add_attr(e, "cn", ptr->s_name); 2328 if (rc != NS_LDAP_SUCCESS) { 2329 __s_cvt_freeEntryRdn(entry, rdn); 2330 return (rc); 2331 } 2332 } 2333 2334 (void) sprintf(ibuf, "%d", ptr->s_port); 2335 rc = __s_add_attr(e, "ipServicePort", ibuf); 2336 if (rc != NS_LDAP_SUCCESS) { 2337 __s_cvt_freeEntryRdn(entry, rdn); 2338 return (rc); 2339 } 2340 rc = __s_add_attr(e, "ipServiceProtocol", ptr->s_proto); 2341 if (rc != NS_LDAP_SUCCESS) { 2342 __s_cvt_freeEntryRdn(entry, rdn); 2343 return (rc); 2344 } 2345 2346 return (NS_LDAP_SUCCESS); 2347 } 2348 2349 /* 2350 * Conversion: networks 2351 * Input format: struct netent 2352 * Exported objectclass: ipNetwork 2353 */ 2354 static int 2355 __s_cvt_networks(const void *data, char **rdn, 2356 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 2357 { 2358 ns_ldap_entry_t *e; 2359 int rc; 2360 char trdn[RDNSIZE]; 2361 /* routine specific */ 2362 struct netent *ptr; 2363 int max_attr = 4; 2364 int i, j; 2365 char cp[64]; 2366 char **nm; 2367 static char *oclist[] = { 2368 "ipNetwork", 2369 "top", 2370 NULL 2371 }; 2372 2373 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 2374 return (NS_LDAP_OP_FAILED); 2375 *entry = e = __s_mk_entry(oclist, max_attr); 2376 if (e == NULL) 2377 return (NS_LDAP_MEMORY); 2378 2379 /* Convert the structure */ 2380 ptr = (struct netent *)data; 2381 2382 if (ptr->n_name == NULL || ptr->n_net == 0) { 2383 __ns_ldap_freeEntry(e); 2384 *entry = NULL; 2385 return (NS_LDAP_INVALID_PARAM); 2386 } 2387 2388 (void) snprintf(cp, sizeof (cp), "%d.%d.%d.%d", 2389 (ptr->n_net & 0xFF000000) >> 24, 2390 (ptr->n_net & 0x00FF0000) >> 16, 2391 (ptr->n_net & 0x0000FF00) >> 8, 2392 (ptr->n_net & 0x000000FF)); 2393 2394 /* Create an appropriate rdn */ 2395 (void) snprintf(trdn, RDNSIZE, "ipNetworkNumber=%s", cp); 2396 *rdn = strdup(trdn); 2397 if (*rdn == NULL) { 2398 __ns_ldap_freeEntry(e); 2399 *entry = NULL; 2400 return (NS_LDAP_MEMORY); 2401 } 2402 2403 /* Error check the data and add the attributes */ 2404 if (ptr->n_aliases && ptr->n_aliases[0]) { 2405 nm = ptr->n_aliases; 2406 for (i = 0; *nm; i++, nm++) 2407 ; 2408 nm = (char **)calloc(i+2, sizeof (char *)); 2409 if (nm == NULL) { 2410 __s_cvt_freeEntryRdn(entry, rdn); 2411 return (NS_LDAP_MEMORY); 2412 } 2413 nm[0] = ptr->n_name; 2414 for (j = 0; j < i; j++) 2415 nm[j+1] = ptr->n_aliases[j]; 2416 2417 rc = __s_add_attrlist(e, "cn", nm); 2418 free(nm); 2419 nm = NULL; 2420 if (rc != NS_LDAP_SUCCESS) { 2421 __s_cvt_freeEntryRdn(entry, rdn); 2422 return (rc); 2423 } 2424 } else { 2425 rc = __s_add_attr(e, "cn", ptr->n_name); 2426 if (rc != NS_LDAP_SUCCESS) { 2427 __s_cvt_freeEntryRdn(entry, rdn); 2428 return (rc); 2429 } 2430 } 2431 2432 rc = __s_add_attr(e, "ipNetworkNumber", cp); 2433 if (rc != NS_LDAP_SUCCESS) { 2434 __s_cvt_freeEntryRdn(entry, rdn); 2435 return (rc); 2436 } 2437 2438 return (NS_LDAP_SUCCESS); 2439 2440 } 2441 /* 2442 * Conversion: netmasks 2443 * Input format: struct _ns_netmasks 2444 * Exported objectclass: ipNetwork 2445 */ 2446 static int 2447 __s_cvt_netmasks(const void *data, char **rdn, 2448 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 2449 { 2450 ns_ldap_entry_t *e; 2451 int rc; 2452 char trdn[RDNSIZE]; 2453 /* routine specific */ 2454 struct _ns_netmasks *ptr; 2455 int max_attr = 4; 2456 static char *oclist[] = { 2457 "ipNetwork", 2458 "top", 2459 NULL 2460 }; 2461 2462 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 2463 return (NS_LDAP_OP_FAILED); 2464 *entry = e = __s_mk_entry(oclist, max_attr); 2465 if (e == NULL) 2466 return (NS_LDAP_MEMORY); 2467 2468 /* Convert the structure */ 2469 ptr = (struct _ns_netmasks *)data; 2470 2471 if (ptr->netnumber == NULL) { 2472 __ns_ldap_freeEntry(e); 2473 *entry = NULL; 2474 return (NS_LDAP_INVALID_PARAM); 2475 } 2476 2477 /* Create an appropriate rdn */ 2478 (void) snprintf(trdn, RDNSIZE, "ipNetworkNumber=%s", ptr->netnumber); 2479 *rdn = strdup(trdn); 2480 if (*rdn == NULL) { 2481 __ns_ldap_freeEntry(e); 2482 *entry = NULL; 2483 return (NS_LDAP_MEMORY); 2484 } 2485 2486 /* Error check the data and add the attributes */ 2487 rc = __s_add_attr(e, "ipNetworkNumber", ptr->netnumber); 2488 if (rc != NS_LDAP_SUCCESS) { 2489 __s_cvt_freeEntryRdn(entry, rdn); 2490 return (rc); 2491 } 2492 2493 if (ptr->netmask != '\0') { 2494 rc = __s_add_attr(e, "ipNetmaskNumber", ptr->netmask); 2495 if (rc != NS_LDAP_SUCCESS) { 2496 __s_cvt_freeEntryRdn(entry, rdn); 2497 return (rc); 2498 } 2499 } 2500 2501 return (NS_LDAP_SUCCESS); 2502 2503 } 2504 /* 2505 * Conversion: netgroups 2506 * Input format: struct _ns_netgroups 2507 * Exported objectclass: nisNetgroup 2508 */ 2509 static int 2510 __s_cvt_netgroups(const void *data, char **rdn, 2511 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 2512 { 2513 ns_ldap_entry_t *e; 2514 int rc; 2515 char trdn[RDNSIZE]; 2516 /* routine specific */ 2517 struct _ns_netgroups *ptr; 2518 int max_attr = 6; 2519 int i, j; 2520 char **nm; 2521 static char *oclist[] = { 2522 "nisNetgroup", 2523 "top", 2524 NULL 2525 }; 2526 2527 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 2528 return (NS_LDAP_OP_FAILED); 2529 *entry = e = __s_mk_entry(oclist, max_attr); 2530 if (e == NULL) 2531 return (NS_LDAP_MEMORY); 2532 2533 /* Convert the structure */ 2534 ptr = (struct _ns_netgroups *)data; 2535 2536 if (ptr->name == NULL) { 2537 __ns_ldap_freeEntry(e); 2538 *entry = NULL; 2539 return (NS_LDAP_INVALID_PARAM); 2540 } 2541 2542 /* Create an appropriate rdn */ 2543 (void) snprintf(trdn, RDNSIZE, "cn=%s", ptr->name); 2544 *rdn = strdup(trdn); 2545 if (*rdn == NULL) { 2546 __ns_ldap_freeEntry(e); 2547 *entry = NULL; 2548 return (NS_LDAP_MEMORY); 2549 } 2550 2551 if (ptr->name != '\0') { 2552 rc = __s_add_attr(e, "cn", ptr->name); 2553 if (rc != NS_LDAP_SUCCESS) { 2554 __s_cvt_freeEntryRdn(entry, rdn); 2555 return (rc); 2556 } 2557 } 2558 2559 /* Error check the data and add the attributes */ 2560 if (ptr->triplet && ptr->triplet[0]) { 2561 nm = ptr->triplet; 2562 for (i = 0; *nm; i++, nm++) 2563 ; 2564 nm = (char **)calloc(i+2, sizeof (char *)); 2565 if (nm == NULL) { 2566 __s_cvt_freeEntryRdn(entry, rdn); 2567 return (NS_LDAP_MEMORY); 2568 } 2569 for (j = 0; j < i; j++) 2570 nm[j] = ptr->triplet[j]; 2571 2572 rc = __s_add_attrlist(e, "nisNetgroupTriple", nm); 2573 free(nm); 2574 nm = NULL; 2575 if (rc != NS_LDAP_SUCCESS) { 2576 __s_cvt_freeEntryRdn(entry, rdn); 2577 return (rc); 2578 } 2579 } 2580 if (ptr->netgroup && ptr->netgroup[0]) { 2581 nm = ptr->netgroup; 2582 for (i = 0; *nm; i++, nm++) 2583 ; 2584 nm = (char **)calloc(i+2, sizeof (char *)); 2585 if (nm == NULL) { 2586 __s_cvt_freeEntryRdn(entry, rdn); 2587 return (NS_LDAP_MEMORY); 2588 } 2589 for (j = 0; j < i; j++) 2590 nm[j] = ptr->netgroup[j]; 2591 2592 rc = __s_add_attrlist(e, "memberNisNetgroup", nm); 2593 free(nm); 2594 nm = NULL; 2595 if (rc != NS_LDAP_SUCCESS) { 2596 __s_cvt_freeEntryRdn(entry, rdn); 2597 return (rc); 2598 } 2599 } 2600 return (NS_LDAP_SUCCESS); 2601 } 2602 /* 2603 * Conversion: bootparams 2604 * Input format: struct _ns_bootp 2605 * Exported objectclass: bootableDevice, device 2606 */ 2607 static int 2608 __s_cvt_bootparams(const void *data, char **rdn, 2609 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 2610 { 2611 ns_ldap_entry_t *e; 2612 int rc; 2613 char trdn[RDNSIZE]; 2614 /* routine specific */ 2615 struct _ns_bootp *ptr; 2616 int max_attr = 4; 2617 int i, j; 2618 char **nm; 2619 static char *oclist[] = { 2620 "bootableDevice", 2621 "device", 2622 "top", 2623 NULL 2624 }; 2625 2626 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 2627 return (NS_LDAP_OP_FAILED); 2628 *entry = e = __s_mk_entry(oclist, max_attr); 2629 if (e == NULL) 2630 return (NS_LDAP_MEMORY); 2631 2632 /* Convert the structure */ 2633 ptr = (struct _ns_bootp *)data; 2634 2635 if (ptr->name == NULL) { 2636 __ns_ldap_freeEntry(e); 2637 *entry = NULL; 2638 return (NS_LDAP_INVALID_PARAM); 2639 } 2640 2641 /* Create an appropriate rdn */ 2642 (void) snprintf(trdn, RDNSIZE, "cn=%s", ptr->name); 2643 *rdn = strdup(trdn); 2644 if (*rdn == NULL) { 2645 __ns_ldap_freeEntry(e); 2646 *entry = NULL; 2647 return (NS_LDAP_MEMORY); 2648 } 2649 2650 if (ptr->name != '\0') { 2651 rc = __s_add_attr(e, "cn", ptr->name); 2652 if (rc != NS_LDAP_SUCCESS) { 2653 __s_cvt_freeEntryRdn(entry, rdn); 2654 return (rc); 2655 } 2656 } 2657 2658 /* Error check the data and add the attributes */ 2659 if (ptr->param && ptr->param[0]) { 2660 nm = ptr->param; 2661 for (i = 0; *nm; i++, nm++) 2662 ; 2663 nm = (char **)calloc(i+2, sizeof (char *)); 2664 if (nm == NULL) { 2665 __s_cvt_freeEntryRdn(entry, rdn); 2666 return (NS_LDAP_MEMORY); 2667 } 2668 for (j = 0; j < i; j++) 2669 nm[j] = ptr->param[j]; 2670 2671 rc = __s_add_attrlist(e, "bootParameter", nm); 2672 free(nm); 2673 nm = NULL; 2674 if (rc != NS_LDAP_SUCCESS) { 2675 __s_cvt_freeEntryRdn(entry, rdn); 2676 return (rc); 2677 } 2678 } 2679 2680 return (NS_LDAP_SUCCESS); 2681 2682 } 2683 /* 2684 * Conversion: ethers 2685 * Input format: struct _ns_ethers 2686 * Exported objectclass: ieee802Device, device 2687 */ 2688 static int 2689 __s_cvt_ethers(const void *data, char **rdn, 2690 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 2691 { 2692 ns_ldap_entry_t *e; 2693 int rc; 2694 char trdn[RDNSIZE]; 2695 /* routine specific */ 2696 struct _ns_ethers *ptr; 2697 int max_attr = 4; 2698 static char *oclist[] = { 2699 "ieee802Device", 2700 "device", 2701 "top", 2702 NULL 2703 }; 2704 2705 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 2706 return (NS_LDAP_OP_FAILED); 2707 *entry = e = __s_mk_entry(oclist, max_attr); 2708 if (e == NULL) 2709 return (NS_LDAP_MEMORY); 2710 2711 /* Convert the structure */ 2712 ptr = (struct _ns_ethers *)data; 2713 2714 if (ptr->name == NULL || ptr->ether == '\0') { 2715 __ns_ldap_freeEntry(e); 2716 *entry = NULL; 2717 return (NS_LDAP_INVALID_PARAM); 2718 } 2719 2720 /* Create an appropriate rdn */ 2721 (void) snprintf(trdn, RDNSIZE, "cn=%s", ptr->name); 2722 *rdn = strdup(trdn); 2723 if (*rdn == NULL) { 2724 __ns_ldap_freeEntry(e); 2725 *entry = NULL; 2726 return (NS_LDAP_MEMORY); 2727 } 2728 2729 /* Error check the data and add the attributes */ 2730 rc = __s_add_attr(e, "cn", ptr->name); 2731 if (rc != NS_LDAP_SUCCESS) { 2732 __s_cvt_freeEntryRdn(entry, rdn); 2733 return (rc); 2734 } 2735 2736 rc = __s_add_attr(e, "macAddress", ptr->ether); 2737 if (rc != NS_LDAP_SUCCESS) { 2738 __s_cvt_freeEntryRdn(entry, rdn); 2739 return (rc); 2740 } 2741 2742 return (NS_LDAP_SUCCESS); 2743 } 2744 /* 2745 * This function is used when processing an ethers (objectclass: ieee802Device) 2746 * or a bootparams (objectclass: bootableDevice) entry, and the entry is 2747 * already found in LDAP. Since both ethers and bootparams share the same 2748 * LDAP container, we want to check that the entry found in LDAP is: 2749 * - either the same entry (same cn, same objectclass): we don't do anything 2750 * in this case 2751 * - or an entry which does not have the objectclass we are interesting in: 2752 * in this case, we modify the existing entry by adding the relevant 2753 * objectclass (ieee802Device or bootableDevice) and the relevant attribute(s) 2754 * from the attribute list previously computing by the relevant conversion 2755 * function. 2756 * Note: from conversion functions __s_cvt_ethers() and __s_cvt_bootparams() 2757 * we know that there is only 1 more attribute today to add (macAddress 2758 * or bootParameter) 2759 */ 2760 #define _MAX_ATTR_ETHBOOTP 2 2761 static int 2762 modify_ethers_bootp( 2763 const char *service, 2764 const char *rdn, 2765 const char *fulldn, 2766 const ns_ldap_attr_t * const *attrlist, 2767 const ns_cred_t *cred, 2768 const int flags, 2769 ns_ldap_error_t **errorp) 2770 { 2771 char filter[BUFSIZ]; 2772 ns_ldap_result_t *resultp; 2773 int rc = 0; 2774 int i; 2775 ns_ldap_attr_t *new_attrlist[_MAX_ATTR_ETHBOOTP+1]; 2776 ns_ldap_attr_t new_attrlist0; 2777 char *new_attrvalue0[1]; 2778 const ns_ldap_attr_t * const *aptr = attrlist; 2779 ns_ldap_attr_t *aptr2; 2780 ns_ldap_error_t *new_errorp = NULL; 2781 2782 if (rdn == NULL || fulldn == NULL || attrlist == NULL || 2783 errorp == NULL || service == NULL) 2784 return (NS_LDAP_OP_FAILED); 2785 2786 bzero(&new_attrlist, sizeof (new_attrlist)); 2787 bzero(&new_attrlist0, sizeof (new_attrlist0)); 2788 new_attrlist[0] = &new_attrlist0; 2789 new_attrlist[0]->attrvalue = new_attrvalue0; 2790 2791 new_attrlist[0]->attrname = "objectclass"; 2792 new_attrlist[0]->value_count = 1; 2793 if (strcasecmp(service, "ethers") == NULL) { 2794 (void) snprintf(&filter[0], sizeof (filter), 2795 "(&(objectClass=ieee802Device)(%s))", rdn); 2796 new_attrlist[0]->attrvalue[0] = "ieee802Device"; 2797 } else { 2798 (void) snprintf(&filter[0], sizeof (filter), 2799 "(&(objectClass=bootableDevice)(%s))", rdn); 2800 new_attrlist[0]->attrvalue[0] = "bootableDevice"; 2801 } 2802 2803 rc = __ns_ldap_list(service, filter, NULL, (const char **)NULL, 2804 NULL, NS_LDAP_SCOPE_SUBTREE, &resultp, &new_errorp, 2805 NULL, NULL); 2806 2807 switch (rc) { 2808 case NS_LDAP_SUCCESS: 2809 /* 2810 * entry already exists for this service 2811 * return NS_LDAP_INTERNAL and do not modify the incoming errorp 2812 */ 2813 rc = NS_LDAP_INTERNAL; 2814 break; 2815 case NS_LDAP_NOTFOUND: 2816 /* 2817 * entry not found with the given objectclasss but entry exists 2818 * hence add the relevant attribute (macAddress or bootparams). 2819 */ 2820 i = 1; 2821 while (*aptr && (i < _MAX_ATTR_ETHBOOTP)) { 2822 /* aptr2 needed here to avoid lint warning */ 2823 aptr2 = (ns_ldap_attr_t *)*aptr++; 2824 if ((strcasecmp(aptr2->attrname, "cn") != 0) && 2825 (strcasecmp(aptr2->attrname, 2826 "objectclass") != 0)) { 2827 new_attrlist[i++] = (ns_ldap_attr_t *)aptr2; 2828 } 2829 } 2830 2831 if (i != _MAX_ATTR_ETHBOOTP) { 2832 /* we haven't found all expected attributes */ 2833 rc = NS_LDAP_OP_FAILED; 2834 break; 2835 } 2836 2837 aptr = (const ns_ldap_attr_t * const *) new_attrlist; 2838 /* clean errorp first */ 2839 (void) __ns_ldap_freeError(errorp); 2840 rc = __ns_ldap_addAttr(service, fulldn, aptr, cred, flags, 2841 errorp); 2842 break; 2843 default: 2844 /* 2845 * unexpected error happenned 2846 * returning relevant error 2847 */ 2848 (void) __ns_ldap_freeError(errorp); 2849 *errorp = new_errorp; 2850 break; 2851 } 2852 2853 return (rc); 2854 } 2855 2856 /* 2857 * Conversion: publickey 2858 * Input format: struct _ns_pubkey 2859 * Exported objectclass: NisKeyObject 2860 */ 2861 static int 2862 __s_cvt_publickey(const void *data, char **rdn, 2863 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 2864 { 2865 ns_ldap_entry_t *e; 2866 int rc; 2867 char trdn[RDNSIZE]; 2868 /* routine specific */ 2869 struct _ns_pubkey *ptr; 2870 int max_attr = 3; 2871 static char *oclist[] = { 2872 "NisKeyObject", 2873 NULL 2874 }; 2875 2876 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 2877 return (NS_LDAP_OP_FAILED); 2878 *entry = e = __s_mk_entry(oclist, max_attr); 2879 if (e == NULL) 2880 return (NS_LDAP_MEMORY); 2881 2882 /* Convert the structure */ 2883 ptr = (struct _ns_pubkey *)data; 2884 2885 if (ptr->name == NULL || ptr->pubkey == '\0' || ptr->privkey == '\0') { 2886 __ns_ldap_freeEntry(e); 2887 *entry = NULL; 2888 return (NS_LDAP_INVALID_PARAM); 2889 } 2890 2891 /* Create an appropriate rdn */ 2892 if (ptr->hostcred == NS_HOSTCRED_FALSE) 2893 (void) snprintf(trdn, RDNSIZE, "uid=%s", ptr->name); 2894 else 2895 (void) snprintf(trdn, RDNSIZE, "cn=%s", ptr->name); 2896 *rdn = strdup(trdn); 2897 if (*rdn == NULL) { 2898 __ns_ldap_freeEntry(e); 2899 *entry = NULL; 2900 return (NS_LDAP_MEMORY); 2901 } 2902 2903 /* Error check the data and add the attributes */ 2904 2905 rc = __s_add_attr(e, "nisPublickey", ptr->pubkey); 2906 if (rc != NS_LDAP_SUCCESS) { 2907 __s_cvt_freeEntryRdn(entry, rdn); 2908 return (rc); 2909 } 2910 2911 rc = __s_add_attr(e, "nisSecretkey", ptr->privkey); 2912 if (rc != NS_LDAP_SUCCESS) { 2913 __s_cvt_freeEntryRdn(entry, rdn); 2914 return (rc); 2915 } 2916 2917 return (NS_LDAP_SUCCESS); 2918 } 2919 /* 2920 * Conversion: aliases 2921 * Input format: struct _ns_alias 2922 * Exported objectclass: mailGroup 2923 */ 2924 static int 2925 __s_cvt_aliases(const void *data, char **rdn, 2926 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 2927 { 2928 ns_ldap_entry_t *e; 2929 int rc; 2930 char trdn[RDNSIZE]; 2931 /* routine specific */ 2932 struct _ns_alias *ptr; 2933 int max_attr = 4; 2934 int i, j; 2935 char **nm; 2936 static char *oclist[] = { 2937 "mailGroup", 2938 "top", 2939 NULL 2940 }; 2941 2942 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 2943 return (NS_LDAP_OP_FAILED); 2944 *entry = e = __s_mk_entry(oclist, max_attr); 2945 if (e == NULL) 2946 return (NS_LDAP_MEMORY); 2947 2948 /* Convert the structure */ 2949 ptr = (struct _ns_alias *)data; 2950 2951 if (ptr->alias == NULL) { 2952 __ns_ldap_freeEntry(e); 2953 *entry = NULL; 2954 return (NS_LDAP_INVALID_PARAM); 2955 } 2956 2957 /* Create an appropriate rdn */ 2958 (void) snprintf(trdn, RDNSIZE, "cn=%s", ptr->alias); 2959 *rdn = strdup(trdn); 2960 if (*rdn == NULL) { 2961 __ns_ldap_freeEntry(e); 2962 *entry = NULL; 2963 return (NS_LDAP_MEMORY); 2964 } 2965 2966 if (ptr->alias != '\0') { 2967 rc = __s_add_attr(e, "mail", (char *)ptr->alias); 2968 if (rc != NS_LDAP_SUCCESS) { 2969 __s_cvt_freeEntryRdn(entry, rdn); 2970 return (rc); 2971 } 2972 } 2973 2974 /* Error check the data and add the attributes */ 2975 if (ptr->member && ptr->member[0]) { 2976 nm = ptr->member; 2977 for (i = 0; *nm; i++, nm++) 2978 ; 2979 nm = (char **)calloc(i+2, sizeof (char *)); 2980 if (nm == NULL) { 2981 __s_cvt_freeEntryRdn(entry, rdn); 2982 return (NS_LDAP_MEMORY); 2983 } 2984 for (j = 0; j < i; j++) 2985 nm[j] = ptr->member[j]; 2986 2987 rc = __s_add_attrlist(e, "mgrpRFC822MailMember", nm); 2988 free(nm); 2989 nm = NULL; 2990 if (rc != NS_LDAP_SUCCESS) { 2991 __s_cvt_freeEntryRdn(entry, rdn); 2992 return (rc); 2993 } 2994 } 2995 2996 return (NS_LDAP_SUCCESS); 2997 2998 } 2999 /* 3000 * Conversion: automount 3001 * Input format: struct _ns_automount 3002 * Exported objectclass: automount 3003 */ 3004 static int 3005 __s_cvt_auto_mount(const void *data, char **rdn, 3006 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 3007 { 3008 ns_ldap_entry_t *e; 3009 int rc; 3010 char trdn[RDNSIZE]; 3011 /* routine specific */ 3012 struct _ns_automount *ptr; 3013 int max_attr = 6; 3014 void **paramVal = NULL; 3015 char **mappedschema = NULL; 3016 int version1 = 0; 3017 static char *oclist[] = { 3018 NULL, 3019 "top", 3020 NULL 3021 }; 3022 3023 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 3024 return (NS_LDAP_OP_FAILED); 3025 3026 /* determine profile version number */ 3027 rc = __ns_ldap_getParam(NS_LDAP_FILE_VERSION_P, ¶mVal, errorp); 3028 if (paramVal && *paramVal && 3029 strcasecmp(*paramVal, NS_LDAP_VERSION_1) == 0) 3030 version1 = 1; 3031 if (paramVal) 3032 (void) __ns_ldap_freeParam(¶mVal); 3033 if (rc && errorp) 3034 (void) __ns_ldap_freeError(errorp); 3035 3036 /* use old schema for version 1 profiles */ 3037 if (version1) 3038 oclist[0] = "nisObject"; 3039 else 3040 oclist[0] = "automount"; 3041 3042 *entry = e = __s_mk_entry(oclist, max_attr); 3043 if (e == NULL) 3044 return (NS_LDAP_MEMORY); 3045 3046 /* Convert the structure */ 3047 ptr = (struct _ns_automount *)data; 3048 3049 if (ptr->key == NULL || ptr->value == '\0' || ptr->mapname == '\0') { 3050 __ns_ldap_freeEntry(e); 3051 *entry = NULL; 3052 return (NS_LDAP_INVALID_PARAM); 3053 } 3054 3055 /* Create an appropriate rdn */ 3056 (void) snprintf(trdn, RDNSIZE, version1 ? "cn=%s" : "automountKey=%s", 3057 ptr->key); 3058 *rdn = strdup(trdn); 3059 if (*rdn == NULL) { 3060 __ns_ldap_freeEntry(e); 3061 *entry = NULL; 3062 return (NS_LDAP_MEMORY); 3063 } 3064 3065 if (ptr->key != '\0') { 3066 rc = __s_add_attr(e, version1 ? "cn" : "automountKey", 3067 (char *)ptr->key); 3068 if (rc != NS_LDAP_SUCCESS) { 3069 __s_cvt_freeEntryRdn(entry, rdn); 3070 return (rc); 3071 } 3072 } 3073 3074 rc = __s_add_attr(e, version1 ? "nisMapEntry" : "automountInformation", 3075 (char *)ptr->value); 3076 if (rc != NS_LDAP_SUCCESS) { 3077 __s_cvt_freeEntryRdn(entry, rdn); 3078 return (rc); 3079 } 3080 3081 /* 3082 * even for version 2, if automount is mapped to nisObject we 3083 * still need 'nisMapName' attribute 3084 */ 3085 mappedschema = __ns_ldap_getMappedObjectClass("automount", "automount"); 3086 if (mappedschema && mappedschema[0] && 3087 strcasecmp(mappedschema[0], "nisObject") == 0) 3088 version1 = 1; 3089 if (mappedschema) 3090 __s_api_free2dArray(mappedschema); 3091 3092 if (version1) { 3093 rc = __s_add_attr(e, "nisMapName", (char *)ptr->mapname); 3094 if (rc != NS_LDAP_SUCCESS) { 3095 __s_cvt_freeEntryRdn(entry, rdn); 3096 return (rc); 3097 } 3098 } 3099 3100 return (NS_LDAP_SUCCESS); 3101 } 3102 /* 3103 * Conversion: auth_attr 3104 * Input format: authstr_t 3105 * Exported objectclass: SolarisAuthAttr 3106 */ 3107 static int 3108 __s_cvt_authattr(const void *data, char **rdn, 3109 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 3110 { 3111 ns_ldap_entry_t *e; 3112 int rc; 3113 char trdn[RDNSIZE]; 3114 /* routine specific */ 3115 authstr_t *ptr; 3116 int max_attr = 6; 3117 static char *oclist[] = { 3118 "SolarisAuthAttr", 3119 "top", 3120 NULL 3121 }; 3122 3123 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 3124 return (NS_LDAP_OP_FAILED); 3125 3126 *entry = e = __s_mk_entry(oclist, max_attr); 3127 if (e == NULL) 3128 return (NS_LDAP_MEMORY); 3129 3130 /* Convert the structure */ 3131 ptr = (authstr_t *)data; 3132 3133 if (ptr->name == NULL || ptr->name[0] == '\0' || ptr->attr == NULL) { 3134 __ns_ldap_freeEntry(e); 3135 *entry = NULL; 3136 return (NS_LDAP_INVALID_PARAM); 3137 } 3138 3139 /* Create an appropriate rdn */ 3140 (void) snprintf(trdn, RDNSIZE, "cn=%s", ptr->name); 3141 *rdn = strdup(trdn); 3142 if (*rdn == NULL) { 3143 __ns_ldap_freeEntry(e); 3144 *entry = NULL; 3145 return (NS_LDAP_MEMORY); 3146 } 3147 3148 rc = __s_add_attr(e, "cn", ptr->name); 3149 if (rc != NS_LDAP_SUCCESS) { 3150 __s_cvt_freeEntryRdn(entry, rdn); 3151 return (rc); 3152 } 3153 3154 rc = __s_add_attr(e, "SolarisAttrKeyValue", ptr->attr); 3155 if (rc != NS_LDAP_SUCCESS) { 3156 __s_cvt_freeEntryRdn(entry, rdn); 3157 return (rc); 3158 } 3159 3160 if (ptr->res1 != NULL) { 3161 rc = __s_add_attr(e, "SolarisAttrReserved1", ptr->res1); 3162 if (rc != NS_LDAP_SUCCESS) { 3163 __s_cvt_freeEntryRdn(entry, rdn); 3164 return (rc); 3165 } 3166 } 3167 3168 if (ptr->res2 != NULL) { 3169 rc = __s_add_attr(e, "SolarisAttrReserved2", ptr->res2); 3170 if (rc != NS_LDAP_SUCCESS) { 3171 __s_cvt_freeEntryRdn(entry, rdn); 3172 return (rc); 3173 } 3174 } 3175 3176 if (ptr->short_desc != NULL) { 3177 rc = __s_add_attr(e, "SolarisAttrShortDesc", ptr->short_desc); 3178 if (rc != NS_LDAP_SUCCESS) { 3179 __s_cvt_freeEntryRdn(entry, rdn); 3180 return (rc); 3181 } 3182 } 3183 3184 if (ptr->long_desc != NULL) { 3185 rc = __s_add_attr(e, "SolarisAttrLongDesc", ptr->long_desc); 3186 if (rc != NS_LDAP_SUCCESS) { 3187 __s_cvt_freeEntryRdn(entry, rdn); 3188 return (rc); 3189 } 3190 } 3191 3192 return (NS_LDAP_SUCCESS); 3193 } 3194 /* 3195 * Conversion: exec_attr 3196 * Input format: execstr_t 3197 * Exported objectclass: SolarisExecAttr 3198 */ 3199 static int 3200 __s_cvt_execattr(const void *data, char **rdn, 3201 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 3202 { 3203 ns_ldap_entry_t *e; 3204 int rc; 3205 char trdn[RDNSIZE]; 3206 /* routine specific */ 3207 execstr_t *ptr; 3208 int max_attr = 7; 3209 static char *oclist[] = { 3210 "SolarisExecAttr", 3211 "SolarisProfAttr", 3212 "top", 3213 NULL 3214 }; 3215 3216 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 3217 return (NS_LDAP_OP_FAILED); 3218 3219 *entry = e = __s_mk_entry(oclist, max_attr); 3220 if (e == NULL) 3221 return (NS_LDAP_MEMORY); 3222 3223 /* Convert the structure */ 3224 ptr = (execstr_t *)data; 3225 3226 if (ptr->name == NULL || ptr->name[0] == '\0' || 3227 ptr->policy == NULL || ptr->policy[0] == '\0' || 3228 ptr->type == NULL || ptr->type[0] == '\0' || 3229 ptr->id == NULL || ptr->id[0] == '\0') { 3230 __ns_ldap_freeEntry(e); 3231 *entry = NULL; 3232 return (NS_LDAP_INVALID_PARAM); 3233 } 3234 3235 /* Create an appropriate rdn */ 3236 (void) snprintf(trdn, RDNSIZE, "cn=%s+SolarisKernelSecurityPolicy=%s" 3237 "+SolarisProfileType=%s+SolarisProfileId=%s", 3238 ptr->name, ptr->policy, ptr->type, ptr->id); 3239 *rdn = strdup(trdn); 3240 if (*rdn == NULL) { 3241 __ns_ldap_freeEntry(e); 3242 *entry = NULL; 3243 return (NS_LDAP_MEMORY); 3244 } 3245 3246 rc = __s_add_attr(e, "cn", ptr->name); 3247 if (rc != NS_LDAP_SUCCESS) { 3248 __s_cvt_freeEntryRdn(entry, rdn); 3249 return (rc); 3250 } 3251 3252 rc = __s_add_attr(e, "SolarisKernelSecurityPolicy", ptr->policy); 3253 if (rc != NS_LDAP_SUCCESS) { 3254 __s_cvt_freeEntryRdn(entry, rdn); 3255 return (rc); 3256 } 3257 3258 rc = __s_add_attr(e, "SolarisProfileType", ptr->type); 3259 if (rc != NS_LDAP_SUCCESS) { 3260 __s_cvt_freeEntryRdn(entry, rdn); 3261 return (rc); 3262 } 3263 3264 rc = __s_add_attr(e, "SolarisProfileId", ptr->id); 3265 if (rc != NS_LDAP_SUCCESS) { 3266 __s_cvt_freeEntryRdn(entry, rdn); 3267 return (rc); 3268 } 3269 3270 rc = __s_add_attr(e, "SolarisAttrKeyValue", ptr->attr); 3271 if (rc != NS_LDAP_SUCCESS) { 3272 __s_cvt_freeEntryRdn(entry, rdn); 3273 return (rc); 3274 } 3275 3276 if (ptr->res1 != NULL) { 3277 rc = __s_add_attr(e, "SolarisAttrRes1", ptr->res1); 3278 if (rc != NS_LDAP_SUCCESS) { 3279 __s_cvt_freeEntryRdn(entry, rdn); 3280 return (rc); 3281 } 3282 } 3283 3284 if (ptr->res2 != NULL) { 3285 rc = __s_add_attr(e, "SolarisAttrRes2", ptr->res2); 3286 if (rc != NS_LDAP_SUCCESS) { 3287 __s_cvt_freeEntryRdn(entry, rdn); 3288 return (rc); 3289 } 3290 } 3291 3292 return (NS_LDAP_SUCCESS); 3293 } 3294 /* 3295 * Conversion: prof_attr 3296 * Input format: profstr_t 3297 * Exported objectclass: SolarisProfAttr 3298 */ 3299 static int 3300 __s_cvt_profattr(const void *data, char **rdn, 3301 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 3302 { 3303 ns_ldap_entry_t *e; 3304 int rc; 3305 char trdn[RDNSIZE]; 3306 /* routine specific */ 3307 profstr_t *ptr; 3308 int max_attr = 5; 3309 static char *oclist[] = { 3310 "SolarisProfAttr", 3311 "top", 3312 NULL 3313 }; 3314 3315 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 3316 return (NS_LDAP_OP_FAILED); 3317 3318 *entry = e = __s_mk_entry(oclist, max_attr); 3319 if (e == NULL) 3320 return (NS_LDAP_MEMORY); 3321 3322 /* Convert the structure */ 3323 ptr = (profstr_t *)data; 3324 3325 if (ptr->name == NULL || ptr->name[0] == '\0' || ptr->attr == NULL) { 3326 __ns_ldap_freeEntry(e); 3327 *entry = NULL; 3328 return (NS_LDAP_INVALID_PARAM); 3329 } 3330 3331 /* Create an appropriate rdn */ 3332 (void) snprintf(trdn, RDNSIZE, "cn=%s", ptr->name); 3333 *rdn = strdup(trdn); 3334 if (*rdn == NULL) { 3335 __ns_ldap_freeEntry(e); 3336 *entry = NULL; 3337 return (NS_LDAP_MEMORY); 3338 } 3339 3340 rc = __s_add_attr(e, "cn", ptr->name); 3341 if (rc != NS_LDAP_SUCCESS) { 3342 __s_cvt_freeEntryRdn(entry, rdn); 3343 return (rc); 3344 } 3345 3346 rc = __s_add_attr(e, "SolarisAttrKeyValue", ptr->attr); 3347 if (rc != NS_LDAP_SUCCESS) { 3348 __s_cvt_freeEntryRdn(entry, rdn); 3349 return (rc); 3350 } 3351 3352 if (ptr->res1 != NULL) { 3353 rc = __s_add_attr(e, "SolarisAttrReserved1", ptr->res1); 3354 if (rc != NS_LDAP_SUCCESS) { 3355 __s_cvt_freeEntryRdn(entry, rdn); 3356 return (rc); 3357 } 3358 } 3359 3360 if (ptr->res2 != NULL) { 3361 rc = __s_add_attr(e, "SolarisAttrReserved2", ptr->res2); 3362 if (rc != NS_LDAP_SUCCESS) { 3363 __s_cvt_freeEntryRdn(entry, rdn); 3364 return (rc); 3365 } 3366 } 3367 3368 if (ptr->desc != NULL) { 3369 rc = __s_add_attr(e, "SolarisAttrLongDesc", ptr->desc); 3370 if (rc != NS_LDAP_SUCCESS) { 3371 __s_cvt_freeEntryRdn(entry, rdn); 3372 return (rc); 3373 } 3374 } 3375 3376 return (NS_LDAP_SUCCESS); 3377 } 3378 /* 3379 * Conversion: user_attr 3380 * Input format: userstr_t 3381 * Exported objectclass: SolarisUserAttr 3382 */ 3383 static int 3384 __s_cvt_userattr(const void *data, char **rdn, 3385 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 3386 { 3387 ns_ldap_entry_t *e; 3388 int rc; 3389 char trdn[RDNSIZE]; 3390 /* routine specific */ 3391 userstr_t *ptr; 3392 int max_attr = 5; 3393 static char *oclist[] = { 3394 "SolarisUserAttr", 3395 NULL 3396 }; 3397 3398 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 3399 return (NS_LDAP_OP_FAILED); 3400 3401 *entry = e = __s_mk_entry(oclist, max_attr); 3402 if (e == NULL) 3403 return (NS_LDAP_MEMORY); 3404 3405 /* Convert the structure */ 3406 ptr = (userstr_t *)data; 3407 3408 if (ptr->name == NULL || ptr->name[0] == '\0' || 3409 ptr->attr == NULL) { 3410 __ns_ldap_freeEntry(e); 3411 *entry = NULL; 3412 return (NS_LDAP_INVALID_PARAM); 3413 } 3414 3415 /* Create an appropriate rdn */ 3416 (void) snprintf(trdn, RDNSIZE, "uid=%s", ptr->name); 3417 *rdn = strdup(trdn); 3418 if (*rdn == NULL) { 3419 __ns_ldap_freeEntry(e); 3420 *entry = NULL; 3421 return (NS_LDAP_MEMORY); 3422 } 3423 3424 /* 3425 * SolarisUserAttr has no uid attribute 3426 */ 3427 3428 rc = __s_add_attr(e, "SolarisAttrKeyValue", ptr->attr); 3429 if (rc != NS_LDAP_SUCCESS) { 3430 __s_cvt_freeEntryRdn(entry, rdn); 3431 return (rc); 3432 } 3433 3434 if (ptr->qualifier != NULL) { 3435 rc = __s_add_attr(e, "SolarisUserQualifier", ptr->qualifier); 3436 if (rc != NS_LDAP_SUCCESS) { 3437 __s_cvt_freeEntryRdn(entry, rdn); 3438 return (rc); 3439 } 3440 } 3441 3442 if (ptr->res1 != NULL) { 3443 rc = __s_add_attr(e, "SolarisAttrReserved1", ptr->res1); 3444 if (rc != NS_LDAP_SUCCESS) { 3445 __s_cvt_freeEntryRdn(entry, rdn); 3446 return (rc); 3447 } 3448 } 3449 3450 if (ptr->res2 != NULL) { 3451 rc = __s_add_attr(e, "SolarisAttrReserved2", ptr->res2); 3452 if (rc != NS_LDAP_SUCCESS) { 3453 __s_cvt_freeEntryRdn(entry, rdn); 3454 return (rc); 3455 } 3456 } 3457 3458 return (NS_LDAP_SUCCESS); 3459 } 3460 /* 3461 * Conversion: audit_user 3462 * Input format: au_user_str_t 3463 * Exported objectclass: SolarisAuditUser 3464 */ 3465 static int 3466 __s_cvt_audituser(const void *data, char **rdn, 3467 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 3468 { 3469 ns_ldap_entry_t *e; 3470 int rc; 3471 char trdn[RDNSIZE]; 3472 /* routine specific */ 3473 au_user_str_t *ptr; 3474 int max_attr = 3; 3475 static char *oclist[] = { 3476 "SolarisAuditUser", 3477 NULL 3478 }; 3479 3480 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 3481 return (NS_LDAP_OP_FAILED); 3482 3483 *entry = e = __s_mk_entry(oclist, max_attr); 3484 if (e == NULL) 3485 return (NS_LDAP_MEMORY); 3486 3487 /* Convert the structure */ 3488 ptr = (au_user_str_t *)data; 3489 3490 if (ptr->au_name == NULL || ptr->au_name[0] == '\0') { 3491 __ns_ldap_freeEntry(e); 3492 *entry = NULL; 3493 return (NS_LDAP_INVALID_PARAM); 3494 } 3495 3496 /* Create an appropriate rdn */ 3497 (void) snprintf(trdn, RDNSIZE, "uid=%s", ptr->au_name); 3498 *rdn = strdup(trdn); 3499 if (*rdn == NULL) { 3500 __ns_ldap_freeEntry(e); 3501 *entry = NULL; 3502 return (NS_LDAP_MEMORY); 3503 } 3504 3505 /* 3506 * Solaris AuditUser has no uid attribute 3507 */ 3508 3509 if (ptr->au_always != NULL) { 3510 rc = __s_add_attr(e, "SolarisAuditAlways", ptr->au_always); 3511 if (rc != NS_LDAP_SUCCESS) { 3512 __s_cvt_freeEntryRdn(entry, rdn); 3513 return (rc); 3514 } 3515 } 3516 3517 if (ptr->au_never != NULL) { 3518 rc = __s_add_attr(e, "SolarisAuditNever", ptr->au_never); 3519 if (rc != NS_LDAP_SUCCESS) { 3520 __s_cvt_freeEntryRdn(entry, rdn); 3521 return (rc); 3522 } 3523 } 3524 3525 return (NS_LDAP_SUCCESS); 3526 } 3527 /* 3528 * Conversion: tnrhtp 3529 * Input format: tsol_tpstr_t 3530 * Exported objectclass: ipTnetTemplate 3531 */ 3532 static int 3533 __s_cvt_tnrhtp(const void *data, char **rdn, 3534 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 3535 { 3536 ns_ldap_entry_t *e; 3537 int rc; 3538 char trdn[RDNSIZE]; 3539 /* routine specific */ 3540 int max_attr = 2; 3541 tsol_tpstr_t *ptr; 3542 static char *oclist[] = { 3543 "ipTnetTemplate", 3544 "top", 3545 NULL 3546 }; 3547 3548 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 3549 return (NS_LDAP_OP_FAILED); 3550 3551 *entry = e = __s_mk_entry(oclist, max_attr); 3552 if (e == NULL) 3553 return (NS_LDAP_MEMORY); 3554 3555 /* Convert the structure */ 3556 ptr = (tsol_tpstr_t *)data; 3557 3558 if (ptr->template == NULL || *ptr->template == '\0') { 3559 __ns_ldap_freeEntry(e); 3560 *entry = NULL; 3561 return (NS_LDAP_INVALID_PARAM); 3562 } 3563 3564 /* Create an appropriate rdn */ 3565 (void) snprintf(trdn, RDNSIZE, "ipTnetTemplateName=%s", ptr->template); 3566 *rdn = strdup(trdn); 3567 if (*rdn == NULL) { 3568 __ns_ldap_freeEntry(e); 3569 *entry = NULL; 3570 return (NS_LDAP_MEMORY); 3571 } 3572 3573 rc = __s_add_attr(e, "ipTnetTemplateName", ptr->template); 3574 if (rc != NS_LDAP_SUCCESS) { 3575 __s_cvt_freeEntryRdn(entry, rdn); 3576 return (rc); 3577 } 3578 3579 rc = __s_add_attr(e, "SolarisAttrKeyValue", ptr->attrs); 3580 if (rc != NS_LDAP_SUCCESS) { 3581 __s_cvt_freeEntryRdn(entry, rdn); 3582 return (rc); 3583 } 3584 3585 return (NS_LDAP_SUCCESS); 3586 } 3587 /* 3588 * Conversion: tnrhdb 3589 * Input format: tsol_rhstr_t 3590 * Exported objectclass: ipTnetHost 3591 */ 3592 static int 3593 __s_cvt_tnrhdb(const void *data, char **rdn, 3594 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 3595 { 3596 ns_ldap_entry_t *e; 3597 int rc; 3598 char trdn[RDNSIZE]; 3599 /* routine specific */ 3600 tsol_rhstr_t *ptr; 3601 int max_attr = 2; 3602 static char *oclist[] = { 3603 "ipTnetHost", 3604 "ipTnetTemplate", 3605 "top", 3606 NULL 3607 }; 3608 3609 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 3610 return (NS_LDAP_OP_FAILED); 3611 3612 *entry = e = __s_mk_entry(oclist, max_attr); 3613 if (e == NULL) 3614 return (NS_LDAP_MEMORY); 3615 3616 /* Convert the structure */ 3617 ptr = (tsol_rhstr_t *)data; 3618 3619 if (ptr->address == NULL || *ptr->address == '\0' || 3620 ptr->template == NULL || *ptr->template == '\0') { 3621 __ns_ldap_freeEntry(e); 3622 *entry = NULL; 3623 return (NS_LDAP_INVALID_PARAM); 3624 } 3625 3626 /* Create an appropriate rdn */ 3627 (void) snprintf(trdn, RDNSIZE, "ipTnetNumber=%s", ptr->address); 3628 *rdn = strdup(trdn); 3629 if (*rdn == NULL) { 3630 __ns_ldap_freeEntry(e); 3631 *entry = NULL; 3632 return (NS_LDAP_MEMORY); 3633 } 3634 3635 rc = __s_add_attr(e, "ipTnetNumber", ptr->address); 3636 if (rc != NS_LDAP_SUCCESS) { 3637 __s_cvt_freeEntryRdn(entry, rdn); 3638 return (rc); 3639 } 3640 3641 rc = __s_add_attr(e, "ipTnetTemplateName", ptr->template); 3642 if (rc != NS_LDAP_SUCCESS) { 3643 __s_cvt_freeEntryRdn(entry, rdn); 3644 return (rc); 3645 } 3646 3647 return (NS_LDAP_SUCCESS); 3648 } 3649 /* 3650 * Add Typed Entry Conversion data structures 3651 */ 3652 3653 typedef struct __ns_cvt_type { 3654 const char *service; 3655 int flags; 3656 #define AE 1 /* alway add entries */ 3657 int (*cvt_rtn)(const void *data, 3658 char **rdn, 3659 ns_ldap_entry_t **entry, 3660 ns_ldap_error_t **errorp); 3661 } __ns_cvt_type_t; 3662 3663 static __ns_cvt_type_t __s_cvtlist[] = { 3664 { NS_LDAP_TYPE_PASSWD, 0, __s_cvt_passwd }, 3665 { NS_LDAP_TYPE_GROUP, 0, __s_cvt_group }, 3666 { NS_LDAP_TYPE_HOSTS, 0, __s_cvt_hosts }, 3667 { NS_LDAP_TYPE_IPNODES, 0, __s_cvt_hosts }, 3668 { NS_LDAP_TYPE_RPC, 0, __s_cvt_rpc }, 3669 { NS_LDAP_TYPE_PROTOCOLS, 0, __s_cvt_protocols }, 3670 { NS_LDAP_TYPE_NETWORKS, 0, __s_cvt_networks }, 3671 { NS_LDAP_TYPE_NETGROUP, 0, __s_cvt_netgroups }, 3672 { NS_LDAP_TYPE_ALIASES, 0, __s_cvt_aliases }, 3673 { NS_LDAP_TYPE_SERVICES, 0, __s_cvt_services }, 3674 { NS_LDAP_TYPE_ETHERS, 0, __s_cvt_ethers }, 3675 { NS_LDAP_TYPE_SHADOW, 0, __s_cvt_shadow }, 3676 { NS_LDAP_TYPE_NETMASKS, 0, __s_cvt_netmasks }, 3677 { NS_LDAP_TYPE_BOOTPARAMS, 0, __s_cvt_bootparams }, 3678 { NS_LDAP_TYPE_AUTHATTR, 0, __s_cvt_authattr }, 3679 { NS_LDAP_TYPE_EXECATTR, 0, __s_cvt_execattr }, 3680 { NS_LDAP_TYPE_PROFILE, 0, __s_cvt_profattr }, 3681 { NS_LDAP_TYPE_USERATTR, AE, __s_cvt_userattr }, 3682 { NS_LDAP_TYPE_AUTOMOUNT, 0, __s_cvt_auto_mount }, 3683 { NS_LDAP_TYPE_PUBLICKEY, AE, __s_cvt_publickey }, 3684 { NS_LDAP_TYPE_AUUSER, AE, __s_cvt_audituser }, 3685 { NS_LDAP_TYPE_TNRHTP, 0, __s_cvt_tnrhtp }, 3686 { NS_LDAP_TYPE_TNRHDB, 0, __s_cvt_tnrhdb }, 3687 { NS_LDAP_TYPE_PROJECT, 0, __s_cvt_project }, 3688 { NULL, 0, NULL }, 3689 }; 3690 3691 /* 3692 * Add Typed Entry Routine 3693 */ 3694 3695 /*ARGSUSED*/ 3696 int __ns_ldap_addTypedEntry( 3697 const char *servicetype, 3698 const char *basedn, 3699 const void *data, 3700 const int create, 3701 const ns_cred_t *cred, 3702 const int flags, 3703 ns_ldap_error_t **errorp) 3704 { 3705 char *rdn = NULL, *fulldn = NULL; 3706 void **paramVal = NULL; 3707 ns_ldap_entry_t *entry = NULL; 3708 const ns_ldap_attr_t *const *modattrlist; 3709 ns_ldap_search_desc_t **sdlist; 3710 char **dns = NULL; 3711 char trdn[RDNSIZE]; 3712 char service[BUFSIZE]; 3713 int rc = 0; 3714 int automount = 0; 3715 int i, s; 3716 3717 rc = NS_LDAP_OP_FAILED; 3718 for (s = 0; __s_cvtlist[s].service != NULL; s++) { 3719 if (__s_cvtlist[s].cvt_rtn == NULL) 3720 continue; 3721 if (strcasecmp(__s_cvtlist[s].service, servicetype) == 0) 3722 break; 3723 /* Or, check if the servicetype is auto_ */ 3724 if (strcmp(__s_cvtlist[s].service, 3725 NS_LDAP_TYPE_AUTOMOUNT) == 0 && 3726 strncasecmp(servicetype, NS_LDAP_TYPE_AUTOMOUNT, 3727 sizeof (NS_LDAP_TYPE_AUTOMOUNT) - 1) == 0) { 3728 automount++; 3729 break; 3730 } 3731 } 3732 if (__s_cvtlist[s].service == NULL) 3733 return (rc); 3734 3735 /* Convert the data */ 3736 rc = (*__s_cvtlist[s].cvt_rtn)(data, &rdn, &entry, errorp); 3737 if (rc != NS_LDAP_SUCCESS) { 3738 __s_cvt_freeEntryRdn(&entry, &rdn); 3739 return (rc); 3740 } 3741 if (rdn == NULL) { 3742 __ns_ldap_freeEntry(entry); 3743 return (NS_LDAP_OP_FAILED); 3744 } 3745 3746 if (strcmp(servicetype, "publickey") == 0) { 3747 struct _ns_pubkey *ptr; 3748 ptr = (struct _ns_pubkey *)data; 3749 if (ptr->hostcred == NS_HOSTCRED_TRUE) 3750 (void) strcpy(service, "hosts"); 3751 else 3752 (void) strcpy(service, "passwd"); 3753 } else 3754 (void) strcpy(service, servicetype); 3755 3756 /* Create the Full DN */ 3757 if (basedn == NULL) { 3758 rc = __s_api_get_SSD_from_SSDtoUse_service(service, 3759 &sdlist, errorp); 3760 if (rc != NS_LDAP_SUCCESS) { 3761 __s_cvt_freeEntryRdn(&entry, &rdn); 3762 return (rc); 3763 } 3764 3765 if (sdlist == NULL) { 3766 rc = __s_api_getDNs(&dns, service, errorp); 3767 if (rc != NS_LDAP_SUCCESS) { 3768 if (dns) { 3769 __s_api_free2dArray(dns); 3770 dns = NULL; 3771 } 3772 __s_cvt_freeEntryRdn(&entry, &rdn); 3773 return (rc); 3774 } 3775 (void) snprintf(trdn, RDNSIZE, "%s,%s", rdn, dns[0]); 3776 __s_api_free2dArray(dns); 3777 } else { 3778 if (sdlist[0]->basedn) { 3779 (void) snprintf(trdn, RDNSIZE, "%s,%s", 3780 rdn, sdlist[0]->basedn); 3781 } else { 3782 __s_cvt_freeEntryRdn(&entry, &rdn); 3783 return (NS_LDAP_OP_FAILED); 3784 } 3785 } 3786 i = strlen(trdn) - 1; 3787 if (trdn[i] == COMMATOK) { 3788 rc = __ns_ldap_getParam(NS_LDAP_SEARCH_BASEDN_P, 3789 ¶mVal, errorp); 3790 if (rc != NS_LDAP_SUCCESS) { 3791 __s_cvt_freeEntryRdn(&entry, &rdn); 3792 return (rc); 3793 } 3794 i = strlen(trdn) + strlen((char *)(paramVal[0])) + 1; 3795 fulldn = (char *)calloc(i, 1); 3796 if (fulldn == NULL) { 3797 (void) __ns_ldap_freeParam(¶mVal); 3798 __s_cvt_freeEntryRdn(&entry, &rdn); 3799 return (NS_LDAP_MEMORY); 3800 } 3801 (void) snprintf(fulldn, i, "%s%s", trdn, 3802 (char *)(paramVal[0])); 3803 (void) __ns_ldap_freeParam(¶mVal); 3804 } else { 3805 fulldn = strdup(trdn); 3806 if (fulldn == NULL) { 3807 __s_cvt_freeEntryRdn(&entry, &rdn); 3808 return (NS_LDAP_MEMORY); 3809 } 3810 } 3811 } else { 3812 i = strlen(rdn) + strlen(basedn) + 2; 3813 fulldn = (char *)calloc(i, 1); 3814 if (fulldn == NULL) { 3815 __s_cvt_freeEntryRdn(&entry, &rdn); 3816 return (NS_LDAP_MEMORY); 3817 } 3818 (void) snprintf(fulldn, i, "%s,%s", rdn, basedn); 3819 } 3820 3821 modattrlist = (const ns_ldap_attr_t * const *)entry->attr_pair; 3822 /* Check to see if the entry exists already */ 3823 /* May need to delete or update first */ 3824 3825 if (create != 1) { 3826 /* Modify the entry */ 3827 /* 3828 * To add a shadow-like entry, the addTypedEntry function 3829 * would call __ns_ldap_repAttr first, and if server says 3830 * LDAP_NO_SUCH_OBJECT, then it tries __ns_ldap_addEntry. 3831 * This is to allow a netmask entry to be added even if the 3832 * base network entry is not in the directory. It would work 3833 * because the difference between the schema for the network 3834 * and netmask data contains only MAY attributes. 3835 * 3836 * But for shadow data, the attributes do not have MUST 3837 * attributes the base entry needs, so if the __ns_ldap_addEntry 3838 * is executed, it would fail. The real reason, however, is that 3839 * the base entry did not exist. So returning 3840 * LDAP_OBJECT_CLASS_VIOLATION would just confused. 3841 */ 3842 if ((__s_cvtlist[s].flags & AE) != 0) 3843 rc = __ns_ldap_addAttr(service, fulldn, modattrlist, 3844 cred, flags, errorp); 3845 else { 3846 rc = __ns_ldap_repAttr(service, fulldn, modattrlist, 3847 cred, flags, errorp); 3848 if (rc == NS_LDAP_INTERNAL && *errorp && 3849 (*errorp)->status == LDAP_NO_SUCH_OBJECT) { 3850 (void) __ns_ldap_freeError(errorp); 3851 rc = __ns_ldap_addEntry(service, fulldn, 3852 entry, cred, flags, errorp); 3853 if (rc == NS_LDAP_INTERNAL && *errorp && 3854 (*errorp)->status == 3855 LDAP_OBJECT_CLASS_VIOLATION) 3856 (*errorp)->status = LDAP_NO_SUCH_OBJECT; 3857 } 3858 } 3859 } else { 3860 /* Add the entry */ 3861 rc = __ns_ldap_addEntry(service, fulldn, entry, 3862 cred, flags, errorp); 3863 if (rc == NS_LDAP_INTERNAL && *errorp && 3864 (*errorp)->status == LDAP_ALREADY_EXISTS && 3865 ((strcmp(service, "ethers") == 0) || 3866 (strcmp(service, "bootparams") == 0))) { 3867 rc = modify_ethers_bootp(service, rdn, fulldn, 3868 modattrlist, cred, flags, errorp); 3869 } 3870 } 3871 3872 /* Free up entry created by conversion routine */ 3873 if (fulldn != NULL) 3874 free(fulldn); 3875 __s_cvt_freeEntryRdn(&entry, &rdn); 3876 return (rc); 3877 } 3878 3879 3880 /* 3881 * Append the default base dn to the dn 3882 * when it ends with ','. 3883 * e.g. 3884 * SSD = service:ou=foo, 3885 */ 3886 int 3887 __s_api_append_default_basedn( 3888 const char *dn, 3889 char **new_dn, 3890 int *allocated, 3891 ns_ldap_error_t **errp) { 3892 3893 int rc = NS_LDAP_SUCCESS, len = 0; 3894 void **param = NULL; 3895 char *str = NULL; 3896 3897 *allocated = FALSE; 3898 *new_dn = NULL; 3899 3900 if (dn == NULL) 3901 return (NS_LDAP_INVALID_PARAM); 3902 3903 rc = __ns_ldap_getParam(NS_LDAP_SEARCH_BASEDN_P, 3904 (void ***)¶m, errp); 3905 3906 if (rc != NS_LDAP_SUCCESS) { 3907 if (param) 3908 (void) __ns_ldap_freeParam(¶m); 3909 return (rc); 3910 } 3911 3912 len = strlen(dn); 3913 str = ((char **)param)[0]; 3914 len = len + strlen(str) +1; 3915 *new_dn = (char *)malloc(len); 3916 if (*new_dn == NULL) { 3917 (void) __ns_ldap_freeParam(¶m); 3918 return (NS_LDAP_MEMORY); 3919 } 3920 *allocated = TRUE; 3921 3922 (void) strcpy(*new_dn, dn); 3923 (void) strcat(*new_dn, str); 3924 3925 (void) __ns_ldap_freeParam(¶m); 3926 return (NS_LDAP_SUCCESS); 3927 } 3928 3929 /* 3930 * Flatten the input ns_ldap_attr_t list, 'attr', and convert it into an 3931 * ldap_strlist_t structure in buffer 'buf', to be used by ldap_cachemgr. 3932 * The output contains a count, a list of offsets, which show where the 3933 * corresponding copied attribute type and attribute value are located. 3934 * For example, for dn=aaaa, userpassword=bbbb, shadowlastchange=cccc, 3935 * the output is the ldap_strlist_t structure with: ldap_count = 6, 3936 * (buf + ldap_offsets[0]) -> "dn" 3937 * (buf + ldap_offsets[1]) -> "aaaa" 3938 * (buf + ldap_offsets[2]) -> "userPassword" 3939 * (buf + ldap_offsets[3]) -> "bbbb" 3940 * (buf + ldap_offsets[4]) -> "shadowlastchange" 3941 * (buf + ldap_offsets[5]) -> "cccc" 3942 * and all the string data shown above copied into the buffer after 3943 * the offset array. The total length of the data will be the return 3944 * value, or -1 if error. 3945 */ 3946 static int 3947 attr2list(const char *dn, ns_ldap_attr_t **attr, 3948 char *buf, int bufsize) 3949 { 3950 int c = 0; 3951 char *ap; 3952 int ao; 3953 ldap_strlist_t *al = (ldap_strlist_t *)buf; 3954 ns_ldap_attr_t *a = (ns_ldap_attr_t *)*attr; 3955 ns_ldap_attr_t **aptr = (ns_ldap_attr_t **)attr; 3956 3957 /* bufsize > strlen(dn) + strlen("dn") + 1 ('\0') */ 3958 if ((strlen(dn) + 2 + 1) >= bufsize) 3959 return (-1); 3960 3961 /* count number of attributes */ 3962 while (*aptr++) 3963 c++; 3964 al->ldap_count = 2 + c * 2; 3965 ao = sizeof (al->ldap_count) + sizeof (al->ldap_offsets[0]) * 3966 al->ldap_count; 3967 if (ao > bufsize) 3968 return (-1); 3969 al->ldap_offsets[0] = ao; 3970 ap = buf + ao; 3971 ao += 3; 3972 3973 /* copy entry DN */ 3974 if (ao > bufsize) 3975 return (-1); 3976 (void) strlcpy(ap, "dn", bufsize); 3977 ap += 3; 3978 3979 al->ldap_offsets[1] = ao; 3980 ao += strlen(dn) + 1; 3981 if (ao > bufsize) 3982 return (-1); 3983 (void) strlcpy(ap, dn, bufsize); 3984 ap = buf + ao; 3985 3986 aptr = attr; 3987 for (c = 2; c < al->ldap_count; c++, aptr++) { 3988 a = *aptr; 3989 if (a->attrname == NULL || a->attrvalue == NULL || 3990 a->value_count != 1 || a->attrvalue[0] == NULL) 3991 return (-1); 3992 al->ldap_offsets[c] = ao; 3993 ao += strlen(a->attrname) + 1; 3994 if (ao > bufsize) 3995 return (-1); 3996 (void) strlcpy(ap, a->attrname, bufsize); 3997 ap = buf + ao; 3998 3999 c++; 4000 al->ldap_offsets[c] = ao; 4001 ao += strlen(a->attrvalue[0]) + 1; 4002 (void) strlcpy(ap, a->attrvalue[0], bufsize); 4003 ap = buf + ao; 4004 }; 4005 4006 return (ao); 4007 } 4008 4009 /* 4010 * Send a modify request to the ldap_cachemgr daemon 4011 * which will use the admin credential to perform the 4012 * operation. 4013 */ 4014 4015 static int 4016 send_to_cachemgr( 4017 const char *dn, 4018 ns_ldap_attr_t **attr, 4019 ns_ldap_error_t **errorp) 4020 { 4021 union { 4022 ldap_data_t s_d; 4023 char s_b[DOORBUFFERSIZE]; 4024 } space; 4025 4026 ldap_data_t *sptr; 4027 int ndata; 4028 int adata; 4029 int len; 4030 int rc; 4031 char errstr[MAXERROR]; 4032 ldap_admin_mod_result_t *admin_result; 4033 4034 *errorp = NULL; 4035 (void) memset(space.s_b, 0, DOORBUFFERSIZE); 4036 len = attr2list(dn, attr, (char *)&space.s_d.ldap_call.ldap_u.strlist, 4037 sizeof (space) - offsetof(ldap_return_t, ldap_u)); 4038 if (len <= 0) 4039 return (NS_LDAP_INVALID_PARAM); 4040 4041 adata = sizeof (ldap_call_t) + len; 4042 ndata = sizeof (space); 4043 space.s_d.ldap_call.ldap_callnumber = ADMINMODIFY; 4044 sptr = &space.s_d; 4045 4046 switch (__ns_ldap_trydoorcall(&sptr, &ndata, &adata)) { 4047 case NS_CACHE_SUCCESS: 4048 break; 4049 case NS_CACHE_NOTFOUND: 4050 (void) snprintf(errstr, sizeof (errstr), 4051 gettext("Door call ADMINMODIFY to " 4052 "ldap_cachemgr failed - error: %d"), 4053 space.s_d.ldap_ret.ldap_errno); 4054 MKERROR(LOG_WARNING, *errorp, NS_CONFIG_CACHEMGR, 4055 strdup(errstr), NULL); 4056 return (NS_LDAP_OP_FAILED); 4057 break; 4058 default: 4059 return (NS_LDAP_OP_FAILED); 4060 } 4061 4062 admin_result = &sptr->ldap_ret.ldap_u.admin_result; 4063 if (admin_result->ns_err == NS_LDAP_SUCCESS) 4064 rc = NS_LDAP_SUCCESS; 4065 else { 4066 rc = admin_result->ns_err; 4067 if (admin_result->msg_size == 0) 4068 *errorp = __s_api_make_error(admin_result->status, 4069 NULL); 4070 else 4071 *errorp = __s_api_make_error(admin_result->status, 4072 admin_result->msg); 4073 } 4074 4075 /* clean up the door call */ 4076 if (sptr != &space.s_d) { 4077 (void) munmap((char *)sptr, ndata); 4078 } 4079 4080 return (rc); 4081 } 4082