1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * ldapaddent.c 30 * 31 * Utility to add /etc files into LDAP. 32 * Can also be used to dump entries from a ldap container in /etc format. 33 */ 34 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <libintl.h> 38 #include <strings.h> 39 #include <sys/param.h> 40 #include <ctype.h> 41 #include <sys/types.h> 42 #include <sys/socket.h> 43 #include <netinet/in.h> 44 #include <arpa/inet.h> 45 #include <locale.h> 46 #include <syslog.h> 47 48 #undef opaque 49 50 #include <nss_dbdefs.h> 51 #include <netdb.h> 52 #include <rpc/rpcent.h> 53 #include <grp.h> 54 #include <pwd.h> 55 #include <shadow.h> 56 #include <sys/systeminfo.h> 57 #include "ns_internal.h" 58 #include "ldapaddent.h" 59 60 #define OP_ADD 0 61 #define OP_DUMP 3 62 63 static struct ttypelist_t { 64 char *ttype; /* type tag */ 65 int (*genent)(char *, int(*)()); 66 /* routine to turn line into ldap entries */ 67 void (*dump)(ns_ldap_result_t *); 68 /* routine to print ldap containers */ 69 int (*filedbmline)(); /* routine to turn file line into dbm line */ 70 char *objclass; /* Objectclass for the servicetype */ 71 } *tt; 72 73 char parse_err_msg [PARSE_ERR_MSG_LEN]; 74 int continue_onerror = 0; /* do not exit on error */ 75 76 static int get_basedn(char *service, char **basedn); 77 static int check_ipaddr(char *addr, char **newaddr); 78 79 extern int optind; 80 extern char *optarg; 81 82 extern char *__nis_quote_key(const char *, char *, int); 83 84 static char *inputbasedn = NULL; 85 static char *databasetype = NULL; 86 static int exit_val = 0; 87 static unsigned nent_add = 0; 88 static FILE *etcf = 0; 89 static ns_cred_t authority; 90 unsigned flags = 0; 91 92 static void 93 perr(ns_ldap_error_t *e) 94 { 95 if (e) 96 (void) fprintf(stderr, gettext("%d: %s\n"), 97 e->status, e->message); 98 } 99 100 101 static int 102 ascii_to_int(char *str) 103 { 104 int i; 105 char *c = str; 106 107 if (c == NULL || *c == '\0') 108 return (-1); 109 110 while (c != '\0' && *c == ' ') 111 c++; 112 if (*c == '\0') 113 return (-1); 114 115 for (i = 0; i < strlen(c); i++) 116 if (!isdigit(c[i])) 117 return (-1); 118 119 return (atoi(c)); 120 } 121 122 /* 123 * Internet network address interpretation routine. 124 * The library routines call this routine to interpret 125 * network numbers. 126 */ 127 static in_addr_t 128 encode_network(const char *cp) 129 { 130 in_addr_t val; 131 int base; 132 ptrdiff_t n; 133 char c; 134 in_addr_t parts[4], *pp = parts; 135 int i; 136 137 again: 138 val = 0; base = 10; 139 if (*cp == '0') { 140 if (*++cp == 'x' || *cp == 'X') 141 base = 16, cp++; 142 else 143 base = 8; 144 } 145 while ((c = *cp) != NULL) { 146 if (isdigit(c)) { 147 if ((c - '0') >= base) 148 break; 149 val = (val * base) + (c - '0'); 150 cp++; 151 continue; 152 } 153 if (base == 16 && isxdigit(c)) { 154 val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A')); 155 cp++; 156 continue; 157 } 158 break; 159 } 160 if (*cp == '.') { 161 if (pp >= parts + 4) 162 return ((in_addr_t)-1); 163 *pp++ = val, cp++; 164 goto again; 165 } 166 if (*cp && !isspace(*cp)) 167 return ((in_addr_t)-1); 168 *pp++ = val; 169 n = pp - parts; 170 if (n > 4) 171 return ((in_addr_t)-1); 172 for (val = 0, i = 0; i < n; i++) { 173 val <<= 8; 174 val |= parts[i] & 0xff; 175 } 176 for (/* no init */; i < 4; i++) 177 val <<= 8; 178 return (val); 179 } 180 181 static void 182 replace_tab2space(char *str) 183 { 184 int i = 0; 185 186 while ((str) && (str[i])) { 187 if (str[i] == '\t') 188 str[i] = ' '; 189 i++; 190 } 191 } 192 193 static int 194 blankline(char *line) 195 { 196 char *p; 197 198 for (p = line; *p; p++) 199 if (*p != ' ' && *p != '\t') 200 return (0); 201 return (1); 202 } 203 204 /* 205 * check whether the token <tok> is a triplet, 206 * i. e. <tok> := (<hostname>,<username>,<domainname>) 207 * where <hostname>, <username>, <domainname> are IA5String 208 * <tok> supposes to contain NO spaces and start with '(' 209 */ 210 static int 211 is_triplet(char *tok) 212 { 213 char *s; 214 return (strchr(++tok, '(') == NULL && /* no more '(' */ 215 (s = strchr(tok, ')')) != NULL && /* find ')' */ 216 !*++s && /* ')' ends token */ 217 (tok = strchr(tok, ',')) != NULL && /* host up to ',' */ 218 (tok = strchr(++tok, ',')) != NULL && /* user up to ',' */ 219 strchr(++tok, ',') == NULL); /* no more ',' */ 220 } 221 222 static void 223 line_buf_expand(struct line_buf *line) 224 { 225 line->alloc += BUFSIZ; 226 line->str = (char *)realloc(line->str, line->alloc); 227 228 if (line->str == NULL) { 229 (void) fprintf(stderr, 230 gettext("line_buf_expand: out of memory\n")); 231 exit(1); 232 } 233 } 234 235 static void 236 line_buf_init(struct line_buf *line) 237 { 238 (void) memset((char *)line, 0, sizeof (*line)); 239 line_buf_expand(line); 240 } 241 242 static int 243 __s_add_attr(ns_ldap_entry_t *e, char *attrname, char *value) 244 { 245 ns_ldap_attr_t *a; 246 char *v; 247 248 a = (ns_ldap_attr_t *)calloc(1, sizeof (ns_ldap_attr_t)); 249 if (a == NULL) 250 return (NS_LDAP_MEMORY); 251 a->attrname = strdup(attrname); 252 if (a->attrname == NULL) { 253 free(a); 254 return (NS_LDAP_MEMORY); 255 } 256 a->attrvalue = (char **)calloc(1, sizeof (char **)); 257 if (a->attrvalue == NULL) { 258 free(a->attrname); 259 free(a); 260 return (NS_LDAP_MEMORY); 261 } 262 a->value_count = 1; 263 a->attrvalue[0] = NULL; 264 v = strdup(value); 265 if (v == NULL) { 266 free(a->attrname); 267 free(a->attrvalue); 268 free(a); 269 return (NS_LDAP_MEMORY); 270 } 271 a->attrvalue[0] = v; 272 e->attr_pair[e->attr_count] = a; 273 e->attr_count++; 274 return (NS_LDAP_SUCCESS); 275 } 276 277 static int 278 __s_add_attrlist(ns_ldap_entry_t *e, char *attrname, char **argv) 279 { 280 ns_ldap_attr_t *a; 281 char *v; 282 char **av; 283 int i, j; 284 285 a = (ns_ldap_attr_t *)calloc(1, sizeof (ns_ldap_attr_t)); 286 if (a == NULL) 287 return (NS_LDAP_MEMORY); 288 a->attrname = strdup(attrname); 289 if (a->attrname == NULL) { 290 free(a); 291 return (NS_LDAP_MEMORY); 292 } 293 294 for (i = 0, av = argv; *av != NULL; av++, i++) 295 ; 296 297 a->attrvalue = (char **)calloc(i, sizeof (char **)); 298 299 if (a->attrvalue == NULL) { 300 free(a->attrname); 301 free(a); 302 return (NS_LDAP_MEMORY); 303 } 304 a->value_count = i; 305 for (j = 0; j < i; j++) { 306 v = strdup(argv[j]); 307 if (v == NULL) { 308 free(a->attrname); 309 free(a->attrvalue); 310 free(a); 311 return (NS_LDAP_MEMORY); 312 } 313 a->attrvalue[j] = v; 314 } 315 e->attr_pair[e->attr_count] = a; 316 e->attr_count++; 317 return (NS_LDAP_SUCCESS); 318 } 319 320 static ns_ldap_entry_t * 321 __s_mk_entry(char **objclass, int max_attr) 322 { 323 ns_ldap_entry_t *e; 324 e = (ns_ldap_entry_t *)calloc(1, sizeof (ns_ldap_entry_t)); 325 if (e == NULL) 326 return (NULL); 327 e->attr_pair = (ns_ldap_attr_t **)calloc(max_attr+1, 328 sizeof (ns_ldap_attr_t *)); 329 if (e->attr_pair == NULL) { 330 free(e); 331 return (NULL); 332 } 333 e->attr_count = 0; 334 if (__s_add_attrlist(e, "objectClass", objclass) != NS_LDAP_SUCCESS) { 335 free(e->attr_pair); 336 free(e); 337 return (NULL); 338 } 339 return (e); 340 } 341 342 static void 343 ldap_freeEntry(ns_ldap_entry_t *ep) 344 { 345 int j, k = 0; 346 347 if (ep == NULL) 348 return; 349 350 if (ep->attr_pair == NULL) { 351 free(ep); 352 return; 353 } 354 for (j = 0; j < ep->attr_count; j++) { 355 if (ep->attr_pair[j] == NULL) 356 continue; 357 if (ep->attr_pair[j]->attrname) 358 free(ep->attr_pair[j]->attrname); 359 if (ep->attr_pair[j]->attrvalue) { 360 for (k = 0; (k < ep->attr_pair[j]->value_count) && 361 (ep->attr_pair[j]->attrvalue[k]); k++) { 362 free(ep->attr_pair[j]->attrvalue[k]); 363 } 364 free(ep->attr_pair[j]->attrvalue); 365 } 366 free(ep->attr_pair[j]); 367 } 368 free(ep->attr_pair); 369 free(ep); 370 } 371 372 static int 373 addentry(void *entry, int mod) 374 { 375 int result = 0; 376 ns_ldap_error_t *eres = NULL; 377 int rc = 1; 378 379 380 /* adds entry into the LDAP tree */ 381 if (mod) 382 result = __ns_ldap_addTypedEntry(databasetype, inputbasedn, 383 entry, 0, &authority, NS_LDAP_FOLLOWREF, &eres); 384 else 385 result = __ns_ldap_addTypedEntry(databasetype, inputbasedn, 386 entry, 1, &authority, NS_LDAP_FOLLOWREF, &eres); 387 /* 388 * Return 0 on success 389 * LDAP_ALREADY_EXISTS if entry exists already 390 * 1 for all other non-fatal errors. 391 * Exit on fatal errors. 392 */ 393 switch (result) { 394 case NS_LDAP_SUCCESS: 395 nent_add++; 396 rc = 0; 397 break; 398 399 case NS_LDAP_OP_FAILED: 400 (void) fprintf(stderr, gettext("operation failed.\n")); 401 rc = 1; 402 break; 403 404 case NS_LDAP_INVALID_PARAM: 405 (void) fprintf(stderr, 406 gettext("invalid parameter(s) passed.\n")); 407 rc = 1; 408 break; 409 410 case NS_LDAP_NOTFOUND: 411 (void) fprintf(stderr, gettext("entry not found.\n")); 412 rc = 1; 413 break; 414 415 case NS_LDAP_MEMORY: 416 (void) fprintf(stderr, 417 gettext("internal memory allocation error.\n")); 418 exit(1); 419 break; 420 421 case NS_LDAP_CONFIG: 422 (void) fprintf(stderr, 423 gettext("LDAP Configuration problem.\n")); 424 perr(eres); 425 exit(1); 426 break; 427 428 case NS_LDAP_PARTIAL: 429 (void) fprintf(stderr, 430 gettext("partial result returned\n")); 431 perr(eres); 432 rc = 1; 433 break; 434 435 case NS_LDAP_INTERNAL: 436 if (eres->status == LDAP_ALREADY_EXISTS || 437 eres->status == LDAP_NO_SUCH_OBJECT) 438 rc = eres->status; 439 else if (eres->status == LDAP_INSUFFICIENT_ACCESS) { 440 (void) fprintf(stderr, 441 gettext("The user does not have permission" 442 " to add/modify entries\n")); 443 perr(eres); 444 exit(1); 445 } else { 446 rc = 1; 447 perr(eres); 448 } 449 break; 450 } 451 452 if (eres) 453 (void) __ns_ldap_freeError(&eres); 454 return (rc); 455 } 456 457 458 /* 459 * usage(char *msg) 460 * Display usage message to STDERR. 461 */ 462 static void 463 usage(char *msg) { 464 465 if (msg) 466 (void) fprintf(stderr, gettext("%s\n"), msg); 467 468 (void) fprintf(stderr, gettext( 469 "usage: ldapaddent [ -cpv ] [ -a authenticationMethod ]\n" 470 "[ -b baseDN ] -D bindDN -w bind_password [ -f file ] database\n\n" 471 "usage: ldapaddent -d [ -cpv ] [ -a authenticationMethod ]\n" 472 "[ -b baseDN ] [ -D bindDN ] [ -w bind_password ] database\n")); 473 exit(1); 474 } 475 476 /* 477 * Determine if the given string is an IP address (IPv4 or IPv6). 478 * If so, it's converted to the preferred form (rfc2373) and 479 * *newaddr will point to the new address. 480 * 481 * Returns -2 : inet_ntop error 482 * -1 : not an IP address 483 * 0 : unsupported IP address (future use) 484 * AF_INET : IPv4 485 * AF_INET6 : IPv6 486 */ 487 static int 488 check_ipaddr(char *addr, char **newaddr) { 489 ipaddr_t addr_ipv4 = 0; 490 in6_addr_t addr_ipv6; 491 492 /* IPv6 */ 493 if (inet_pton(AF_INET6, addr, &addr_ipv6) == 1) { 494 if (newaddr == NULL) 495 return (AF_INET6); 496 497 /* Convert IPv4-mapped IPv6 address to IPv4 */ 498 if (IN6_IS_ADDR_V4MAPPED(&addr_ipv6) || 499 IN6_IS_ADDR_V4COMPAT(&addr_ipv6)) { 500 IN6_V4MAPPED_TO_IPADDR(&addr_ipv6, addr_ipv4); 501 if ((*newaddr = calloc(1, INET_ADDRSTRLEN)) == NULL) { 502 (void) fprintf(stderr, 503 gettext("out of memory\n")); 504 exit(1); 505 } 506 if (inet_ntop(AF_INET, &addr_ipv4, *newaddr, 507 INET_ADDRSTRLEN)) 508 return (AF_INET6); 509 free(*newaddr); 510 return (-2); 511 } 512 513 /* Processing general IPv6 addresses */ 514 if ((*newaddr = calloc(1, INET6_ADDRSTRLEN)) == NULL) { 515 (void) fprintf(stderr, gettext("out of memory\n")); 516 exit(1); 517 } 518 if (inet_ntop(AF_INET6, &addr_ipv6, *newaddr, INET6_ADDRSTRLEN)) 519 return (AF_INET6); 520 free(*newaddr); 521 return (-2); 522 } 523 524 /* Processing IPv4 addresses of the type d.d.d.d. */ 525 if (inet_pton(AF_INET, addr, &addr_ipv4) == 1) { 526 if (newaddr == NULL) 527 return (AF_INET); 528 if ((*newaddr = calloc(1, INET_ADDRSTRLEN)) == NULL) { 529 (void) fprintf(stderr, gettext("out of memory\n")); 530 exit(1); 531 } 532 if (inet_ntop(AF_INET, &addr_ipv4, *newaddr, INET_ADDRSTRLEN)) 533 return (AF_INET); 534 free(*newaddr); 535 return (-2); 536 } 537 538 /* Processing IPv4 addresses d.d.d , d.d and d */ 539 if (inet_addr(addr) != (in_addr_t)-1) { 540 if (newaddr == NULL) 541 return (AF_INET); 542 if ((*newaddr = strdup(addr)) == NULL) { 543 (void) fprintf(stderr, gettext("out of memory\n")); 544 exit(1); 545 } 546 return (AF_INET); 547 } 548 549 return (-1); 550 } 551 552 static int 553 genent_hosts(char *line, int (*cback)()) 554 { 555 char buf[BUFSIZ+1]; 556 char *t, *comment; 557 entry_col ecol[4]; 558 char *cname, *pref_addr; 559 int ctr = 0, retval = 1; 560 int rc = GENENT_OK, af; 561 562 struct hostent data; 563 char *alias; 564 565 /* 566 * don't clobber our argument 567 */ 568 if (strlen(line) >= sizeof (buf)) { 569 (void) strcpy(parse_err_msg, "line too long"); 570 return (GENENT_PARSEERR); 571 } 572 (void) strcpy(buf, line); 573 574 /* 575 * clear column data 576 */ 577 (void) memset((char *)ecol, 0, sizeof (ecol)); 578 579 /* 580 * comment (col 3) 581 * All leading spaces will be deleted from the comment 582 */ 583 ecol[3].ec_value.ec_value_val = ""; 584 ecol[3].ec_value.ec_value_len = 0; 585 comment = t = strchr(buf, '#'); 586 if (comment) { 587 do { 588 ++comment; 589 } while (*comment != '\0' && isspace(*comment)); 590 if (*comment != '\0') { 591 *--comment = '#'; 592 ecol[3].ec_value.ec_value_val = strdup(comment); 593 ecol[3].ec_value.ec_value_len = strlen(comment)+1; 594 } 595 596 *t = '\0'; 597 } 598 599 /* 600 * addr(col 2) 601 */ 602 if ((t = strtok(buf, " \t")) == 0) { 603 (void) strcpy(parse_err_msg, "no host"); 604 return (GENENT_PARSEERR); 605 } 606 607 af = check_ipaddr(t, &pref_addr); 608 if (af == -2) { 609 (void) strcpy(parse_err_msg, "Internal error"); 610 } else if (af == -1) { 611 (void) snprintf(parse_err_msg, sizeof (parse_err_msg), 612 "Invalid IP address: %s", t); 613 } else if (flags & F_VERBOSE) { 614 if ((strncasecmp(t, pref_addr, strlen(t))) != 0) { 615 (void) fprintf(stdout, 616 gettext("IP address %s converted to %s\n"), 617 t, pref_addr); 618 } 619 } 620 621 if (af < 0) { 622 (void) fprintf(stderr, gettext("%s\n"), parse_err_msg); 623 if (continue_onerror == 0) 624 return (GENENT_CBERR); 625 else 626 return (rc); 627 } 628 629 ecol[2].ec_value.ec_value_val = pref_addr; 630 ecol[2].ec_value.ec_value_len = strlen(pref_addr)+1; 631 632 /* 633 * cname (col 0) 634 */ 635 if ((t = strtok(NULL, " \t")) == 0) { 636 (void) strcpy(parse_err_msg, "no cname"); 637 return (GENENT_PARSEERR); 638 } 639 ecol[0].ec_value.ec_value_val = t; 640 ecol[0].ec_value.ec_value_len = strlen(t)+1; 641 cname = t; 642 643 644 /* build entry */ 645 if ((data.h_addr_list = (char **)calloc(2, sizeof (char **))) == NULL) { 646 (void) fprintf(stderr, gettext("out of memory\n")); 647 exit(1); 648 } 649 data.h_addr_list[0] = strdup(ecol[2].ec_value.ec_value_val); 650 data.h_addr_list[1] = NULL; 651 652 free(pref_addr); 653 data.h_name = strdup(ecol[0].ec_value.ec_value_val); 654 655 /* 656 * name (col 1) 657 */ 658 659 data.h_aliases = NULL; 660 661 do { 662 /* 663 * don't clobber comment in canonical entry 664 */ 665 666 /* This call to AddEntry may move out of the loop */ 667 /* This is because we have to call the function just once */ 668 if (t != cname && strcasecmp(t, cname) == 0) 669 continue; 670 if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0) 671 continue; 672 673 ecol[1].ec_value.ec_value_val = t; 674 ecol[1].ec_value.ec_value_len = strlen(t)+1; 675 676 ctr++; 677 alias = strdup(ecol[1].ec_value.ec_value_val); 678 if ((data.h_aliases = (char **)realloc(data.h_aliases, 679 ctr * sizeof (char **))) == NULL) { 680 (void) fprintf(stderr, gettext("out of memory\n")); 681 exit(1); 682 } 683 data.h_aliases[ctr-1] = alias; 684 } while (t = strtok(NULL, " \t")); 685 686 /* 687 * End the list of all the aliases by NULL 688 * If there is some comment, it will be stored as the last entry 689 * in the list of the host aliases 690 */ 691 if ((data.h_aliases = (char **)realloc(data.h_aliases, 692 (ecol[3].ec_value.ec_value_len != 0 ? 693 ctr + 2 : ctr + 1) * sizeof (char **))) == NULL) { 694 (void) fprintf(stderr, gettext("out of memory\n")); 695 exit(1); 696 } 697 698 if (ecol[3].ec_value.ec_value_len != 0) { 699 data.h_aliases[ctr++] = ecol[3].ec_value.ec_value_val; 700 } 701 data.h_aliases[ctr] = NULL; 702 703 if (flags & F_VERBOSE) 704 (void) fprintf(stdout, 705 gettext("Adding entry : cn=%s+ipHostNumber=%s\n"), 706 data.h_name, data.h_addr_list[0]); 707 708 retval = (*cback)(&data, 0); 709 710 if (ecol[3].ec_value.ec_value_len != 0) { 711 free(ecol[3].ec_value.ec_value_val); 712 } 713 714 if (retval == LDAP_ALREADY_EXISTS) { 715 if (continue_onerror) 716 (void) fprintf(stderr, 717 gettext("Entry: cn=%s+ipHostNumber=%s " 718 "already Exists -skipping it\n"), 719 data.h_name, data.h_addr_list[0]); 720 else { 721 rc = GENENT_CBERR; 722 (void) fprintf(stderr, 723 gettext("Entry: cn=%s+ipHostNumber=%s" 724 " already Exists\n"), 725 data.h_name, data.h_addr_list[0]); 726 } 727 } else if (retval) 728 rc = GENENT_CBERR; 729 730 free(data.h_name); 731 free(data.h_aliases); 732 free(data.h_addr_list); 733 734 return (rc); 735 } 736 737 738 739 static void 740 dump_hosts(ns_ldap_result_t *res) 741 { 742 ns_ldap_attr_t *attrptr = NULL, 743 *cn = NULL, 744 *iphostnumber = NULL, 745 *desc = NULL; 746 int i, j; 747 char *name; /* host name */ 748 749 if (res == NULL || res->entry == NULL) 750 return; 751 for (i = 0; i < res->entry->attr_count; i++) { 752 attrptr = res->entry->attr_pair[i]; 753 if (strcasecmp(attrptr->attrname, "cn") == 0) 754 cn = attrptr; 755 else if (strcasecmp(attrptr->attrname, "iphostnumber") == 0) 756 iphostnumber = attrptr; 757 else if (strcasecmp(attrptr->attrname, "description") == 0) { 758 desc = attrptr; 759 } 760 } 761 /* sanity check */ 762 if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL || 763 iphostnumber == NULL || iphostnumber->attrvalue == NULL || 764 iphostnumber->attrvalue[0] == NULL) 765 return; 766 767 if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL) 768 return; 769 770 /* ip host/ipnode number */ 771 if (strlen(iphostnumber->attrvalue[0]) <= INET_ADDRSTRLEN) 772 /* IPV4 or IPV6 but <= NET_ADDRSTRLEN */ 773 (void) fprintf(stdout, "%-18s", iphostnumber->attrvalue[0]); 774 else 775 /* IPV6 */ 776 (void) fprintf(stdout, "%-48s", iphostnumber->attrvalue[0]); 777 778 /* host/ipnode name */ 779 (void) fprintf(stdout, "%s ", name); 780 781 /* aliases */ 782 for (j = 0; j < cn->value_count; j++) { 783 if (cn->attrvalue[j]) { 784 if (strcasecmp(name, cn->attrvalue[j]) == 0) 785 /* skip host name */ 786 continue; 787 (void) fprintf(stdout, "%s ", cn->attrvalue[j]); 788 } 789 } 790 791 /* description */ 792 if (desc != NULL && desc->attrvalue != NULL && 793 desc->attrvalue[0] != NULL) { 794 (void) fprintf(stdout, "#%s", desc->attrvalue[0]); 795 } 796 797 /* end of line */ 798 (void) fprintf(stdout, "\n"); 799 } 800 801 /* 802 * /etc/rpc 803 */ 804 805 static int 806 genent_rpc(char *line, int (*cback)()) 807 { 808 char buf[BUFSIZ+1]; 809 char *t; 810 entry_col ecol[4]; 811 char *cname; 812 813 struct rpcent data; 814 char *alias; 815 int ctr = 0; 816 int retval = 1; 817 int rc = GENENT_OK; 818 819 /* 820 * don't clobber our argument 821 */ 822 if (strlen(line) >= sizeof (buf)) { 823 (void) strcpy(parse_err_msg, "line too long"); 824 return (GENENT_PARSEERR); 825 } 826 (void) strcpy(buf, line); 827 828 /* 829 * clear column data 830 */ 831 (void) memset((char *)ecol, 0, sizeof (ecol)); 832 833 /* 834 * comment (col 3) 835 */ 836 t = strchr(buf, '#'); 837 if (t) { 838 *t++ = 0; 839 ecol[3].ec_value.ec_value_val = t; 840 ecol[3].ec_value.ec_value_len = strlen(t)+1; 841 } else { 842 ecol[3].ec_value.ec_value_val = 0; 843 ecol[3].ec_value.ec_value_len = 0; 844 } 845 846 /* 847 * cname(col 0) 848 */ 849 if ((t = strtok(buf, " \t")) == 0) { 850 (void) strcpy(parse_err_msg, "no number"); 851 return (GENENT_PARSEERR); 852 } 853 ecol[0].ec_value.ec_value_val = t; 854 ecol[0].ec_value.ec_value_len = strlen(t)+1; 855 cname = t; 856 857 /* 858 * number (col 2) 859 */ 860 if ((t = strtok(NULL, " \t")) == 0) { 861 (void) strcpy(parse_err_msg, "no number"); 862 return (GENENT_PARSEERR); 863 } 864 ecol[2].ec_value.ec_value_val = t; 865 ecol[2].ec_value.ec_value_len = strlen(t)+1; 866 867 868 /* 869 * build entry 870 */ 871 872 data.r_name = strdup(ecol[0].ec_value.ec_value_val); 873 if (ecol[2].ec_value.ec_value_val != NULL && 874 ecol[2].ec_value.ec_value_val[0] != '\0') { 875 876 data.r_number = ascii_to_int(ecol[2].ec_value.ec_value_val); 877 if (data.r_number == -1) { 878 (void) snprintf(parse_err_msg, sizeof (parse_err_msg), 879 "invalid program number: %s", 880 ecol[2].ec_value.ec_value_val); 881 return (GENENT_PARSEERR); 882 } 883 } else 884 data.r_number = -1; 885 886 /* 887 * name (col 1) 888 */ 889 t = cname; 890 data.r_aliases = NULL; 891 do { 892 893 /* 894 * don't clobber comment in canonical entry 895 */ 896 if (t != cname && strcasecmp(t, cname) == 0) 897 continue; 898 if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0) 899 continue; 900 901 ecol[1].ec_value.ec_value_val = t; 902 ecol[1].ec_value.ec_value_len = strlen(t)+1; 903 904 ctr++; 905 alias = strdup(ecol[1].ec_value.ec_value_val); 906 if ((data.r_aliases = (char **)realloc(data.r_aliases, 907 ctr * sizeof (char **))) == NULL) { 908 (void) fprintf(stderr, gettext("out of memory\n")); 909 exit(1); 910 } 911 data.r_aliases[ctr-1] = alias; 912 913 914 /* 915 * only put comment in canonical entry 916 */ 917 ecol[3].ec_value.ec_value_val = 0; 918 ecol[3].ec_value.ec_value_len = 0; 919 920 } while (t = strtok(NULL, " \t")); 921 922 /* End the list of all the aliases by NULL */ 923 if ((data.r_aliases = (char **)realloc(data.r_aliases, 924 (ctr + 1) * sizeof (char **))) == NULL) { 925 (void) fprintf(stderr, gettext("out of memory\n")); 926 exit(1); 927 } 928 data.r_aliases[ctr] = NULL; 929 930 if (flags & F_VERBOSE) 931 (void) fprintf(stdout, 932 gettext("Adding entry : %s\n"), data.r_name); 933 934 retval = (*cback)(&data, 0); 935 936 if (retval == LDAP_ALREADY_EXISTS) { 937 if (continue_onerror) 938 (void) fprintf(stderr, 939 gettext("Entry: %s - already Exists, skipping it.\n"), 940 data.r_name); 941 else { 942 rc = GENENT_CBERR; 943 (void) fprintf(stderr, 944 gettext("Entry: %s - already Exists\n"), 945 data.r_name); 946 } 947 } else if (retval) 948 rc = GENENT_CBERR; 949 950 free(data.r_name); 951 free(data.r_aliases); 952 953 return (rc); 954 } 955 956 957 958 static void 959 dump_rpc(ns_ldap_result_t *res) 960 { 961 ns_ldap_attr_t *attrptr = NULL, *cn = NULL, *rpcnumber = NULL; 962 int i, j; 963 char *name; /* rpc name */ 964 965 if (res == NULL || res->entry == NULL) 966 return; 967 for (i = 0; i < res->entry->attr_count; i++) { 968 attrptr = res->entry->attr_pair[i]; 969 if (strcasecmp(attrptr->attrname, "cn") == 0) 970 cn = attrptr; 971 else if (strcasecmp(attrptr->attrname, "oncRpcNumber") == 0) 972 rpcnumber = attrptr; 973 } 974 /* sanity check */ 975 if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL || 976 rpcnumber == NULL || rpcnumber->attrvalue == NULL || 977 rpcnumber->attrvalue[0] == NULL) 978 return; 979 980 if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL) 981 return; 982 983 /* rpc name */ 984 if (strlen(name) < 8) 985 (void) fprintf(stdout, "%s\t\t", name); 986 else 987 (void) fprintf(stdout, "%s\t", name); 988 989 /* rpc number */ 990 (void) fprintf(stdout, "%-8s", rpcnumber->attrvalue[0]); 991 992 993 /* aliases */ 994 for (j = 0; j < cn->value_count; j++) { 995 if (cn->attrvalue[j]) { 996 if (strcasecmp(name, cn->attrvalue[j]) == 0) 997 /* skip rpc name */ 998 continue; 999 (void) fprintf(stdout, "%s ", cn->attrvalue[j]); 1000 } 1001 } 1002 1003 /* end of line */ 1004 (void) fprintf(stdout, "\n"); 1005 1006 } 1007 1008 /* 1009 * /etc/protocols 1010 * 1011 */ 1012 1013 static int 1014 genent_protocols(char *line, int (*cback)()) 1015 { 1016 char buf[BUFSIZ+1]; 1017 char *t; 1018 entry_col ecol[4]; 1019 char *cname; 1020 1021 struct protoent data; 1022 char *alias; 1023 int ctr = 0; 1024 int retval = 1; 1025 int rc = GENENT_OK; 1026 1027 /* 1028 * don't clobber our argument 1029 */ 1030 if (strlen(line) >= sizeof (buf)) { 1031 (void) strcpy(parse_err_msg, "line too long"); 1032 return (GENENT_PARSEERR); 1033 } 1034 (void) strcpy(buf, line); 1035 1036 /* 1037 * clear column data 1038 */ 1039 (void) memset((char *)ecol, 0, sizeof (ecol)); 1040 1041 /* 1042 * comment (col 3) 1043 */ 1044 t = strchr(buf, '#'); 1045 if (t) { 1046 *t++ = 0; 1047 ecol[3].ec_value.ec_value_val = t; 1048 ecol[3].ec_value.ec_value_len = strlen(t)+1; 1049 } else { 1050 ecol[3].ec_value.ec_value_val = 0; 1051 ecol[3].ec_value.ec_value_len = 0; 1052 } 1053 1054 /* 1055 * cname(col 0) 1056 */ 1057 if ((t = strtok(buf, " \t")) == 0) { 1058 (void) strcpy(parse_err_msg, "no number"); 1059 return (GENENT_PARSEERR); 1060 } 1061 ecol[0].ec_value.ec_value_val = t; 1062 ecol[0].ec_value.ec_value_len = strlen(t)+1; 1063 cname = t; 1064 1065 /* 1066 * number (col 2) 1067 */ 1068 if ((t = strtok(NULL, " \t")) == 0) { 1069 (void) strcpy(parse_err_msg, "no number"); 1070 return (GENENT_PARSEERR); 1071 } 1072 ecol[2].ec_value.ec_value_val = t; 1073 ecol[2].ec_value.ec_value_len = strlen(t)+1; 1074 1075 1076 /* 1077 * build entry 1078 */ 1079 data.p_name = strdup(ecol[0].ec_value.ec_value_val); 1080 1081 if (ecol[2].ec_value.ec_value_val != NULL && 1082 ecol[2].ec_value.ec_value_val[0] != '\0') { 1083 1084 data.p_proto = ascii_to_int(ecol[2].ec_value.ec_value_val); 1085 if (data.p_proto == -1) { 1086 (void) snprintf(parse_err_msg, sizeof (parse_err_msg), 1087 "invalid protocol number: %s", 1088 ecol[2].ec_value.ec_value_val); 1089 return (GENENT_PARSEERR); 1090 } 1091 } else 1092 data.p_proto = -1; 1093 1094 /* 1095 * name (col 1) 1096 */ 1097 t = cname; 1098 ctr = 0; 1099 data.p_aliases = NULL; 1100 1101 do { 1102 /* 1103 * don't clobber comment in canonical entry 1104 */ 1105 if (t != cname && strcasecmp(t, cname) == 0) 1106 continue; 1107 if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0) 1108 continue; 1109 1110 ecol[1].ec_value.ec_value_val = t; 1111 ecol[1].ec_value.ec_value_len = strlen(t)+1; 1112 1113 ctr++; 1114 alias = strdup(ecol[1].ec_value.ec_value_val); 1115 if ((data.p_aliases = (char **)realloc(data.p_aliases, 1116 ctr * sizeof (char **))) == NULL) { 1117 (void) fprintf(stderr, gettext("out of memory\n")); 1118 exit(1); 1119 } 1120 data.p_aliases[ctr-1] = alias; 1121 1122 /* 1123 * only put comment in canonical entry 1124 */ 1125 ecol[3].ec_value.ec_value_val = 0; 1126 ecol[3].ec_value.ec_value_len = 0; 1127 1128 } while (t = strtok(NULL, " \t")); 1129 1130 /* End the list of all the aliases by NULL */ 1131 if ((data.p_aliases = (char **)realloc(data.p_aliases, 1132 (ctr + 1) * sizeof (char **))) == NULL) { 1133 (void) fprintf(stderr, gettext("out of memory\n")); 1134 exit(1); 1135 } 1136 data.p_aliases[ctr] = NULL; 1137 1138 if (flags & F_VERBOSE) 1139 (void) fprintf(stdout, 1140 gettext("Adding entry : %s\n"), data.p_name); 1141 1142 retval = (*cback)(&data, 0); 1143 1144 if (retval == LDAP_ALREADY_EXISTS) { 1145 if (continue_onerror) 1146 (void) fprintf(stderr, 1147 gettext("Entry: %s - already Exists, skipping it.\n"), 1148 data.p_name); 1149 else { 1150 rc = GENENT_CBERR; 1151 (void) fprintf(stderr, 1152 gettext("Entry: %s - already Exists\n"), 1153 data.p_name); 1154 } 1155 } else if (retval) 1156 rc = GENENT_CBERR; 1157 1158 free(data.p_name); 1159 free(data.p_aliases); 1160 1161 return (rc); 1162 } 1163 1164 1165 static void 1166 dump_protocols(ns_ldap_result_t *res) 1167 { 1168 ns_ldap_attr_t *attrptr = NULL, *cn = NULL, *protocolnumber = NULL; 1169 int i, j; 1170 char *name, *cp; 1171 1172 if (res == NULL || res->entry == NULL) 1173 return; 1174 for (i = 0; i < res->entry->attr_count; i++) { 1175 attrptr = res->entry->attr_pair[i]; 1176 if (strcasecmp(attrptr->attrname, "cn") == 0) 1177 cn = attrptr; 1178 else if (strcasecmp(attrptr->attrname, "ipProtocolNumber") 1179 == 0) 1180 protocolnumber = attrptr; 1181 } 1182 /* sanity check */ 1183 if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL || 1184 protocolnumber == NULL || protocolnumber->attrvalue == NULL || 1185 protocolnumber->attrvalue[0] == NULL) 1186 return; 1187 1188 if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL) 1189 return; 1190 1191 /* protocol name */ 1192 if (strlen(name) < 8) 1193 (void) fprintf(stdout, "%s\t\t", name); 1194 else 1195 (void) fprintf(stdout, "%s\t", name); 1196 1197 /* protocol number */ 1198 (void) fprintf(stdout, "%-16s", protocolnumber->attrvalue[0]); 1199 1200 /* aliases */ 1201 for (j = 0; j < cn->value_count; j++) { 1202 if (cn->attrvalue[j]) { 1203 if (strcasecmp(name, cn->attrvalue[j]) == 0) { 1204 if (cn->value_count > 1) 1205 /* Do not replicate */ 1206 continue; 1207 /* 1208 * Replicate name in uppercase as an aliase 1209 */ 1210 for (cp = cn->attrvalue[j]; *cp; cp++) 1211 *cp = toupper(*cp); 1212 } 1213 (void) fprintf(stdout, "%s ", cn->attrvalue[j]); 1214 } 1215 } 1216 1217 /* end of line */ 1218 (void) fprintf(stdout, "\n"); 1219 1220 } 1221 1222 1223 1224 1225 1226 /* 1227 * /etc/networks 1228 * 1229 */ 1230 1231 static int 1232 genent_networks(char *line, int (*cback)()) 1233 { 1234 char buf[BUFSIZ+1]; 1235 char *t; 1236 entry_col ecol[4]; 1237 char *cname; 1238 1239 struct netent data; 1240 char *alias; 1241 int ctr = 0; 1242 int retval = 1; 1243 int enet; 1244 int rc = GENENT_OK; 1245 1246 /* 1247 * don't clobber our argument 1248 */ 1249 if (strlen(line) >= sizeof (buf)) { 1250 (void) strcpy(parse_err_msg, "line too long"); 1251 return (GENENT_PARSEERR); 1252 } 1253 (void) strcpy(buf, line); 1254 1255 /* 1256 * clear column data 1257 */ 1258 (void) memset((char *)ecol, 0, sizeof (ecol)); 1259 1260 /* 1261 * comment (col 3) 1262 */ 1263 t = strchr(buf, '#'); 1264 if (t) { 1265 *t++ = 0; 1266 ecol[3].ec_value.ec_value_val = t; 1267 ecol[3].ec_value.ec_value_len = strlen(t)+1; 1268 } else { 1269 ecol[3].ec_value.ec_value_val = 0; 1270 ecol[3].ec_value.ec_value_len = 0; 1271 } 1272 1273 /* 1274 * cname(col 0) 1275 */ 1276 if ((t = strtok(buf, " \t")) == 0) { 1277 (void) strcpy(parse_err_msg, "no number"); 1278 return (GENENT_PARSEERR); 1279 } 1280 ecol[0].ec_value.ec_value_val = t; 1281 ecol[0].ec_value.ec_value_len = strlen(t)+1; 1282 cname = t; 1283 1284 /* 1285 * number (col 2) 1286 */ 1287 if ((t = strtok(NULL, " \t")) == 0) { 1288 (void) strcpy(parse_err_msg, "no number"); 1289 return (GENENT_PARSEERR); 1290 } 1291 ecol[2].ec_value.ec_value_val = t; 1292 ecol[2].ec_value.ec_value_len = strlen(t)+1; 1293 1294 1295 /* 1296 * build entry 1297 */ 1298 1299 data.n_name = strdup(ecol[0].ec_value.ec_value_val); 1300 /* 1301 * data.n_net is an unsigned field, 1302 * assign -1 to it, make no sense. 1303 * Use enet here to avoid lint warning. 1304 */ 1305 enet = encode_network(ecol[2].ec_value.ec_value_val); 1306 1307 if (enet == -1 && continue_onerror == 0) { 1308 (void) fprintf(stderr, gettext("Invalid network number\n")); 1309 if (continue_onerror == 0) 1310 return (GENENT_CBERR); 1311 } else 1312 data.n_net = enet; 1313 1314 /* 1315 * name (col 1) 1316 */ 1317 t = cname; 1318 data.n_aliases = NULL; 1319 1320 do { 1321 /* 1322 * don't clobber comment in canonical entry 1323 */ 1324 if (t != cname && strcasecmp(t, cname) == 0) 1325 continue; 1326 if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0) 1327 continue; 1328 1329 ecol[1].ec_value.ec_value_val = t; 1330 ecol[1].ec_value.ec_value_len = strlen(t)+1; 1331 1332 ctr++; 1333 alias = strdup(ecol[1].ec_value.ec_value_val); 1334 if ((data.n_aliases = (char **)realloc(data.n_aliases, 1335 ctr * sizeof (char **))) == NULL) { 1336 (void) fprintf(stderr, gettext("out of memory\n")); 1337 exit(1); 1338 } 1339 data.n_aliases[ctr-1] = alias; 1340 1341 /* 1342 * only put comment in canonical entry 1343 */ 1344 ecol[3].ec_value.ec_value_val = 0; 1345 ecol[3].ec_value.ec_value_len = 0; 1346 1347 } while (t = strtok(NULL, " \t")); 1348 1349 /* End the list of all the aliases by NULL */ 1350 if ((data.n_aliases = (char **)realloc(data.n_aliases, 1351 (ctr + 1) * sizeof (char **))) == NULL) { 1352 (void) fprintf(stderr, gettext("out of memory\n")); 1353 exit(1); 1354 } 1355 data.n_aliases[ctr] = NULL; 1356 1357 if (flags & F_VERBOSE) 1358 (void) fprintf(stdout, 1359 gettext("Adding entry : %s\n"), data.n_name); 1360 1361 retval = (*cback)(&data, 0); 1362 1363 if (retval == LDAP_ALREADY_EXISTS) { 1364 if (continue_onerror) 1365 (void) fprintf(stderr, 1366 gettext("Entry: %s - already Exists, skipping it.\n"), 1367 data.n_name); 1368 else { 1369 rc = GENENT_CBERR; 1370 (void) fprintf(stderr, 1371 gettext("Entry: %s - already Exists\n"), 1372 data.n_name); 1373 } 1374 } else if (retval) 1375 rc = GENENT_CBERR; 1376 1377 free(data.n_name); 1378 free(data.n_aliases); 1379 1380 return (rc); 1381 } 1382 1383 1384 static void 1385 dump_networks(ns_ldap_result_t *res) 1386 { 1387 ns_ldap_attr_t *attrptr = NULL, *cn = NULL, *networknumber = NULL; 1388 int i, j; 1389 char *name; 1390 1391 if (res == NULL || res->entry == NULL) 1392 return; 1393 for (i = 0; i < res->entry->attr_count; i++) { 1394 attrptr = res->entry->attr_pair[i]; 1395 if (strcasecmp(attrptr->attrname, "cn") == 0) 1396 cn = attrptr; 1397 else if (strcasecmp(attrptr->attrname, "ipNetworkNumber") 1398 == 0) 1399 networknumber = attrptr; 1400 } 1401 /* sanity check */ 1402 if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL || 1403 networknumber == NULL || networknumber->attrvalue == NULL || 1404 networknumber->attrvalue[0] == NULL) 1405 return; 1406 1407 /* 1408 * cn can be a MUST attribute(RFC 2307) or MAY attribute(2307bis). 1409 * If the canonical name can not be found (2307bis), use the 1st 1410 * value as the official name. 1411 */ 1412 1413 /* network name */ 1414 if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL) 1415 name = cn->attrvalue[0]; 1416 1417 if (strlen(name) < 8) 1418 (void) fprintf(stdout, "%s\t\t", name); 1419 else 1420 (void) fprintf(stdout, "%s\t", name); 1421 1422 /* network number */ 1423 (void) fprintf(stdout, "%-16s", networknumber->attrvalue[0]); 1424 1425 /* aliases */ 1426 for (j = 0; j < cn->value_count; j++) { 1427 if (cn->attrvalue[j]) { 1428 if (strcasecmp(name, cn->attrvalue[j]) == 0) 1429 /* skip name */ 1430 continue; 1431 (void) fprintf(stdout, "%s ", cn->attrvalue[j]); 1432 } 1433 } 1434 1435 /* end of line */ 1436 (void) fprintf(stdout, "\n"); 1437 1438 } 1439 1440 1441 1442 1443 /* 1444 * /etc/services 1445 * 1446 */ 1447 1448 static int 1449 genent_services(char *line, int (*cback)()) 1450 { 1451 char buf[BUFSIZ+1]; 1452 char *t, *p; 1453 entry_col ecol[5]; 1454 char *cname; 1455 1456 struct servent data; 1457 char *alias; 1458 int ctr = 0; 1459 int retval = 1; 1460 int rc = GENENT_OK; 1461 1462 /* 1463 * don't clobber our argument 1464 */ 1465 if (strlen(line) >= sizeof (buf)) { 1466 (void) strcpy(parse_err_msg, "line too long"); 1467 return (GENENT_PARSEERR); 1468 } 1469 (void) strcpy(buf, line); 1470 1471 /* 1472 * clear column data 1473 */ 1474 (void) memset((char *)ecol, 0, sizeof (ecol)); 1475 1476 /* 1477 * comment (col 4) 1478 */ 1479 t = strchr(buf, '#'); 1480 if (t) { 1481 *t++ = 0; 1482 ecol[4].ec_value.ec_value_val = t; 1483 ecol[4].ec_value.ec_value_len = strlen(t)+1; 1484 } else { 1485 ecol[4].ec_value.ec_value_val = 0; 1486 ecol[4].ec_value.ec_value_len = 0; 1487 } 1488 1489 /* 1490 * cname(col 0) 1491 */ 1492 if ((t = strtok(buf, " \t")) == 0) { 1493 (void) strcpy(parse_err_msg, "no port"); 1494 return (GENENT_PARSEERR); 1495 } 1496 ecol[0].ec_value.ec_value_val = t; 1497 ecol[0].ec_value.ec_value_len = strlen(t)+1; 1498 cname = t; 1499 1500 /* 1501 * port (col 3) 1502 */ 1503 if ((t = strtok(NULL, " \t")) == 0) { 1504 (void) strcpy(parse_err_msg, "no protocol"); 1505 return (GENENT_PARSEERR); 1506 } 1507 if ((p = strchr(t, '/')) == 0) { 1508 (void) strcpy(parse_err_msg, "bad port/proto"); 1509 return (GENENT_PARSEERR); 1510 } 1511 *(p++) = 0; 1512 ecol[3].ec_value.ec_value_val = t; 1513 ecol[3].ec_value.ec_value_len = strlen(t)+1; 1514 1515 /* 1516 * proto (col 2) 1517 */ 1518 ecol[2].ec_value.ec_value_val = p; 1519 ecol[2].ec_value.ec_value_len = strlen(p)+1; 1520 1521 1522 /* 1523 * build entry 1524 */ 1525 1526 data.s_name = strdup(ecol[0].ec_value.ec_value_val); 1527 data.s_proto = strdup(ecol[2].ec_value.ec_value_val); 1528 1529 if (ecol[3].ec_value.ec_value_val != NULL && 1530 ecol[3].ec_value.ec_value_val[0] != '\0') { 1531 1532 data.s_port = ascii_to_int(ecol[3].ec_value.ec_value_val); 1533 if (data.s_port == -1) { 1534 (void) snprintf(parse_err_msg, sizeof (parse_err_msg), 1535 "invalid port number: %s", 1536 ecol[3].ec_value.ec_value_val); 1537 return (GENENT_PARSEERR); 1538 } 1539 } else 1540 data.s_port = -1; 1541 1542 /* 1543 * name (col 1) 1544 */ 1545 t = cname; 1546 data.s_aliases = NULL; 1547 1548 do { 1549 /* 1550 * don't clobber comment in canonical entry 1551 */ 1552 if (t != cname && strcasecmp(t, cname) == 0) 1553 continue; 1554 if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0) 1555 continue; 1556 1557 ecol[1].ec_value.ec_value_val = t; 1558 ecol[1].ec_value.ec_value_len = strlen(t)+1; 1559 1560 ctr++; 1561 alias = strdup(ecol[1].ec_value.ec_value_val); 1562 if ((data.s_aliases = (char **)realloc(data.s_aliases, 1563 ctr * sizeof (char **))) == NULL) { 1564 (void) fprintf(stderr, gettext("out of memory\n")); 1565 exit(1); 1566 } 1567 data.s_aliases[ctr-1] = alias; 1568 1569 /* 1570 * only put comment in canonical entry 1571 */ 1572 ecol[4].ec_value.ec_value_val = 0; 1573 ecol[4].ec_value.ec_value_len = 0; 1574 1575 } while (t = strtok(NULL, " \t")); 1576 1577 /* End the list of all the aliases by NULL */ 1578 if ((data.s_aliases = (char **)realloc(data.s_aliases, 1579 (ctr + 1) * sizeof (char **))) == NULL) { 1580 (void) fprintf(stderr, gettext("out of memory\n")); 1581 exit(1); 1582 } 1583 data.s_aliases[ctr] = NULL; 1584 1585 if (flags & F_VERBOSE) 1586 (void) fprintf(stdout, 1587 gettext("Adding entry : %s\n"), line); 1588 1589 retval = (*cback)(&data, 0); 1590 1591 if (retval == LDAP_ALREADY_EXISTS) { 1592 if (continue_onerror) 1593 (void) fprintf(stderr, gettext( 1594 "Entry: cn=%s+ipServiceProtocol=%s" 1595 " already Exists, skipping it.\n"), 1596 data.s_name, data.s_proto); 1597 else { 1598 rc = GENENT_CBERR; 1599 (void) fprintf(stderr, 1600 gettext("Entry: cn=%s+ipServiceProtocol=%s" 1601 " - already Exists\n"), 1602 data.s_name, data.s_proto); 1603 } 1604 } else if (retval) 1605 rc = GENENT_CBERR; 1606 1607 free(data.s_name); 1608 free(data.s_proto); 1609 free(data.s_aliases); 1610 1611 return (rc); 1612 } 1613 1614 1615 1616 static void 1617 dump_services(ns_ldap_result_t *res) 1618 { 1619 ns_ldap_attr_t *attrptr = NULL, *cn = NULL, *port = NULL; 1620 ns_ldap_attr_t *protocol = NULL; 1621 int i, j, len; 1622 char *name; /* service name */ 1623 1624 /* 1625 * cn can have multiple values.(service name and its aliases) 1626 * In order to support RFC 2307, section 5.5, ipserviceprotocol can 1627 * have multiple values too. 1628 * The output format should look like 1629 * 1630 * test 2345/udp mytest 1631 * test 2345/tcp mytest 1632 */ 1633 if (res == NULL || res->entry == NULL) 1634 return; 1635 for (i = 0; i < res->entry->attr_count; i++) { 1636 attrptr = res->entry->attr_pair[i]; 1637 if (strcasecmp(attrptr->attrname, "cn") == 0) 1638 cn = attrptr; 1639 else if (strcasecmp(attrptr->attrname, "ipServicePort") == 0) 1640 port = attrptr; 1641 else if (strcasecmp(attrptr->attrname, 1642 "ipServiceProtocol") == 0) 1643 protocol = attrptr; 1644 } 1645 /* sanity check */ 1646 if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL || 1647 port == NULL || port->attrvalue == NULL || 1648 port->attrvalue[0] == NULL || protocol == NULL || 1649 protocol->attrvalue == NULL || protocol->attrvalue[0] == NULL) 1650 return; 1651 1652 if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL) 1653 return; 1654 for (i = 0; i < protocol->value_count; i++) { 1655 if (protocol->attrvalue[i] == NULL) 1656 return; 1657 /* service name */ 1658 (void) fprintf(stdout, "%-16s", name); 1659 1660 /* port & protocol */ 1661 (void) fprintf(stdout, "%s/%s%n", port->attrvalue[0], 1662 protocol->attrvalue[i], &len); 1663 1664 if (len < 8) 1665 (void) fprintf(stdout, "\t\t"); 1666 else 1667 (void) fprintf(stdout, "\t"); 1668 1669 /* aliases */ 1670 for (j = 0; j < cn->value_count; j++) { 1671 if (cn->attrvalue[j]) { 1672 if (strcasecmp(name, cn->attrvalue[j]) == 0) 1673 /* skip service name */ 1674 continue; 1675 (void) fprintf(stdout, "%s ", cn->attrvalue[j]); 1676 } 1677 } 1678 1679 /* end of line */ 1680 (void) fprintf(stdout, "\n"); 1681 } 1682 } 1683 1684 1685 /* 1686 * /etc/group 1687 */ 1688 1689 static int 1690 genent_group(char *line, int (*cback)()) 1691 { 1692 char buf[BIGBUF+1]; 1693 char *s, *t; 1694 entry_col ecol[5]; 1695 1696 struct group data; 1697 int ctr = 0; 1698 int retval = 1; 1699 int rc = GENENT_OK; 1700 1701 /* 1702 * don't clobber our argument 1703 */ 1704 if (strlen(line) >= sizeof (buf)) { 1705 (void) strcpy(parse_err_msg, "line too long"); 1706 return (GENENT_PARSEERR); 1707 } 1708 (void) strcpy(buf, line); 1709 t = buf; 1710 1711 /* ignore empty entries */ 1712 if (*t == '\0') 1713 return (GENENT_OK); 1714 1715 /* 1716 * clear column data 1717 */ 1718 (void) memset((char *)ecol, 0, sizeof (ecol)); 1719 1720 /* 1721 * name (col 0) 1722 */ 1723 if ((s = strchr(t, ':')) == 0) { 1724 (void) strcpy(parse_err_msg, "no passwd"); 1725 return (GENENT_PARSEERR); 1726 } 1727 *s++ = 0; 1728 ecol[0].ec_value.ec_value_val = t; 1729 ecol[0].ec_value.ec_value_len = strlen(t)+1; 1730 t = s; 1731 1732 /* 1733 * passwd (col 1) 1734 */ 1735 if ((s = strchr(t, ':')) == 0) { 1736 (void) strcpy(parse_err_msg, "no gid"); 1737 return (GENENT_PARSEERR); 1738 } 1739 *s++ = 0; 1740 ecol[1].ec_value.ec_value_val = t; 1741 ecol[1].ec_value.ec_value_len = strlen(t)+1; 1742 t = s; 1743 1744 1745 /* 1746 * gid (col 2) 1747 */ 1748 if ((s = strchr(t, ':')) == 0 || s == t) { 1749 (void) strcpy(parse_err_msg, "no members"); 1750 return (GENENT_PARSEERR); 1751 } 1752 *s++ = 0; 1753 ecol[2].ec_value.ec_value_val = t; 1754 ecol[2].ec_value.ec_value_len = strlen(t)+1; 1755 t = s; 1756 1757 /* 1758 * members (col 3) 1759 */ 1760 ecol[3].ec_value.ec_value_val = t; 1761 ecol[3].ec_value.ec_value_len = strlen(t)+1; 1762 1763 1764 /* 1765 * build entry 1766 */ 1767 data.gr_name = strdup(ecol[0].ec_value.ec_value_val); 1768 data.gr_passwd = strdup(ecol[1].ec_value.ec_value_val); 1769 if (ecol[2].ec_value.ec_value_val != NULL && 1770 ecol[2].ec_value.ec_value_val[0] != '\0') { 1771 1772 data.gr_gid = ascii_to_int(ecol[2].ec_value.ec_value_val); 1773 if (data.gr_gid == -1) { 1774 (void) snprintf(parse_err_msg, sizeof (parse_err_msg), 1775 "invalid group id: %s", 1776 ecol[2].ec_value.ec_value_val); 1777 return (GENENT_PARSEERR); 1778 } 1779 } else 1780 data.gr_gid = -1; 1781 1782 data.gr_mem = NULL; 1783 1784 /* Compute maximum amount of members */ 1785 s = t; 1786 while (s = strchr(s, ',')) { 1787 s++; 1788 ctr++; 1789 } 1790 1791 /* Allocate memory for all members */ 1792 data.gr_mem = calloc(ctr + 2, sizeof (char **)); 1793 if (data.gr_mem == NULL) { 1794 (void) fprintf(stderr, gettext("out of memory\n")); 1795 exit(1); 1796 } 1797 1798 ctr = 0; 1799 while (s = strchr(t, ',')) { 1800 1801 *s++ = 0; 1802 ecol[3].ec_value.ec_value_val = t; 1803 t = s; 1804 /* Send to server only non empty member names */ 1805 if (strlen(ecol[3].ec_value.ec_value_val) != 0) 1806 data.gr_mem[ctr++] = ecol[3].ec_value.ec_value_val; 1807 } 1808 1809 /* Send to server only non empty member names */ 1810 if (strlen(t) != 0) 1811 data.gr_mem[ctr++] = t; 1812 1813 /* Array of members completed, finished by NULL, see calloc() */ 1814 1815 if (flags & F_VERBOSE) 1816 (void) fprintf(stdout, 1817 gettext("Adding entry : %s\n"), data.gr_name); 1818 1819 retval = (*cback)(&data, 0); 1820 1821 if (retval == LDAP_ALREADY_EXISTS) { 1822 if (continue_onerror) 1823 (void) fprintf(stderr, 1824 gettext("Entry: %s - already Exists, skipping it.\n"), 1825 data.gr_name); 1826 else { 1827 rc = GENENT_CBERR; 1828 (void) fprintf(stderr, 1829 gettext("Entry: %s - already Exists\n"), 1830 data.gr_name); 1831 } 1832 } else if (retval) 1833 rc = GENENT_CBERR; 1834 1835 free(data.gr_name); 1836 free(data.gr_passwd); 1837 free(data.gr_mem); 1838 1839 return (rc); 1840 } 1841 1842 static void 1843 dump_group(ns_ldap_result_t *res) 1844 { 1845 char **value = NULL; 1846 char pnam[256]; 1847 int attr_count = 0; 1848 1849 value = __ns_ldap_getAttr(res->entry, "cn"); 1850 if (value && value[0]) 1851 (void) fprintf(stdout, "%s:", value[0]); 1852 value = __ns_ldap_getAttr(res->entry, "userPassword"); 1853 if (value == NULL || value[0] == NULL) 1854 (void) fprintf(stdout, "*:"); 1855 else { 1856 (void) strcpy(pnam, value[0]); 1857 if (strncasecmp(value[0], "{crypt}", 7) == 0) 1858 (void) fprintf(stdout, "%s:", (pnam+7)); 1859 else 1860 (void) fprintf(stdout, "*:"); 1861 } 1862 value = __ns_ldap_getAttr(res->entry, "gidNumber"); 1863 if (value && value[0]) 1864 (void) fprintf(stdout, "%s:", value[0]); 1865 1866 value = __ns_ldap_getAttr(res->entry, "memberUid"); 1867 if (value != NULL && value[0] != NULL) { 1868 while (value[attr_count] != NULL) { 1869 if (value[attr_count+1] == NULL) 1870 (void) fprintf(stdout, "%s", value[attr_count]); 1871 else 1872 (void) fprintf(stdout, "%s,", 1873 value[attr_count]); 1874 attr_count++; 1875 } 1876 (void) fprintf(stdout, "\n"); 1877 } 1878 else 1879 (void) fprintf(stdout, "\n"); 1880 } 1881 1882 1883 1884 1885 1886 /* 1887 * /etc/ethers 1888 */ 1889 1890 static int 1891 genent_ethers(char *line, int (*cback)()) 1892 { 1893 char buf[BUFSIZ+1]; 1894 char *t; 1895 entry_col ecol[3]; 1896 int retval = 1; 1897 struct _ns_ethers data; 1898 int rc = GENENT_OK; 1899 1900 /* 1901 * don't clobber our argument 1902 */ 1903 if (strlen(line) >= sizeof (buf)) { 1904 (void) strcpy(parse_err_msg, "line too long"); 1905 return (GENENT_PARSEERR); 1906 } 1907 (void) strcpy(buf, line); 1908 1909 /* 1910 * clear column data 1911 */ 1912 (void) memset((char *)ecol, 0, sizeof (ecol)); 1913 1914 /* 1915 * comment (col 2) 1916 */ 1917 t = strchr(buf, '#'); 1918 if (t) { 1919 *t++ = 0; 1920 ecol[2].ec_value.ec_value_val = t; 1921 ecol[2].ec_value.ec_value_len = strlen(t)+1; 1922 } else { 1923 ecol[2].ec_value.ec_value_val = 0; 1924 ecol[2].ec_value.ec_value_len = 0; 1925 } 1926 1927 /* 1928 * addr(col 0) 1929 */ 1930 if ((t = strtok(buf, " \t")) == 0) { 1931 (void) strcpy(parse_err_msg, "no name"); 1932 return (GENENT_PARSEERR); 1933 } 1934 ecol[0].ec_value.ec_value_val = t; 1935 ecol[0].ec_value.ec_value_len = strlen(t)+1; 1936 1937 /* 1938 * name(col 1) 1939 */ 1940 if ((t = strtok(NULL, " \t")) == 0) { 1941 (void) strcpy(parse_err_msg, "no white space allowed in name"); 1942 return (GENENT_PARSEERR); 1943 } 1944 ecol[1].ec_value.ec_value_val = t; 1945 ecol[1].ec_value.ec_value_len = strlen(t)+1; 1946 1947 1948 /* 1949 * build entry 1950 */ 1951 1952 data.ether = strdup(ecol[0].ec_value.ec_value_val); 1953 data.name = strdup(ecol[1].ec_value.ec_value_val); 1954 1955 1956 if (flags & F_VERBOSE) 1957 (void) fprintf(stdout, 1958 gettext("Adding entry : %s\n"), data.name); 1959 1960 retval = (*cback)(&data, 0); 1961 1962 if (retval == LDAP_ALREADY_EXISTS) { 1963 if (continue_onerror) 1964 (void) fprintf(stderr, 1965 gettext("Entry: %s - already Exists, skipping it.\n"), 1966 data.name); 1967 else { 1968 rc = GENENT_CBERR; 1969 (void) fprintf(stderr, 1970 gettext("Entry: %s - already Exists\n"), 1971 data.name); 1972 } 1973 } else if (retval) 1974 rc = GENENT_CBERR; 1975 1976 free(data.ether); 1977 free(data.name); 1978 1979 return (rc); 1980 } 1981 1982 1983 static void 1984 dump_ethers(ns_ldap_result_t *res) 1985 { 1986 char **value = NULL; 1987 1988 value = __ns_ldap_getAttr(res->entry, "macAddress"); 1989 if (value && value[0]) 1990 (void) fprintf(stdout, "%s", value[0]); 1991 else 1992 return; 1993 value = __ns_ldap_getAttr(res->entry, "cn"); 1994 if (value && value[0]) 1995 (void) fprintf(stdout, " %s\n", value[0]); 1996 } 1997 1998 static int 1999 genent_aliases(char *line, int (*cback)()) 2000 { 2001 char buf[BUFSIZ+1]; 2002 char *t, *aliases; 2003 char *cname; 2004 int ctr = 0; 2005 int retval = 1; 2006 int i; 2007 2008 struct _ns_alias data; 2009 char *alias; 2010 int rc = GENENT_OK; 2011 2012 /* 2013 * don't clobber our argument 2014 */ 2015 if (strlen(line) >= sizeof (buf)) { 2016 (void) strcpy(parse_err_msg, "line too long"); 2017 return (GENENT_PARSEERR); 2018 } 2019 2020 (void) strcpy(buf, line); 2021 2022 if ((t = strchr(buf, ':')) == 0) { 2023 (void) strcpy(parse_err_msg, "no alias name"); 2024 return (GENENT_PARSEERR); 2025 } 2026 2027 t[0] = '\0'; 2028 if (++t == '\0') { 2029 (void) strcpy(parse_err_msg, "no alias value"); 2030 return (GENENT_PARSEERR); 2031 } 2032 2033 cname = buf; 2034 aliases = t; 2035 2036 /* build entry */ 2037 data.alias = strdup(cname); 2038 if (!data.alias) { 2039 (void) fprintf(stderr, gettext("out of memory\n")); 2040 exit(1); 2041 } 2042 2043 data.member = NULL; 2044 t = strtok(aliases, ","); 2045 do { 2046 ctr++; 2047 while (t[0] == ' ') 2048 t++; 2049 alias = strdup(t); 2050 if ((alias == NULL) || 2051 ((data.member = (char **)realloc(data.member, 2052 (ctr + 1) * sizeof (char **))) == NULL)) { 2053 (void) fprintf(stderr, gettext("out of memory\n")); 2054 exit(1); 2055 } 2056 data.member[ctr-1] = alias; 2057 2058 } while (t = strtok(NULL, ",")); 2059 2060 data.member[ctr] = NULL; 2061 2062 if (flags & F_VERBOSE) 2063 (void) fprintf(stdout, 2064 gettext("Adding entry : %s\n"), data.alias); 2065 2066 retval = (*cback)(&data, 0); 2067 2068 if (retval == LDAP_ALREADY_EXISTS) { 2069 if (continue_onerror) 2070 (void) fprintf(stderr, 2071 gettext("Entry: %s - already Exists, skipping it.\n"), 2072 data.alias); 2073 else { 2074 rc = GENENT_CBERR; 2075 (void) fprintf(stderr, 2076 gettext("Entry: %s - already Exists\n"), 2077 data.alias); 2078 } 2079 } else if (retval) 2080 rc = GENENT_CBERR; 2081 2082 free(data.alias); 2083 i = 0; 2084 while (data.member[i]) 2085 free(data.member[i++]); 2086 free(data.member); 2087 2088 return (rc); 2089 } 2090 2091 2092 static void 2093 dump_aliases(ns_ldap_result_t *res) 2094 { 2095 2096 char **value = NULL; 2097 int attr_count = 0; 2098 2099 value = __ns_ldap_getAttr(res->entry, "mail"); 2100 if (value && value[0]) 2101 (void) fprintf(stdout, "%s:", value[0]); 2102 value = __ns_ldap_getAttr(res->entry, "mgrpRFC822MailMember"); 2103 if (value != NULL) 2104 while (value[attr_count] != NULL) { 2105 (void) fprintf(stdout, "%s,", value[attr_count]); 2106 attr_count++; 2107 } 2108 (void) fprintf(stdout, "\n"); 2109 2110 } 2111 2112 /* 2113 * /etc/publickey 2114 */ 2115 2116 static char *h_errno2str(int h_errno); 2117 2118 static int 2119 genent_publickey(char *line, int (*cback)()) 2120 { 2121 char buf[BUFSIZ+1], tmpbuf[BUFSIZ+1], cname[BUFSIZ+1]; 2122 char *t, *p, *tmppubkey, *tmpprivkey; 2123 entry_col ecol[3]; 2124 int buflen, uid, retval = 1, errnum = 0; 2125 struct passwd *pwd; 2126 char auth_type[BUFSIZ+1], *dot; 2127 keylen_t keylen; 2128 algtype_t algtype; 2129 struct _ns_pubkey data; 2130 struct hostent *hp; 2131 struct in_addr in; 2132 struct in6_addr in6; 2133 char abuf[INET6_ADDRSTRLEN]; 2134 2135 /* 2136 * don't clobber our argument 2137 */ 2138 if (strlen(line) >= sizeof (buf)) { 2139 (void) strcpy(parse_err_msg, "line too long"); 2140 return (GENENT_PARSEERR); 2141 } 2142 (void) strcpy(buf, line); 2143 2144 /* 2145 * clear column data 2146 */ 2147 (void) memset((char *)ecol, 0, sizeof (ecol)); 2148 2149 if ((t = strtok(buf, " \t")) == 0) { 2150 (void) strcpy(parse_err_msg, "no cname"); 2151 return (GENENT_PARSEERR); 2152 } 2153 2154 /* 2155 * Special case: /etc/publickey usually has an entry 2156 * for principal "nobody". We skip it. 2157 */ 2158 if (strcmp(t, "nobody") == 0) 2159 return (GENENT_OK); 2160 2161 /* 2162 * cname (col 0) 2163 */ 2164 if (strncmp(t, "unix.", 5)) { 2165 (void) strcpy(parse_err_msg, "bad cname"); 2166 return (GENENT_PARSEERR); 2167 } 2168 (void) strcpy(tmpbuf, &(t[5])); 2169 if ((p = strchr(tmpbuf, '@')) == 0) { 2170 (void) strcpy(parse_err_msg, "bad cname"); 2171 return (GENENT_PARSEERR); 2172 } 2173 *(p++) = 0; 2174 if (isdigit(*tmpbuf)) { 2175 2176 uid = atoi(tmpbuf); 2177 /* 2178 * don't generate entries for uids without passwd entries 2179 */ 2180 if ((pwd = getpwuid(uid)) == 0) { 2181 (void) fprintf(stderr, 2182 gettext("can't map uid %d to username, skipping\n"), 2183 uid); 2184 return (GENENT_OK); 2185 } 2186 (void) strcpy(cname, pwd->pw_name); 2187 data.hostcred = NS_HOSTCRED_FALSE; 2188 } else { 2189 if ((hp = getipnodebyname(tmpbuf, AF_INET6, 2190 AI_ALL | AI_V4MAPPED, &errnum)) == NULL) { 2191 (void) fprintf(stderr, 2192 gettext("can't map hostname %s to hostaddress, " 2193 "errnum %d %s skipping\n"), tmpbuf, errnum, 2194 h_errno2str(errnum)); 2195 return (GENENT_OK); 2196 } 2197 (void) memcpy((char *)&in6.s6_addr, hp->h_addr_list[0], 2198 hp->h_length); 2199 if (IN6_IS_ADDR_V4MAPPED(&in6) || 2200 IN6_IS_ADDR_V4COMPAT(&in6)) { 2201 IN6_V4MAPPED_TO_INADDR(&in6, &in); 2202 if (inet_ntop(AF_INET, (const void *)&in, abuf, 2203 INET6_ADDRSTRLEN) == NULL) { 2204 (void) fprintf(stderr, 2205 gettext("can't convert IPV4 address of" 2206 " hostname %s to string, " 2207 "skipping\n"), tmpbuf); 2208 return (GENENT_OK); 2209 } 2210 } else { 2211 if (inet_ntop(AF_INET6, (const void *)&in6, abuf, 2212 INET6_ADDRSTRLEN) == NULL) { 2213 (void) fprintf(stderr, 2214 gettext("can't convert IPV6 address of" 2215 " hostname %s to string, " 2216 "skipping\n"), tmpbuf); 2217 return (GENENT_OK); 2218 } 2219 } 2220 data.hostcred = NS_HOSTCRED_TRUE; 2221 /* 2222 * tmpbuf could be an alias, use hp->h_name instead. 2223 * hp->h_name is in FQDN format, so extract 1st field. 2224 */ 2225 if ((dot = strchr(hp->h_name, '.')) != NULL) 2226 *dot = '\0'; 2227 (void) snprintf(cname, sizeof (cname), 2228 "%s+ipHostNumber=%s", hp->h_name, abuf); 2229 if (dot) 2230 *dot = '.'; 2231 } 2232 2233 ecol[0].ec_value.ec_value_val = cname; 2234 ecol[0].ec_value.ec_value_len = strlen(cname)+1; 2235 2236 /* 2237 * public_data (col 1) 2238 */ 2239 if ((t = strtok(NULL, " \t")) == 0) { 2240 (void) strcpy(parse_err_msg, "no private_data"); 2241 return (GENENT_PARSEERR); 2242 } 2243 if ((p = strchr(t, ':')) == 0) { 2244 (void) strcpy(parse_err_msg, "bad public_data"); 2245 return (GENENT_PARSEERR); 2246 } 2247 *(p++) = 0; 2248 ecol[1].ec_value.ec_value_val = t; 2249 ecol[1].ec_value.ec_value_len = strlen(t)+1; 2250 keylen = (strlen(t) / 2) * 8; 2251 2252 /* 2253 * private_data (col 2) and algtype extraction 2254 */ 2255 if (*p == ':') 2256 p++; 2257 t = p; 2258 if (!(t = strchr(t, ':'))) { 2259 (void) fprintf(stderr, 2260 gettext("WARNING: No algorithm type data found " 2261 "in publickey file, assuming 0\n")); 2262 algtype = 0; 2263 } else { 2264 *t = '\0'; 2265 t++; 2266 algtype = atoi(t); 2267 } 2268 ecol[2].ec_value.ec_value_val = p; 2269 ecol[2].ec_value.ec_value_len = strlen(p)+1; 2270 2271 /* 2272 * auth_type (col 1) 2273 */ 2274 if (AUTH_DES_KEY(keylen, algtype)) 2275 /* 2276 * {DES} and {DH192-0} means same thing. 2277 * However, nisplus uses "DES" and ldap uses "DH192-0" 2278 * internally. 2279 * See newkey(1M), __nis_mechalias2authtype() which is 2280 * called by __nis_keyalg2authtype() and getkey_ldap_g() 2281 */ 2282 (void) strlcpy(auth_type, "DH192-0", BUFSIZ+1); 2283 else if (!(__nis_keyalg2authtype(keylen, algtype, auth_type, 2284 MECH_MAXATNAME))) { 2285 (void) fprintf(stderr, 2286 gettext("Could not convert algorithm type to " 2287 "corresponding auth type string\n")); 2288 return (GENENT_ERR); 2289 } 2290 2291 /* 2292 * build entry 2293 */ 2294 data.name = strdup(ecol[0].ec_value.ec_value_val); 2295 if (data.name == NULL) { 2296 (void) fprintf(stderr, gettext("out of memory\n")); 2297 exit(1); 2298 } 2299 2300 buflen = sizeof (auth_type) + strlen(ecol[1].ec_value.ec_value_val) + 3; 2301 if ((tmppubkey = (char *)malloc(buflen)) == NULL) { 2302 (void) fprintf(stderr, gettext("out of memory\n")); 2303 exit(1); 2304 } 2305 (void) snprintf(tmppubkey, buflen, "{%s}%s", auth_type, 2306 ecol[1].ec_value.ec_value_val); 2307 data.pubkey = tmppubkey; 2308 2309 buflen = sizeof (auth_type) + strlen(ecol[2].ec_value.ec_value_val) + 3; 2310 if ((tmpprivkey = (char *)malloc(buflen)) == NULL) { 2311 (void) fprintf(stderr, gettext("out of memory\n")); 2312 exit(1); 2313 } 2314 2315 (void) snprintf(tmpprivkey, buflen, "{%s}%s", auth_type, 2316 ecol[2].ec_value.ec_value_val); 2317 data.privkey = tmpprivkey; 2318 2319 retval = (*cback)(&data, 1); 2320 if (retval != NS_LDAP_SUCCESS) { 2321 if (retval == LDAP_NO_SUCH_OBJECT) { 2322 if (data.hostcred == NS_HOSTCRED_TRUE) 2323 (void) fprintf(stdout, 2324 gettext("Cannot add publickey entry (%s), " 2325 "add host entry first\n"), 2326 tmpbuf); 2327 else 2328 (void) fprintf(stdout, 2329 gettext("Cannot add publickey entry (%s), " 2330 "add passwd entry first\n"), 2331 data.name); 2332 } 2333 if (continue_onerror == 0) 2334 return (GENENT_CBERR); 2335 } 2336 2337 free(data.name); 2338 free(data.pubkey); 2339 free(data.privkey); 2340 return (GENENT_OK); 2341 } 2342 2343 static void 2344 dump_publickey(ns_ldap_result_t *res, char *container) 2345 { 2346 char **value = NULL; 2347 char buf[BUFSIZ]; 2348 char domainname[BUFSIZ]; 2349 char *pubptr, *prvptr; 2350 2351 if (res == NULL) 2352 return; 2353 2354 if (sysinfo(SI_SRPC_DOMAIN, domainname, BUFSIZ) < 0) { 2355 (void) fprintf(stderr, 2356 gettext("could not obtain domainname\n")); 2357 exit(1); 2358 } 2359 2360 /* 2361 * Retrieve all the attributes, but don't print 2362 * until we have all the required ones. 2363 */ 2364 2365 if (strcmp(container, "passwd") == 0) 2366 value = __ns_ldap_getAttr(res->entry, "uidNumber"); 2367 else 2368 value = __ns_ldap_getAttr(res->entry, "cn"); 2369 2370 if (value && value[0]) 2371 (void) snprintf(buf, sizeof (buf), "unix.%s@%s", 2372 value[0], domainname); 2373 else 2374 return; 2375 2376 value = __ns_ldap_getAttr(res->entry, "nisPublickey"); 2377 if (value != NULL && value[0] != NULL) { 2378 if ((pubptr = strchr(value[0], '}')) == NULL) 2379 return; 2380 } 2381 2382 value = __ns_ldap_getAttr(res->entry, "nisSecretkey"); 2383 if (value != NULL && value[0] != NULL) 2384 if ((prvptr = strchr(value[0], '}')) == NULL) 2385 return; 2386 2387 /* print the attributes, algorithm type is always 0 */ 2388 (void) fprintf(stdout, "%s %s:%s:0\n", buf, ++pubptr, ++prvptr); 2389 } 2390 2391 2392 2393 /* 2394 * /etc/netmasks 2395 */ 2396 2397 static int 2398 genent_netmasks(char *line, int (*cback)()) 2399 { 2400 char buf[BUFSIZ+1]; 2401 char *t; 2402 entry_col ecol[3]; 2403 int retval; 2404 2405 struct _ns_netmasks data; 2406 2407 2408 /* 2409 * don't clobber our argument 2410 */ 2411 if (strlen(line) >= sizeof (buf)) { 2412 (void) strcpy(parse_err_msg, "line too long"); 2413 return (GENENT_PARSEERR); 2414 } 2415 (void) strcpy(buf, line); 2416 2417 /* 2418 * clear column data 2419 */ 2420 (void) memset((char *)ecol, 0, sizeof (ecol)); 2421 2422 /* 2423 * comment (col 2) 2424 */ 2425 t = strchr(buf, '#'); 2426 if (t) { 2427 *t++ = 0; 2428 ecol[2].ec_value.ec_value_val = t; 2429 ecol[2].ec_value.ec_value_len = strlen(t)+1; 2430 } else { 2431 ecol[2].ec_value.ec_value_val = 0; 2432 ecol[2].ec_value.ec_value_len = 0; 2433 } 2434 2435 /* 2436 * addr(col 0) 2437 */ 2438 if ((t = strtok(buf, " \t")) == 0) { 2439 (void) strcpy(parse_err_msg, "no mask"); 2440 return (GENENT_PARSEERR); 2441 } 2442 ecol[0].ec_value.ec_value_val = t; 2443 ecol[0].ec_value.ec_value_len = strlen(t)+1; 2444 2445 /* 2446 * mask (col 1) 2447 */ 2448 if ((t = strtok(NULL, " \t")) == 0) { 2449 (void) strcpy(parse_err_msg, "no mask"); 2450 return (GENENT_PARSEERR); 2451 } 2452 ecol[1].ec_value.ec_value_val = t; 2453 ecol[1].ec_value.ec_value_len = strlen(t)+1; 2454 2455 /* build entry */ 2456 data.netnumber = ecol[0].ec_value.ec_value_val; 2457 data.netmask = ecol[1].ec_value.ec_value_val; 2458 2459 if (flags & F_VERBOSE) 2460 (void) fprintf(stdout, 2461 gettext("Adding entry : %s\n"), data.netnumber); 2462 2463 retval = (*cback)(&data, 1); 2464 if (retval != NS_LDAP_SUCCESS) { 2465 if (retval == LDAP_NO_SUCH_OBJECT) 2466 (void) fprintf(stdout, 2467 gettext("Cannot add netmask entry (%s), " 2468 "add network entry first\n"), data.netnumber); 2469 if (continue_onerror == 0) 2470 return (GENENT_CBERR); 2471 } 2472 2473 return (GENENT_OK); 2474 } 2475 2476 static void 2477 dump_netmasks(ns_ldap_result_t *res) 2478 { 2479 char **value = NULL; 2480 2481 value = __ns_ldap_getAttr(res->entry, "ipNetworkNumber"); 2482 if (value && value[0]) 2483 (void) fprintf(stdout, "%s", value[0]); 2484 value = __ns_ldap_getAttr(res->entry, "ipNetmaskNumber"); 2485 if (value && value[0]) 2486 (void) fprintf(stdout, " %s\n", value[0]); 2487 } 2488 2489 2490 /* 2491 * /etc/netgroup 2492 * column data format is: 2493 * col 0: netgroup name (or cname) 2494 * col 1: netgroup member, if this is a triplet 2495 * col 2: netgroup member, if not a triplet 2496 * col 3: comment 2497 */ 2498 2499 static int 2500 genent_netgroup(char *line, int (*cback)()) 2501 { 2502 char buf[BIGBUF+1]; /* netgroup entries tend to be big */ 2503 char *t; 2504 char *cname = NULL; 2505 entry_col ecol[4]; 2506 char *netg_tmp = NULL, *triplet_tmp = NULL; 2507 int netgcount = 0, tripletcount = 0, retval = 1, i; 2508 struct _ns_netgroups data; 2509 int rc = GENENT_OK; 2510 2511 /* don't clobber our argument */ 2512 if (strlen(line) >= sizeof (buf)) { 2513 (void) strcpy(parse_err_msg, "line too long"); 2514 return (GENENT_PARSEERR); 2515 } 2516 (void) strcpy(buf, line); 2517 2518 /* clear column data */ 2519 (void) memset((char *)ecol, 0, sizeof (ecol)); 2520 2521 /* 2522 * process 1st minimal entry, to validate that there is no 2523 * parsing error. 2524 * start with comment(col 3) 2525 */ 2526 t = strchr(buf, '#'); 2527 if (t) { 2528 *t++ = 0; 2529 ecol[3].ec_value.ec_value_val = t; 2530 ecol[3].ec_value.ec_value_len = strlen(t)+1; 2531 } else { 2532 ecol[3].ec_value.ec_value_val = ""; 2533 ecol[3].ec_value.ec_value_len = 0; 2534 } 2535 2536 ecol[1].ec_value.ec_value_val = NULL; 2537 ecol[2].ec_value.ec_value_val = NULL; 2538 2539 /* cname (col 0) */ 2540 if ((t = strtok(buf, " \t")) == 0) { 2541 (void) strcpy(parse_err_msg, "no cname"); 2542 return (GENENT_PARSEERR); 2543 } 2544 2545 ecol[0].ec_value.ec_value_val = t; 2546 ecol[0].ec_value.ec_value_len = strlen(t)+1; 2547 cname = t; 2548 2549 /* addr(col 1 and 2) */ 2550 if ((t = strtok(NULL, " \t")) == 0) { 2551 (void) strcpy(parse_err_msg, "no members for netgroup"); 2552 return (GENENT_PARSEERR); 2553 } 2554 2555 if (*t == '(') { 2556 /* if token starts with '(' it must be a valid triplet */ 2557 if (is_triplet(t)) { 2558 ecol[1].ec_value.ec_value_val = t; 2559 ecol[1].ec_value.ec_value_len = strlen(t)+1; 2560 } else { 2561 (void) strcpy(parse_err_msg, "invalid triplet"); 2562 return (GENENT_PARSEERR); 2563 } 2564 } else { 2565 ecol[2].ec_value.ec_value_val = t; 2566 ecol[2].ec_value.ec_value_len = strlen(t)+1; 2567 } 2568 2569 /* 2570 * now build entry. 2571 * start by clearing entry data 2572 */ 2573 (void) memset((struct _ns_netgroups *)&data, 0, sizeof (data)); 2574 2575 data.name = strdup(ecol[0].ec_value.ec_value_val); 2576 2577 if (ecol[1].ec_value.ec_value_val != NULL) { 2578 if ((data.triplet = calloc(1, sizeof (char **))) == NULL) { 2579 (void) fprintf(stderr, 2580 gettext("out of memory\n")); 2581 exit(1); 2582 } 2583 data.triplet[tripletcount++] = 2584 strdup(ecol[1].ec_value.ec_value_val); 2585 } else if (ecol[2].ec_value.ec_value_val != NULL) { 2586 if ((data.netgroup = calloc(1, sizeof (char **))) 2587 == NULL) { 2588 (void) fprintf(stderr, 2589 gettext("out of memory\n")); 2590 exit(1); 2591 } 2592 data.netgroup[netgcount++] = 2593 strdup(ecol[2].ec_value.ec_value_val); 2594 } 2595 2596 /* 2597 * we now have a valid entry (at least 1 netgroup name and 2598 * 1 netgroup member), proceed with the rest of the line 2599 */ 2600 while (rc == GENENT_OK && (t = strtok(NULL, " \t"))) { 2601 2602 /* if next token is equal to netgroup name, ignore */ 2603 if (t != cname && strcasecmp(t, cname) == 0) 2604 continue; 2605 if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0) 2606 continue; 2607 2608 if (*t == '(') { 2609 if (is_triplet(t)) { 2610 /* skip a triplet if it is added already */ 2611 for (i = 0; i < tripletcount && 2612 strcmp(t, data.triplet[i]); i++) 2613 ; 2614 if (i < tripletcount) 2615 continue; 2616 2617 tripletcount++; 2618 triplet_tmp = strdup(t); 2619 if ((data.triplet = (char **)realloc( 2620 data.triplet, 2621 tripletcount * sizeof (char **))) 2622 == NULL) { 2623 (void) fprintf(stderr, 2624 gettext("out of memory\n")); 2625 exit(1); 2626 } 2627 data.triplet[tripletcount-1] = triplet_tmp; 2628 } else { 2629 (void) strcpy(parse_err_msg, "invalid triplet"); 2630 rc = GENENT_PARSEERR; 2631 } 2632 } else { 2633 /* skip a netgroup if it is added already */ 2634 for (i = 0; i < netgcount && 2635 strcmp(t, data.netgroup[i]); i++) 2636 ; 2637 if (i < netgcount) 2638 continue; 2639 2640 netgcount++; 2641 netg_tmp = strdup(t); 2642 if ((data.netgroup = (char **)realloc(data.netgroup, 2643 netgcount * sizeof (char **))) == NULL) { 2644 (void) fprintf(stderr, 2645 gettext("out of memory\n")); 2646 exit(1); 2647 } 2648 data.netgroup[netgcount-1] = netg_tmp; 2649 } 2650 } 2651 2652 /* End the list with NULL */ 2653 if ((data.triplet = (char **)realloc(data.triplet, 2654 (tripletcount + 1) * sizeof (char **))) == NULL) { 2655 (void) fprintf(stderr, gettext("out of memory\n")); 2656 exit(1); 2657 } 2658 data.triplet[tripletcount] = NULL; 2659 if ((data.netgroup = (char **)realloc(data.netgroup, 2660 (netgcount + 1) * sizeof (char **))) == NULL) { 2661 (void) fprintf(stderr, gettext("out of memory\n")); 2662 exit(1); 2663 } 2664 data.netgroup[netgcount] = NULL; 2665 2666 if (rc == GENENT_OK) { 2667 if (flags & F_VERBOSE) 2668 (void) fprintf(stdout, 2669 gettext("Adding entry : %s\n"), data.name); 2670 2671 retval = (*cback)(&data, 0); 2672 2673 if (retval == LDAP_ALREADY_EXISTS) { 2674 if (continue_onerror) 2675 (void) fprintf(stderr, gettext( 2676 "Entry: %s - already Exists, skipping it.\n"), 2677 data.name); 2678 else { 2679 rc = GENENT_CBERR; 2680 (void) fprintf(stderr, 2681 gettext("Entry: %s - already Exists\n"), 2682 data.name); 2683 } 2684 } else if (retval) 2685 rc = GENENT_CBERR; 2686 } 2687 2688 /* release memory allocated by strdup() */ 2689 for (i = 0; i < tripletcount; i++) { 2690 free(data.triplet[i]); 2691 } 2692 for (i = 0; i < netgcount; i++) { 2693 free(data.netgroup[i]); 2694 } 2695 2696 free(data.name); 2697 free(data.triplet); 2698 free(data.netgroup); 2699 2700 return (rc); 2701 } 2702 2703 static void 2704 dump_netgroup(ns_ldap_result_t *res) 2705 { 2706 char **value = NULL; 2707 int attr_count = 0; 2708 2709 value = __ns_ldap_getAttr(res->entry, "cn"); 2710 if ((value != NULL) && (value[0] != NULL)) 2711 (void) fprintf(stdout, "%s", value[0]); 2712 else 2713 return; 2714 value = __ns_ldap_getAttr(res->entry, "nisNetgroupTriple"); 2715 if (value != NULL) 2716 while (value[attr_count] != NULL) { 2717 (void) fprintf(stdout, " %s", value[attr_count]); 2718 attr_count++; 2719 } 2720 attr_count = 0; 2721 value = __ns_ldap_getAttr(res->entry, "memberNisNetgroup"); 2722 if (value != NULL) 2723 while (value[attr_count] != NULL) { 2724 (void) fprintf(stdout, " %s", value[attr_count]); 2725 attr_count++; 2726 } 2727 (void) fprintf(stdout, "\n"); 2728 2729 } 2730 2731 static int 2732 genent_automount(char *line, int (*cback)()) 2733 { 2734 char buf[BUFSIZ+1]; 2735 char *t, *s; 2736 entry_col ecol[2]; 2737 struct _ns_automount data; 2738 int retval = 1; 2739 int rc = GENENT_OK; 2740 2741 /* 2742 * don't clobber our argument 2743 */ 2744 if (strlen(line) >= sizeof (buf)) { 2745 (void) strcpy(parse_err_msg, "line too long"); 2746 return (GENENT_PARSEERR); 2747 } 2748 2749 /* replace every tabspace with single space */ 2750 replace_tab2space(line); 2751 (void) strcpy(buf, line); 2752 2753 /* 2754 * clear column data 2755 */ 2756 (void) memset((char *)ecol, 0, sizeof (ecol)); 2757 2758 /* 2759 * key (col 0) 2760 */ 2761 t = buf; 2762 while (t[0] == ' ') 2763 t++; 2764 2765 if ((s = strchr(t, ' ')) == 0) { 2766 return (GENENT_PARSEERR); 2767 } 2768 *s++ = 0; 2769 2770 ecol[0].ec_value.ec_value_val = t; 2771 ecol[0].ec_value.ec_value_len = strlen(t)+1; 2772 t = s; 2773 2774 while (t[0] == ' ') 2775 t++; 2776 2777 /* 2778 * mapentry (col 1) 2779 */ 2780 2781 ecol[1].ec_value.ec_value_val = t; 2782 ecol[1].ec_value.ec_value_len = strlen(t)+1; 2783 2784 data.mapname = strdup(databasetype); 2785 data.key = strdup(ecol[0].ec_value.ec_value_val); 2786 data.value = strdup(ecol[1].ec_value.ec_value_val); 2787 2788 if (flags & F_VERBOSE) 2789 (void) fprintf(stdout, 2790 gettext("Adding entry : %s\n"), data.key); 2791 2792 retval = (*cback)(&data, 0); 2793 2794 if (retval == LDAP_ALREADY_EXISTS) { 2795 if (continue_onerror) 2796 (void) fprintf(stderr, 2797 gettext("Entry: %s - already Exists, skipping it.\n"), 2798 data.key); 2799 else { 2800 rc = GENENT_CBERR; 2801 (void) fprintf(stderr, 2802 gettext("Entry: %s - already Exists\n"), 2803 data.key); 2804 } 2805 } else if (retval) 2806 rc = GENENT_CBERR; 2807 2808 free(data.mapname); 2809 free(data.key); 2810 free(data.value); 2811 return (rc); 2812 } 2813 2814 static void 2815 dump_automount(ns_ldap_result_t *res) 2816 { 2817 char **value = NULL; 2818 2819 if (res == NULL) 2820 return; 2821 2822 value = __ns_ldap_getAttr(res->entry, "automountKey"); 2823 if (value != NULL) { 2824 (void) fprintf(stdout, "%s", value[0]); 2825 value = __ns_ldap_getAttr(res->entry, "automountInformation"); 2826 if (value != NULL) 2827 (void) fprintf(stdout, " %s\n", value[0]); 2828 else 2829 (void) fprintf(stdout, "\n"); 2830 } 2831 } 2832 2833 2834 /* 2835 * /etc/passwd 2836 * 2837 */ 2838 2839 static int 2840 genent_passwd(char *line, int (*cback)()) 2841 { 2842 char buf[BUFSIZ+1]; 2843 char *s, *t; 2844 entry_col ecol[8]; 2845 int retval = 1; 2846 char pname[BUFSIZ]; 2847 2848 struct passwd data; 2849 int rc = GENENT_OK; 2850 2851 2852 /* 2853 * don't clobber our argument 2854 */ 2855 if (strlen(line) >= sizeof (buf)) { 2856 (void) strcpy(parse_err_msg, "line too long"); 2857 return (GENENT_PARSEERR); 2858 } 2859 (void) strcpy(buf, line); 2860 t = buf; 2861 2862 /* ignore empty entries */ 2863 if (*t == '\0') 2864 return (GENENT_OK); 2865 2866 /* 2867 * clear column data 2868 */ 2869 (void) memset((char *)ecol, 0, sizeof (ecol)); 2870 2871 /* 2872 * name (col 0) 2873 */ 2874 if ((s = strchr(t, ':')) == 0) { 2875 (void) strcpy(parse_err_msg, "no password"); 2876 return (GENENT_PARSEERR); 2877 } 2878 *s++ = 0; 2879 ecol[0].ec_value.ec_value_val = t; 2880 ecol[0].ec_value.ec_value_len = strlen(t)+1; 2881 t = s; 2882 2883 /* 2884 * passwd (col 1) 2885 */ 2886 if ((s = strchr(t, ':')) == 0) { 2887 (void) strcpy(parse_err_msg, "no uid"); 2888 return (GENENT_PARSEERR); 2889 } 2890 *s++ = 0; 2891 2892 ecol[1].ec_value.ec_value_val = t; 2893 ecol[1].ec_value.ec_value_len = strlen(t)+1; 2894 2895 t = s; 2896 2897 /* 2898 * uid (col 2) 2899 */ 2900 if ((s = strchr(t, ':')) == 0 || s == t) { 2901 (void) strcpy(parse_err_msg, "no gid"); 2902 return (GENENT_PARSEERR); 2903 } 2904 *s++ = 0; 2905 ecol[2].ec_value.ec_value_val = t; 2906 ecol[2].ec_value.ec_value_len = strlen(t)+1; 2907 t = s; 2908 2909 /* 2910 * gid (col 3) 2911 */ 2912 if ((s = strchr(t, ':')) == 0 || s == t) { 2913 (void) strcpy(parse_err_msg, "no gcos"); 2914 return (GENENT_PARSEERR); 2915 } 2916 *s++ = 0; 2917 ecol[3].ec_value.ec_value_val = t; 2918 ecol[3].ec_value.ec_value_len = strlen(t)+1; 2919 t = s; 2920 2921 /* 2922 * gcos (col 4) 2923 */ 2924 if ((s = strchr(t, ':')) == 0) { 2925 (void) strcpy(parse_err_msg, "no home"); 2926 return (GENENT_PARSEERR); 2927 } 2928 *s++ = 0; 2929 ecol[4].ec_value.ec_value_val = t; 2930 ecol[4].ec_value.ec_value_len = strlen(t)+1; 2931 t = s; 2932 2933 /* 2934 * home (col 5) 2935 */ 2936 if ((s = strchr(t, ':')) == 0) { 2937 (void) strcpy(parse_err_msg, "no shell"); 2938 return (GENENT_PARSEERR); 2939 } 2940 *s++ = 0; 2941 ecol[5].ec_value.ec_value_val = t; 2942 ecol[5].ec_value.ec_value_len = strlen(t)+1; 2943 t = s; 2944 2945 /* 2946 * shell (col 6) 2947 */ 2948 ecol[6].ec_value.ec_value_val = t; 2949 ecol[6].ec_value.ec_value_len = strlen(t)+1; 2950 2951 /* 2952 * build entry 2953 */ 2954 data.pw_name = strdup(ecol[0].ec_value.ec_value_val); 2955 2956 if (flags & F_PASSWD) { 2957 /* Add {crypt} before passwd entry */ 2958 (void) snprintf(pname, sizeof (pname), "{crypt}%s", 2959 ecol[1].ec_value.ec_value_val); 2960 data.pw_passwd = strdup(pname); 2961 } 2962 else 2963 data.pw_passwd = NULL; 2964 2965 if (ecol[2].ec_value.ec_value_val != NULL && 2966 ecol[2].ec_value.ec_value_val[0] != '\0') { 2967 data.pw_uid = ascii_to_int(ecol[2].ec_value.ec_value_val); 2968 if (data.pw_uid == -1) { 2969 (void) snprintf(parse_err_msg, sizeof (parse_err_msg), 2970 "invalid uid : %s", ecol[2].ec_value.ec_value_val); 2971 return (GENENT_PARSEERR); 2972 } 2973 } else 2974 data.pw_uid = -1; 2975 2976 if (ecol[3].ec_value.ec_value_val != NULL && 2977 ecol[3].ec_value.ec_value_val[0] != '\0') { 2978 2979 data.pw_gid = ascii_to_int(ecol[3].ec_value.ec_value_val); 2980 if (data.pw_gid == -1) { 2981 (void) snprintf(parse_err_msg, sizeof (parse_err_msg), 2982 "invalid gid : %s", ecol[3].ec_value.ec_value_val); 2983 return (GENENT_PARSEERR); 2984 } 2985 } else 2986 data.pw_gid = -1; 2987 2988 data.pw_age = NULL; 2989 data.pw_comment = NULL; 2990 data.pw_gecos = strdup(ecol[4].ec_value.ec_value_val); 2991 data.pw_dir = strdup(ecol[5].ec_value.ec_value_val); 2992 data.pw_shell = strdup(ecol[6].ec_value.ec_value_val); 2993 2994 if (flags & F_VERBOSE) 2995 (void) fprintf(stdout, 2996 gettext("Adding entry : %s\n"), data.pw_name); 2997 2998 retval = (*cback)(&data, 0); 2999 3000 if (retval == LDAP_ALREADY_EXISTS) { 3001 if (continue_onerror) 3002 (void) fprintf(stderr, 3003 gettext("Entry: %s - already Exists, skipping it.\n"), 3004 data.pw_name); 3005 else { 3006 rc = GENENT_CBERR; 3007 (void) fprintf(stderr, 3008 gettext("Entry: %s - already Exists\n"), 3009 data.pw_name); 3010 } 3011 } else if (retval) 3012 rc = GENENT_CBERR; 3013 3014 free(data.pw_name); 3015 free(data.pw_gecos); 3016 free(data.pw_dir); 3017 free(data.pw_shell); 3018 return (rc); 3019 } 3020 3021 3022 static void 3023 dump_passwd(ns_ldap_result_t *res) 3024 { 3025 char **value = NULL; 3026 char pnam[256]; 3027 3028 value = __ns_ldap_getAttr(res->entry, "uid"); 3029 if (value == NULL) 3030 return; 3031 else 3032 (void) fprintf(stdout, "%s:", value[0]); 3033 value = __ns_ldap_getAttr(res->entry, "userPassword"); 3034 if (value == NULL) 3035 (void) fprintf(stdout, "*:"); 3036 else { 3037 (void) strcpy(pnam, value[0]); 3038 if (strncasecmp(value[0], "{crypt}", 7) == 0) 3039 (void) fprintf(stdout, "%s:", (pnam+7)); 3040 else 3041 (void) fprintf(stdout, "*:"); 3042 } 3043 value = __ns_ldap_getAttr(res->entry, "uidNumber"); 3044 if (value && value[0]) 3045 (void) fprintf(stdout, "%s:", value[0]); 3046 value = __ns_ldap_getAttr(res->entry, "gidNumber"); 3047 if (value && value[0]) 3048 (void) fprintf(stdout, "%s:", value[0]); 3049 value = __ns_ldap_getAttr(res->entry, "gecos"); 3050 if (value == NULL) 3051 (void) fprintf(stdout, ":"); 3052 else 3053 (void) fprintf(stdout, "%s:", value[0]); 3054 value = __ns_ldap_getAttr(res->entry, "homeDirectory"); 3055 if (value == NULL) 3056 (void) fprintf(stdout, ":"); 3057 else 3058 (void) fprintf(stdout, "%s:", value[0]); 3059 value = __ns_ldap_getAttr(res->entry, "loginShell"); 3060 if (value == NULL) 3061 (void) fprintf(stdout, "\n"); 3062 else 3063 (void) fprintf(stdout, "%s\n", value[0]); 3064 3065 } 3066 3067 /* 3068 * /etc/shadow 3069 */ 3070 3071 static int 3072 genent_shadow(char *line, int (*cback)()) 3073 { 3074 char buf[BUFSIZ+1]; 3075 char *s, *t; 3076 entry_col ecol[9]; 3077 char pname[BUFSIZ]; 3078 3079 struct spwd data; 3080 int spflag; 3081 int retval; 3082 3083 3084 /* 3085 * don't clobber our argument 3086 */ 3087 if (strlen(line) >= sizeof (buf)) { 3088 (void) strcpy(parse_err_msg, "line too long"); 3089 return (GENENT_PARSEERR); 3090 } 3091 (void) strcpy(buf, line); 3092 t = buf; 3093 3094 /* ignore empty entries */ 3095 if (*t == '\0') 3096 return (GENENT_OK); 3097 3098 /* 3099 * clear column data 3100 */ 3101 (void) memset((char *)ecol, 0, sizeof (ecol)); 3102 3103 /* 3104 * name (col 0) 3105 */ 3106 if ((s = strchr(t, ':')) == 0) { 3107 (void) strcpy(parse_err_msg, "no uid"); 3108 return (GENENT_PARSEERR); 3109 } 3110 *s++ = 0; 3111 ecol[0].ec_value.ec_value_val = t; 3112 ecol[0].ec_value.ec_value_len = strlen(t)+1; 3113 t = s; 3114 3115 /* 3116 * passwd (col 1) 3117 */ 3118 if ((s = strchr(t, ':')) == 0) { 3119 (void) strcpy(parse_err_msg, "Improper format"); 3120 return (GENENT_PARSEERR); 3121 } 3122 *s++ = 0; 3123 3124 ecol[1].ec_value.ec_value_val = t; 3125 ecol[1].ec_value.ec_value_len = strlen(t)+1; 3126 3127 t = s; 3128 3129 /* 3130 * shadow last change (col 2) 3131 */ 3132 if ((s = strchr(t, ':')) == 0) { 3133 (void) strcpy(parse_err_msg, "Improper format"); 3134 return (GENENT_PARSEERR); 3135 } 3136 *s++ = 0; 3137 ecol[2].ec_value.ec_value_val = t; 3138 ecol[2].ec_value.ec_value_len = strlen(t)+1; 3139 t = s; 3140 3141 /* 3142 * shadow min (col 3) 3143 */ 3144 if ((s = strchr(t, ':')) == 0) { 3145 (void) strcpy(parse_err_msg, "Improper format"); 3146 return (GENENT_PARSEERR); 3147 } 3148 *s++ = 0; 3149 ecol[3].ec_value.ec_value_val = t; 3150 ecol[3].ec_value.ec_value_len = strlen(t)+1; 3151 t = s; 3152 3153 /* 3154 * shadow max (col 4) 3155 */ 3156 if ((s = strchr(t, ':')) == 0) { 3157 (void) strcpy(parse_err_msg, "Improper format"); 3158 return (GENENT_PARSEERR); 3159 } 3160 *s++ = 0; 3161 ecol[4].ec_value.ec_value_val = t; 3162 ecol[4].ec_value.ec_value_len = strlen(t)+1; 3163 t = s; 3164 3165 /* 3166 * shadow warn (col 5) 3167 */ 3168 if ((s = strchr(t, ':')) == 0) { 3169 (void) strcpy(parse_err_msg, "Improper format"); 3170 return (GENENT_PARSEERR); 3171 } 3172 *s++ = 0; 3173 ecol[5].ec_value.ec_value_val = t; 3174 ecol[5].ec_value.ec_value_len = strlen(t)+1; 3175 t = s; 3176 3177 /* 3178 * shadow inactive (col 6) 3179 */ 3180 if ((s = strchr(t, ':')) != 0) { 3181 *s++ = 0; 3182 ecol[6].ec_value.ec_value_val = t; 3183 ecol[6].ec_value.ec_value_len = strlen(t)+1; 3184 t = s; 3185 } 3186 3187 /* 3188 * shadow expire (col 7) 3189 */ 3190 if ((s = strchr(t, ':')) != 0) { 3191 *s++ = 0; 3192 ecol[7].ec_value.ec_value_val = t; 3193 ecol[7].ec_value.ec_value_len = strlen(t)+1; 3194 t = s; 3195 3196 /* 3197 * flag (col 8) 3198 */ 3199 ecol[8].ec_value.ec_value_val = t; 3200 ecol[8].ec_value.ec_value_len = strlen(t)+1; 3201 } 3202 3203 /* 3204 * build entry 3205 */ 3206 3207 data.sp_namp = strdup(ecol[0].ec_value.ec_value_val); 3208 3209 if (ecol[1].ec_value.ec_value_val != NULL && 3210 ecol[1].ec_value.ec_value_val[0] != '\0') { 3211 /* Add {crypt} before passwd entry */ 3212 (void) snprintf(pname, sizeof (pname), "{crypt}%s", 3213 ecol[1].ec_value.ec_value_val); 3214 data.sp_pwdp = strdup(pname); 3215 } else 3216 data.sp_pwdp = NULL; 3217 3218 if (ecol[2].ec_value.ec_value_val != NULL && 3219 ecol[2].ec_value.ec_value_val[0] != '\0') { 3220 3221 data.sp_lstchg = ascii_to_int(ecol[2].ec_value.ec_value_val); 3222 if (data.sp_lstchg < -1) { 3223 (void) snprintf(parse_err_msg, sizeof (parse_err_msg), 3224 "invalid last changed date: %s", 3225 ecol[2].ec_value.ec_value_val); 3226 return (GENENT_PARSEERR); 3227 } 3228 } else 3229 data.sp_lstchg = -1; 3230 3231 if (ecol[3].ec_value.ec_value_val != NULL && 3232 ecol[3].ec_value.ec_value_val[0] != '\0') { 3233 3234 data.sp_min = ascii_to_int(ecol[3].ec_value.ec_value_val); 3235 if (data.sp_min < -1) { 3236 (void) snprintf(parse_err_msg, sizeof (parse_err_msg), 3237 "invalid sp_min : %s", 3238 ecol[3].ec_value.ec_value_val); 3239 return (GENENT_PARSEERR); 3240 } 3241 } else 3242 data.sp_min = -1; 3243 3244 if (ecol[4].ec_value.ec_value_val != NULL && 3245 ecol[4].ec_value.ec_value_val[0] != '\0') { 3246 3247 data.sp_max = ascii_to_int(ecol[4].ec_value.ec_value_val); 3248 if (data.sp_max < -1) { 3249 (void) snprintf(parse_err_msg, sizeof (parse_err_msg), 3250 "invalid sp_max : %s", 3251 ecol[4].ec_value.ec_value_val); 3252 return (GENENT_PARSEERR); 3253 } 3254 } else 3255 data.sp_max = -1; 3256 3257 if (ecol[5].ec_value.ec_value_val != NULL && 3258 ecol[5].ec_value.ec_value_val[0] != '\0') { 3259 3260 data.sp_warn = ascii_to_int(ecol[5].ec_value.ec_value_val); 3261 if (data.sp_warn < -1) { 3262 (void) snprintf(parse_err_msg, sizeof (parse_err_msg), 3263 "invalid sp_warn : %s", 3264 ecol[5].ec_value.ec_value_val); 3265 return (GENENT_PARSEERR); 3266 } 3267 } else 3268 data.sp_warn = -1; 3269 3270 if (ecol[6].ec_value.ec_value_val != NULL && 3271 ecol[6].ec_value.ec_value_val[0] != '\0') { 3272 3273 data.sp_inact = ascii_to_int(ecol[6].ec_value.ec_value_val); 3274 if (data.sp_inact < -1) { 3275 (void) snprintf(parse_err_msg, sizeof (parse_err_msg), 3276 "invalid sp_inact : %s", 3277 ecol[6].ec_value.ec_value_val); 3278 return (GENENT_PARSEERR); 3279 } 3280 } else 3281 data.sp_inact = -1; 3282 3283 if (ecol[7].ec_value.ec_value_val != NULL && 3284 ecol[7].ec_value.ec_value_val[0] != '\0') { 3285 3286 data.sp_expire = ascii_to_int(ecol[7].ec_value.ec_value_val); 3287 if (data.sp_expire < -1) { 3288 (void) snprintf(parse_err_msg, sizeof (parse_err_msg), 3289 "invalid login expiry date : %s", 3290 ecol[7].ec_value.ec_value_val); 3291 return (GENENT_PARSEERR); 3292 } 3293 } else 3294 data.sp_expire = -1; 3295 3296 if (ecol[8].ec_value.ec_value_val != NULL && 3297 ecol[8].ec_value.ec_value_val[0] != '\0') { 3298 3299 /* 3300 * data.sp_flag is an unsigned int, 3301 * assign -1 to it, make no sense. 3302 * Use spflag here to avoid lint warning. 3303 */ 3304 spflag = ascii_to_int(ecol[8].ec_value.ec_value_val); 3305 if (spflag < 0) { 3306 (void) snprintf(parse_err_msg, sizeof (parse_err_msg), 3307 "invalid flag value: %s", 3308 ecol[8].ec_value.ec_value_val); 3309 return (GENENT_PARSEERR); 3310 } else 3311 data.sp_flag = spflag; 3312 } else 3313 data.sp_flag = 0; 3314 3315 if (flags & F_VERBOSE) 3316 (void) fprintf(stdout, 3317 gettext("Adding entry : %s\n"), data.sp_namp); 3318 3319 retval = (*cback)(&data, 1); 3320 if (retval != NS_LDAP_SUCCESS) { 3321 if (retval == LDAP_NO_SUCH_OBJECT) 3322 (void) fprintf(stdout, 3323 gettext("Cannot add shadow entry (%s), " 3324 "add passwd entry first\n"), data.sp_namp); 3325 if (continue_onerror == 0) 3326 return (GENENT_CBERR); 3327 } 3328 3329 free(data.sp_namp); 3330 free(data.sp_pwdp); 3331 return (GENENT_OK); 3332 } 3333 3334 static void 3335 dump_shadow(ns_ldap_result_t *res) 3336 { 3337 char **value = NULL; 3338 char pnam[256]; 3339 3340 value = __ns_ldap_getAttr(res->entry, "uid"); 3341 if (value == NULL) 3342 return; 3343 else 3344 (void) fprintf(stdout, "%s:", value[0]); 3345 value = __ns_ldap_getAttr(res->entry, "userPassword"); 3346 if (value == NULL) 3347 (void) fprintf(stdout, "*:"); 3348 else { 3349 (void) strcpy(pnam, value[0]); 3350 if (strncasecmp(value[0], "{crypt}", 7) == 0) 3351 (void) fprintf(stdout, "%s:", (pnam+7)); 3352 else 3353 (void) fprintf(stdout, "*:"); 3354 } 3355 value = __ns_ldap_getAttr(res->entry, "shadowLastChange"); 3356 if (value == NULL) 3357 (void) fprintf(stdout, ":"); 3358 else 3359 (void) fprintf(stdout, "%s:", value[0]); 3360 value = __ns_ldap_getAttr(res->entry, "shadowMin"); 3361 if (value == NULL) 3362 (void) fprintf(stdout, ":"); 3363 else 3364 (void) fprintf(stdout, "%s:", value[0]); 3365 value = __ns_ldap_getAttr(res->entry, "shadowMax"); 3366 if (value == NULL) 3367 (void) fprintf(stdout, ":"); 3368 else 3369 (void) fprintf(stdout, "%s:", value[0]); 3370 3371 /* ignore shadowWarning, shadowInactive, shadowExpire, shadowFlag */ 3372 (void) fprintf(stdout, ":::\n"); 3373 3374 } 3375 3376 3377 static int 3378 genent_bootparams(char *line, int (*cback)()) 3379 { 3380 char buf[BUFSIZ+1]; 3381 char *t; 3382 entry_col ecol[2]; 3383 int ctr = 0, retval = 1; 3384 3385 struct _ns_bootp data; 3386 char *parameter; 3387 int rc = GENENT_OK; 3388 3389 /* 3390 * don't clobber our argument 3391 */ 3392 if (strlen(line) >= sizeof (buf)) { 3393 (void) strcpy(parse_err_msg, "line too long"); 3394 return (GENENT_PARSEERR); 3395 } 3396 (void) strcpy(buf, line); 3397 3398 /* 3399 * clear column data 3400 */ 3401 (void) memset((char *)ecol, 0, sizeof (ecol)); 3402 3403 3404 /* 3405 * cname (col 0) 3406 */ 3407 if ((t = strtok(buf, " \t")) == 0) { 3408 (void) strcpy(parse_err_msg, "no cname"); 3409 return (GENENT_PARSEERR); 3410 } 3411 ecol[0].ec_value.ec_value_val = t; 3412 ecol[0].ec_value.ec_value_len = strlen(t)+1; 3413 3414 3415 3416 /* build entry */ 3417 data.name = strdup(ecol[0].ec_value.ec_value_val); 3418 3419 /* 3420 * name (col 1) 3421 */ 3422 3423 data.param = NULL; 3424 3425 while (t = strtok(NULL, " \t")) { 3426 3427 /* 3428 * don't clobber comment in canonical entry 3429 */ 3430 3431 3432 ecol[1].ec_value.ec_value_val = t; 3433 ecol[1].ec_value.ec_value_len = strlen(t)+1; 3434 3435 ctr++; 3436 parameter = strdup(ecol[1].ec_value.ec_value_val); 3437 if ((data.param = (char **)realloc(data.param, 3438 (ctr + 1) * sizeof (char **))) == NULL) { 3439 (void) fprintf(stderr, gettext("out of memory\n")); 3440 exit(1); 3441 } 3442 data.param[ctr-1] = parameter; 3443 3444 } 3445 3446 3447 /* End the list of all the aliases by NULL */ 3448 if ((data.param = (char **)realloc(data.param, 3449 (ctr + 1) * sizeof (char **))) == NULL) { 3450 (void) fprintf(stderr, gettext("out of memory\n")); 3451 exit(1); 3452 } 3453 data.param[ctr] = NULL; 3454 3455 if (flags & F_VERBOSE) 3456 (void) fprintf(stdout, 3457 gettext("Adding entry : %s\n"), data.name); 3458 3459 retval = (*cback)(&data, 0); 3460 3461 if (retval == LDAP_ALREADY_EXISTS) { 3462 if (continue_onerror) 3463 (void) fprintf(stderr, 3464 gettext("Entry: %s - already Exists, skipping it.\n"), 3465 data.name); 3466 else { 3467 rc = GENENT_CBERR; 3468 (void) fprintf(stderr, 3469 gettext("Entry: %s - already Exists\n"), 3470 data.name); 3471 } 3472 } else if (retval) 3473 rc = GENENT_CBERR; 3474 3475 free(data.name); 3476 free(data.param); 3477 3478 return (rc); 3479 3480 } 3481 3482 3483 static void 3484 dump_bootparams(ns_ldap_result_t *res) 3485 { 3486 char **value = NULL; 3487 int attr_count = 0; 3488 3489 value = __ns_ldap_getAttr(res->entry, "cn"); 3490 if (value[0] != NULL) 3491 (void) fprintf(stdout, "%s", value[0]); 3492 value = __ns_ldap_getAttr(res->entry, "bootParameter"); 3493 if (value != NULL) 3494 while (value[attr_count] != NULL) { 3495 (void) fprintf(stdout, "\t%s", value[attr_count]); 3496 attr_count++; 3497 } 3498 (void) fprintf(stdout, "\n"); 3499 3500 3501 } 3502 3503 static char * 3504 fget_line_at(struct line_buf *line, int n, FILE *fp) 3505 { 3506 int c; 3507 3508 line->len = n; 3509 3510 for (;;) { 3511 c = fgetc(fp); 3512 if (c == -1) 3513 break; 3514 if (line->len >= line->alloc) 3515 line_buf_expand(line); 3516 line->str[line->len++] = c; 3517 3518 if (c == '\n') 3519 break; 3520 } 3521 3522 /* Null Terminate */ 3523 if (line->len >= line->alloc) 3524 line_buf_expand(line); 3525 line->str[line->len++] = 0; 3526 3527 /* if no characters are read, return NULL to indicate EOF */ 3528 if (line->str[0] == '\0') 3529 return (0); 3530 3531 return (line->str); 3532 } 3533 3534 /* 3535 * return a line from the file, discarding comments and blank lines 3536 */ 3537 static int 3538 filedbmline_comment(struct line_buf *line, FILE *etcf, int *lineno, 3539 struct file_loc *loc) 3540 { 3541 int i, len = 0; 3542 3543 loc->offset = ftell(etcf); 3544 for (;;) { 3545 if (fget_line_at(line, len, etcf) == 0) 3546 return (0); 3547 3548 if (lineno) 3549 (*lineno)++; 3550 3551 len = strlen(line->str); 3552 if (len >= 2 && 3553 line->str[0] != '#' && 3554 line->str[len-2] == '\\' && line->str[len-1] == '\n') { 3555 line->str[len-2] = 0; 3556 len -= 2; 3557 continue; /* append next line at end */ 3558 } 3559 3560 if (line->str[len-1] == '\n') { 3561 line->str[len-1] = 0; 3562 len -= 1; 3563 } 3564 3565 /* 3566 * Skip lines where '#' is the first non-blank character. 3567 */ 3568 for (i = 0; i < len; i++) { 3569 if (line->str[i] == '#') { 3570 line->str[i] = '\0'; 3571 len = i; 3572 break; 3573 } 3574 if (line->str[i] != ' ' && line->str[i] != '\t') 3575 break; 3576 } 3577 3578 /* 3579 * A line with one or more white space characters followed 3580 * by a comment will now be blank. The special case of a 3581 * line with '#' in the first byte will have len == 0. 3582 */ 3583 if (len > 0 && !blankline(line->str)) 3584 break; 3585 3586 len = 0; 3587 loc->offset = ftell(etcf); 3588 } 3589 3590 loc->size = len; 3591 return (1); 3592 } 3593 3594 /* 3595 * return a line from the file, discarding comments, blanks, and '+' lines 3596 */ 3597 static int 3598 filedbmline_plus(struct line_buf *line, FILE *etcf, int *lineno, 3599 struct file_loc *loc) 3600 { 3601 int len = 0; 3602 3603 loc->offset = ftell(etcf); 3604 for (;;) { 3605 if (fget_line_at(line, len, etcf) == 0) 3606 return (0); 3607 3608 if (lineno) 3609 (*lineno)++; 3610 3611 len = strlen(line->str); 3612 if (line->str[len-1] == '\n') { 3613 line->str[len-1] = 0; 3614 len -= 1; 3615 } 3616 3617 if (!blankline(line->str) && 3618 line->str[0] != '+' && line->str[0] != '-' && 3619 line->str[0] != '#') 3620 break; 3621 3622 len = 0; 3623 loc->offset = ftell(etcf); 3624 } 3625 3626 loc->size = len; 3627 return (1); 3628 } 3629 3630 3631 /* Populating the ttypelist structure */ 3632 3633 static struct ttypelist_t ttypelist[] = { 3634 { NS_LDAP_TYPE_HOSTS, genent_hosts, dump_hosts, 3635 filedbmline_comment, "iphost" }, 3636 { NS_LDAP_TYPE_IPNODES, genent_hosts, dump_hosts, 3637 filedbmline_comment, "iphost" }, 3638 { NS_LDAP_TYPE_RPC, genent_rpc, dump_rpc, 3639 filedbmline_comment, "oncrpc" }, 3640 { NS_LDAP_TYPE_PROTOCOLS, genent_protocols, dump_protocols, 3641 filedbmline_comment, "ipprotocol" }, 3642 { NS_LDAP_TYPE_NETWORKS, genent_networks, dump_networks, 3643 filedbmline_comment, "ipnetwork" }, 3644 { NS_LDAP_TYPE_SERVICES, genent_services, dump_services, 3645 filedbmline_comment, "ipservice" }, 3646 { NS_LDAP_TYPE_GROUP, genent_group, dump_group, 3647 filedbmline_plus, "posixgroup" }, 3648 { NS_LDAP_TYPE_NETMASKS, genent_netmasks, dump_netmasks, 3649 filedbmline_comment, "ipnetwork" }, 3650 { NS_LDAP_TYPE_ETHERS, genent_ethers, dump_ethers, 3651 filedbmline_comment, "ieee802Device" }, 3652 { NS_LDAP_TYPE_NETGROUP, genent_netgroup, dump_netgroup, 3653 filedbmline_comment, "nisnetgroup" }, 3654 { NS_LDAP_TYPE_BOOTPARAMS, genent_bootparams, dump_bootparams, 3655 filedbmline_comment, "bootableDevice" }, 3656 { NS_LDAP_TYPE_PUBLICKEY, genent_publickey, NULL /* dump_publickey */, 3657 filedbmline_comment, "niskeyobject" }, 3658 { NS_LDAP_TYPE_PASSWD, genent_passwd, dump_passwd, 3659 filedbmline_plus, "posixaccount" }, 3660 { NS_LDAP_TYPE_SHADOW, genent_shadow, dump_shadow, 3661 filedbmline_plus, "shadowaccount" }, 3662 { NS_LDAP_TYPE_ALIASES, genent_aliases, dump_aliases, 3663 filedbmline_plus, "mailGroup" }, 3664 { NS_LDAP_TYPE_AUTOMOUNT, genent_automount, dump_automount, 3665 filedbmline_comment, "automount" }, 3666 { NS_LDAP_TYPE_USERATTR, genent_user_attr, dump_user_attr, 3667 filedbmline_comment, "SolarisUserAttr" }, 3668 { NS_LDAP_TYPE_PROFILE, genent_prof_attr, dump_prof_attr, 3669 filedbmline_comment, "SolarisProfAttr" }, 3670 { NS_LDAP_TYPE_EXECATTR, genent_exec_attr, dump_exec_attr, 3671 filedbmline_comment, "SolarisExecAttr" }, 3672 { NS_LDAP_TYPE_AUTHATTR, genent_auth_attr, dump_auth_attr, 3673 filedbmline_comment, "SolarisAuthAttr" }, 3674 { NS_LDAP_TYPE_AUUSER, genent_audit_user, dump_audit_user, 3675 filedbmline_comment, "SolarisAuditUser" }, 3676 { NS_LDAP_TYPE_TNRHDB, genent_tnrhdb, dump_tnrhdb, 3677 filedbmline_comment, "ipTnetHost" }, 3678 { NS_LDAP_TYPE_TNRHTP, genent_tnrhtp, dump_tnrhtp, 3679 filedbmline_comment, "ipTnetTemplate" }, 3680 { 0, 0, 0, 0, 0 } 3681 }; 3682 3683 3684 3685 3686 static int lineno = 0; 3687 3688 static void 3689 addfile() 3690 { 3691 struct line_buf line; 3692 struct file_loc loc; 3693 3694 /* Initializing the Line Buffer */ 3695 line_buf_init(&line); 3696 3697 /* Loop through all the lines in the file */ 3698 while (tt->filedbmline(&line, etcf, &lineno, &loc)) { 3699 switch ((*(tt->genent))(line.str, addentry)) { 3700 case GENENT_OK: 3701 break; 3702 case GENENT_PARSEERR: 3703 (void) fprintf(stderr, 3704 gettext("parse error: %s (line %d)\n"), 3705 parse_err_msg, lineno); 3706 exit_val = 1; 3707 break; 3708 case GENENT_CBERR: 3709 (void) fprintf(stderr, 3710 gettext("Error while adding line: %s\n"), 3711 line.str); 3712 exit_val = 2; 3713 free(line.str); 3714 return; 3715 break; 3716 case GENENT_ERR: 3717 (void) fprintf(stderr, 3718 gettext("Internal Error while adding line: %s\n"), 3719 line.str); 3720 exit_val = 3; 3721 free(line.str); 3722 return; 3723 break; 3724 } 3725 } 3726 free(line.str); 3727 } 3728 3729 static void 3730 dumptable(char *service) 3731 { 3732 3733 ns_ldap_result_t *eres = NULL; 3734 ns_ldap_error_t *err = NULL; 3735 int rc = 0, success = 0; 3736 char filter[BUFSIZ]; 3737 int done = 0; 3738 void *cookie = NULL; 3739 3740 /* set the appropriate filter */ 3741 if (strcmp(tt->ttype, NS_LDAP_TYPE_PROFILE) == 0) { 3742 /* 3743 * prof_attr entries are SolarisProfAttr 3744 * without AUXILIARY SolarisExecAttr 3745 */ 3746 (void) snprintf(filter, sizeof (filter), 3747 "(&(objectclass=%s)(!(objectclass=SolarisExecAttr)))", 3748 tt->objclass); 3749 } else if (strcmp(tt->ttype, NS_LDAP_TYPE_TNRHDB) == 0) { 3750 /* 3751 * tnrhtp entries are ipTnet entries with SolarisAttrKeyValue 3752 */ 3753 (void) snprintf(filter, sizeof (filter), 3754 "(&(objectclass=%s)(SolarisAttrKeyValue=*)))", 3755 tt->objclass); 3756 } else { 3757 (void) snprintf(filter, sizeof (filter), 3758 "(objectclass=%s)", tt->objclass); 3759 } 3760 3761 if (flags & F_VERBOSE) 3762 (void) fprintf(stdout, gettext("FILTER = %s\n"), filter); 3763 3764 /* Pass cred only if supplied. Cred is not always needed for dump */ 3765 if (authority.cred.unix_cred.userID == NULL || 3766 authority.cred.unix_cred.passwd == NULL) 3767 rc = __ns_ldap_firstEntry(service, filter, NULL, NULL, 3768 NULL, NS_LDAP_HARD, &cookie, &eres, &err, NULL); 3769 else 3770 rc = __ns_ldap_firstEntry(service, filter, NULL, NULL, 3771 &authority, NS_LDAP_HARD, &cookie, &eres, &err, NULL); 3772 3773 switch (rc) { 3774 case NS_LDAP_SUCCESS: 3775 nent_add++; 3776 success = 1; 3777 if (eres != NULL) { 3778 if (strcmp(databasetype, "publickey") == 0) 3779 dump_publickey(eres, service); 3780 else 3781 (*(tt->dump))(eres); 3782 } 3783 else 3784 (void) fprintf(stderr, gettext("No entries found.\n")); 3785 break; 3786 3787 case NS_LDAP_OP_FAILED: 3788 exit_val = 2; 3789 (void) fprintf(stderr, gettext("operation failed.\n")); 3790 break; 3791 3792 case NS_LDAP_INVALID_PARAM: 3793 exit_val = 2; 3794 (void) fprintf(stderr, 3795 gettext("invalid parameter(s) passed.\n")); 3796 break; 3797 3798 case NS_LDAP_NOTFOUND: 3799 exit_val = 2; 3800 (void) fprintf(stderr, gettext("entry not found.\n")); 3801 break; 3802 3803 case NS_LDAP_MEMORY: 3804 exit_val = 2; 3805 (void) fprintf(stderr, 3806 gettext("internal memory allocation error.\n")); 3807 break; 3808 3809 case NS_LDAP_CONFIG: 3810 exit_val = 2; 3811 (void) fprintf(stderr, 3812 gettext("LDAP Configuration problem.\n")); 3813 perr(err); 3814 break; 3815 3816 case NS_LDAP_PARTIAL: 3817 exit_val = 2; 3818 (void) fprintf(stderr, 3819 gettext("partial result returned\n")); 3820 perr(err); 3821 break; 3822 3823 case NS_LDAP_INTERNAL: 3824 exit_val = 2; 3825 (void) fprintf(stderr, 3826 gettext("internal LDAP error occured.\n")); 3827 perr(err); 3828 break; 3829 } 3830 3831 if (eres != NULL) { 3832 (void) __ns_ldap_freeResult(&eres); 3833 eres = NULL; 3834 } 3835 3836 if (success) { 3837 while (!done) { 3838 rc = __ns_ldap_nextEntry(cookie, &eres, &err); 3839 if (rc != NS_LDAP_SUCCESS || eres == NULL) { 3840 done = 1; 3841 continue; 3842 } 3843 3844 /* Print the result */ 3845 if (eres != NULL) { 3846 if (strcmp(databasetype, "publickey") == 0) 3847 dump_publickey(eres, service); 3848 else 3849 (*(tt->dump))(eres); 3850 (void) __ns_ldap_freeResult(&eres); 3851 eres = NULL; 3852 } 3853 } 3854 } 3855 } 3856 3857 int 3858 main(int argc, char **argv) 3859 { 3860 char *password; 3861 int c; 3862 int rc; 3863 int ldaprc; 3864 int authstried = 0; 3865 int supportedauth = 0, gssapi = 0; 3866 int op = OP_ADD; 3867 char *ttype, *authmech = 0, *etcfile = 0; 3868 char ps[LDAP_MAXNAMELEN]; /* Temporary password variable */ 3869 char filter[BUFSIZ]; 3870 void **paramVal = NULL; 3871 ns_auth_t **app; 3872 ns_auth_t **authpp = NULL; 3873 ns_auth_t *authp = NULL; 3874 ns_ldap_error_t *errorp = NULL; 3875 ns_ldap_result_t *resultp; 3876 ns_ldap_entry_t *e; 3877 int flag = 0; 3878 int version1 = 0; 3879 3880 (void) setlocale(LC_ALL, ""); 3881 (void) textdomain(TEXT_DOMAIN); 3882 3883 openlog("ldapaddent", LOG_PID, LOG_USER); 3884 3885 inputbasedn = NULL; 3886 authority.cred.unix_cred.passwd = NULL; 3887 authority.cred.unix_cred.userID = NULL; 3888 authority.auth.type = NS_LDAP_AUTH_SIMPLE; 3889 3890 while ((c = getopt(argc, argv, "cdhvpf:D:w:b:a:")) != EOF) { 3891 switch (c) { 3892 case 'd': 3893 if (op) 3894 usage("no other option should be specified"); 3895 op = OP_DUMP; 3896 break; 3897 case 'c': 3898 continue_onerror = 1; 3899 break; 3900 case 'v': 3901 flags |= F_VERBOSE; 3902 break; 3903 case 'p': 3904 flags |= F_PASSWD; 3905 break; 3906 case 'f': 3907 etcfile = optarg; 3908 break; 3909 case 'D': 3910 authority.cred.unix_cred.userID = strdup(optarg); 3911 break; 3912 case 'w': 3913 authority.cred.unix_cred.passwd = strdup(optarg); 3914 break; 3915 case 'b': 3916 inputbasedn = strdup(optarg); 3917 break; 3918 case 'a': 3919 authmech = strdup(optarg); 3920 break; 3921 3922 default: 3923 usage(gettext("Invalid option")); 3924 } 3925 } 3926 3927 3928 if (authority.cred.unix_cred.userID == NULL && op != OP_DUMP) { 3929 /* This is not an optional parameter. Exit */ 3930 (void) fprintf(stderr, 3931 gettext("Distinguished Name to bind to directory" 3932 " must be specified. use option -D.\n")); 3933 exit(1); 3934 } 3935 3936 if (authority.cred.unix_cred.passwd == NULL && op != OP_DUMP) { 3937 /* If password is not specified, then prompt user for it. */ 3938 password = getpassphrase("Enter password:"); 3939 (void) strcpy(ps, password); 3940 authority.cred.unix_cred.passwd = strdup(ps); 3941 } 3942 3943 if (authmech != NULL) { 3944 if (strcasecmp(authmech, "simple") == 0) { 3945 authority.auth.type = NS_LDAP_AUTH_SIMPLE; 3946 authority.auth.tlstype = NS_LDAP_TLS_NONE; 3947 authority.auth.saslmech = NS_LDAP_SASL_NONE; 3948 authority.auth.saslopt = NS_LDAP_SASLOPT_NONE; 3949 supportedauth = 1; 3950 } 3951 if (strcasecmp(authmech, "sasl/CRAM-MD5") == 0) { 3952 authority.auth.type = NS_LDAP_AUTH_SASL; 3953 authority.auth.tlstype = NS_LDAP_TLS_SASL; 3954 authority.auth.saslmech = NS_LDAP_SASL_CRAM_MD5; 3955 authority.auth.saslopt = NS_LDAP_SASLOPT_NONE; 3956 supportedauth = 1; 3957 } 3958 if (strcasecmp(authmech, "sasl/DIGEST-MD5") == 0) { 3959 authority.auth.type = NS_LDAP_AUTH_SASL; 3960 authority.auth.tlstype = NS_LDAP_TLS_SASL; 3961 authority.auth.saslmech = NS_LDAP_SASL_DIGEST_MD5; 3962 authority.auth.saslopt = NS_LDAP_SASLOPT_NONE; 3963 supportedauth = 1; 3964 } 3965 if (strcasecmp(authmech, "sasl/GSSAPI") == 0) { 3966 authority.auth.type = NS_LDAP_AUTH_SASL; 3967 authority.auth.tlstype = NS_LDAP_TLS_SASL; 3968 authority.auth.saslmech = NS_LDAP_SASL_GSSAPI; 3969 authority.auth.saslopt = NS_LDAP_SASLOPT_PRIV | 3970 NS_LDAP_SASLOPT_INT; 3971 gssapi = 1; 3972 supportedauth = 1; 3973 } 3974 if (strcasecmp(authmech, "tls:simple") == 0) { 3975 authority.auth.type = NS_LDAP_AUTH_TLS; 3976 authority.auth.tlstype = NS_LDAP_TLS_SIMPLE; 3977 authority.auth.saslmech = NS_LDAP_SASL_NONE; 3978 authority.auth.saslopt = NS_LDAP_SASLOPT_NONE; 3979 supportedauth = 1; 3980 } 3981 if (strcasecmp(authmech, "tls:sasl/CRAM-MD5") == 0) { 3982 authority.auth.type = NS_LDAP_AUTH_TLS; 3983 authority.auth.tlstype = NS_LDAP_TLS_SASL; 3984 authority.auth.saslmech = NS_LDAP_SASL_CRAM_MD5; 3985 authority.auth.saslopt = NS_LDAP_SASLOPT_NONE; 3986 supportedauth = 1; 3987 } 3988 if (strcasecmp(authmech, "tls:sasl/DIGEST-MD5") == 0) { 3989 authority.auth.type = NS_LDAP_AUTH_TLS; 3990 authority.auth.tlstype = NS_LDAP_TLS_SASL; 3991 authority.auth.saslmech = NS_LDAP_SASL_DIGEST_MD5; 3992 authority.auth.saslopt = NS_LDAP_SASLOPT_NONE; 3993 supportedauth = 1; 3994 } 3995 if (!supportedauth) { 3996 (void) fprintf(stderr, 3997 gettext("Invalid authentication method specified")); 3998 exit(1); 3999 } 4000 } 4001 4002 if (!gssapi && authority.cred.unix_cred.userID == NULL && 4003 op != OP_DUMP) { 4004 /* This is not an optional parameter. Exit */ 4005 (void) fprintf(stderr, 4006 gettext("Distinguished Name to bind to directory" 4007 " must be specified. use option -D.\n")); 4008 exit(1); 4009 } 4010 4011 if (!gssapi && authority.cred.unix_cred.passwd == NULL && 4012 op != OP_DUMP) { 4013 /* If password is not specified, then prompt user for it. */ 4014 password = getpassphrase("Enter password:"); 4015 (void) strcpy(ps, password); 4016 authority.cred.unix_cred.passwd = strdup(ps); 4017 } 4018 4019 if (authmech == NULL) { 4020 ldaprc = __ns_ldap_getParam(NS_LDAP_AUTH_P, (void ***)&authpp, 4021 &errorp); 4022 if (ldaprc != NS_LDAP_SUCCESS || 4023 (authpp == NULL && op != OP_DUMP)) { 4024 (void) fprintf(stderr, 4025 gettext("No legal authentication method " 4026 "configured.\n")); 4027 (void) fprintf(stderr, 4028 gettext("Provide a legal authentication method " 4029 "using -a option\n")); 4030 exit(1); 4031 } 4032 4033 /* Use the first authentication method which is not none */ 4034 for (app = authpp; *app; app++) { 4035 authp = *app; 4036 if (authp->type != NS_LDAP_AUTH_NONE) { 4037 authstried++; 4038 authority.auth.type = authp->type; 4039 authority.auth.tlstype = authp->tlstype; 4040 authority.auth.saslmech = authp->saslmech; 4041 authority.auth.saslopt = authp->saslopt; 4042 break; 4043 } 4044 } 4045 if (authstried == 0 && op != OP_DUMP) { 4046 (void) fprintf(stderr, 4047 gettext("No legal authentication method configured.\n" 4048 "Provide a legal authentication method using " 4049 "-a option")); 4050 exit(1); 4051 } 4052 if (authority.auth.saslmech == NS_LDAP_SASL_GSSAPI && 4053 authority.cred.unix_cred.passwd != NULL && 4054 authority.cred.unix_cred.userID != NULL) { 4055 /* 4056 * -a is not specified and the auth method sasl/GSSAPI 4057 * is defined in the configuration of the ldap profile. 4058 * Even -D and -w is provided it's not valid usage. 4059 */ 4060 4061 (void) fprintf(stderr, 4062 gettext("The default authentication is sasl/GSSAPI.\n" 4063 "The bind DN and and password is not allowed." 4064 "\n")); 4065 exit(1); 4066 } 4067 } 4068 4069 ttype = argv[optind++]; 4070 4071 if (ttype == NULL) { 4072 usage(gettext("No database type specified")); 4073 exit(1); 4074 } 4075 4076 if (strncasecmp(ttype, "automount", 9) == 0) { 4077 (void) fprintf(stderr, 4078 gettext("automount is not a valid service for ldapaddent.\n" 4079 "Please use auto_*.\n" 4080 "e.g. auto_home, auto_ws etc.\n ")); 4081 exit(1); 4082 } 4083 4084 for (tt = ttypelist; tt->ttype; tt++) { 4085 if (strcmp(tt->ttype, ttype) == 0) 4086 break; 4087 if (strcmp(tt->ttype, NS_LDAP_TYPE_AUTOMOUNT) == 0 && 4088 strncmp(ttype, NS_LDAP_TYPE_AUTOMOUNT, 4089 sizeof (NS_LDAP_TYPE_AUTOMOUNT) - 1) == 0) 4090 break; 4091 } 4092 4093 if (tt->ttype == 0) { 4094 (void) fprintf(stderr, 4095 gettext("database %s not supported;" 4096 " supported databases are:\n"), ttype); 4097 for (tt = ttypelist; tt->ttype; tt++) 4098 (void) fprintf(stderr, gettext("\t%s\n"), tt->ttype); 4099 exit(1); 4100 } 4101 4102 if (flags & F_VERBOSE) 4103 (void) fprintf(stdout, gettext("SERVICE = %s\n"), tt->ttype); 4104 4105 databasetype = ttype; 4106 4107 if (strcmp(tt->ttype, NS_LDAP_TYPE_AUTOMOUNT) == 0) { 4108 paramVal = NULL; 4109 errorp = NULL; 4110 rc = __ns_ldap_getParam(NS_LDAP_FILE_VERSION_P, ¶mVal, 4111 &errorp); 4112 if (paramVal && *paramVal && 4113 strcasecmp(*paramVal, NS_LDAP_VERSION_1) == 0) 4114 version1 = 1; 4115 if (paramVal) 4116 (void) __ns_ldap_freeParam(¶mVal); 4117 if (errorp) 4118 (void) __ns_ldap_freeError(&errorp); 4119 } 4120 4121 /* Check if the container exists in first place */ 4122 (void) strcpy(&filter[0], "(objectclass=*)"); 4123 4124 rc = __ns_ldap_list(databasetype, filter, NULL, (const char **)NULL, 4125 NULL, NS_LDAP_SCOPE_BASE, &resultp, &errorp, NULL, NULL); 4126 4127 /* create a container for auto_* if it does not exist already */ 4128 if ((rc == NS_LDAP_NOTFOUND) && (op == OP_ADD) && 4129 (strcmp(tt->ttype, NS_LDAP_TYPE_AUTOMOUNT) == 0)) { 4130 static char *oclist[] = {NULL, "top", NULL}; 4131 if (version1) 4132 oclist[0] = "nisMap"; 4133 else 4134 oclist[0] = "automountMap"; 4135 e = __s_mk_entry(oclist, 3); 4136 if (e == NULL) { 4137 (void) fprintf(stderr, 4138 gettext("internal memory allocation error.\n")); 4139 exit(1); 4140 } 4141 if (__s_add_attr(e, 4142 version1 ? "nisMapName" : "automountMapName", 4143 databasetype) != NS_LDAP_SUCCESS) { 4144 (void) fprintf(stderr, 4145 gettext("internal memory allocation error.\n")); 4146 ldap_freeEntry(e); 4147 exit(1); 4148 } 4149 4150 if (inputbasedn == NULL) { 4151 if (get_basedn(databasetype, &inputbasedn) != 4152 NS_LDAP_SUCCESS) { 4153 (void) fprintf(stderr, 4154 gettext("Could not obtain basedn\n")); 4155 ldap_freeEntry(e); 4156 exit(1); 4157 } 4158 } 4159 if (__ns_ldap_addEntry(databasetype, inputbasedn, e, 4160 &authority, flag, &errorp) != NS_LDAP_SUCCESS) { 4161 (void) fprintf(stderr, 4162 gettext("Could not create container for %s\n"), 4163 databasetype); 4164 ldap_freeEntry(e); 4165 } 4166 } else if (strcmp(databasetype, "publickey") != 0) { 4167 if (rc == NS_LDAP_NOTFOUND) { 4168 (void) fprintf(stderr, 4169 gettext("Container %s does not exist\n"), 4170 databasetype); 4171 exit(1); 4172 } 4173 } 4174 4175 if (op == OP_DUMP) { 4176 if (strcmp(databasetype, "publickey") == 0) { 4177 dumptable("hosts"); 4178 dumptable("passwd"); 4179 } else { 4180 dumptable(databasetype); 4181 } 4182 exit(exit_val); 4183 } 4184 4185 if (etcfile) { 4186 if ((etcf = fopen(etcfile, "r")) == 0) { 4187 (void) fprintf(stderr, 4188 gettext("can't open file %s\n"), etcfile); 4189 exit(1); 4190 } 4191 } else { 4192 etcfile = "stdin"; 4193 etcf = stdin; 4194 } 4195 4196 if (op == OP_ADD) { 4197 (void) addfile(); 4198 (void) fprintf(stdout, gettext("%d entries added\n"), nent_add); 4199 } 4200 4201 /* exit() -> return for make lint */ 4202 return (exit_val); 4203 } 4204 4205 4206 /* 4207 * This is called when service == auto_*. 4208 * It calls __ns_ldap_getSearchDescriptors 4209 * to generate the dn from SSD's base dn. 4210 * If there is no SSD available, 4211 * default base dn will be used 4212 * Only the first baseDN in the SSD is used 4213 */ 4214 4215 static int get_basedn(char *service, char **basedn) { 4216 int rc = NS_LDAP_SUCCESS; 4217 char *dn = NULL; 4218 ns_ldap_search_desc_t **desc = NULL; 4219 ns_ldap_error_t *errp = NULL; 4220 void **paramVal = NULL; 4221 int prepend_automountmapname = FALSE; 4222 4223 /* 4224 * Get auto_* SSD first 4225 */ 4226 4227 if ((rc = __ns_ldap_getSearchDescriptors( 4228 (const char *) service, 4229 &desc, &errp)) == NS_LDAP_SUCCESS && 4230 desc != NULL) { 4231 4232 if (desc[0] != NULL && desc[0]->basedn != NULL) { 4233 dn = strdup(desc[0]->basedn); 4234 if (dn == NULL) { 4235 (void) __ns_ldap_freeSearchDescriptors 4236 (&desc); 4237 return (NS_LDAP_MEMORY); 4238 } 4239 } 4240 } 4241 4242 /* clean up */ 4243 if (desc) (void) __ns_ldap_freeSearchDescriptors(&desc); 4244 if (errp) (void) __ns_ldap_freeError(&errp); 4245 4246 /* 4247 * If no dn is duplicated from auto_* SSD, try automount SSD 4248 */ 4249 if (dn == NULL) { 4250 if ((rc = __ns_ldap_getSearchDescriptors( 4251 "automount", &desc, &errp)) 4252 == NS_LDAP_SUCCESS && desc != NULL) { 4253 4254 if (desc[0] != NULL && desc[0]->basedn != NULL) { 4255 dn = strdup(desc[0]->basedn); 4256 if (dn == NULL) { 4257 (void) __ns_ldap_freeSearchDescriptors 4258 (&desc); 4259 return (NS_LDAP_MEMORY); 4260 } 4261 prepend_automountmapname = TRUE; 4262 } 4263 } 4264 /* clean up */ 4265 if (desc) (void) __ns_ldap_freeSearchDescriptors(&desc); 4266 if (errp) (void) __ns_ldap_freeError(&errp); 4267 } 4268 4269 /* 4270 * If no dn is duplicated from auto_* or automount SSD, 4271 * use default DN 4272 */ 4273 4274 if (dn == NULL) { 4275 if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_BASEDN_P, 4276 ¶mVal, &errp)) == NS_LDAP_SUCCESS) { 4277 dn = strdup((char *)paramVal[0]); 4278 if (dn == NULL) { 4279 (void) __ns_ldap_freeParam(¶mVal); 4280 return (NS_LDAP_MEMORY); 4281 } 4282 prepend_automountmapname = TRUE; 4283 } 4284 if (paramVal) (void) __ns_ldap_freeParam(¶mVal); 4285 if (errp) (void) __ns_ldap_freeError(&errp); 4286 } 4287 4288 4289 if (dn == NULL) { 4290 return (NS_LDAP_OP_FAILED); 4291 } else { 4292 /* 4293 * If dn is duplicated from 4294 * automount SSD basedn or 4295 * default base dn 4296 * then prepend automountMapName=auto_xxx 4297 */ 4298 if (prepend_automountmapname) 4299 rc = __s_api_prepend_automountmapname_to_dn( 4300 service, &dn, &errp); 4301 4302 if (rc != NS_LDAP_SUCCESS) { 4303 (void) __ns_ldap_freeError(&errp); 4304 free(dn); 4305 return (rc); 4306 } 4307 4308 *basedn = dn; 4309 4310 return (NS_LDAP_SUCCESS); 4311 } 4312 } 4313 static char * 4314 h_errno2str(int h_errno) { 4315 switch (h_errno) { 4316 case HOST_NOT_FOUND: 4317 return ("HOST_NOT_FOUND"); 4318 break; 4319 case TRY_AGAIN: 4320 return ("TRY_AGAIN"); 4321 break; 4322 case NO_RECOVERY: 4323 return ("NO_RECOVERY"); 4324 break; 4325 case NO_DATA: 4326 return ("NO_DATA"); 4327 break; 4328 default: 4329 break; 4330 } 4331 return ("UNKNOWN_ERROR"); 4332 } 4333