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