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