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