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