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