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