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