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 for (i = 0; *lm; i++, lm++) 1735 ; 1736 lm = ptr->h_aliases; 1737 nm = (char **)calloc(i+2, sizeof (char *)); 1738 if (nm == NULL) { 1739 __s_cvt_freeEntryRdn(entry, rdn); 1740 return (NS_LDAP_MEMORY); 1741 } 1742 nm[0] = ptr->h_name; 1743 for (j = 0; j < i; j++) 1744 nm[j+1] = ptr->h_aliases[j]; 1745 1746 rc = __s_add_attrlist(e, "cn", nm); 1747 free(nm); 1748 nm = NULL; 1749 if (rc != NS_LDAP_SUCCESS) { 1750 __s_cvt_freeEntryRdn(entry, rdn); 1751 return (rc); 1752 } 1753 } else { 1754 rc = __s_add_attr(e, "cn", ptr->h_name); 1755 if (rc != NS_LDAP_SUCCESS) { 1756 __s_cvt_freeEntryRdn(entry, rdn); 1757 return (rc); 1758 } 1759 } 1760 1761 if (ptr->h_addr_list && ptr->h_addr_list[0]) { 1762 lm = ptr->h_addr_list; 1763 for (i = 0; *lm; i++, lm++) 1764 ; 1765 lm = ptr->h_addr_list; 1766 nm = (char **)calloc(i+2, sizeof (char *)); 1767 if (nm == NULL) { 1768 __s_cvt_freeEntryRdn(entry, rdn); 1769 return (NS_LDAP_MEMORY); 1770 } 1771 for (j = 0; j < i; j++) { 1772 nm[j] = strdup(lm[j]); 1773 if (nm[j] == NULL) { 1774 for (k = 0; k < j; k++) 1775 free(nm[k]); 1776 free(nm); 1777 __s_cvt_freeEntryRdn(entry, rdn); 1778 return (NS_LDAP_MEMORY); 1779 } 1780 } 1781 rc = __s_add_attrlist(e, "ipHostNumber", nm); 1782 for (j = 0; j < i; j++) { 1783 free(nm[j]); 1784 } 1785 free(nm); 1786 nm = NULL; 1787 if (rc != NS_LDAP_SUCCESS) { 1788 __s_cvt_freeEntryRdn(entry, rdn); 1789 return (rc); 1790 } 1791 } else { 1792 __s_cvt_freeEntryRdn(entry, rdn); 1793 return (NS_LDAP_INVALID_PARAM); 1794 } 1795 1796 return (NS_LDAP_SUCCESS); 1797 } 1798 1799 /* 1800 * Conversion: rpc 1801 * Input format: struct rpcent 1802 * Exported objectclass: oncRpc 1803 */ 1804 static int 1805 __s_cvt_rpc(const void *data, char **rdn, 1806 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 1807 { 1808 ns_ldap_entry_t *e; 1809 int rc; 1810 char trdn[RDNSIZE]; 1811 /* routine specific */ 1812 struct rpcent *ptr; 1813 int max_attr = 3; 1814 int i, j; 1815 char **nm; 1816 char ibuf[10]; 1817 static char *oclist[] = { 1818 "oncRpc", 1819 "top", 1820 NULL 1821 }; 1822 1823 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 1824 return (NS_LDAP_OP_FAILED); 1825 *entry = e = __s_mk_entry(oclist, max_attr); 1826 if (e == NULL) 1827 return (NS_LDAP_MEMORY); 1828 1829 /* Convert the structure */ 1830 ptr = (struct rpcent *)data; 1831 1832 if (ptr->r_name == NULL || ptr->r_number < 0) { 1833 __ns_ldap_freeEntry(e); 1834 *entry = NULL; 1835 return (NS_LDAP_INVALID_PARAM); 1836 } 1837 1838 /* Create an appropriate rdn */ 1839 (void) snprintf(trdn, RDNSIZE, "cn=%s", ptr->r_name); 1840 *rdn = strdup(trdn); 1841 if (*rdn == NULL) { 1842 __ns_ldap_freeEntry(e); 1843 *entry = NULL; 1844 return (NS_LDAP_MEMORY); 1845 } 1846 1847 /* Error check the data and add the attributes */ 1848 if (ptr->r_aliases && ptr->r_aliases[0]) { 1849 nm = ptr->r_aliases; 1850 for (i = 0; *nm; i++, nm++) 1851 ; 1852 nm = (char **)calloc(i+2, sizeof (char *)); 1853 if (nm == NULL) { 1854 __s_cvt_freeEntryRdn(entry, rdn); 1855 return (NS_LDAP_MEMORY); 1856 } 1857 nm[0] = ptr->r_name; 1858 for (j = 0; j < i; j++) 1859 nm[j+1] = ptr->r_aliases[j]; 1860 1861 rc = __s_add_attrlist(e, "cn", nm); 1862 free(nm); 1863 nm = NULL; 1864 if (rc != NS_LDAP_SUCCESS) { 1865 __s_cvt_freeEntryRdn(entry, rdn); 1866 return (rc); 1867 } 1868 } else { 1869 rc = __s_add_attr(e, "cn", ptr->r_name); 1870 if (rc != NS_LDAP_SUCCESS) { 1871 __s_cvt_freeEntryRdn(entry, rdn); 1872 return (rc); 1873 } 1874 } 1875 1876 if (ptr->r_number >= 0) { 1877 (void) sprintf(ibuf, "%d", ptr->r_number); 1878 rc = __s_add_attr(e, "oncRpcNumber", ibuf); 1879 if (rc != NS_LDAP_SUCCESS) { 1880 __s_cvt_freeEntryRdn(entry, rdn); 1881 return (rc); 1882 } 1883 } 1884 1885 return (NS_LDAP_SUCCESS); 1886 1887 } 1888 1889 /* 1890 * Conversion: protocols 1891 * Input format: struct protoent 1892 * Exported objectclass: ipProtocol 1893 */ 1894 static int 1895 __s_cvt_protocols(const void *data, char **rdn, 1896 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 1897 { 1898 ns_ldap_entry_t *e; 1899 int rc; 1900 char trdn[RDNSIZE]; 1901 /* routine specific */ 1902 struct protoent *ptr; 1903 int max_attr = 3; 1904 int i, j; 1905 char ibuf[10]; 1906 char **nm; 1907 static char *oclist[] = { 1908 "ipProtocol", 1909 "top", 1910 NULL 1911 }; 1912 1913 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 1914 return (NS_LDAP_OP_FAILED); 1915 *entry = e = __s_mk_entry(oclist, max_attr); 1916 if (e == NULL) 1917 return (NS_LDAP_MEMORY); 1918 1919 /* Convert the structure */ 1920 ptr = (struct protoent *)data; 1921 1922 if (ptr->p_name == NULL || ptr->p_proto < 0) { 1923 __ns_ldap_freeEntry(e); 1924 *entry = NULL; 1925 return (NS_LDAP_INVALID_PARAM); 1926 } 1927 1928 /* Create an appropriate rdn */ 1929 (void) snprintf(trdn, RDNSIZE, "cn=%s", ptr->p_name); 1930 *rdn = strdup(trdn); 1931 if (*rdn == NULL) { 1932 __ns_ldap_freeEntry(e); 1933 *entry = NULL; 1934 return (NS_LDAP_MEMORY); 1935 } 1936 1937 /* Error check the data and add the attributes */ 1938 if (ptr->p_aliases && ptr->p_aliases[0]) { 1939 nm = ptr->p_aliases; 1940 for (i = 0; *nm; i++, nm++) 1941 ; 1942 nm = (char **)calloc(i+2, sizeof (char *)); 1943 if (nm == NULL) { 1944 __s_cvt_freeEntryRdn(entry, rdn); 1945 return (NS_LDAP_MEMORY); 1946 } 1947 nm[0] = ptr->p_name; 1948 for (j = 0; j < i; j++) 1949 nm[j+1] = ptr->p_aliases[j]; 1950 1951 rc = __s_add_attrlist(e, "cn", nm); 1952 free(nm); 1953 nm = NULL; 1954 if (rc != NS_LDAP_SUCCESS) { 1955 __s_cvt_freeEntryRdn(entry, rdn); 1956 return (rc); 1957 } 1958 } else { 1959 rc = __s_add_attr(e, "cn", ptr->p_name); 1960 if (rc != NS_LDAP_SUCCESS) { 1961 __s_cvt_freeEntryRdn(entry, rdn); 1962 return (rc); 1963 } 1964 } 1965 1966 (void) sprintf(ibuf, "%d", ptr->p_proto); 1967 rc = __s_add_attr(e, "ipProtocolNumber", ibuf); 1968 if (rc != NS_LDAP_SUCCESS) { 1969 __s_cvt_freeEntryRdn(entry, rdn); 1970 return (rc); 1971 } 1972 1973 return (NS_LDAP_SUCCESS); 1974 1975 } 1976 1977 /* 1978 * Conversion: services 1979 * Input format: struct servent 1980 * Exported objectclass: ipService 1981 */ 1982 static int 1983 __s_cvt_services(const void *data, char **rdn, 1984 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 1985 { 1986 ns_ldap_entry_t *e; 1987 int rc; 1988 char trdn[RDNSIZE]; 1989 /* routine specific */ 1990 struct servent *ptr; 1991 int max_attr = 4; 1992 int i, j; 1993 char ibuf[10]; 1994 char **nm; 1995 static char *oclist[] = { 1996 "ipService", 1997 "top", 1998 NULL 1999 }; 2000 2001 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 2002 return (NS_LDAP_OP_FAILED); 2003 *entry = e = __s_mk_entry(oclist, max_attr); 2004 if (e == NULL) 2005 return (NS_LDAP_MEMORY); 2006 2007 /* Convert the structure */ 2008 ptr = (struct servent *)data; 2009 2010 if (ptr->s_name == NULL || ptr->s_port < 0 || ptr->s_proto == '\0') { 2011 __ns_ldap_freeEntry(e); 2012 *entry = NULL; 2013 return (NS_LDAP_INVALID_PARAM); 2014 } 2015 2016 /* Create an appropriate rdn */ 2017 (void) snprintf(trdn, RDNSIZE, "cn=%s+ipServiceProtocol=%s", 2018 ptr->s_name, ptr->s_proto); 2019 *rdn = strdup(trdn); 2020 if (*rdn == NULL) { 2021 __ns_ldap_freeEntry(e); 2022 *entry = NULL; 2023 return (NS_LDAP_MEMORY); 2024 } 2025 2026 /* Error check the data and add the attributes */ 2027 if (ptr->s_aliases && ptr->s_aliases[0]) { 2028 nm = ptr->s_aliases; 2029 for (i = 0; *nm; i++, nm++) 2030 ; 2031 nm = (char **)calloc(i+2, sizeof (char *)); 2032 if (nm == NULL) { 2033 __s_cvt_freeEntryRdn(entry, rdn); 2034 return (NS_LDAP_MEMORY); 2035 } 2036 nm[0] = ptr->s_name; 2037 for (j = 0; j < i; j++) 2038 nm[j+1] = ptr->s_aliases[j]; 2039 2040 rc = __s_add_attrlist(e, "cn", nm); 2041 free(nm); 2042 nm = NULL; 2043 if (rc != NS_LDAP_SUCCESS) { 2044 __s_cvt_freeEntryRdn(entry, rdn); 2045 return (rc); 2046 } 2047 } else { 2048 rc = __s_add_attr(e, "cn", ptr->s_name); 2049 if (rc != NS_LDAP_SUCCESS) { 2050 __s_cvt_freeEntryRdn(entry, rdn); 2051 return (rc); 2052 } 2053 } 2054 2055 (void) sprintf(ibuf, "%d", ptr->s_port); 2056 rc = __s_add_attr(e, "ipServicePort", ibuf); 2057 if (rc != NS_LDAP_SUCCESS) { 2058 __s_cvt_freeEntryRdn(entry, rdn); 2059 return (rc); 2060 } 2061 rc = __s_add_attr(e, "ipServiceProtocol", ptr->s_proto); 2062 if (rc != NS_LDAP_SUCCESS) { 2063 __s_cvt_freeEntryRdn(entry, rdn); 2064 return (rc); 2065 } 2066 2067 return (NS_LDAP_SUCCESS); 2068 } 2069 2070 /* 2071 * Conversion: networks 2072 * Input format: struct netent 2073 * Exported objectclass: ipNetwork 2074 */ 2075 static int 2076 __s_cvt_networks(const void *data, char **rdn, 2077 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 2078 { 2079 ns_ldap_entry_t *e; 2080 int rc; 2081 char trdn[RDNSIZE]; 2082 /* routine specific */ 2083 struct netent *ptr; 2084 int max_attr = 4; 2085 int i, j; 2086 char cp[64]; 2087 char **nm; 2088 static char *oclist[] = { 2089 "ipNetwork", 2090 "top", 2091 NULL 2092 }; 2093 2094 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 2095 return (NS_LDAP_OP_FAILED); 2096 *entry = e = __s_mk_entry(oclist, max_attr); 2097 if (e == NULL) 2098 return (NS_LDAP_MEMORY); 2099 2100 /* Convert the structure */ 2101 ptr = (struct netent *)data; 2102 2103 if (ptr->n_name == NULL || ptr->n_net == 0) { 2104 __ns_ldap_freeEntry(e); 2105 *entry = NULL; 2106 return (NS_LDAP_INVALID_PARAM); 2107 } 2108 2109 (void) snprintf(cp, sizeof (cp), "%d.%d.%d.%d", 2110 (ptr->n_net & 0xFF000000) >> 24, 2111 (ptr->n_net & 0x00FF0000) >> 16, 2112 (ptr->n_net & 0x0000FF00) >> 8, 2113 (ptr->n_net & 0x000000FF)); 2114 2115 /* Create an appropriate rdn */ 2116 (void) snprintf(trdn, RDNSIZE, "ipNetworkNumber=%s", cp); 2117 *rdn = strdup(trdn); 2118 if (*rdn == NULL) { 2119 __ns_ldap_freeEntry(e); 2120 *entry = NULL; 2121 return (NS_LDAP_MEMORY); 2122 } 2123 2124 /* Error check the data and add the attributes */ 2125 if (ptr->n_aliases && ptr->n_aliases[0]) { 2126 nm = ptr->n_aliases; 2127 for (i = 0; *nm; i++, nm++) 2128 ; 2129 nm = (char **)calloc(i+2, sizeof (char *)); 2130 if (nm == NULL) { 2131 __s_cvt_freeEntryRdn(entry, rdn); 2132 return (NS_LDAP_MEMORY); 2133 } 2134 nm[0] = ptr->n_name; 2135 for (j = 0; j < i; j++) 2136 nm[j+1] = ptr->n_aliases[j]; 2137 2138 rc = __s_add_attrlist(e, "cn", nm); 2139 free(nm); 2140 nm = NULL; 2141 if (rc != NS_LDAP_SUCCESS) { 2142 __s_cvt_freeEntryRdn(entry, rdn); 2143 return (rc); 2144 } 2145 } else { 2146 rc = __s_add_attr(e, "cn", ptr->n_name); 2147 if (rc != NS_LDAP_SUCCESS) { 2148 __s_cvt_freeEntryRdn(entry, rdn); 2149 return (rc); 2150 } 2151 } 2152 2153 rc = __s_add_attr(e, "ipNetworkNumber", cp); 2154 if (rc != NS_LDAP_SUCCESS) { 2155 __s_cvt_freeEntryRdn(entry, rdn); 2156 return (rc); 2157 } 2158 2159 return (NS_LDAP_SUCCESS); 2160 2161 } 2162 /* 2163 * Conversion: netmasks 2164 * Input format: struct _ns_netmasks 2165 * Exported objectclass: ipNetwork 2166 */ 2167 static int 2168 __s_cvt_netmasks(const void *data, char **rdn, 2169 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 2170 { 2171 ns_ldap_entry_t *e; 2172 int rc; 2173 char trdn[RDNSIZE]; 2174 /* routine specific */ 2175 struct _ns_netmasks *ptr; 2176 int max_attr = 4; 2177 static char *oclist[] = { 2178 "ipNetwork", 2179 "top", 2180 NULL 2181 }; 2182 2183 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 2184 return (NS_LDAP_OP_FAILED); 2185 *entry = e = __s_mk_entry(oclist, max_attr); 2186 if (e == NULL) 2187 return (NS_LDAP_MEMORY); 2188 2189 /* Convert the structure */ 2190 ptr = (struct _ns_netmasks *)data; 2191 2192 if (ptr->netnumber == NULL) { 2193 __ns_ldap_freeEntry(e); 2194 *entry = NULL; 2195 return (NS_LDAP_INVALID_PARAM); 2196 } 2197 2198 /* Create an appropriate rdn */ 2199 (void) snprintf(trdn, RDNSIZE, "ipNetworkNumber=%s", ptr->netnumber); 2200 *rdn = strdup(trdn); 2201 if (*rdn == NULL) { 2202 __ns_ldap_freeEntry(e); 2203 *entry = NULL; 2204 return (NS_LDAP_MEMORY); 2205 } 2206 2207 /* Error check the data and add the attributes */ 2208 rc = __s_add_attr(e, "ipNetworkNumber", ptr->netnumber); 2209 if (rc != NS_LDAP_SUCCESS) { 2210 __s_cvt_freeEntryRdn(entry, rdn); 2211 return (rc); 2212 } 2213 2214 if (ptr->netmask != '\0') { 2215 rc = __s_add_attr(e, "ipNetmaskNumber", ptr->netmask); 2216 if (rc != NS_LDAP_SUCCESS) { 2217 __s_cvt_freeEntryRdn(entry, rdn); 2218 return (rc); 2219 } 2220 } 2221 2222 return (NS_LDAP_SUCCESS); 2223 2224 } 2225 /* 2226 * Conversion: netgroups 2227 * Input format: struct _ns_netgroups 2228 * Exported objectclass: nisNetgroup 2229 */ 2230 static int 2231 __s_cvt_netgroups(const void *data, char **rdn, 2232 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 2233 { 2234 ns_ldap_entry_t *e; 2235 int rc; 2236 char trdn[RDNSIZE]; 2237 /* routine specific */ 2238 struct _ns_netgroups *ptr; 2239 int max_attr = 6; 2240 int i, j; 2241 char **nm; 2242 static char *oclist[] = { 2243 "nisNetgroup", 2244 "top", 2245 NULL 2246 }; 2247 2248 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 2249 return (NS_LDAP_OP_FAILED); 2250 *entry = e = __s_mk_entry(oclist, max_attr); 2251 if (e == NULL) 2252 return (NS_LDAP_MEMORY); 2253 2254 /* Convert the structure */ 2255 ptr = (struct _ns_netgroups *)data; 2256 2257 if (ptr->name == NULL) { 2258 __ns_ldap_freeEntry(e); 2259 *entry = NULL; 2260 return (NS_LDAP_INVALID_PARAM); 2261 } 2262 2263 /* Create an appropriate rdn */ 2264 (void) snprintf(trdn, RDNSIZE, "cn=%s", ptr->name); 2265 *rdn = strdup(trdn); 2266 if (*rdn == NULL) { 2267 __ns_ldap_freeEntry(e); 2268 *entry = NULL; 2269 return (NS_LDAP_MEMORY); 2270 } 2271 2272 if (ptr->name != '\0') { 2273 rc = __s_add_attr(e, "cn", ptr->name); 2274 if (rc != NS_LDAP_SUCCESS) { 2275 __s_cvt_freeEntryRdn(entry, rdn); 2276 return (rc); 2277 } 2278 } 2279 2280 /* Error check the data and add the attributes */ 2281 if (ptr->triplet && ptr->triplet[0]) { 2282 nm = ptr->triplet; 2283 for (i = 0; *nm; i++, nm++) 2284 ; 2285 nm = (char **)calloc(i+2, sizeof (char *)); 2286 if (nm == NULL) { 2287 __s_cvt_freeEntryRdn(entry, rdn); 2288 return (NS_LDAP_MEMORY); 2289 } 2290 for (j = 0; j < i; j++) 2291 nm[j] = ptr->triplet[j]; 2292 2293 rc = __s_add_attrlist(e, "nisNetgroupTriple", nm); 2294 free(nm); 2295 nm = NULL; 2296 if (rc != NS_LDAP_SUCCESS) { 2297 __s_cvt_freeEntryRdn(entry, rdn); 2298 return (rc); 2299 } 2300 } 2301 if (ptr->netgroup && ptr->netgroup[0]) { 2302 nm = ptr->netgroup; 2303 for (i = 0; *nm; i++, nm++) 2304 ; 2305 nm = (char **)calloc(i+2, sizeof (char *)); 2306 if (nm == NULL) { 2307 __s_cvt_freeEntryRdn(entry, rdn); 2308 return (NS_LDAP_MEMORY); 2309 } 2310 for (j = 0; j < i; j++) 2311 nm[j] = ptr->netgroup[j]; 2312 2313 rc = __s_add_attrlist(e, "memberNisNetgroup", nm); 2314 free(nm); 2315 nm = NULL; 2316 if (rc != NS_LDAP_SUCCESS) { 2317 __s_cvt_freeEntryRdn(entry, rdn); 2318 return (rc); 2319 } 2320 } 2321 return (NS_LDAP_SUCCESS); 2322 } 2323 /* 2324 * Conversion: bootparams 2325 * Input format: struct _ns_bootp 2326 * Exported objectclass: bootableDevice, device 2327 */ 2328 static int 2329 __s_cvt_bootparams(const void *data, char **rdn, 2330 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 2331 { 2332 ns_ldap_entry_t *e; 2333 int rc; 2334 char trdn[RDNSIZE]; 2335 /* routine specific */ 2336 struct _ns_bootp *ptr; 2337 int max_attr = 4; 2338 int i, j; 2339 char **nm; 2340 static char *oclist[] = { 2341 "bootableDevice", 2342 "device", 2343 "top", 2344 NULL 2345 }; 2346 2347 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 2348 return (NS_LDAP_OP_FAILED); 2349 *entry = e = __s_mk_entry(oclist, max_attr); 2350 if (e == NULL) 2351 return (NS_LDAP_MEMORY); 2352 2353 /* Convert the structure */ 2354 ptr = (struct _ns_bootp *)data; 2355 2356 if (ptr->name == NULL) { 2357 __ns_ldap_freeEntry(e); 2358 *entry = NULL; 2359 return (NS_LDAP_INVALID_PARAM); 2360 } 2361 2362 /* Create an appropriate rdn */ 2363 (void) snprintf(trdn, RDNSIZE, "cn=%s", ptr->name); 2364 *rdn = strdup(trdn); 2365 if (*rdn == NULL) { 2366 __ns_ldap_freeEntry(e); 2367 *entry = NULL; 2368 return (NS_LDAP_MEMORY); 2369 } 2370 2371 if (ptr->name != '\0') { 2372 rc = __s_add_attr(e, "cn", ptr->name); 2373 if (rc != NS_LDAP_SUCCESS) { 2374 __s_cvt_freeEntryRdn(entry, rdn); 2375 return (rc); 2376 } 2377 } 2378 2379 /* Error check the data and add the attributes */ 2380 if (ptr->param && ptr->param[0]) { 2381 nm = ptr->param; 2382 for (i = 0; *nm; i++, nm++) 2383 ; 2384 nm = (char **)calloc(i+2, sizeof (char *)); 2385 if (nm == NULL) { 2386 __s_cvt_freeEntryRdn(entry, rdn); 2387 return (NS_LDAP_MEMORY); 2388 } 2389 for (j = 0; j < i; j++) 2390 nm[j] = ptr->param[j]; 2391 2392 rc = __s_add_attrlist(e, "bootParameter", nm); 2393 free(nm); 2394 nm = NULL; 2395 if (rc != NS_LDAP_SUCCESS) { 2396 __s_cvt_freeEntryRdn(entry, rdn); 2397 return (rc); 2398 } 2399 } 2400 2401 return (NS_LDAP_SUCCESS); 2402 2403 } 2404 /* 2405 * Conversion: ethers 2406 * Input format: struct _ns_ethers 2407 * Exported objectclass: ieee802Device, device 2408 */ 2409 static int 2410 __s_cvt_ethers(const void *data, char **rdn, 2411 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 2412 { 2413 ns_ldap_entry_t *e; 2414 int rc; 2415 char trdn[RDNSIZE]; 2416 /* routine specific */ 2417 struct _ns_ethers *ptr; 2418 int max_attr = 4; 2419 static char *oclist[] = { 2420 "ieee802Device", 2421 "device", 2422 "top", 2423 NULL 2424 }; 2425 2426 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 2427 return (NS_LDAP_OP_FAILED); 2428 *entry = e = __s_mk_entry(oclist, max_attr); 2429 if (e == NULL) 2430 return (NS_LDAP_MEMORY); 2431 2432 /* Convert the structure */ 2433 ptr = (struct _ns_ethers *)data; 2434 2435 if (ptr->name == NULL || ptr->ether == '\0') { 2436 __ns_ldap_freeEntry(e); 2437 *entry = NULL; 2438 return (NS_LDAP_INVALID_PARAM); 2439 } 2440 2441 /* Create an appropriate rdn */ 2442 (void) snprintf(trdn, RDNSIZE, "cn=%s", ptr->name); 2443 *rdn = strdup(trdn); 2444 if (*rdn == NULL) { 2445 __ns_ldap_freeEntry(e); 2446 *entry = NULL; 2447 return (NS_LDAP_MEMORY); 2448 } 2449 2450 /* Error check the data and add the attributes */ 2451 rc = __s_add_attr(e, "cn", ptr->name); 2452 if (rc != NS_LDAP_SUCCESS) { 2453 __s_cvt_freeEntryRdn(entry, rdn); 2454 return (rc); 2455 } 2456 2457 rc = __s_add_attr(e, "macAddress", ptr->ether); 2458 if (rc != NS_LDAP_SUCCESS) { 2459 __s_cvt_freeEntryRdn(entry, rdn); 2460 return (rc); 2461 } 2462 2463 return (NS_LDAP_SUCCESS); 2464 } 2465 /* 2466 * This function is used when processing an ethers (objectclass: ieee802Device) 2467 * or a bootparams (objectclass: bootableDevice) entry, and the entry is 2468 * already found in LDAP. Since both ethers and bootparams share the same 2469 * LDAP container, we want to check that the entry found in LDAP is: 2470 * - either the same entry (same cn, same objectclass): we don't do anything 2471 * in this case 2472 * - or an entry which does not have the objectclass we are interesting in: 2473 * in this case, we modify the existing entry by adding the relevant 2474 * objectclass (ieee802Device or bootableDevice) and the relevant attribute(s) 2475 * from the attribute list previously computing by the relevant conversion 2476 * function. 2477 * Note: from conversion functions __s_cvt_ethers() and __s_cvt_bootparams() 2478 * we know that there is only 1 more attribute today to add (macAddress 2479 * or bootParameter) 2480 */ 2481 #define _MAX_ATTR_ETHBOOTP 2 2482 static int 2483 modify_ethers_bootp( 2484 const char *service, 2485 const char *rdn, 2486 const char *fulldn, 2487 const ns_ldap_attr_t * const *attrlist, 2488 const ns_cred_t *cred, 2489 const int flags, 2490 ns_ldap_error_t **errorp) 2491 { 2492 char filter[BUFSIZ]; 2493 ns_ldap_result_t *resultp; 2494 int rc = 0; 2495 int i; 2496 ns_ldap_attr_t *new_attrlist[_MAX_ATTR_ETHBOOTP+1]; 2497 ns_ldap_attr_t new_attrlist0; 2498 char *new_attrvalue0[1]; 2499 const ns_ldap_attr_t * const *aptr = attrlist; 2500 ns_ldap_attr_t *aptr2; 2501 ns_ldap_error_t *new_errorp = NULL; 2502 2503 if (rdn == NULL || fulldn == NULL || attrlist == NULL || 2504 errorp == NULL || service == NULL) 2505 return (NS_LDAP_OP_FAILED); 2506 2507 bzero(&new_attrlist, sizeof (new_attrlist)); 2508 bzero(&new_attrlist0, sizeof (new_attrlist0)); 2509 new_attrlist[0] = &new_attrlist0; 2510 new_attrlist[0]->attrvalue = new_attrvalue0; 2511 2512 new_attrlist[0]->attrname = "objectclass"; 2513 new_attrlist[0]->value_count = 1; 2514 if (strcasecmp(service, "ethers") == NULL) { 2515 (void) snprintf(&filter[0], sizeof (filter), 2516 "(&(objectClass=ieee802Device)(%s))", 2517 rdn); 2518 new_attrlist[0]->attrvalue[0] = "ieee802Device"; 2519 } else { 2520 (void) snprintf(&filter[0], sizeof (filter), 2521 "(&(objectClass=bootableDevice)(%s))", 2522 rdn); 2523 new_attrlist[0]->attrvalue[0] = "bootableDevice"; 2524 } 2525 2526 rc = __ns_ldap_list(service, filter, NULL, (const char **)NULL, 2527 NULL, NS_LDAP_SCOPE_SUBTREE, &resultp, &new_errorp, 2528 NULL, NULL); 2529 2530 switch (rc) { 2531 case NS_LDAP_SUCCESS: 2532 /* 2533 * entry already exists for this service 2534 * return NS_LDAP_INTERNAL and do not modify the incoming errorp 2535 */ 2536 rc = NS_LDAP_INTERNAL; 2537 break; 2538 case NS_LDAP_NOTFOUND: 2539 /* 2540 * entry not found with the given objectclasss but entry exists 2541 * hence add the relevant attribute (macAddress or bootparams). 2542 */ 2543 i = 1; 2544 while (*aptr && (i < _MAX_ATTR_ETHBOOTP)) { 2545 /* aptr2 needed here to avoid lint warning */ 2546 aptr2 = (ns_ldap_attr_t *)*aptr++; 2547 if ((strcasecmp(aptr2->attrname, "cn") != 0) && 2548 (strcasecmp(aptr2->attrname, 2549 "objectclass") != 0)) { 2550 new_attrlist[i++] = (ns_ldap_attr_t *)aptr2; 2551 } 2552 } 2553 2554 if (i != _MAX_ATTR_ETHBOOTP) { 2555 /* we haven't found all expected attributes */ 2556 rc = NS_LDAP_OP_FAILED; 2557 break; 2558 } 2559 2560 aptr = (const ns_ldap_attr_t * const *) new_attrlist; 2561 /* clean errorp first */ 2562 (void) __ns_ldap_freeError(errorp); 2563 rc = __ns_ldap_addAttr(service, fulldn, aptr, cred, flags, 2564 errorp); 2565 break; 2566 default: 2567 /* 2568 * unexpected error happenned 2569 * returning relevant error 2570 */ 2571 (void) __ns_ldap_freeError(errorp); 2572 *errorp = new_errorp; 2573 break; 2574 } 2575 2576 return (rc); 2577 } 2578 2579 /* 2580 * Conversion: publickey 2581 * Input format: struct _ns_pubkey 2582 * Exported objectclass: NisKeyObject 2583 */ 2584 static int 2585 __s_cvt_publickey(const void *data, char **rdn, 2586 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 2587 { 2588 ns_ldap_entry_t *e; 2589 int rc; 2590 char trdn[RDNSIZE]; 2591 /* routine specific */ 2592 struct _ns_pubkey *ptr; 2593 int max_attr = 3; 2594 static char *oclist[] = { 2595 "NisKeyObject", 2596 NULL 2597 }; 2598 2599 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 2600 return (NS_LDAP_OP_FAILED); 2601 *entry = e = __s_mk_entry(oclist, max_attr); 2602 if (e == NULL) 2603 return (NS_LDAP_MEMORY); 2604 2605 /* Convert the structure */ 2606 ptr = (struct _ns_pubkey *)data; 2607 2608 if (ptr->name == NULL || ptr->pubkey == '\0' || ptr->privkey == '\0') { 2609 __ns_ldap_freeEntry(e); 2610 *entry = NULL; 2611 return (NS_LDAP_INVALID_PARAM); 2612 } 2613 2614 /* Create an appropriate rdn */ 2615 if (ptr->hostcred == NS_HOSTCRED_FALSE) 2616 (void) snprintf(trdn, RDNSIZE, "uid=%s", ptr->name); 2617 else 2618 (void) snprintf(trdn, RDNSIZE, "cn=%s", ptr->name); 2619 *rdn = strdup(trdn); 2620 if (*rdn == NULL) { 2621 __ns_ldap_freeEntry(e); 2622 *entry = NULL; 2623 return (NS_LDAP_MEMORY); 2624 } 2625 2626 /* Error check the data and add the attributes */ 2627 2628 rc = __s_add_attr(e, "nisPublickey", ptr->pubkey); 2629 if (rc != NS_LDAP_SUCCESS) { 2630 __s_cvt_freeEntryRdn(entry, rdn); 2631 return (rc); 2632 } 2633 2634 rc = __s_add_attr(e, "nisSecretkey", ptr->privkey); 2635 if (rc != NS_LDAP_SUCCESS) { 2636 __s_cvt_freeEntryRdn(entry, rdn); 2637 return (rc); 2638 } 2639 2640 return (NS_LDAP_SUCCESS); 2641 } 2642 /* 2643 * Conversion: aliases 2644 * Input format: struct _ns_alias 2645 * Exported objectclass: mailGroup 2646 */ 2647 static int 2648 __s_cvt_aliases(const void *data, char **rdn, 2649 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 2650 { 2651 ns_ldap_entry_t *e; 2652 int rc; 2653 char trdn[RDNSIZE]; 2654 /* routine specific */ 2655 struct _ns_alias *ptr; 2656 int max_attr = 4; 2657 int i, j; 2658 char **nm; 2659 static char *oclist[] = { 2660 "mailGroup", 2661 "top", 2662 NULL 2663 }; 2664 2665 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 2666 return (NS_LDAP_OP_FAILED); 2667 *entry = e = __s_mk_entry(oclist, max_attr); 2668 if (e == NULL) 2669 return (NS_LDAP_MEMORY); 2670 2671 /* Convert the structure */ 2672 ptr = (struct _ns_alias *)data; 2673 2674 if (ptr->alias == NULL) { 2675 __ns_ldap_freeEntry(e); 2676 *entry = NULL; 2677 return (NS_LDAP_INVALID_PARAM); 2678 } 2679 2680 /* Create an appropriate rdn */ 2681 (void) snprintf(trdn, RDNSIZE, "cn=%s", ptr->alias); 2682 *rdn = strdup(trdn); 2683 if (*rdn == NULL) { 2684 __ns_ldap_freeEntry(e); 2685 *entry = NULL; 2686 return (NS_LDAP_MEMORY); 2687 } 2688 2689 if (ptr->alias != '\0') { 2690 rc = __s_add_attr(e, "mail", (char *)ptr->alias); 2691 if (rc != NS_LDAP_SUCCESS) { 2692 __s_cvt_freeEntryRdn(entry, rdn); 2693 return (rc); 2694 } 2695 } 2696 2697 /* Error check the data and add the attributes */ 2698 if (ptr->member && ptr->member[0]) { 2699 nm = ptr->member; 2700 for (i = 0; *nm; i++, nm++) 2701 ; 2702 nm = (char **)calloc(i+2, sizeof (char *)); 2703 if (nm == NULL) { 2704 __s_cvt_freeEntryRdn(entry, rdn); 2705 return (NS_LDAP_MEMORY); 2706 } 2707 for (j = 0; j < i; j++) 2708 nm[j] = ptr->member[j]; 2709 2710 rc = __s_add_attrlist(e, "mgrpRFC822MailMember", nm); 2711 free(nm); 2712 nm = NULL; 2713 if (rc != NS_LDAP_SUCCESS) { 2714 __s_cvt_freeEntryRdn(entry, rdn); 2715 return (rc); 2716 } 2717 } 2718 2719 return (NS_LDAP_SUCCESS); 2720 2721 } 2722 /* 2723 * Conversion: automount 2724 * Input format: struct _ns_automount 2725 * Exported objectclass: automount 2726 */ 2727 static int 2728 __s_cvt_auto_mount(const void *data, char **rdn, 2729 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 2730 { 2731 ns_ldap_entry_t *e; 2732 int rc; 2733 char trdn[RDNSIZE]; 2734 /* routine specific */ 2735 struct _ns_automount *ptr; 2736 int max_attr = 6; 2737 void **paramVal = NULL; 2738 char **mappedschema = NULL; 2739 int version1 = 0; 2740 static char *oclist[] = { 2741 NULL, 2742 "top", 2743 NULL 2744 }; 2745 2746 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 2747 return (NS_LDAP_OP_FAILED); 2748 2749 /* determine profile version number */ 2750 rc = __ns_ldap_getParam(NS_LDAP_FILE_VERSION_P, ¶mVal, errorp); 2751 if (paramVal && *paramVal && 2752 strcasecmp(*paramVal, NS_LDAP_VERSION_1) == 0) 2753 version1 = 1; 2754 if (paramVal) 2755 (void) __ns_ldap_freeParam(¶mVal); 2756 if (rc && errorp) 2757 (void) __ns_ldap_freeError(errorp); 2758 2759 /* use old schema for version 1 profiles */ 2760 if (version1) 2761 oclist[0] = "nisObject"; 2762 else 2763 oclist[0] = "automount"; 2764 2765 *entry = e = __s_mk_entry(oclist, max_attr); 2766 if (e == NULL) 2767 return (NS_LDAP_MEMORY); 2768 2769 /* Convert the structure */ 2770 ptr = (struct _ns_automount *)data; 2771 2772 if (ptr->key == NULL || ptr->value == '\0' || ptr->mapname == '\0') { 2773 __ns_ldap_freeEntry(e); 2774 *entry = NULL; 2775 return (NS_LDAP_INVALID_PARAM); 2776 } 2777 2778 /* Create an appropriate rdn */ 2779 (void) snprintf(trdn, RDNSIZE, version1 ? "cn=%s" : "automountKey=%s", 2780 ptr->key); 2781 *rdn = strdup(trdn); 2782 if (*rdn == NULL) { 2783 __ns_ldap_freeEntry(e); 2784 *entry = NULL; 2785 return (NS_LDAP_MEMORY); 2786 } 2787 2788 if (ptr->key != '\0') { 2789 rc = __s_add_attr(e, version1 ? "cn" : "automountKey", 2790 (char *)ptr->key); 2791 if (rc != NS_LDAP_SUCCESS) { 2792 __s_cvt_freeEntryRdn(entry, rdn); 2793 return (rc); 2794 } 2795 } 2796 2797 rc = __s_add_attr(e, version1 ? "nisMapEntry" : "automountInformation", 2798 (char *)ptr->value); 2799 if (rc != NS_LDAP_SUCCESS) { 2800 __s_cvt_freeEntryRdn(entry, rdn); 2801 return (rc); 2802 } 2803 2804 /* 2805 * even for version 2, if automount is mapped to nisObject we 2806 * still need 'nisMapName' attribute 2807 */ 2808 mappedschema = __ns_ldap_getMappedObjectClass("automount", "automount"); 2809 if (mappedschema && mappedschema[0] && 2810 strcasecmp(mappedschema[0], "nisObject") == 0) 2811 version1 = 1; 2812 if (mappedschema) 2813 __s_api_free2dArray(mappedschema); 2814 2815 if (version1) { 2816 rc = __s_add_attr(e, "nisMapName", (char *)ptr->mapname); 2817 if (rc != NS_LDAP_SUCCESS) { 2818 __s_cvt_freeEntryRdn(entry, rdn); 2819 return (rc); 2820 } 2821 } 2822 2823 return (NS_LDAP_SUCCESS); 2824 } 2825 /* 2826 * Conversion: auth_attr 2827 * Input format: authstr_t 2828 * Exported objectclass: SolarisAuthAttr 2829 */ 2830 static int 2831 __s_cvt_authattr(const void *data, char **rdn, 2832 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 2833 { 2834 ns_ldap_entry_t *e; 2835 int rc; 2836 char trdn[RDNSIZE]; 2837 /* routine specific */ 2838 authstr_t *ptr; 2839 int max_attr = 6; 2840 static char *oclist[] = { 2841 "SolarisAuthAttr", 2842 "top", 2843 NULL 2844 }; 2845 2846 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 2847 return (NS_LDAP_OP_FAILED); 2848 2849 *entry = e = __s_mk_entry(oclist, max_attr); 2850 if (e == NULL) 2851 return (NS_LDAP_MEMORY); 2852 2853 /* Convert the structure */ 2854 ptr = (authstr_t *)data; 2855 2856 if (ptr->name == NULL || ptr->name[0] == '\0' || ptr->attr == NULL) { 2857 __ns_ldap_freeEntry(e); 2858 *entry = NULL; 2859 return (NS_LDAP_INVALID_PARAM); 2860 } 2861 2862 /* Create an appropriate rdn */ 2863 (void) snprintf(trdn, RDNSIZE, "cn=%s", ptr->name); 2864 *rdn = strdup(trdn); 2865 if (*rdn == NULL) { 2866 __ns_ldap_freeEntry(e); 2867 *entry = NULL; 2868 return (NS_LDAP_MEMORY); 2869 } 2870 2871 rc = __s_add_attr(e, "cn", ptr->name); 2872 if (rc != NS_LDAP_SUCCESS) { 2873 __s_cvt_freeEntryRdn(entry, rdn); 2874 return (rc); 2875 } 2876 2877 rc = __s_add_attr(e, "SolarisAttrKeyValue", ptr->attr); 2878 if (rc != NS_LDAP_SUCCESS) { 2879 __s_cvt_freeEntryRdn(entry, rdn); 2880 return (rc); 2881 } 2882 2883 if (ptr->res1 != NULL) { 2884 rc = __s_add_attr(e, "SolarisAttrReserved1", ptr->res1); 2885 if (rc != NS_LDAP_SUCCESS) { 2886 __s_cvt_freeEntryRdn(entry, rdn); 2887 return (rc); 2888 } 2889 } 2890 2891 if (ptr->res2 != NULL) { 2892 rc = __s_add_attr(e, "SolarisAttrReserved2", ptr->res2); 2893 if (rc != NS_LDAP_SUCCESS) { 2894 __s_cvt_freeEntryRdn(entry, rdn); 2895 return (rc); 2896 } 2897 } 2898 2899 if (ptr->short_desc != NULL) { 2900 rc = __s_add_attr(e, "SolarisAttrShortDesc", ptr->short_desc); 2901 if (rc != NS_LDAP_SUCCESS) { 2902 __s_cvt_freeEntryRdn(entry, rdn); 2903 return (rc); 2904 } 2905 } 2906 2907 if (ptr->long_desc != NULL) { 2908 rc = __s_add_attr(e, "SolarisAttrLongDesc", ptr->long_desc); 2909 if (rc != NS_LDAP_SUCCESS) { 2910 __s_cvt_freeEntryRdn(entry, rdn); 2911 return (rc); 2912 } 2913 } 2914 2915 return (NS_LDAP_SUCCESS); 2916 } 2917 /* 2918 * Conversion: exec_attr 2919 * Input format: execstr_t 2920 * Exported objectclass: SolarisExecAttr 2921 */ 2922 static int 2923 __s_cvt_execattr(const void *data, char **rdn, 2924 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 2925 { 2926 ns_ldap_entry_t *e; 2927 int rc; 2928 char trdn[RDNSIZE]; 2929 /* routine specific */ 2930 execstr_t *ptr; 2931 int max_attr = 7; 2932 static char *oclist[] = { 2933 "SolarisExecAttr", 2934 "SolarisProfAttr", 2935 "top", 2936 NULL 2937 }; 2938 2939 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 2940 return (NS_LDAP_OP_FAILED); 2941 2942 *entry = e = __s_mk_entry(oclist, max_attr); 2943 if (e == NULL) 2944 return (NS_LDAP_MEMORY); 2945 2946 /* Convert the structure */ 2947 ptr = (execstr_t *)data; 2948 2949 if (ptr->name == NULL || ptr->name[0] == '\0' || 2950 ptr->policy == NULL || ptr->policy[0] == '\0' || 2951 ptr->type == NULL || ptr->type[0] == '\0' || 2952 ptr->id == NULL || ptr->id[0] == '\0') { 2953 __ns_ldap_freeEntry(e); 2954 *entry = NULL; 2955 return (NS_LDAP_INVALID_PARAM); 2956 } 2957 2958 /* Create an appropriate rdn */ 2959 (void) snprintf(trdn, RDNSIZE, "cn=%s+SolarisKernelSecurityPolicy=%s" 2960 "+SolarisProfileType=%s+SolarisProfileId=%s", 2961 ptr->name, ptr->policy, ptr->type, ptr->id); 2962 *rdn = strdup(trdn); 2963 if (*rdn == NULL) { 2964 __ns_ldap_freeEntry(e); 2965 *entry = NULL; 2966 return (NS_LDAP_MEMORY); 2967 } 2968 2969 rc = __s_add_attr(e, "cn", ptr->name); 2970 if (rc != NS_LDAP_SUCCESS) { 2971 __s_cvt_freeEntryRdn(entry, rdn); 2972 return (rc); 2973 } 2974 2975 rc = __s_add_attr(e, "SolarisKernelSecurityPolicy", ptr->policy); 2976 if (rc != NS_LDAP_SUCCESS) { 2977 __s_cvt_freeEntryRdn(entry, rdn); 2978 return (rc); 2979 } 2980 2981 rc = __s_add_attr(e, "SolarisProfileType", ptr->type); 2982 if (rc != NS_LDAP_SUCCESS) { 2983 __s_cvt_freeEntryRdn(entry, rdn); 2984 return (rc); 2985 } 2986 2987 rc = __s_add_attr(e, "SolarisProfileId", ptr->id); 2988 if (rc != NS_LDAP_SUCCESS) { 2989 __s_cvt_freeEntryRdn(entry, rdn); 2990 return (rc); 2991 } 2992 2993 rc = __s_add_attr(e, "SolarisAttrKeyValue", ptr->attr); 2994 if (rc != NS_LDAP_SUCCESS) { 2995 __s_cvt_freeEntryRdn(entry, rdn); 2996 return (rc); 2997 } 2998 2999 if (ptr->res1 != NULL) { 3000 rc = __s_add_attr(e, "SolarisAttrRes1", ptr->res1); 3001 if (rc != NS_LDAP_SUCCESS) { 3002 __s_cvt_freeEntryRdn(entry, rdn); 3003 return (rc); 3004 } 3005 } 3006 3007 if (ptr->res2 != NULL) { 3008 rc = __s_add_attr(e, "SolarisAttrRes2", ptr->res2); 3009 if (rc != NS_LDAP_SUCCESS) { 3010 __s_cvt_freeEntryRdn(entry, rdn); 3011 return (rc); 3012 } 3013 } 3014 3015 return (NS_LDAP_SUCCESS); 3016 } 3017 /* 3018 * Conversion: prof_attr 3019 * Input format: profstr_t 3020 * Exported objectclass: SolarisProfAttr 3021 */ 3022 static int 3023 __s_cvt_profattr(const void *data, char **rdn, 3024 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 3025 { 3026 ns_ldap_entry_t *e; 3027 int rc; 3028 char trdn[RDNSIZE]; 3029 /* routine specific */ 3030 profstr_t *ptr; 3031 int max_attr = 5; 3032 static char *oclist[] = { 3033 "SolarisProfAttr", 3034 "top", 3035 NULL 3036 }; 3037 3038 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 3039 return (NS_LDAP_OP_FAILED); 3040 3041 *entry = e = __s_mk_entry(oclist, max_attr); 3042 if (e == NULL) 3043 return (NS_LDAP_MEMORY); 3044 3045 /* Convert the structure */ 3046 ptr = (profstr_t *)data; 3047 3048 if (ptr->name == NULL || ptr->name[0] == '\0' || ptr->attr == NULL) { 3049 __ns_ldap_freeEntry(e); 3050 *entry = NULL; 3051 return (NS_LDAP_INVALID_PARAM); 3052 } 3053 3054 /* Create an appropriate rdn */ 3055 (void) snprintf(trdn, RDNSIZE, "cn=%s", ptr->name); 3056 *rdn = strdup(trdn); 3057 if (*rdn == NULL) { 3058 __ns_ldap_freeEntry(e); 3059 *entry = NULL; 3060 return (NS_LDAP_MEMORY); 3061 } 3062 3063 rc = __s_add_attr(e, "cn", ptr->name); 3064 if (rc != NS_LDAP_SUCCESS) { 3065 __s_cvt_freeEntryRdn(entry, rdn); 3066 return (rc); 3067 } 3068 3069 rc = __s_add_attr(e, "SolarisAttrKeyValue", ptr->attr); 3070 if (rc != NS_LDAP_SUCCESS) { 3071 __s_cvt_freeEntryRdn(entry, rdn); 3072 return (rc); 3073 } 3074 3075 if (ptr->res1 != NULL) { 3076 rc = __s_add_attr(e, "SolarisAttrReserved1", ptr->res1); 3077 if (rc != NS_LDAP_SUCCESS) { 3078 __s_cvt_freeEntryRdn(entry, rdn); 3079 return (rc); 3080 } 3081 } 3082 3083 if (ptr->res2 != NULL) { 3084 rc = __s_add_attr(e, "SolarisAttrReserved2", ptr->res2); 3085 if (rc != NS_LDAP_SUCCESS) { 3086 __s_cvt_freeEntryRdn(entry, rdn); 3087 return (rc); 3088 } 3089 } 3090 3091 if (ptr->desc != NULL) { 3092 rc = __s_add_attr(e, "SolarisAttrLongDesc", ptr->desc); 3093 if (rc != NS_LDAP_SUCCESS) { 3094 __s_cvt_freeEntryRdn(entry, rdn); 3095 return (rc); 3096 } 3097 } 3098 3099 return (NS_LDAP_SUCCESS); 3100 } 3101 /* 3102 * Conversion: user_attr 3103 * Input format: userstr_t 3104 * Exported objectclass: SolarisUserAttr 3105 */ 3106 static int 3107 __s_cvt_userattr(const void *data, char **rdn, 3108 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 3109 { 3110 ns_ldap_entry_t *e; 3111 int rc; 3112 char trdn[RDNSIZE]; 3113 /* routine specific */ 3114 userstr_t *ptr; 3115 int max_attr = 5; 3116 static char *oclist[] = { 3117 "SolarisUserAttr", 3118 NULL 3119 }; 3120 3121 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 3122 return (NS_LDAP_OP_FAILED); 3123 3124 *entry = e = __s_mk_entry(oclist, max_attr); 3125 if (e == NULL) 3126 return (NS_LDAP_MEMORY); 3127 3128 /* Convert the structure */ 3129 ptr = (userstr_t *)data; 3130 3131 if (ptr->name == NULL || ptr->name[0] == '\0' || 3132 ptr->attr == NULL) { 3133 __ns_ldap_freeEntry(e); 3134 *entry = NULL; 3135 return (NS_LDAP_INVALID_PARAM); 3136 } 3137 3138 /* Create an appropriate rdn */ 3139 (void) snprintf(trdn, RDNSIZE, "uid=%s", ptr->name); 3140 *rdn = strdup(trdn); 3141 if (*rdn == NULL) { 3142 __ns_ldap_freeEntry(e); 3143 *entry = NULL; 3144 return (NS_LDAP_MEMORY); 3145 } 3146 3147 /* 3148 * SolarisUserAttr has no uid attribute 3149 */ 3150 3151 rc = __s_add_attr(e, "SolarisAttrKeyValue", ptr->attr); 3152 if (rc != NS_LDAP_SUCCESS) { 3153 __s_cvt_freeEntryRdn(entry, rdn); 3154 return (rc); 3155 } 3156 3157 if (ptr->qualifier != NULL) { 3158 rc = __s_add_attr(e, "SolarisUserQualifier", ptr->qualifier); 3159 if (rc != NS_LDAP_SUCCESS) { 3160 __s_cvt_freeEntryRdn(entry, rdn); 3161 return (rc); 3162 } 3163 } 3164 3165 if (ptr->res1 != NULL) { 3166 rc = __s_add_attr(e, "SolarisAttrReserved1", ptr->res1); 3167 if (rc != NS_LDAP_SUCCESS) { 3168 __s_cvt_freeEntryRdn(entry, rdn); 3169 return (rc); 3170 } 3171 } 3172 3173 if (ptr->res2 != NULL) { 3174 rc = __s_add_attr(e, "SolarisAttrReserved2", ptr->res2); 3175 if (rc != NS_LDAP_SUCCESS) { 3176 __s_cvt_freeEntryRdn(entry, rdn); 3177 return (rc); 3178 } 3179 } 3180 3181 return (NS_LDAP_SUCCESS); 3182 } 3183 /* 3184 * Conversion: audit_user 3185 * Input format: au_user_str_t 3186 * Exported objectclass: SolarisAuditUser 3187 */ 3188 static int 3189 __s_cvt_audituser(const void *data, char **rdn, 3190 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 3191 { 3192 ns_ldap_entry_t *e; 3193 int rc; 3194 char trdn[RDNSIZE]; 3195 /* routine specific */ 3196 au_user_str_t *ptr; 3197 int max_attr = 3; 3198 static char *oclist[] = { 3199 "SolarisAuditUser", 3200 NULL 3201 }; 3202 3203 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 3204 return (NS_LDAP_OP_FAILED); 3205 3206 *entry = e = __s_mk_entry(oclist, max_attr); 3207 if (e == NULL) 3208 return (NS_LDAP_MEMORY); 3209 3210 /* Convert the structure */ 3211 ptr = (au_user_str_t *)data; 3212 3213 if (ptr->au_name == NULL || ptr->au_name[0] == '\0') { 3214 __ns_ldap_freeEntry(e); 3215 *entry = NULL; 3216 return (NS_LDAP_INVALID_PARAM); 3217 } 3218 3219 /* Create an appropriate rdn */ 3220 (void) snprintf(trdn, RDNSIZE, "uid=%s", ptr->au_name); 3221 *rdn = strdup(trdn); 3222 if (*rdn == NULL) { 3223 __ns_ldap_freeEntry(e); 3224 *entry = NULL; 3225 return (NS_LDAP_MEMORY); 3226 } 3227 3228 /* 3229 * Solaris AuditUser has no uid attribute 3230 */ 3231 3232 if (ptr->au_always != NULL) { 3233 rc = __s_add_attr(e, "SolarisAuditAlways", ptr->au_always); 3234 if (rc != NS_LDAP_SUCCESS) { 3235 __s_cvt_freeEntryRdn(entry, rdn); 3236 return (rc); 3237 } 3238 } 3239 3240 if (ptr->au_never != NULL) { 3241 rc = __s_add_attr(e, "SolarisAuditNever", ptr->au_never); 3242 if (rc != NS_LDAP_SUCCESS) { 3243 __s_cvt_freeEntryRdn(entry, rdn); 3244 return (rc); 3245 } 3246 } 3247 3248 return (NS_LDAP_SUCCESS); 3249 } 3250 /* 3251 * Conversion: tnrhtp 3252 * Input format: tsol_tpstr_t 3253 * Exported objectclass: ipTnetTemplate 3254 */ 3255 static int 3256 __s_cvt_tnrhtp(const void *data, char **rdn, 3257 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 3258 { 3259 ns_ldap_entry_t *e; 3260 int rc; 3261 char trdn[RDNSIZE]; 3262 /* routine specific */ 3263 int max_attr = 2; 3264 tsol_tpstr_t *ptr; 3265 static char *oclist[] = { 3266 "ipTnetTemplate", 3267 "top", 3268 NULL 3269 }; 3270 3271 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 3272 return (NS_LDAP_OP_FAILED); 3273 3274 *entry = e = __s_mk_entry(oclist, max_attr); 3275 if (e == NULL) 3276 return (NS_LDAP_MEMORY); 3277 3278 /* Convert the structure */ 3279 ptr = (tsol_tpstr_t *)data; 3280 3281 if ((ptr->template == NULL) || (strlen(ptr->template) <= 1)) { 3282 __ns_ldap_freeEntry(e); 3283 *entry = NULL; 3284 return (NS_LDAP_INVALID_PARAM); 3285 } 3286 3287 /* Create an appropriate rdn */ 3288 (void) snprintf(trdn, RDNSIZE, "ipTnetTemplateName=%s", ptr->template); 3289 *rdn = strdup(trdn); 3290 if (*rdn == NULL) { 3291 __ns_ldap_freeEntry(e); 3292 *entry = NULL; 3293 return (NS_LDAP_MEMORY); 3294 } 3295 3296 rc = __s_add_attr(e, "ipTnetTemplateName", ptr->template); 3297 if (rc != NS_LDAP_SUCCESS) { 3298 __s_cvt_freeEntryRdn(entry, rdn); 3299 return (rc); 3300 } 3301 3302 rc = __s_add_attr(e, "SolarisAttrKeyValue", ptr->attrs); 3303 if (rc != NS_LDAP_SUCCESS) { 3304 __s_cvt_freeEntryRdn(entry, rdn); 3305 return (rc); 3306 } 3307 3308 return (NS_LDAP_SUCCESS); 3309 } 3310 /* 3311 * Conversion: tnrhdb 3312 * Input format: tsol_rhstr_t 3313 * Exported objectclass: ipTnetHost 3314 */ 3315 static int 3316 __s_cvt_tnrhdb(const void *data, char **rdn, 3317 ns_ldap_entry_t **entry, ns_ldap_error_t **errorp) 3318 { 3319 ns_ldap_entry_t *e; 3320 int rc; 3321 char trdn[RDNSIZE]; 3322 /* routine specific */ 3323 tsol_rhstr_t *ptr; 3324 int max_attr = 2; 3325 static char *oclist[] = { 3326 "ipTnetHost", 3327 "ipTnetTemplate", 3328 "top", 3329 NULL 3330 }; 3331 3332 if (data == NULL || rdn == NULL || entry == NULL || errorp == NULL) 3333 return (NS_LDAP_OP_FAILED); 3334 3335 *entry = e = __s_mk_entry(oclist, max_attr); 3336 if (e == NULL) 3337 return (NS_LDAP_MEMORY); 3338 3339 /* Convert the structure */ 3340 ptr = (tsol_rhstr_t *)data; 3341 3342 if ((ptr->address == NULL) || (strlen(ptr->address) <= 1) || 3343 (ptr->template == NULL) || (strlen(ptr->template) <= 1)) { 3344 __ns_ldap_freeEntry(e); 3345 *entry = NULL; 3346 return (NS_LDAP_INVALID_PARAM); 3347 } 3348 3349 /* Create an appropriate rdn */ 3350 (void) snprintf(trdn, RDNSIZE, "ipTnetNumber=%s", ptr->address); 3351 *rdn = strdup(trdn); 3352 if (*rdn == NULL) { 3353 __ns_ldap_freeEntry(e); 3354 *entry = NULL; 3355 return (NS_LDAP_MEMORY); 3356 } 3357 3358 rc = __s_add_attr(e, "ipTnetNumber", ptr->address); 3359 if (rc != NS_LDAP_SUCCESS) { 3360 __s_cvt_freeEntryRdn(entry, rdn); 3361 return (rc); 3362 } 3363 3364 rc = __s_add_attr(e, "ipTnetTemplateName", ptr->template); 3365 if (rc != NS_LDAP_SUCCESS) { 3366 __s_cvt_freeEntryRdn(entry, rdn); 3367 return (rc); 3368 } 3369 3370 return (NS_LDAP_SUCCESS); 3371 } 3372 /* 3373 * Add Typed Entry Conversion data structures 3374 */ 3375 3376 typedef struct __ns_cvt_type { 3377 const char *service; 3378 int flags; 3379 #define AE 1 /* alway add entries */ 3380 int (*cvt_rtn)(const void *data, 3381 char **rdn, 3382 ns_ldap_entry_t **entry, 3383 ns_ldap_error_t **errorp); 3384 } __ns_cvt_type_t; 3385 3386 static __ns_cvt_type_t __s_cvtlist[] = { 3387 { NS_LDAP_TYPE_PASSWD, 0, __s_cvt_passwd }, 3388 { NS_LDAP_TYPE_GROUP, 0, __s_cvt_group }, 3389 { NS_LDAP_TYPE_HOSTS, 0, __s_cvt_hosts }, 3390 { NS_LDAP_TYPE_IPNODES, 0, __s_cvt_hosts }, 3391 { NS_LDAP_TYPE_RPC, 0, __s_cvt_rpc }, 3392 { NS_LDAP_TYPE_PROTOCOLS, 0, __s_cvt_protocols }, 3393 { NS_LDAP_TYPE_NETWORKS, 0, __s_cvt_networks }, 3394 { NS_LDAP_TYPE_NETGROUP, 0, __s_cvt_netgroups }, 3395 { NS_LDAP_TYPE_ALIASES, 0, __s_cvt_aliases }, 3396 { NS_LDAP_TYPE_SERVICES, 0, __s_cvt_services }, 3397 { NS_LDAP_TYPE_ETHERS, 0, __s_cvt_ethers }, 3398 { NS_LDAP_TYPE_SHADOW, 0, __s_cvt_shadow }, 3399 { NS_LDAP_TYPE_NETMASKS, 0, __s_cvt_netmasks }, 3400 { NS_LDAP_TYPE_BOOTPARAMS, 0, __s_cvt_bootparams }, 3401 { NS_LDAP_TYPE_AUTHATTR, 0, __s_cvt_authattr }, 3402 { NS_LDAP_TYPE_EXECATTR, 0, __s_cvt_execattr }, 3403 { NS_LDAP_TYPE_PROFILE, 0, __s_cvt_profattr }, 3404 { NS_LDAP_TYPE_USERATTR, AE, __s_cvt_userattr }, 3405 { NS_LDAP_TYPE_AUTOMOUNT, 0, __s_cvt_auto_mount }, 3406 { NS_LDAP_TYPE_PUBLICKEY, AE, __s_cvt_publickey }, 3407 { NS_LDAP_TYPE_AUUSER, AE, __s_cvt_audituser }, 3408 { NS_LDAP_TYPE_TNRHTP, 0, __s_cvt_tnrhtp }, 3409 { NS_LDAP_TYPE_TNRHDB, 0, __s_cvt_tnrhdb }, 3410 { NULL, 0, NULL }, 3411 }; 3412 3413 /* 3414 * Add Typed Entry Routine 3415 */ 3416 3417 /*ARGSUSED*/ 3418 int __ns_ldap_addTypedEntry( 3419 const char *servicetype, 3420 const char *basedn, 3421 const void *data, 3422 const int create, 3423 const ns_cred_t *cred, 3424 const int flags, 3425 ns_ldap_error_t **errorp) 3426 { 3427 char *rdn = NULL, *fulldn = NULL; 3428 void **paramVal = NULL; 3429 ns_ldap_entry_t *entry = NULL; 3430 const ns_ldap_attr_t *const *modattrlist; 3431 ns_ldap_search_desc_t **sdlist; 3432 char **dns = NULL; 3433 char trdn[RDNSIZE]; 3434 char service[BUFSIZE]; 3435 int rc = 0; 3436 int automount = 0; 3437 int i, s; 3438 3439 rc = NS_LDAP_OP_FAILED; 3440 for (s = 0; __s_cvtlist[s].service != NULL; s++) { 3441 if (__s_cvtlist[s].cvt_rtn == NULL) 3442 continue; 3443 if (strcasecmp(__s_cvtlist[s].service, servicetype) == 0) 3444 break; 3445 /* Or, check if the servicetype is auto_ */ 3446 if (strcmp(__s_cvtlist[s].service, 3447 NS_LDAP_TYPE_AUTOMOUNT) == 0 && 3448 strncasecmp(servicetype, NS_LDAP_TYPE_AUTOMOUNT, 3449 sizeof (NS_LDAP_TYPE_AUTOMOUNT) - 1) == 0) { 3450 automount++; 3451 break; 3452 } 3453 } 3454 if (__s_cvtlist[s].service == NULL) 3455 return (rc); 3456 3457 /* Convert the data */ 3458 rc = (*__s_cvtlist[s].cvt_rtn)(data, &rdn, &entry, errorp); 3459 if (rc != NS_LDAP_SUCCESS) { 3460 __s_cvt_freeEntryRdn(&entry, &rdn); 3461 return (rc); 3462 } 3463 if (rdn == NULL) { 3464 __ns_ldap_freeEntry(entry); 3465 return (NS_LDAP_OP_FAILED); 3466 } 3467 3468 if (strcmp(servicetype, "publickey") == 0) { 3469 struct _ns_pubkey *ptr; 3470 ptr = (struct _ns_pubkey *)data; 3471 if (ptr->hostcred == NS_HOSTCRED_TRUE) 3472 (void) strcpy(service, "hosts"); 3473 else 3474 (void) strcpy(service, "passwd"); 3475 } else 3476 (void) strcpy(service, servicetype); 3477 3478 /* Create the Full DN */ 3479 if (basedn == NULL) { 3480 rc = __s_api_get_SSD_from_SSDtoUse_service(service, 3481 &sdlist, errorp); 3482 if (rc != NS_LDAP_SUCCESS) { 3483 __s_cvt_freeEntryRdn(&entry, &rdn); 3484 return (rc); 3485 } 3486 3487 if (sdlist == NULL) { 3488 rc = __s_api_getDNs(&dns, service, errorp); 3489 if (rc != NS_LDAP_SUCCESS) { 3490 if (dns) { 3491 __s_api_free2dArray(dns); 3492 dns = NULL; 3493 } 3494 __s_cvt_freeEntryRdn(&entry, &rdn); 3495 return (rc); 3496 } 3497 (void) snprintf(trdn, RDNSIZE, "%s,%s", rdn, dns[0]); 3498 __s_api_free2dArray(dns); 3499 } else { 3500 if (sdlist[0]->basedn) { 3501 (void) snprintf(trdn, RDNSIZE, "%s,%s", 3502 rdn, sdlist[0]->basedn); 3503 } else { 3504 __s_cvt_freeEntryRdn(&entry, &rdn); 3505 return (NS_LDAP_OP_FAILED); 3506 } 3507 } 3508 i = strlen(trdn) - 1; 3509 if (trdn[i] == COMMATOK) { 3510 rc = __ns_ldap_getParam(NS_LDAP_SEARCH_BASEDN_P, 3511 ¶mVal, errorp); 3512 if (rc != NS_LDAP_SUCCESS) { 3513 __s_cvt_freeEntryRdn(&entry, &rdn); 3514 return (rc); 3515 } 3516 i = strlen(trdn) + strlen((char *)(paramVal[0])) + 1; 3517 fulldn = (char *)calloc(i, 1); 3518 if (fulldn == NULL) { 3519 (void) __ns_ldap_freeParam(¶mVal); 3520 __s_cvt_freeEntryRdn(&entry, &rdn); 3521 return (NS_LDAP_MEMORY); 3522 } 3523 (void) snprintf(fulldn, i, "%s%s", trdn, 3524 (char *)(paramVal[0])); 3525 (void) __ns_ldap_freeParam(¶mVal); 3526 } else { 3527 fulldn = strdup(trdn); 3528 if (fulldn == NULL) { 3529 __s_cvt_freeEntryRdn(&entry, &rdn); 3530 return (NS_LDAP_MEMORY); 3531 } 3532 } 3533 } else { 3534 i = strlen(rdn) + strlen(basedn) + 2; 3535 fulldn = (char *)calloc(i, 1); 3536 if (fulldn == NULL) { 3537 __s_cvt_freeEntryRdn(&entry, &rdn); 3538 return (NS_LDAP_MEMORY); 3539 } 3540 (void) snprintf(fulldn, i, "%s,%s", rdn, basedn); 3541 } 3542 3543 modattrlist = (const ns_ldap_attr_t * const *)entry->attr_pair; 3544 /* Check to see if the entry exists already */ 3545 /* May need to delete or update first */ 3546 3547 if (create != 1) { 3548 /* Modify the entry */ 3549 /* 3550 * To add a shadow-like entry, the addTypedEntry function 3551 * would call __ns_ldap_repAttr first, and if server says 3552 * LDAP_NO_SUCH_OBJECT, then it tries __ns_ldap_addEntry. 3553 * This is to allow a netmask entry to be added even if the 3554 * base network entry is not in the directory. It would work 3555 * because the difference between the schema for the network 3556 * and netmask data contains only MAY attributes. 3557 * 3558 * But for shadow data, the attributes do not have MUST 3559 * attributes the base entry needs, so if the __ns_ldap_addEntry 3560 * is executed, it would fail. The real reason, however, is that 3561 * the base entry did not exist. So returning 3562 * LDAP_OBJECT_CLASS_VIOLATION would just confused. 3563 */ 3564 if ((__s_cvtlist[s].flags & AE) != 0) 3565 rc = __ns_ldap_addAttr(service, fulldn, modattrlist, 3566 cred, flags, errorp); 3567 else { 3568 rc = __ns_ldap_repAttr(service, fulldn, modattrlist, 3569 cred, flags, errorp); 3570 if (rc == NS_LDAP_INTERNAL && *errorp && 3571 (*errorp)->status == LDAP_NO_SUCH_OBJECT) { 3572 (void) __ns_ldap_freeError(errorp); 3573 rc = __ns_ldap_addEntry(service, fulldn, 3574 entry, cred, flags, errorp); 3575 if (rc == NS_LDAP_INTERNAL && *errorp && 3576 (*errorp)->status == 3577 LDAP_OBJECT_CLASS_VIOLATION) 3578 (*errorp)->status = LDAP_NO_SUCH_OBJECT; 3579 } 3580 } 3581 } else { 3582 /* Add the entry */ 3583 rc = __ns_ldap_addEntry(service, fulldn, entry, 3584 cred, flags, errorp); 3585 if (rc == NS_LDAP_INTERNAL && *errorp && 3586 (*errorp)->status == LDAP_ALREADY_EXISTS && 3587 ((strcmp(service, "ethers") == 0) || 3588 (strcmp(service, "bootparams") == 0))) { 3589 rc = modify_ethers_bootp(service, rdn, fulldn, 3590 modattrlist, cred, flags, errorp); 3591 } 3592 } 3593 3594 /* Free up entry created by conversion routine */ 3595 if (fulldn != NULL) 3596 free(fulldn); 3597 __s_cvt_freeEntryRdn(&entry, &rdn); 3598 return (rc); 3599 } 3600 3601 3602 /* 3603 * Append the default base dn to the dn 3604 * when it ends with ','. 3605 * e.g. 3606 * SSD = service:ou=foo, 3607 */ 3608 int 3609 __s_api_append_default_basedn( 3610 const char *dn, 3611 char **new_dn, 3612 int *allocated, 3613 ns_ldap_error_t **errp) { 3614 3615 int rc = NS_LDAP_SUCCESS, len = 0; 3616 void **param = NULL; 3617 char *str = NULL; 3618 3619 *allocated = FALSE; 3620 *new_dn = NULL; 3621 3622 if (dn == NULL) 3623 return (NS_LDAP_INVALID_PARAM); 3624 3625 rc = __ns_ldap_getParam(NS_LDAP_SEARCH_BASEDN_P, 3626 (void ***)¶m, errp); 3627 3628 if (rc != NS_LDAP_SUCCESS) { 3629 if (param) 3630 (void) __ns_ldap_freeParam(¶m); 3631 return (rc); 3632 } 3633 3634 len = strlen(dn); 3635 str = ((char **)param)[0]; 3636 len = len + strlen(str) +1; 3637 *new_dn = (char *)malloc(len); 3638 if (*new_dn == NULL) { 3639 (void) __ns_ldap_freeParam(¶m); 3640 return (NS_LDAP_MEMORY); 3641 } 3642 *allocated = TRUE; 3643 3644 (void) strcpy(*new_dn, dn); 3645 (void) strcat(*new_dn, str); 3646 3647 (void) __ns_ldap_freeParam(¶m); 3648 return (NS_LDAP_SUCCESS); 3649 } 3650