dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / ldap / ns_ldap / ldapaddent.c
blobf8de59277af88f19316b2139dde25a0408e9a978
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2012 Milan Jurik. All rights reserved.
27 * ldapaddent.c
29 * Utility to add /etc files into LDAP.
30 * Can also be used to dump entries from a ldap container in /etc format.
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <libintl.h>
36 #include <strings.h>
37 #include <sys/param.h>
38 #include <ctype.h>
39 #include <sys/types.h>
40 #include <sys/socket.h>
41 #include <netinet/in.h>
42 #include <arpa/inet.h>
43 #include <locale.h>
44 #include <syslog.h>
46 #undef opaque
48 #include <nss_dbdefs.h>
49 #include <netdb.h>
50 #include <rpc/rpcent.h>
51 #include <grp.h>
52 #include <pwd.h>
53 #include <project.h>
54 #include <shadow.h>
55 #include <sys/systeminfo.h>
56 #include "ns_internal.h"
57 #include "ldapaddent.h"
58 #include "standalone.h"
60 #define OP_ADD 0
61 #define OP_DUMP 3
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 char *sortattr; /* Sort attr for enumeration */
72 } *tt;
74 char parse_err_msg [PARSE_ERR_MSG_LEN];
75 int continue_onerror = 0; /* do not exit on error */
77 static int get_basedn(char *service, char **basedn);
78 static int check_ipaddr(char *addr, char **newaddr);
79 static int check_projname(char *addr);
81 extern int optind;
82 extern char *optarg;
84 extern char *__nis_quote_key(const char *, char *, int);
86 static char *inputbasedn = NULL;
87 static char *databasetype = NULL;
88 static int exit_val = 0;
89 static unsigned nent_add = 0;
90 static FILE *etcf = 0;
91 static ns_cred_t authority;
92 unsigned flags = 0;
94 static void
95 perr(ns_ldap_error_t *e)
97 if (e)
98 (void) fprintf(stderr, "%d: %s\n",
99 e->status, e->message);
103 static int
104 ascii_to_int(char *str)
106 int i;
107 char *c = str;
109 if (c == NULL || *c == '\0')
110 return (-1);
112 while (c != '\0' && *c == ' ')
113 c++;
114 if (*c == '\0')
115 return (-1);
117 for (i = 0; i < strlen(c); i++)
118 if (!isdigit(c[i]))
119 return (-1);
121 return (atoi(c));
125 * Internet network address interpretation routine.
126 * The library routines call this routine to interpret
127 * network numbers.
129 static in_addr_t
130 encode_network(const char *cp)
132 in_addr_t val;
133 int base;
134 ptrdiff_t n;
135 char c;
136 in_addr_t parts[4], *pp = parts;
137 int i;
139 again:
140 val = 0; base = 10;
141 if (*cp == '0') {
142 if (*++cp == 'x' || *cp == 'X')
143 base = 16, cp++;
144 else
145 base = 8;
147 while ((c = *cp) != '\0') {
148 if (isdigit(c)) {
149 if ((c - '0') >= base)
150 break;
151 val = (val * base) + (c - '0');
152 cp++;
153 continue;
155 if (base == 16 && isxdigit(c)) {
156 val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
157 cp++;
158 continue;
160 break;
162 if (*cp == '.') {
163 if (pp >= parts + 4)
164 return ((in_addr_t)-1);
165 *pp++ = val, cp++;
166 goto again;
168 if (*cp && !isspace(*cp))
169 return ((in_addr_t)-1);
170 *pp++ = val;
171 n = pp - parts;
172 if (n > 4)
173 return ((in_addr_t)-1);
174 for (val = 0, i = 0; i < n; i++) {
175 val <<= 8;
176 val |= parts[i] & 0xff;
178 for (/* no init */; i < 4; i++)
179 val <<= 8;
180 return (val);
183 static void
184 replace_tab2space(char *str)
186 int i = 0;
188 while ((str) && (str[i])) {
189 if (str[i] == '\t')
190 str[i] = ' ';
191 i++;
195 static int
196 blankline(char *line)
198 char *p;
200 for (p = line; *p; p++)
201 if (*p != ' ' && *p != '\t')
202 return (0);
203 return (1);
207 * check whether the token <tok> is a triplet,
208 * i. e. <tok> := (<hostname>,<username>,<domainname>)
209 * where <hostname>, <username>, <domainname> are IA5String
210 * <tok> supposes to contain NO spaces and start with '('
212 static int
213 is_triplet(char *tok)
215 char *s;
216 return (strchr(++tok, '(') == NULL && /* no more '(' */
217 (s = strchr(tok, ')')) != NULL && /* find ')' */
218 !*++s && /* ')' ends token */
219 (tok = strchr(tok, ',')) != NULL && /* host up to ',' */
220 (tok = strchr(++tok, ',')) != NULL && /* user up to ',' */
221 strchr(++tok, ',') == NULL); /* no more ',' */
224 static void
225 line_buf_expand(struct line_buf *line)
227 line->alloc += BUFSIZ;
228 line->str = (char *)realloc(line->str, line->alloc);
230 if (line->str == NULL) {
231 (void) fprintf(stderr,
232 gettext("line_buf_expand: out of memory\n"));
233 exit(1);
237 static void
238 line_buf_init(struct line_buf *line)
240 (void) memset((char *)line, 0, sizeof (*line));
241 line_buf_expand(line);
244 static int
245 __s_add_attr(ns_ldap_entry_t *e, char *attrname, char *value)
247 ns_ldap_attr_t *a;
248 char *v;
250 a = (ns_ldap_attr_t *)calloc(1, sizeof (ns_ldap_attr_t));
251 if (a == NULL)
252 return (NS_LDAP_MEMORY);
253 a->attrname = strdup(attrname);
254 if (a->attrname == NULL) {
255 free(a);
256 return (NS_LDAP_MEMORY);
258 a->attrvalue = (char **)calloc(1, sizeof (char **));
259 if (a->attrvalue == NULL) {
260 free(a->attrname);
261 free(a);
262 return (NS_LDAP_MEMORY);
264 a->value_count = 1;
265 a->attrvalue[0] = NULL;
266 v = strdup(value);
267 if (v == NULL) {
268 free(a->attrname);
269 free(a->attrvalue);
270 free(a);
271 return (NS_LDAP_MEMORY);
273 a->attrvalue[0] = v;
274 e->attr_pair[e->attr_count] = a;
275 e->attr_count++;
276 return (NS_LDAP_SUCCESS);
279 static int
280 __s_add_attrlist(ns_ldap_entry_t *e, char *attrname, char **argv)
282 ns_ldap_attr_t *a;
283 char *v;
284 char **av;
285 int i, j;
287 a = (ns_ldap_attr_t *)calloc(1, sizeof (ns_ldap_attr_t));
288 if (a == NULL)
289 return (NS_LDAP_MEMORY);
290 a->attrname = strdup(attrname);
291 if (a->attrname == NULL) {
292 free(a);
293 return (NS_LDAP_MEMORY);
296 for (i = 0, av = argv; *av != NULL; av++, i++)
299 a->attrvalue = (char **)calloc(i, sizeof (char **));
301 if (a->attrvalue == NULL) {
302 free(a->attrname);
303 free(a);
304 return (NS_LDAP_MEMORY);
306 a->value_count = i;
307 for (j = 0; j < i; j++) {
308 v = strdup(argv[j]);
309 if (v == NULL) {
310 free(a->attrname);
311 free(a->attrvalue);
312 free(a);
313 return (NS_LDAP_MEMORY);
315 a->attrvalue[j] = v;
317 e->attr_pair[e->attr_count] = a;
318 e->attr_count++;
319 return (NS_LDAP_SUCCESS);
322 static ns_ldap_entry_t *
323 __s_mk_entry(char **objclass, int max_attr)
325 ns_ldap_entry_t *e;
326 e = (ns_ldap_entry_t *)calloc(1, sizeof (ns_ldap_entry_t));
327 if (e == NULL)
328 return (NULL);
329 e->attr_pair = (ns_ldap_attr_t **)calloc(max_attr+1,
330 sizeof (ns_ldap_attr_t *));
331 if (e->attr_pair == NULL) {
332 free(e);
333 return (NULL);
335 e->attr_count = 0;
336 if (__s_add_attrlist(e, "objectClass", objclass) != NS_LDAP_SUCCESS) {
337 free(e->attr_pair);
338 free(e);
339 return (NULL);
341 return (e);
344 static void
345 ldap_freeEntry(ns_ldap_entry_t *ep)
347 int j, k = 0;
349 if (ep == NULL)
350 return;
352 if (ep->attr_pair == NULL) {
353 free(ep);
354 return;
356 for (j = 0; j < ep->attr_count; j++) {
357 if (ep->attr_pair[j] == NULL)
358 continue;
359 free(ep->attr_pair[j]->attrname);
360 if (ep->attr_pair[j]->attrvalue) {
361 for (k = 0; (k < ep->attr_pair[j]->value_count) &&
362 (ep->attr_pair[j]->attrvalue[k]); k++) {
363 free(ep->attr_pair[j]->attrvalue[k]);
365 free(ep->attr_pair[j]->attrvalue);
367 free(ep->attr_pair[j]);
369 free(ep->attr_pair);
370 free(ep);
373 static int
374 addentry(void *entry, int mod)
376 int result = 0;
377 ns_ldap_error_t *eres = NULL;
378 int rc = 1;
381 /* adds entry into the LDAP tree */
382 if (mod)
383 result = __ns_ldap_addTypedEntry(databasetype, inputbasedn,
384 entry, 0, &authority, NS_LDAP_FOLLOWREF | NS_LDAP_KEEP_CONN,
385 &eres);
386 else
387 result = __ns_ldap_addTypedEntry(databasetype, inputbasedn,
388 entry, 1, &authority, NS_LDAP_FOLLOWREF | NS_LDAP_KEEP_CONN,
389 &eres);
391 * Return 0 on success
392 * LDAP_ALREADY_EXISTS if entry exists already
393 * 1 for all other non-fatal errors.
394 * Exit on fatal errors.
396 switch (result) {
397 case NS_LDAP_SUCCESS:
398 nent_add++;
399 rc = 0;
400 break;
402 case NS_LDAP_OP_FAILED:
403 (void) fprintf(stderr, gettext("operation failed.\n"));
404 rc = 1;
405 break;
407 case NS_LDAP_INVALID_PARAM:
408 (void) fprintf(stderr,
409 gettext("invalid parameter(s) passed.\n"));
410 rc = 1;
411 break;
413 case NS_LDAP_NOTFOUND:
414 (void) fprintf(stderr, gettext("entry not found.\n"));
415 rc = 1;
416 break;
418 case NS_LDAP_MEMORY:
419 (void) fprintf(stderr,
420 gettext("internal memory allocation error.\n"));
421 exit(1);
422 break;
424 case NS_LDAP_CONFIG:
425 (void) fprintf(stderr,
426 gettext("LDAP Configuration problem.\n"));
427 perr(eres);
428 exit(1);
429 break;
431 case NS_LDAP_PARTIAL:
432 (void) fprintf(stderr,
433 gettext("partial result returned\n"));
434 perr(eres);
435 rc = 1;
436 break;
438 case NS_LDAP_INTERNAL:
439 if (eres->status == LDAP_ALREADY_EXISTS ||
440 eres->status == LDAP_NO_SUCH_OBJECT)
441 rc = eres->status;
442 else if (eres->status == LDAP_INSUFFICIENT_ACCESS) {
443 (void) fprintf(stderr,
444 gettext("The user does not have permission"
445 " to add/modify entries\n"));
446 perr(eres);
447 exit(1);
448 } else {
449 rc = 1;
450 perr(eres);
452 break;
455 if (eres)
456 (void) __ns_ldap_freeError(&eres);
457 return (rc);
461 * usage(char *msg)
462 * Display usage message to STDERR.
464 static void
465 usage(char *msg) {
467 if (msg)
468 (void) fprintf(stderr, "%s\n", msg);
470 (void) fprintf(stderr, gettext(
471 "usage: ldapaddent [-cpv] [-a authenticationMethod] [-b baseDN]\n"
472 "-D bindDN [-w bindPassword] [-j passwdFile] [-f filename]\n"
473 "database\n"
474 "\n"
475 "usage: ldapaddent [-cpv] -asasl/GSSAPI [-b baseDN] [-f filename]\n"
476 "database\n"
477 "\n"
478 "usage: ldapaddent -d [-v] [-a authenticationMethod] [-D bindDN]\n"
479 "[-w bindPassword] [-j passwdFile] database\n"
480 "\n"
481 "usage: ldapaddent [-cpv] -h LDAP_server[:serverPort] [-M domainName]\n"
482 "[-N profileName] [-P certifPath] [-a authenticationMethod]\n"
483 "[-b baseDN] -D bindDN [-w bindPassword] [-f filename]\n"
484 "[-j passwdFile] database\n"
485 "\n"
486 "usage: ldapaddent [-cpv] -h LDAP_server[:serverPort] [-M domainName]\n"
487 "[-N profileName] [-P certifPath] -asasl/GSSAPI [-b baseDN]\n"
488 "[-f filename] database\n"
489 "\n"
490 "usage: ldapaddent -d [-v] -h LDAP_server[:serverPort]"
491 " [-M domainName]\n"
492 "[-N profileName] [-P certifPath] [-a authenticationMethod]\n"
493 "[-b baseDN] -D bindDN [-w bindPassword] [-j passwdFile]\n"
494 "database\n"));
495 exit(1);
499 * Determine if the given string is an IP address (IPv4 or IPv6).
500 * If so, it's converted to the preferred form (rfc2373) and
501 * *newaddr will point to the new address.
503 * Returns -2 : inet_ntop error
504 * -1 : not an IP address
505 * 0 : unsupported IP address (future use)
506 * AF_INET : IPv4
507 * AF_INET6 : IPv6
509 static int
510 check_ipaddr(char *addr, char **newaddr) {
511 ipaddr_t addr_ipv4 = 0;
512 in6_addr_t addr_ipv6;
514 /* IPv6 */
515 if (inet_pton(AF_INET6, addr, &addr_ipv6) == 1) {
516 if (newaddr == NULL)
517 return (AF_INET6);
519 /* Convert IPv4-mapped IPv6 address to IPv4 */
520 if (IN6_IS_ADDR_V4MAPPED(&addr_ipv6) ||
521 IN6_IS_ADDR_V4COMPAT(&addr_ipv6)) {
522 IN6_V4MAPPED_TO_IPADDR(&addr_ipv6, addr_ipv4);
523 if ((*newaddr = calloc(1, INET_ADDRSTRLEN)) == NULL) {
524 (void) fprintf(stderr,
525 gettext("out of memory\n"));
526 exit(1);
528 if (inet_ntop(AF_INET, &addr_ipv4, *newaddr,
529 INET_ADDRSTRLEN))
530 return (AF_INET6);
531 free(*newaddr);
532 return (-2);
535 /* Processing general IPv6 addresses */
536 if ((*newaddr = calloc(1, INET6_ADDRSTRLEN)) == NULL) {
537 (void) fprintf(stderr, gettext("out of memory\n"));
538 exit(1);
540 if (inet_ntop(AF_INET6, &addr_ipv6, *newaddr, INET6_ADDRSTRLEN))
541 return (AF_INET6);
542 free(*newaddr);
543 return (-2);
546 /* Processing IPv4 addresses of the type d.d.d.d. */
547 if (inet_pton(AF_INET, addr, &addr_ipv4) == 1) {
548 if (newaddr == NULL)
549 return (AF_INET);
550 if ((*newaddr = calloc(1, INET_ADDRSTRLEN)) == NULL) {
551 (void) fprintf(stderr, gettext("out of memory\n"));
552 exit(1);
554 if (inet_ntop(AF_INET, &addr_ipv4, *newaddr, INET_ADDRSTRLEN))
555 return (AF_INET);
556 free(*newaddr);
557 return (-2);
560 /* Processing IPv4 addresses d.d.d , d.d and d */
561 if (inet_addr(addr) != (in_addr_t)-1) {
562 if (newaddr == NULL)
563 return (AF_INET);
564 if ((*newaddr = strdup(addr)) == NULL) {
565 (void) fprintf(stderr, gettext("out of memory\n"));
566 exit(1);
568 return (AF_INET);
571 return (-1);
575 * Verifies that project name meets the restrictions defined by project(4).
577 static int
578 check_projname(char *addr)
580 int i;
581 if (addr == NULL || *addr == '\0')
582 return (-1);
584 for (i = 0; i < strlen(addr); i++) {
585 if (!isalpha(addr[i]) &&
586 !isdigit(addr[i]) &&
587 addr[i] != '_' &&
588 addr[i] != '-' &&
589 addr[i] != '.')
590 return (-1);
593 return (0);
596 static int
597 genent_hosts(char *line, int (*cback)())
599 char buf[BUFSIZ+1];
600 char *t, *comment;
601 entry_col ecol[4];
602 char *cname, *pref_addr;
603 int ctr = 0, retval = 1;
604 int rc = GENENT_OK, af;
606 struct hostent data;
607 char *alias;
610 * don't clobber our argument
612 if (strlen(line) >= sizeof (buf)) {
613 (void) strlcpy(parse_err_msg, gettext("line too long"),
614 PARSE_ERR_MSG_LEN);
615 return (GENENT_PARSEERR);
617 (void) strcpy(buf, line);
620 * clear column data
622 (void) memset((char *)ecol, 0, sizeof (ecol));
625 * comment (col 3)
626 * All leading spaces will be deleted from the comment
628 ecol[3].ec_value.ec_value_val = "";
629 ecol[3].ec_value.ec_value_len = 0;
630 comment = t = strchr(buf, '#');
631 if (comment) {
632 do {
633 ++comment;
634 } while (*comment != '\0' && isspace(*comment));
635 if (*comment != '\0') {
636 *--comment = '#';
637 ecol[3].ec_value.ec_value_val = strdup(comment);
638 ecol[3].ec_value.ec_value_len = strlen(comment)+1;
641 *t = '\0';
645 * addr(col 2)
647 if ((t = strtok(buf, " \t")) == 0) {
648 (void) strlcpy(parse_err_msg, gettext("no host"),
649 PARSE_ERR_MSG_LEN);
650 return (GENENT_PARSEERR);
653 af = check_ipaddr(t, &pref_addr);
654 if (af == -2) {
655 (void) strlcpy(parse_err_msg, gettext("Internal error"),
656 PARSE_ERR_MSG_LEN);
657 } else if (af == -1) {
658 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
659 gettext("Invalid IP address: %s"), t);
660 } else if (flags & F_VERBOSE) {
661 if ((strncasecmp(t, pref_addr, strlen(t))) != 0) {
662 (void) fprintf(stdout,
663 gettext("IP address %s converted to %s\n"),
664 t, pref_addr);
668 if (af < 0) {
669 (void) fprintf(stderr, "%s\n", parse_err_msg);
670 if (continue_onerror == 0)
671 return (GENENT_CBERR);
672 else
673 return (rc);
676 ecol[2].ec_value.ec_value_val = pref_addr;
677 ecol[2].ec_value.ec_value_len = strlen(pref_addr)+1;
680 * cname (col 0)
682 if ((t = strtok(NULL, " \t")) == 0) {
683 (void) strlcpy(parse_err_msg, gettext("no cname"),
684 PARSE_ERR_MSG_LEN);
685 return (GENENT_PARSEERR);
687 ecol[0].ec_value.ec_value_val = t;
688 ecol[0].ec_value.ec_value_len = strlen(t)+1;
689 cname = t;
692 /* build entry */
693 if ((data.h_addr_list = (char **)calloc(2, sizeof (char **))) == NULL) {
694 (void) fprintf(stderr, gettext("out of memory\n"));
695 exit(1);
697 data.h_addr_list[0] = strdup(ecol[2].ec_value.ec_value_val);
698 data.h_addr_list[1] = NULL;
700 free(pref_addr);
701 data.h_name = strdup(ecol[0].ec_value.ec_value_val);
704 * name (col 1)
707 data.h_aliases = NULL;
709 do {
711 * don't clobber comment in canonical entry
714 /* This call to AddEntry may move out of the loop */
715 /* This is because we have to call the function just once */
716 if (t != cname && strcasecmp(t, cname) == 0)
717 continue;
718 if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
719 continue;
721 ecol[1].ec_value.ec_value_val = t;
722 ecol[1].ec_value.ec_value_len = strlen(t)+1;
724 ctr++;
725 alias = strdup(ecol[1].ec_value.ec_value_val);
726 if ((data.h_aliases = reallocarray(data.h_aliases, ctr,
727 sizeof (char **))) == NULL) {
728 (void) fprintf(stderr, gettext("out of memory\n"));
729 exit(1);
731 data.h_aliases[ctr-1] = alias;
732 } while (t = strtok(NULL, " \t"));
735 * End the list of all the aliases by NULL
736 * If there is some comment, it will be stored as the last entry
737 * in the list of the host aliases
739 if ((data.h_aliases = reallocarray(data.h_aliases,
740 ecol[3].ec_value.ec_value_len != 0 ? ctr + 2 : ctr + 1,
741 sizeof (char **))) == NULL) {
742 (void) fprintf(stderr, gettext("out of memory\n"));
743 exit(1);
746 if (ecol[3].ec_value.ec_value_len != 0) {
747 data.h_aliases[ctr++] = ecol[3].ec_value.ec_value_val;
749 data.h_aliases[ctr] = NULL;
751 if (flags & F_VERBOSE)
752 (void) fprintf(stdout,
753 gettext("Adding entry : cn=%s+ipHostNumber=%s\n"),
754 data.h_name, data.h_addr_list[0]);
756 retval = (*cback)(&data, 0);
758 if (ecol[3].ec_value.ec_value_len != 0) {
759 free(ecol[3].ec_value.ec_value_val);
762 if (retval == LDAP_ALREADY_EXISTS) {
763 if (continue_onerror)
764 (void) fprintf(stderr,
765 gettext("Entry: cn=%s+ipHostNumber=%s "
766 "already Exists -skipping it\n"),
767 data.h_name, data.h_addr_list[0]);
768 else {
769 rc = GENENT_CBERR;
770 (void) fprintf(stderr,
771 gettext("Entry: cn=%s+ipHostNumber=%s"
772 " already Exists\n"),
773 data.h_name, data.h_addr_list[0]);
775 } else if (retval)
776 rc = GENENT_CBERR;
778 free(data.h_name);
779 free(data.h_aliases);
780 free(data.h_addr_list);
782 return (rc);
787 static void
788 dump_hosts(ns_ldap_result_t *res)
790 ns_ldap_attr_t *attrptr = NULL,
791 *cn = NULL,
792 *iphostnumber = NULL,
793 *desc = NULL;
794 int i, j;
795 char *name; /* host name */
797 if (res == NULL || res->entry == NULL)
798 return;
799 for (i = 0; i < res->entry->attr_count; i++) {
800 attrptr = res->entry->attr_pair[i];
801 if (strcasecmp(attrptr->attrname, "cn") == 0)
802 cn = attrptr;
803 else if (strcasecmp(attrptr->attrname, "iphostnumber") == 0)
804 iphostnumber = attrptr;
805 else if (strcasecmp(attrptr->attrname, "description") == 0) {
806 desc = attrptr;
809 /* sanity check */
810 if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL ||
811 iphostnumber == NULL || iphostnumber->attrvalue == NULL ||
812 iphostnumber->attrvalue[0] == NULL)
813 return;
815 if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL)
816 return;
818 /* ip host/ipnode number */
819 if (strlen(iphostnumber->attrvalue[0]) <= INET_ADDRSTRLEN)
820 /* IPV4 or IPV6 but <= NET_ADDRSTRLEN */
821 (void) fprintf(stdout, "%-18s", iphostnumber->attrvalue[0]);
822 else
823 /* IPV6 */
824 (void) fprintf(stdout, "%-48s", iphostnumber->attrvalue[0]);
826 /* host/ipnode name */
827 (void) fprintf(stdout, "%s ", name);
829 /* aliases */
830 for (j = 0; j < cn->value_count; j++) {
831 if (cn->attrvalue[j]) {
832 if (strcasecmp(name, cn->attrvalue[j]) == 0)
833 /* skip host name */
834 continue;
835 (void) fprintf(stdout, "%s ", cn->attrvalue[j]);
839 /* description */
840 if (desc != NULL && desc->attrvalue != NULL &&
841 desc->attrvalue[0] != NULL) {
842 (void) fprintf(stdout, "#%s", desc->attrvalue[0]);
845 /* end of line */
846 (void) fprintf(stdout, "\n");
850 * /etc/rpc
853 static int
854 genent_rpc(char *line, int (*cback)())
856 char buf[BUFSIZ+1];
857 char *t;
858 entry_col ecol[4];
859 char *cname;
861 struct rpcent data;
862 char *alias;
863 int ctr = 0;
864 int retval = 1;
865 int rc = GENENT_OK;
868 * don't clobber our argument
870 if (strlen(line) >= sizeof (buf)) {
871 (void) strlcpy(parse_err_msg, gettext("line too long"),
872 PARSE_ERR_MSG_LEN);
873 return (GENENT_PARSEERR);
875 (void) strcpy(buf, line);
878 * clear column data
880 (void) memset((char *)ecol, 0, sizeof (ecol));
883 * comment (col 3)
885 t = strchr(buf, '#');
886 if (t) {
887 *t++ = 0;
888 ecol[3].ec_value.ec_value_val = t;
889 ecol[3].ec_value.ec_value_len = strlen(t)+1;
890 } else {
891 ecol[3].ec_value.ec_value_val = 0;
892 ecol[3].ec_value.ec_value_len = 0;
896 * cname(col 0)
898 if ((t = strtok(buf, " \t")) == 0) {
899 (void) strlcpy(parse_err_msg, gettext("no number"),
900 PARSE_ERR_MSG_LEN);
901 return (GENENT_PARSEERR);
903 ecol[0].ec_value.ec_value_val = t;
904 ecol[0].ec_value.ec_value_len = strlen(t)+1;
905 cname = t;
908 * number (col 2)
910 if ((t = strtok(NULL, " \t")) == 0) {
911 (void) strlcpy(parse_err_msg, gettext("no number"),
912 PARSE_ERR_MSG_LEN);
913 return (GENENT_PARSEERR);
915 ecol[2].ec_value.ec_value_val = t;
916 ecol[2].ec_value.ec_value_len = strlen(t)+1;
920 * build entry
923 data.r_name = strdup(ecol[0].ec_value.ec_value_val);
924 if (ecol[2].ec_value.ec_value_val != NULL &&
925 ecol[2].ec_value.ec_value_val[0] != '\0') {
927 data.r_number = ascii_to_int(ecol[2].ec_value.ec_value_val);
928 if (data.r_number == -1) {
929 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
930 gettext("invalid program number: %s"),
931 ecol[2].ec_value.ec_value_val);
932 return (GENENT_PARSEERR);
934 } else
935 data.r_number = -1;
938 * name (col 1)
940 t = cname;
941 data.r_aliases = NULL;
942 do {
945 * don't clobber comment in canonical entry
947 if (t != cname && strcasecmp(t, cname) == 0)
948 continue;
949 if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
950 continue;
952 ecol[1].ec_value.ec_value_val = t;
953 ecol[1].ec_value.ec_value_len = strlen(t)+1;
955 ctr++;
956 alias = strdup(ecol[1].ec_value.ec_value_val);
957 if ((data.r_aliases = reallocarray(data.r_aliases, ctr,
958 sizeof (char **))) == NULL) {
959 (void) fprintf(stderr, gettext("out of memory\n"));
960 exit(1);
962 data.r_aliases[ctr-1] = alias;
966 * only put comment in canonical entry
968 ecol[3].ec_value.ec_value_val = 0;
969 ecol[3].ec_value.ec_value_len = 0;
971 } while (t = strtok(NULL, " \t"));
973 /* End the list of all the aliases by NULL */
974 if ((data.r_aliases = reallocarray(data.r_aliases, ctr + 1,
975 sizeof (char **))) == NULL) {
976 (void) fprintf(stderr, gettext("out of memory\n"));
977 exit(1);
979 data.r_aliases[ctr] = NULL;
981 if (flags & F_VERBOSE)
982 (void) fprintf(stdout,
983 gettext("Adding entry : %s\n"), data.r_name);
985 retval = (*cback)(&data, 0);
987 if (retval == LDAP_ALREADY_EXISTS) {
988 if (continue_onerror)
989 (void) fprintf(stderr,
990 gettext("Entry: %s - already Exists,"
991 " skipping it.\n"), data.r_name);
992 else {
993 rc = GENENT_CBERR;
994 (void) fprintf(stderr,
995 gettext("Entry: %s - already Exists\n"),
996 data.r_name);
998 } else if (retval)
999 rc = GENENT_CBERR;
1001 free(data.r_name);
1002 free(data.r_aliases);
1004 return (rc);
1009 static void
1010 dump_rpc(ns_ldap_result_t *res)
1012 ns_ldap_attr_t *attrptr = NULL, *cn = NULL, *rpcnumber = NULL;
1013 int i, j;
1014 char *name; /* rpc name */
1016 if (res == NULL || res->entry == NULL)
1017 return;
1018 for (i = 0; i < res->entry->attr_count; i++) {
1019 attrptr = res->entry->attr_pair[i];
1020 if (strcasecmp(attrptr->attrname, "cn") == 0)
1021 cn = attrptr;
1022 else if (strcasecmp(attrptr->attrname, "oncRpcNumber") == 0)
1023 rpcnumber = attrptr;
1025 /* sanity check */
1026 if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL ||
1027 rpcnumber == NULL || rpcnumber->attrvalue == NULL ||
1028 rpcnumber->attrvalue[0] == NULL)
1029 return;
1031 if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL)
1032 return;
1034 /* rpc name */
1035 if (strlen(name) < 8)
1036 (void) fprintf(stdout, "%s\t\t", name);
1037 else
1038 (void) fprintf(stdout, "%s\t", name);
1040 /* rpc number */
1041 (void) fprintf(stdout, "%-8s", rpcnumber->attrvalue[0]);
1044 /* aliases */
1045 for (j = 0; j < cn->value_count; j++) {
1046 if (cn->attrvalue[j]) {
1047 if (strcasecmp(name, cn->attrvalue[j]) == 0)
1048 /* skip rpc name */
1049 continue;
1050 (void) fprintf(stdout, "%s ", cn->attrvalue[j]);
1054 /* end of line */
1055 (void) fprintf(stdout, "\n");
1060 * /etc/protocols
1064 static int
1065 genent_protocols(char *line, int (*cback)())
1067 char buf[BUFSIZ+1];
1068 char *t;
1069 entry_col ecol[4];
1070 char *cname;
1072 struct protoent data;
1073 char *alias;
1074 int ctr = 0;
1075 int retval = 1;
1076 int rc = GENENT_OK;
1079 * don't clobber our argument
1081 if (strlen(line) >= sizeof (buf)) {
1082 (void) strlcpy(parse_err_msg, gettext("line too long"),
1083 PARSE_ERR_MSG_LEN);
1084 return (GENENT_PARSEERR);
1086 (void) strcpy(buf, line);
1089 * clear column data
1091 (void) memset((char *)ecol, 0, sizeof (ecol));
1094 * comment (col 3)
1096 t = strchr(buf, '#');
1097 if (t) {
1098 *t++ = 0;
1099 ecol[3].ec_value.ec_value_val = t;
1100 ecol[3].ec_value.ec_value_len = strlen(t)+1;
1101 } else {
1102 ecol[3].ec_value.ec_value_val = 0;
1103 ecol[3].ec_value.ec_value_len = 0;
1107 * cname(col 0)
1109 if ((t = strtok(buf, " \t")) == 0) {
1110 (void) strlcpy(parse_err_msg, gettext("no number"),
1111 PARSE_ERR_MSG_LEN);
1112 return (GENENT_PARSEERR);
1114 ecol[0].ec_value.ec_value_val = t;
1115 ecol[0].ec_value.ec_value_len = strlen(t)+1;
1116 cname = t;
1119 * number (col 2)
1121 if ((t = strtok(NULL, " \t")) == 0) {
1122 (void) strlcpy(parse_err_msg, gettext("no number"),
1123 PARSE_ERR_MSG_LEN);
1124 return (GENENT_PARSEERR);
1126 ecol[2].ec_value.ec_value_val = t;
1127 ecol[2].ec_value.ec_value_len = strlen(t)+1;
1131 * build entry
1133 data.p_name = strdup(ecol[0].ec_value.ec_value_val);
1135 if (ecol[2].ec_value.ec_value_val != NULL &&
1136 ecol[2].ec_value.ec_value_val[0] != '\0') {
1138 data.p_proto = ascii_to_int(ecol[2].ec_value.ec_value_val);
1139 if (data.p_proto == -1) {
1140 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
1141 gettext("invalid protocol number: %s"),
1142 ecol[2].ec_value.ec_value_val);
1143 return (GENENT_PARSEERR);
1145 } else
1146 data.p_proto = -1;
1149 * name (col 1)
1151 t = cname;
1152 ctr = 0;
1153 data.p_aliases = NULL;
1155 do {
1157 * don't clobber comment in canonical entry
1159 if (t != cname && strcasecmp(t, cname) == 0)
1160 continue;
1161 if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
1162 continue;
1164 ecol[1].ec_value.ec_value_val = t;
1165 ecol[1].ec_value.ec_value_len = strlen(t)+1;
1167 ctr++;
1168 alias = strdup(ecol[1].ec_value.ec_value_val);
1169 if ((data.p_aliases = reallocarray(data.p_aliases, ctr,
1170 sizeof (char **))) == NULL) {
1171 (void) fprintf(stderr, gettext("out of memory\n"));
1172 exit(1);
1174 data.p_aliases[ctr-1] = alias;
1177 * only put comment in canonical entry
1179 ecol[3].ec_value.ec_value_val = 0;
1180 ecol[3].ec_value.ec_value_len = 0;
1182 } while (t = strtok(NULL, " \t"));
1184 /* End the list of all the aliases by NULL */
1185 if ((data.p_aliases = reallocarray(data.p_aliases, ctr + 1,
1186 sizeof (char **))) == NULL) {
1187 (void) fprintf(stderr, gettext("out of memory\n"));
1188 exit(1);
1190 data.p_aliases[ctr] = NULL;
1192 if (flags & F_VERBOSE)
1193 (void) fprintf(stdout,
1194 gettext("Adding entry : %s\n"), data.p_name);
1196 retval = (*cback)(&data, 0);
1198 if (retval == LDAP_ALREADY_EXISTS) {
1199 if (continue_onerror)
1200 (void) fprintf(stderr,
1201 gettext("Entry: %s - already Exists,"
1202 " skipping it.\n"), data.p_name);
1203 else {
1204 rc = GENENT_CBERR;
1205 (void) fprintf(stderr,
1206 gettext("Entry: %s - already Exists\n"),
1207 data.p_name);
1209 } else if (retval)
1210 rc = GENENT_CBERR;
1212 free(data.p_name);
1213 free(data.p_aliases);
1215 return (rc);
1219 static void
1220 dump_protocols(ns_ldap_result_t *res)
1222 ns_ldap_attr_t *attrptr = NULL, *cn = NULL, *protocolnumber = NULL;
1223 int i, j;
1224 char *name, *cp;
1226 if (res == NULL || res->entry == NULL)
1227 return;
1228 for (i = 0; i < res->entry->attr_count; i++) {
1229 attrptr = res->entry->attr_pair[i];
1230 if (strcasecmp(attrptr->attrname, "cn") == 0)
1231 cn = attrptr;
1232 else if (strcasecmp(attrptr->attrname, "ipProtocolNumber")
1233 == 0)
1234 protocolnumber = attrptr;
1236 /* sanity check */
1237 if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL ||
1238 protocolnumber == NULL || protocolnumber->attrvalue == NULL ||
1239 protocolnumber->attrvalue[0] == NULL)
1240 return;
1242 if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL)
1243 return;
1245 /* protocol name */
1246 if (strlen(name) < 8)
1247 (void) fprintf(stdout, "%s\t\t", name);
1248 else
1249 (void) fprintf(stdout, "%s\t", name);
1251 /* protocol number */
1252 (void) fprintf(stdout, "%-16s", protocolnumber->attrvalue[0]);
1254 /* aliases */
1255 for (j = 0; j < cn->value_count; j++) {
1256 if (cn->attrvalue[j]) {
1257 if (strcasecmp(name, cn->attrvalue[j]) == 0) {
1258 if (cn->value_count > 1)
1259 /* Do not replicate */
1260 continue;
1262 * Replicate name in uppercase as an aliase
1264 for (cp = cn->attrvalue[j]; *cp; cp++)
1265 *cp = toupper(*cp);
1267 (void) fprintf(stdout, "%s ", cn->attrvalue[j]);
1271 /* end of line */
1272 (void) fprintf(stdout, "\n");
1281 * /etc/networks
1285 static int
1286 genent_networks(char *line, int (*cback)())
1288 char buf[BUFSIZ+1];
1289 char *t;
1290 entry_col ecol[4];
1291 char *cname;
1293 struct netent data;
1294 char *alias;
1295 int ctr = 0;
1296 int retval = 1;
1297 int enet;
1298 int rc = GENENT_OK;
1301 * don't clobber our argument
1303 if (strlen(line) >= sizeof (buf)) {
1304 (void) strlcpy(parse_err_msg, gettext("line too long"),
1305 PARSE_ERR_MSG_LEN);
1306 return (GENENT_PARSEERR);
1308 (void) strcpy(buf, line);
1311 * clear column data
1313 (void) memset((char *)ecol, 0, sizeof (ecol));
1316 * comment (col 3)
1318 t = strchr(buf, '#');
1319 if (t) {
1320 *t++ = 0;
1321 ecol[3].ec_value.ec_value_val = t;
1322 ecol[3].ec_value.ec_value_len = strlen(t)+1;
1323 } else {
1324 ecol[3].ec_value.ec_value_val = 0;
1325 ecol[3].ec_value.ec_value_len = 0;
1329 * cname(col 0)
1331 if ((t = strtok(buf, " \t")) == 0) {
1332 (void) strlcpy(parse_err_msg, gettext("no number"),
1333 PARSE_ERR_MSG_LEN);
1334 return (GENENT_PARSEERR);
1336 ecol[0].ec_value.ec_value_val = t;
1337 ecol[0].ec_value.ec_value_len = strlen(t)+1;
1338 cname = t;
1341 * number (col 2)
1343 if ((t = strtok(NULL, " \t")) == 0) {
1344 (void) strlcpy(parse_err_msg, gettext("no number"),
1345 PARSE_ERR_MSG_LEN);
1346 return (GENENT_PARSEERR);
1348 ecol[2].ec_value.ec_value_val = t;
1349 ecol[2].ec_value.ec_value_len = strlen(t)+1;
1353 * build entry
1356 data.n_name = strdup(ecol[0].ec_value.ec_value_val);
1358 * data.n_net is an unsigned field,
1359 * assign -1 to it, make no sense.
1360 * Use enet here to avoid lint warning.
1362 enet = encode_network(ecol[2].ec_value.ec_value_val);
1364 if (enet == -1 && continue_onerror == 0) {
1365 (void) fprintf(stderr, gettext("Invalid network number\n"));
1366 if (continue_onerror == 0)
1367 return (GENENT_CBERR);
1368 } else
1369 data.n_net = enet;
1372 * name (col 1)
1374 t = cname;
1375 data.n_aliases = NULL;
1377 do {
1379 * don't clobber comment in canonical entry
1381 if (t != cname && strcasecmp(t, cname) == 0)
1382 continue;
1383 if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
1384 continue;
1386 ecol[1].ec_value.ec_value_val = t;
1387 ecol[1].ec_value.ec_value_len = strlen(t)+1;
1389 ctr++;
1390 alias = strdup(ecol[1].ec_value.ec_value_val);
1391 if ((data.n_aliases = reallocarray(data.n_aliases, ctr,
1392 sizeof (char **))) == NULL) {
1393 (void) fprintf(stderr, gettext("out of memory\n"));
1394 exit(1);
1396 data.n_aliases[ctr-1] = alias;
1399 * only put comment in canonical entry
1401 ecol[3].ec_value.ec_value_val = 0;
1402 ecol[3].ec_value.ec_value_len = 0;
1404 } while (t = strtok(NULL, " \t"));
1406 /* End the list of all the aliases by NULL */
1407 if ((data.n_aliases = reallocarray(data.n_aliases, ctr + 1,
1408 sizeof (char **))) == NULL) {
1409 (void) fprintf(stderr, gettext("out of memory\n"));
1410 exit(1);
1412 data.n_aliases[ctr] = NULL;
1414 if (flags & F_VERBOSE)
1415 (void) fprintf(stdout,
1416 gettext("Adding entry : %s\n"), data.n_name);
1418 retval = (*cback)(&data, 0);
1420 if (retval == LDAP_ALREADY_EXISTS) {
1421 if (continue_onerror)
1422 (void) fprintf(stderr,
1423 gettext("Entry: %s - already Exists,"
1424 " skipping it.\n"), data.n_name);
1425 else {
1426 rc = GENENT_CBERR;
1427 (void) fprintf(stderr,
1428 gettext("Entry: %s - already Exists\n"),
1429 data.n_name);
1431 } else if (retval)
1432 rc = GENENT_CBERR;
1434 free(data.n_name);
1435 free(data.n_aliases);
1437 return (rc);
1441 static void
1442 dump_networks(ns_ldap_result_t *res)
1444 ns_ldap_attr_t *attrptr = NULL, *cn = NULL, *networknumber = NULL;
1445 int i, j;
1446 char *name;
1448 if (res == NULL || res->entry == NULL)
1449 return;
1450 for (i = 0; i < res->entry->attr_count; i++) {
1451 attrptr = res->entry->attr_pair[i];
1452 if (strcasecmp(attrptr->attrname, "cn") == 0)
1453 cn = attrptr;
1454 else if (strcasecmp(attrptr->attrname, "ipNetworkNumber")
1455 == 0)
1456 networknumber = attrptr;
1458 /* sanity check */
1459 if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL ||
1460 networknumber == NULL || networknumber->attrvalue == NULL ||
1461 networknumber->attrvalue[0] == NULL)
1462 return;
1465 * cn can be a MUST attribute(RFC 2307) or MAY attribute(2307bis).
1466 * If the canonical name can not be found (2307bis), use the 1st
1467 * value as the official name.
1470 /* network name */
1471 if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL)
1472 name = cn->attrvalue[0];
1474 if (strlen(name) < 8)
1475 (void) fprintf(stdout, "%s\t\t", name);
1476 else
1477 (void) fprintf(stdout, "%s\t", name);
1479 /* network number */
1480 (void) fprintf(stdout, "%-16s", networknumber->attrvalue[0]);
1482 /* aliases */
1483 for (j = 0; j < cn->value_count; j++) {
1484 if (cn->attrvalue[j]) {
1485 if (strcasecmp(name, cn->attrvalue[j]) == 0)
1486 /* skip name */
1487 continue;
1488 (void) fprintf(stdout, "%s ", cn->attrvalue[j]);
1492 /* end of line */
1493 (void) fprintf(stdout, "\n");
1501 * /etc/services
1505 static int
1506 genent_services(char *line, int (*cback)())
1508 char buf[BUFSIZ+1];
1509 char *t, *p;
1510 entry_col ecol[5];
1511 char *cname;
1513 struct servent data;
1514 char *alias;
1515 int ctr = 0;
1516 int retval = 1;
1517 int rc = GENENT_OK;
1520 * don't clobber our argument
1522 if (strlen(line) >= sizeof (buf)) {
1523 (void) strlcpy(parse_err_msg, gettext("line too long"),
1524 PARSE_ERR_MSG_LEN);
1525 return (GENENT_PARSEERR);
1527 (void) strcpy(buf, line);
1530 * clear column data
1532 (void) memset((char *)ecol, 0, sizeof (ecol));
1535 * comment (col 4)
1537 t = strchr(buf, '#');
1538 if (t) {
1539 *t++ = 0;
1540 ecol[4].ec_value.ec_value_val = t;
1541 ecol[4].ec_value.ec_value_len = strlen(t)+1;
1542 } else {
1543 ecol[4].ec_value.ec_value_val = 0;
1544 ecol[4].ec_value.ec_value_len = 0;
1548 * cname(col 0)
1550 if ((t = strtok(buf, " \t")) == 0) {
1551 (void) strlcpy(parse_err_msg, gettext("no port"),
1552 PARSE_ERR_MSG_LEN);
1553 return (GENENT_PARSEERR);
1555 ecol[0].ec_value.ec_value_val = t;
1556 ecol[0].ec_value.ec_value_len = strlen(t)+1;
1557 cname = t;
1560 * port (col 3)
1562 if ((t = strtok(NULL, " \t")) == 0) {
1563 (void) strlcpy(parse_err_msg, gettext("no protocol"),
1564 PARSE_ERR_MSG_LEN);
1565 return (GENENT_PARSEERR);
1567 if ((p = strchr(t, '/')) == 0) {
1568 (void) strlcpy(parse_err_msg, gettext("bad port/proto"),
1569 PARSE_ERR_MSG_LEN);
1570 return (GENENT_PARSEERR);
1572 *(p++) = 0;
1573 ecol[3].ec_value.ec_value_val = t;
1574 ecol[3].ec_value.ec_value_len = strlen(t)+1;
1577 * proto (col 2)
1579 ecol[2].ec_value.ec_value_val = p;
1580 ecol[2].ec_value.ec_value_len = strlen(p)+1;
1584 * build entry
1587 data.s_name = strdup(ecol[0].ec_value.ec_value_val);
1588 data.s_proto = strdup(ecol[2].ec_value.ec_value_val);
1590 if (ecol[3].ec_value.ec_value_val != NULL &&
1591 ecol[3].ec_value.ec_value_val[0] != '\0') {
1593 data.s_port = ascii_to_int(ecol[3].ec_value.ec_value_val);
1594 if (data.s_port == -1) {
1595 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
1596 gettext("invalid port number: %s"),
1597 ecol[3].ec_value.ec_value_val);
1598 return (GENENT_PARSEERR);
1600 } else
1601 data.s_port = -1;
1604 * name (col 1)
1606 t = cname;
1607 data.s_aliases = NULL;
1609 do {
1611 * don't clobber comment in canonical entry
1613 if (t != cname && strcasecmp(t, cname) == 0)
1614 continue;
1615 if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
1616 continue;
1618 ecol[1].ec_value.ec_value_val = t;
1619 ecol[1].ec_value.ec_value_len = strlen(t)+1;
1621 ctr++;
1622 alias = strdup(ecol[1].ec_value.ec_value_val);
1623 if ((data.s_aliases = (char **)reallocarray(data.s_aliases,
1624 ctr, sizeof (char **))) == NULL) {
1625 (void) fprintf(stderr, gettext("out of memory\n"));
1626 exit(1);
1628 data.s_aliases[ctr-1] = alias;
1631 * only put comment in canonical entry
1633 ecol[4].ec_value.ec_value_val = 0;
1634 ecol[4].ec_value.ec_value_len = 0;
1636 } while (t = strtok(NULL, " \t"));
1638 /* End the list of all the aliases by NULL */
1639 if ((data.s_aliases = reallocarray(data.s_aliases, ctr + 1,
1640 sizeof (char **))) == NULL) {
1641 (void) fprintf(stderr, gettext("out of memory\n"));
1642 exit(1);
1644 data.s_aliases[ctr] = NULL;
1646 if (flags & F_VERBOSE)
1647 (void) fprintf(stdout,
1648 gettext("Adding entry : %s\n"), line);
1650 retval = (*cback)(&data, 0);
1652 if (retval == LDAP_ALREADY_EXISTS) {
1653 if (continue_onerror)
1654 (void) fprintf(stderr, gettext(
1655 "Entry: cn=%s+ipServiceProtocol=%s"
1656 " already Exists, skipping it.\n"),
1657 data.s_name, data.s_proto);
1658 else {
1659 rc = GENENT_CBERR;
1660 (void) fprintf(stderr,
1661 gettext("Entry: cn=%s+ipServiceProtocol=%s"
1662 " - already Exists\n"),
1663 data.s_name, data.s_proto);
1665 } else if (retval)
1666 rc = GENENT_CBERR;
1668 free(data.s_name);
1669 free(data.s_proto);
1670 free(data.s_aliases);
1672 return (rc);
1677 static void
1678 dump_services(ns_ldap_result_t *res)
1680 ns_ldap_attr_t *attrptr = NULL, *cn = NULL, *port = NULL;
1681 ns_ldap_attr_t *protocol = NULL;
1682 int i, j, len;
1683 char *name; /* service name */
1686 * cn can have multiple values.(service name and its aliases)
1687 * In order to support RFC 2307, section 5.5, ipserviceprotocol can
1688 * have multiple values too.
1689 * The output format should look like
1691 * test 2345/udp mytest
1692 * test 2345/tcp mytest
1694 if (res == NULL || res->entry == NULL)
1695 return;
1696 for (i = 0; i < res->entry->attr_count; i++) {
1697 attrptr = res->entry->attr_pair[i];
1698 if (strcasecmp(attrptr->attrname, "cn") == 0)
1699 cn = attrptr;
1700 else if (strcasecmp(attrptr->attrname, "ipServicePort") == 0)
1701 port = attrptr;
1702 else if (strcasecmp(attrptr->attrname,
1703 "ipServiceProtocol") == 0)
1704 protocol = attrptr;
1706 /* sanity check */
1707 if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL ||
1708 port == NULL || port->attrvalue == NULL ||
1709 port->attrvalue[0] == NULL || protocol == NULL ||
1710 protocol->attrvalue == NULL || protocol->attrvalue[0] == NULL)
1711 return;
1713 if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL)
1714 return;
1715 for (i = 0; i < protocol->value_count; i++) {
1716 if (protocol->attrvalue[i] == NULL)
1717 return;
1718 /* service name */
1719 (void) fprintf(stdout, "%-16s", name);
1721 /* port & protocol */
1722 (void) fprintf(stdout, "%s/%s%n", port->attrvalue[0],
1723 protocol->attrvalue[i], &len);
1725 if (len < 8)
1726 (void) fprintf(stdout, "\t\t");
1727 else
1728 (void) fprintf(stdout, "\t");
1730 /* aliases */
1731 for (j = 0; j < cn->value_count; j++) {
1732 if (cn->attrvalue[j]) {
1733 if (strcasecmp(name, cn->attrvalue[j]) == 0)
1734 /* skip service name */
1735 continue;
1736 (void) fprintf(stdout, "%s ", cn->attrvalue[j]);
1740 /* end of line */
1741 (void) fprintf(stdout, "\n");
1747 * /etc/group
1750 static int
1751 genent_group(char *line, int (*cback)())
1753 char buf[BIGBUF+1];
1754 char *s, *t;
1755 entry_col ecol[5];
1757 struct group data;
1758 int ctr = 0;
1759 int retval = 1;
1760 int rc = GENENT_OK;
1763 * don't clobber our argument
1765 if (strlen(line) >= sizeof (buf)) {
1766 (void) strlcpy(parse_err_msg, gettext("line too long"),
1767 PARSE_ERR_MSG_LEN);
1768 return (GENENT_PARSEERR);
1770 (void) strcpy(buf, line);
1771 t = buf;
1773 /* ignore empty entries */
1774 if (*t == '\0')
1775 return (GENENT_OK);
1778 * clear column data
1780 (void) memset((char *)ecol, 0, sizeof (ecol));
1783 * name (col 0)
1785 if ((s = strchr(t, ':')) == 0) {
1786 (void) strlcpy(parse_err_msg, gettext("no passwd"),
1787 PARSE_ERR_MSG_LEN);
1788 return (GENENT_PARSEERR);
1790 *s++ = 0;
1791 ecol[0].ec_value.ec_value_val = t;
1792 ecol[0].ec_value.ec_value_len = strlen(t)+1;
1793 t = s;
1796 * passwd (col 1)
1798 if ((s = strchr(t, ':')) == 0) {
1799 (void) strlcpy(parse_err_msg, gettext("no gid"),
1800 PARSE_ERR_MSG_LEN);
1801 return (GENENT_PARSEERR);
1803 *s++ = 0;
1804 ecol[1].ec_value.ec_value_val = t;
1805 ecol[1].ec_value.ec_value_len = strlen(t)+1;
1806 t = s;
1810 * gid (col 2)
1812 if ((s = strchr(t, ':')) == 0 || s == t) {
1813 (void) strlcpy(parse_err_msg, gettext("no members"),
1814 PARSE_ERR_MSG_LEN);
1815 return (GENENT_PARSEERR);
1817 *s++ = 0;
1818 ecol[2].ec_value.ec_value_val = t;
1819 ecol[2].ec_value.ec_value_len = strlen(t)+1;
1820 t = s;
1823 * members (col 3)
1825 ecol[3].ec_value.ec_value_val = t;
1826 ecol[3].ec_value.ec_value_len = strlen(t)+1;
1830 * build entry
1832 data.gr_name = strdup(ecol[0].ec_value.ec_value_val);
1833 data.gr_passwd = strdup(ecol[1].ec_value.ec_value_val);
1834 if (ecol[2].ec_value.ec_value_val != NULL &&
1835 ecol[2].ec_value.ec_value_val[0] != '\0') {
1837 data.gr_gid = ascii_to_int(ecol[2].ec_value.ec_value_val);
1838 if (data.gr_gid == (uid_t)-1) {
1839 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
1840 gettext("invalid group id: %s"),
1841 ecol[2].ec_value.ec_value_val);
1842 return (GENENT_PARSEERR);
1844 } else
1845 data.gr_gid = (uid_t)-1;
1847 data.gr_mem = NULL;
1849 /* Compute maximum amount of members */
1850 s = t;
1851 while (s = strchr(s, ',')) {
1852 s++;
1853 ctr++;
1856 /* Allocate memory for all members */
1857 data.gr_mem = calloc(ctr + 2, sizeof (char **));
1858 if (data.gr_mem == NULL) {
1859 (void) fprintf(stderr, gettext("out of memory\n"));
1860 exit(1);
1863 ctr = 0;
1864 while (s = strchr(t, ',')) {
1866 *s++ = 0;
1867 ecol[3].ec_value.ec_value_val = t;
1868 t = s;
1869 /* Send to server only non empty member names */
1870 if (strlen(ecol[3].ec_value.ec_value_val) != 0)
1871 data.gr_mem[ctr++] = ecol[3].ec_value.ec_value_val;
1874 /* Send to server only non empty member names */
1875 if (strlen(t) != 0)
1876 data.gr_mem[ctr++] = t;
1878 /* Array of members completed, finished by NULL, see calloc() */
1880 if (flags & F_VERBOSE)
1881 (void) fprintf(stdout,
1882 gettext("Adding entry : %s\n"), data.gr_name);
1884 retval = (*cback)(&data, 0);
1886 if (retval == LDAP_ALREADY_EXISTS) {
1887 if (continue_onerror)
1888 (void) fprintf(stderr,
1889 gettext("Entry: %s - already Exists,"
1890 " skipping it.\n"), data.gr_name);
1891 else {
1892 rc = GENENT_CBERR;
1893 (void) fprintf(stderr,
1894 gettext("Entry: %s - already Exists\n"),
1895 data.gr_name);
1897 } else if (retval)
1898 rc = GENENT_CBERR;
1900 free(data.gr_name);
1901 free(data.gr_passwd);
1902 free(data.gr_mem);
1904 return (rc);
1907 static void
1908 dump_group(ns_ldap_result_t *res)
1910 char **value = NULL;
1911 char pnam[256];
1912 int attr_count = 0;
1914 value = __ns_ldap_getAttr(res->entry, "cn");
1915 if (value && value[0])
1916 (void) fprintf(stdout, "%s:", value[0]);
1917 value = __ns_ldap_getAttr(res->entry, "userPassword");
1918 if (value == NULL || value[0] == NULL)
1919 (void) fprintf(stdout, "*:");
1920 else {
1921 (void) strcpy(pnam, value[0]);
1922 if (strncasecmp(value[0], "{crypt}", 7) == 0)
1923 (void) fprintf(stdout, "%s:", (pnam+7));
1924 else
1925 (void) fprintf(stdout, "*:");
1927 value = __ns_ldap_getAttr(res->entry, "gidNumber");
1928 if (value && value[0])
1929 (void) fprintf(stdout, "%s:", value[0]);
1931 value = __ns_ldap_getAttr(res->entry, "memberUid");
1932 if (value != NULL && value[0] != NULL) {
1933 while (value[attr_count] != NULL) {
1934 if (value[attr_count+1] == NULL)
1935 (void) fprintf(stdout, "%s", value[attr_count]);
1936 else
1937 (void) fprintf(stdout, "%s,",
1938 value[attr_count]);
1939 attr_count++;
1941 (void) fprintf(stdout, "\n");
1943 else
1944 (void) fprintf(stdout, "\n");
1952 * /etc/ethers
1955 static int
1956 genent_ethers(char *line, int (*cback)())
1958 char buf[BUFSIZ+1];
1959 char *t;
1960 entry_col ecol[3];
1961 int retval = 1;
1962 struct _ns_ethers data;
1963 int rc = GENENT_OK;
1966 * don't clobber our argument
1968 if (strlen(line) >= sizeof (buf)) {
1969 (void) strlcpy(parse_err_msg, gettext("line too long"),
1970 PARSE_ERR_MSG_LEN);
1971 return (GENENT_PARSEERR);
1973 (void) strcpy(buf, line);
1976 * clear column data
1978 (void) memset((char *)ecol, 0, sizeof (ecol));
1981 * comment (col 2)
1983 t = strchr(buf, '#');
1984 if (t) {
1985 *t++ = 0;
1986 ecol[2].ec_value.ec_value_val = t;
1987 ecol[2].ec_value.ec_value_len = strlen(t)+1;
1988 } else {
1989 ecol[2].ec_value.ec_value_val = 0;
1990 ecol[2].ec_value.ec_value_len = 0;
1994 * addr(col 0)
1996 if ((t = strtok(buf, " \t")) == 0) {
1997 (void) strlcpy(parse_err_msg, gettext("no name"),
1998 PARSE_ERR_MSG_LEN);
1999 return (GENENT_PARSEERR);
2001 ecol[0].ec_value.ec_value_val = t;
2002 ecol[0].ec_value.ec_value_len = strlen(t)+1;
2005 * name(col 1)
2007 if ((t = strtok(NULL, " \t")) == 0) {
2008 (void) strlcpy(parse_err_msg,
2009 gettext("no white space allowed in name"),
2010 PARSE_ERR_MSG_LEN);
2011 return (GENENT_PARSEERR);
2013 ecol[1].ec_value.ec_value_val = t;
2014 ecol[1].ec_value.ec_value_len = strlen(t)+1;
2018 * build entry
2021 data.ether = strdup(ecol[0].ec_value.ec_value_val);
2022 data.name = strdup(ecol[1].ec_value.ec_value_val);
2025 if (flags & F_VERBOSE)
2026 (void) fprintf(stdout,
2027 gettext("Adding entry : %s\n"), data.name);
2029 retval = (*cback)(&data, 0);
2031 if (retval == LDAP_ALREADY_EXISTS) {
2032 if (continue_onerror)
2033 (void) fprintf(stderr,
2034 gettext("Entry: %s - already Exists,"
2035 " skipping it.\n"), data.name);
2036 else {
2037 rc = GENENT_CBERR;
2038 (void) fprintf(stderr,
2039 gettext("Entry: %s - already Exists\n"),
2040 data.name);
2042 } else if (retval)
2043 rc = GENENT_CBERR;
2045 free(data.ether);
2046 free(data.name);
2048 return (rc);
2052 static void
2053 dump_ethers(ns_ldap_result_t *res)
2055 char **value = NULL;
2057 value = __ns_ldap_getAttr(res->entry, "macAddress");
2058 if (value && value[0])
2059 (void) fprintf(stdout, "%s", value[0]);
2060 else
2061 return;
2062 value = __ns_ldap_getAttr(res->entry, "cn");
2063 if (value && value[0])
2064 (void) fprintf(stdout, " %s\n", value[0]);
2067 static int
2068 genent_aliases(char *line, int (*cback)())
2070 char buf[BUFSIZ+1];
2071 char *t, *aliases;
2072 char *cname;
2073 int ctr = 0;
2074 int retval = 1;
2075 int i;
2077 struct _ns_alias data;
2078 char *alias;
2079 int rc = GENENT_OK;
2082 * don't clobber our argument
2084 if (strlen(line) >= sizeof (buf)) {
2085 (void) strlcpy(parse_err_msg, gettext("line too long"),
2086 PARSE_ERR_MSG_LEN);
2087 return (GENENT_PARSEERR);
2090 (void) strcpy(buf, line);
2092 if ((t = strchr(buf, ':')) == 0) {
2093 (void) strlcpy(parse_err_msg, gettext("no alias name"),
2094 PARSE_ERR_MSG_LEN);
2095 return (GENENT_PARSEERR);
2098 t[0] = '\0';
2099 if (++t == '\0') {
2100 (void) strlcpy(parse_err_msg, gettext("no alias value"),
2101 PARSE_ERR_MSG_LEN);
2102 return (GENENT_PARSEERR);
2105 cname = buf;
2106 aliases = t;
2108 /* build entry */
2109 data.alias = strdup(cname);
2110 if (!data.alias) {
2111 (void) fprintf(stderr, gettext("out of memory\n"));
2112 exit(1);
2115 data.member = NULL;
2116 t = strtok(aliases, ",");
2117 do {
2118 ctr++;
2119 while (t[0] == ' ')
2120 t++;
2121 alias = strdup(t);
2122 if ((alias == NULL) ||
2123 ((data.member = reallocarray(data.member, ctr + 1,
2124 sizeof (char **))) == NULL)) {
2125 (void) fprintf(stderr, gettext("out of memory\n"));
2126 exit(1);
2128 data.member[ctr-1] = alias;
2130 } while (t = strtok(NULL, ","));
2132 data.member[ctr] = NULL;
2134 if (flags & F_VERBOSE)
2135 (void) fprintf(stdout,
2136 gettext("Adding entry : %s\n"), data.alias);
2138 retval = (*cback)(&data, 0);
2140 if (retval == LDAP_ALREADY_EXISTS) {
2141 if (continue_onerror)
2142 (void) fprintf(stderr,
2143 gettext("Entry: %s - already Exists,"
2144 " skipping it.\n"), data.alias);
2145 else {
2146 rc = GENENT_CBERR;
2147 (void) fprintf(stderr,
2148 gettext("Entry: %s - already Exists\n"),
2149 data.alias);
2151 } else if (retval)
2152 rc = GENENT_CBERR;
2154 free(data.alias);
2155 i = 0;
2156 while (data.member[i])
2157 free(data.member[i++]);
2158 free(data.member);
2160 return (rc);
2164 static void
2165 dump_aliases(ns_ldap_result_t *res)
2168 char **value = NULL;
2169 int attr_count = 0;
2171 value = __ns_ldap_getAttr(res->entry, "mail");
2172 if (value && value[0])
2173 (void) fprintf(stdout, "%s:", value[0]);
2174 value = __ns_ldap_getAttr(res->entry, "mgrpRFC822MailMember");
2175 if (value != NULL)
2176 while (value[attr_count] != NULL) {
2177 (void) fprintf(stdout, "%s,", value[attr_count]);
2178 attr_count++;
2180 (void) fprintf(stdout, "\n");
2185 * /etc/publickey
2188 static char *h_errno2str(int h_errno);
2190 static int
2191 genent_publickey(char *line, int (*cback)())
2193 char buf[BUFSIZ+1], tmpbuf[BUFSIZ+1], cname[BUFSIZ+1];
2194 char *t, *p, *tmppubkey, *tmpprivkey;
2195 entry_col ecol[3];
2196 int buflen, uid, retval = 1, errnum = 0;
2197 struct passwd *pwd;
2198 char auth_type[BUFSIZ+1], *dot;
2199 keylen_t keylen;
2200 algtype_t algtype;
2201 struct _ns_pubkey data;
2202 struct hostent *hp;
2203 struct in_addr in;
2204 struct in6_addr in6;
2205 char abuf[INET6_ADDRSTRLEN];
2208 * don't clobber our argument
2210 if (strlen(line) >= sizeof (buf)) {
2211 (void) strlcpy(parse_err_msg, gettext("line too long"),
2212 PARSE_ERR_MSG_LEN);
2213 return (GENENT_PARSEERR);
2215 (void) strcpy(buf, line);
2218 * clear column data
2220 (void) memset((char *)ecol, 0, sizeof (ecol));
2222 if ((t = strtok(buf, " \t")) == 0) {
2223 (void) strlcpy(parse_err_msg, gettext("no cname"),
2224 PARSE_ERR_MSG_LEN);
2225 return (GENENT_PARSEERR);
2229 * Special case: /etc/publickey usually has an entry
2230 * for principal "nobody". We skip it.
2232 if (strcmp(t, "nobody") == 0)
2233 return (GENENT_OK);
2236 * cname (col 0)
2238 if (strncmp(t, "unix.", 5)) {
2239 (void) strlcpy(parse_err_msg, gettext("bad cname"),
2240 PARSE_ERR_MSG_LEN);
2241 return (GENENT_PARSEERR);
2243 (void) strcpy(tmpbuf, &(t[5]));
2244 if ((p = strchr(tmpbuf, '@')) == 0) {
2245 (void) strlcpy(parse_err_msg, gettext("bad cname"),
2246 PARSE_ERR_MSG_LEN);
2247 return (GENENT_PARSEERR);
2249 *(p++) = 0;
2250 if (isdigit(*tmpbuf)) {
2252 uid = atoi(tmpbuf);
2254 * don't generate entries for uids without passwd entries
2256 if ((pwd = getpwuid(uid)) == 0) {
2257 (void) fprintf(stderr,
2258 gettext("can't map uid %d to username, skipping\n"),
2259 uid);
2260 return (GENENT_OK);
2262 (void) strcpy(cname, pwd->pw_name);
2263 data.hostcred = NS_HOSTCRED_FALSE;
2264 } else {
2265 if ((hp = getipnodebyname(tmpbuf, AF_INET6,
2266 AI_ALL | AI_V4MAPPED, &errnum)) == NULL) {
2267 (void) fprintf(stderr,
2268 gettext("can't map hostname %s to hostaddress, "
2269 "errnum %d %s skipping\n"), tmpbuf, errnum,
2270 h_errno2str(errnum));
2271 return (GENENT_OK);
2273 (void) memcpy((char *)&in6.s6_addr, hp->h_addr_list[0],
2274 hp->h_length);
2275 if (IN6_IS_ADDR_V4MAPPED(&in6) ||
2276 IN6_IS_ADDR_V4COMPAT(&in6)) {
2277 IN6_V4MAPPED_TO_INADDR(&in6, &in);
2278 if (inet_ntop(AF_INET, (const void *)&in, abuf,
2279 INET6_ADDRSTRLEN) == NULL) {
2280 (void) fprintf(stderr,
2281 gettext("can't convert IPV4 address of"
2282 " hostname %s to string, "
2283 "skipping\n"), tmpbuf);
2284 return (GENENT_OK);
2286 } else {
2287 if (inet_ntop(AF_INET6, (const void *)&in6, abuf,
2288 INET6_ADDRSTRLEN) == NULL) {
2289 (void) fprintf(stderr,
2290 gettext("can't convert IPV6 address of"
2291 " hostname %s to string, "
2292 "skipping\n"), tmpbuf);
2293 return (GENENT_OK);
2296 data.hostcred = NS_HOSTCRED_TRUE;
2298 * tmpbuf could be an alias, use hp->h_name instead.
2299 * hp->h_name is in FQDN format, so extract 1st field.
2301 if ((dot = strchr(hp->h_name, '.')) != NULL)
2302 *dot = '\0';
2303 (void) snprintf(cname, sizeof (cname),
2304 "%s+ipHostNumber=%s", hp->h_name, abuf);
2305 if (dot)
2306 *dot = '.';
2309 ecol[0].ec_value.ec_value_val = cname;
2310 ecol[0].ec_value.ec_value_len = strlen(cname)+1;
2313 * public_data (col 1)
2315 if ((t = strtok(NULL, " \t")) == 0) {
2316 (void) strlcpy(parse_err_msg, gettext("no private_data"),
2317 PARSE_ERR_MSG_LEN);
2318 return (GENENT_PARSEERR);
2320 if ((p = strchr(t, ':')) == 0) {
2321 (void) strlcpy(parse_err_msg, gettext("bad public_data"),
2322 PARSE_ERR_MSG_LEN);
2323 return (GENENT_PARSEERR);
2325 *(p++) = 0;
2326 ecol[1].ec_value.ec_value_val = t;
2327 ecol[1].ec_value.ec_value_len = strlen(t)+1;
2328 keylen = (strlen(t) / 2) * 8;
2331 * private_data (col 2) and algtype extraction
2333 if (*p == ':')
2334 p++;
2335 t = p;
2336 if (!(t = strchr(t, ':'))) {
2337 (void) fprintf(stderr,
2338 gettext("WARNING: No algorithm type data found "
2339 "in publickey file, assuming 0\n"));
2340 algtype = 0;
2341 } else {
2342 *t = '\0';
2343 t++;
2344 algtype = atoi(t);
2346 ecol[2].ec_value.ec_value_val = p;
2347 ecol[2].ec_value.ec_value_len = strlen(p)+1;
2350 * auth_type (col 1)
2352 if (AUTH_DES_KEY(keylen, algtype))
2354 * {DES} and {DH192-0} means same thing.
2355 * However, nisplus uses "DES" and ldap uses "DH192-0"
2356 * internally.
2357 * See newkey(1M), __nis_mechalias2authtype() which is
2358 * called by __nis_keyalg2authtype() and getkey_ldap_g()
2360 (void) strlcpy(auth_type, "DH192-0", BUFSIZ+1);
2361 else if (!(__nis_keyalg2authtype(keylen, algtype, auth_type,
2362 MECH_MAXATNAME))) {
2363 (void) fprintf(stderr,
2364 gettext("Could not convert algorithm type to "
2365 "corresponding auth type string\n"));
2366 return (GENENT_ERR);
2370 * build entry
2372 data.name = strdup(ecol[0].ec_value.ec_value_val);
2373 if (data.name == NULL) {
2374 (void) fprintf(stderr, gettext("out of memory\n"));
2375 exit(1);
2378 buflen = sizeof (auth_type) + strlen(ecol[1].ec_value.ec_value_val) + 3;
2379 if ((tmppubkey = (char *)malloc(buflen)) == NULL) {
2380 (void) fprintf(stderr, gettext("out of memory\n"));
2381 exit(1);
2383 (void) snprintf(tmppubkey, buflen, "{%s}%s", auth_type,
2384 ecol[1].ec_value.ec_value_val);
2385 data.pubkey = tmppubkey;
2387 buflen = sizeof (auth_type) + strlen(ecol[2].ec_value.ec_value_val) + 3;
2388 if ((tmpprivkey = (char *)malloc(buflen)) == NULL) {
2389 (void) fprintf(stderr, gettext("out of memory\n"));
2390 exit(1);
2393 (void) snprintf(tmpprivkey, buflen, "{%s}%s", auth_type,
2394 ecol[2].ec_value.ec_value_val);
2395 data.privkey = tmpprivkey;
2397 retval = (*cback)(&data, 1);
2398 if (retval != NS_LDAP_SUCCESS) {
2399 if (retval == LDAP_NO_SUCH_OBJECT) {
2400 if (data.hostcred == NS_HOSTCRED_TRUE)
2401 (void) fprintf(stdout,
2402 gettext("Cannot add publickey entry"" (%s),"
2403 " add host entry first\n"),
2404 tmpbuf);
2405 else
2406 (void) fprintf(stdout,
2407 gettext("Cannot add publickey entry (%s), "
2408 "add passwd entry first\n"),
2409 data.name);
2411 if (continue_onerror == 0)
2412 return (GENENT_CBERR);
2415 free(data.name);
2416 free(data.pubkey);
2417 free(data.privkey);
2418 return (GENENT_OK);
2421 static void
2422 dump_publickey(ns_ldap_result_t *res, char *container)
2424 char **value = NULL;
2425 char buf[BUFSIZ];
2426 char domainname[BUFSIZ];
2427 char *pubptr, *prvptr;
2429 if (res == NULL)
2430 return;
2432 if (sysinfo(SI_SRPC_DOMAIN, domainname, BUFSIZ) < 0) {
2433 (void) fprintf(stderr,
2434 gettext("could not obtain domainname\n"));
2435 exit(1);
2439 * Retrieve all the attributes, but don't print
2440 * until we have all the required ones.
2443 if (strcmp(container, "passwd") == 0)
2444 value = __ns_ldap_getAttr(res->entry, "uidNumber");
2445 else
2446 value = __ns_ldap_getAttr(res->entry, "cn");
2448 if (value && value[0])
2449 (void) snprintf(buf, sizeof (buf), "unix.%s@%s",
2450 value[0], domainname);
2451 else
2452 return;
2454 value = __ns_ldap_getAttr(res->entry, "nisPublickey");
2455 if (value != NULL && value[0] != NULL) {
2456 if ((pubptr = strchr(value[0], '}')) == NULL)
2457 return;
2460 value = __ns_ldap_getAttr(res->entry, "nisSecretkey");
2461 if (value != NULL && value[0] != NULL)
2462 if ((prvptr = strchr(value[0], '}')) == NULL)
2463 return;
2465 /* print the attributes, algorithm type is always 0 */
2466 (void) fprintf(stdout, "%s %s:%s:0\n", buf, ++pubptr, ++prvptr);
2472 * /etc/netmasks
2475 static int
2476 genent_netmasks(char *line, int (*cback)())
2478 char buf[BUFSIZ+1];
2479 char *t;
2480 entry_col ecol[3];
2481 int retval;
2483 struct _ns_netmasks data;
2487 * don't clobber our argument
2489 if (strlen(line) >= sizeof (buf)) {
2490 (void) strlcpy(parse_err_msg, gettext("line too long"),
2491 PARSE_ERR_MSG_LEN);
2492 return (GENENT_PARSEERR);
2494 (void) strcpy(buf, line);
2497 * clear column data
2499 (void) memset((char *)ecol, 0, sizeof (ecol));
2502 * comment (col 2)
2504 t = strchr(buf, '#');
2505 if (t) {
2506 *t++ = 0;
2507 ecol[2].ec_value.ec_value_val = t;
2508 ecol[2].ec_value.ec_value_len = strlen(t)+1;
2509 } else {
2510 ecol[2].ec_value.ec_value_val = 0;
2511 ecol[2].ec_value.ec_value_len = 0;
2515 * addr(col 0)
2517 if ((t = strtok(buf, " \t")) == 0) {
2518 (void) strlcpy(parse_err_msg, gettext("no mask"),
2519 PARSE_ERR_MSG_LEN);
2520 return (GENENT_PARSEERR);
2522 ecol[0].ec_value.ec_value_val = t;
2523 ecol[0].ec_value.ec_value_len = strlen(t)+1;
2526 * mask (col 1)
2528 if ((t = strtok(NULL, " \t")) == 0) {
2529 (void) strlcpy(parse_err_msg, gettext("no mask"),
2530 PARSE_ERR_MSG_LEN);
2531 return (GENENT_PARSEERR);
2533 ecol[1].ec_value.ec_value_val = t;
2534 ecol[1].ec_value.ec_value_len = strlen(t)+1;
2536 /* build entry */
2537 data.netnumber = ecol[0].ec_value.ec_value_val;
2538 data.netmask = ecol[1].ec_value.ec_value_val;
2540 if (flags & F_VERBOSE)
2541 (void) fprintf(stdout,
2542 gettext("Adding entry : %s\n"), data.netnumber);
2544 retval = (*cback)(&data, 1);
2545 if (retval != NS_LDAP_SUCCESS) {
2546 if (retval == LDAP_NO_SUCH_OBJECT)
2547 (void) fprintf(stdout,
2548 gettext("Cannot add netmask entry (%s), "
2549 "add network entry first\n"), data.netnumber);
2550 if (continue_onerror == 0)
2551 return (GENENT_CBERR);
2554 return (GENENT_OK);
2557 static void
2558 dump_netmasks(ns_ldap_result_t *res)
2560 char **value = NULL;
2562 value = __ns_ldap_getAttr(res->entry, "ipNetworkNumber");
2563 if (value && value[0])
2564 (void) fprintf(stdout, "%s", value[0]);
2565 value = __ns_ldap_getAttr(res->entry, "ipNetmaskNumber");
2566 if (value && value[0])
2567 (void) fprintf(stdout, " %s\n", value[0]);
2572 * /etc/netgroup
2573 * column data format is:
2574 * col 0: netgroup name (or cname)
2575 * col 1: netgroup member, if this is a triplet
2576 * col 2: netgroup member, if not a triplet
2577 * col 3: comment
2580 static int
2581 genent_netgroup(char *line, int (*cback)())
2583 char buf[BIGBUF+1]; /* netgroup entries tend to be big */
2584 char *t;
2585 char *cname = NULL;
2586 entry_col ecol[4];
2587 char *netg_tmp = NULL, *triplet_tmp = NULL;
2588 int netgcount = 0, tripletcount = 0, retval = 1, i;
2589 struct _ns_netgroups data;
2590 int rc = GENENT_OK;
2592 /* don't clobber our argument */
2593 if (strlen(line) >= sizeof (buf)) {
2594 (void) strlcpy(parse_err_msg, gettext("line too long"),
2595 PARSE_ERR_MSG_LEN);
2596 return (GENENT_PARSEERR);
2598 (void) strcpy(buf, line);
2600 /* clear column data */
2601 (void) memset((char *)ecol, 0, sizeof (ecol));
2604 * process 1st minimal entry, to validate that there is no
2605 * parsing error.
2606 * start with comment(col 3)
2608 t = strchr(buf, '#');
2609 if (t) {
2610 *t++ = 0;
2611 ecol[3].ec_value.ec_value_val = t;
2612 ecol[3].ec_value.ec_value_len = strlen(t)+1;
2613 } else {
2614 ecol[3].ec_value.ec_value_val = "";
2615 ecol[3].ec_value.ec_value_len = 0;
2618 ecol[1].ec_value.ec_value_val = NULL;
2619 ecol[2].ec_value.ec_value_val = NULL;
2621 /* cname (col 0) */
2622 if ((t = strtok(buf, " \t")) == 0) {
2623 (void) strlcpy(parse_err_msg, gettext("no cname"),
2624 PARSE_ERR_MSG_LEN);
2625 return (GENENT_PARSEERR);
2628 ecol[0].ec_value.ec_value_val = t;
2629 ecol[0].ec_value.ec_value_len = strlen(t)+1;
2630 cname = t;
2632 /* addr(col 1 and 2) */
2633 if ((t = strtok(NULL, " \t")) == 0) {
2634 (void) strlcpy(parse_err_msg,
2635 gettext("no members for netgroup"), PARSE_ERR_MSG_LEN);
2636 return (GENENT_PARSEERR);
2639 if (*t == '(') {
2640 /* if token starts with '(' it must be a valid triplet */
2641 if (is_triplet(t)) {
2642 ecol[1].ec_value.ec_value_val = t;
2643 ecol[1].ec_value.ec_value_len = strlen(t)+1;
2644 } else {
2645 (void) strlcpy(parse_err_msg,
2646 gettext("invalid triplet"), PARSE_ERR_MSG_LEN);
2647 return (GENENT_PARSEERR);
2649 } else {
2650 ecol[2].ec_value.ec_value_val = t;
2651 ecol[2].ec_value.ec_value_len = strlen(t)+1;
2655 * now build entry.
2656 * start by clearing entry data
2658 (void) memset((struct _ns_netgroups *)&data, 0, sizeof (data));
2660 data.name = strdup(ecol[0].ec_value.ec_value_val);
2662 if (ecol[1].ec_value.ec_value_val != NULL) {
2663 if ((data.triplet = calloc(1, sizeof (char **))) == NULL) {
2664 (void) fprintf(stderr,
2665 gettext("out of memory\n"));
2666 exit(1);
2668 data.triplet[tripletcount++] =
2669 strdup(ecol[1].ec_value.ec_value_val);
2670 } else if (ecol[2].ec_value.ec_value_val != NULL) {
2671 if ((data.netgroup = calloc(1, sizeof (char **)))
2672 == NULL) {
2673 (void) fprintf(stderr,
2674 gettext("out of memory\n"));
2675 exit(1);
2677 data.netgroup[netgcount++] =
2678 strdup(ecol[2].ec_value.ec_value_val);
2682 * we now have a valid entry (at least 1 netgroup name and
2683 * 1 netgroup member), proceed with the rest of the line
2685 while (rc == GENENT_OK && (t = strtok(NULL, " \t"))) {
2687 /* if next token is equal to netgroup name, ignore */
2688 if (t != cname && strcasecmp(t, cname) == 0)
2689 continue;
2690 if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
2691 continue;
2693 if (*t == '(') {
2694 if (is_triplet(t)) {
2695 /* skip a triplet if it is added already */
2696 for (i = 0; i < tripletcount &&
2697 strcmp(t, data.triplet[i]); i++)
2699 if (i < tripletcount)
2700 continue;
2702 tripletcount++;
2703 triplet_tmp = strdup(t);
2704 if ((data.triplet = reallocarray(data.triplet,
2705 tripletcount, sizeof (char **))) == NULL) {
2706 (void) fprintf(stderr,
2707 gettext("out of memory\n"));
2708 exit(1);
2710 data.triplet[tripletcount-1] = triplet_tmp;
2711 } else {
2712 (void) strlcpy(parse_err_msg,
2713 gettext("invalid triplet"),
2714 PARSE_ERR_MSG_LEN);
2715 rc = GENENT_PARSEERR;
2717 } else {
2718 /* skip a netgroup if it is added already */
2719 for (i = 0; i < netgcount &&
2720 strcmp(t, data.netgroup[i]); i++)
2722 if (i < netgcount)
2723 continue;
2725 netgcount++;
2726 netg_tmp = strdup(t);
2727 if ((data.netgroup = reallocarray(data.netgroup,
2728 netgcount, sizeof (char **))) == NULL) {
2729 (void) fprintf(stderr,
2730 gettext("out of memory\n"));
2731 exit(1);
2733 data.netgroup[netgcount-1] = netg_tmp;
2737 /* End the list with NULL */
2738 if ((data.triplet = reallocarray(data.triplet, tripletcount + 1,
2739 sizeof (char **))) == NULL) {
2740 (void) fprintf(stderr, gettext("out of memory\n"));
2741 exit(1);
2743 data.triplet[tripletcount] = NULL;
2744 if ((data.netgroup = reallocarray(data.netgroup, netgcount + 1,
2745 sizeof (char **))) == NULL) {
2746 (void) fprintf(stderr, gettext("out of memory\n"));
2747 exit(1);
2749 data.netgroup[netgcount] = NULL;
2751 if (rc == GENENT_OK) {
2752 if (flags & F_VERBOSE)
2753 (void) fprintf(stdout,
2754 gettext("Adding entry : %s\n"), data.name);
2756 retval = (*cback)(&data, 0);
2758 if (retval == LDAP_ALREADY_EXISTS) {
2759 if (continue_onerror)
2760 (void) fprintf(stderr, gettext(
2761 "Entry: %s - already Exists,"
2762 " skipping it.\n"), data.name);
2763 else {
2764 rc = GENENT_CBERR;
2765 (void) fprintf(stderr,
2766 gettext("Entry: %s - already Exists\n"),
2767 data.name);
2769 } else if (retval)
2770 rc = GENENT_CBERR;
2773 /* release memory allocated by strdup() */
2774 for (i = 0; i < tripletcount; i++) {
2775 free(data.triplet[i]);
2777 for (i = 0; i < netgcount; i++) {
2778 free(data.netgroup[i]);
2781 free(data.name);
2782 free(data.triplet);
2783 free(data.netgroup);
2785 return (rc);
2788 static void
2789 dump_netgroup(ns_ldap_result_t *res)
2791 char **value = NULL;
2792 int attr_count = 0;
2794 value = __ns_ldap_getAttr(res->entry, "cn");
2795 if ((value != NULL) && (value[0] != NULL))
2796 (void) fprintf(stdout, "%s", value[0]);
2797 else
2798 return;
2799 value = __ns_ldap_getAttr(res->entry, "nisNetgroupTriple");
2800 if (value != NULL)
2801 while (value[attr_count] != NULL) {
2802 (void) fprintf(stdout, " %s", value[attr_count]);
2803 attr_count++;
2805 attr_count = 0;
2806 value = __ns_ldap_getAttr(res->entry, "memberNisNetgroup");
2807 if (value != NULL)
2808 while (value[attr_count] != NULL) {
2809 (void) fprintf(stdout, " %s", value[attr_count]);
2810 attr_count++;
2812 (void) fprintf(stdout, "\n");
2816 static int
2817 genent_automount(char *line, int (*cback)())
2819 char buf[BUFSIZ+1];
2820 char *t, *s;
2821 entry_col ecol[2];
2822 struct _ns_automount data;
2823 int retval = 1;
2824 int rc = GENENT_OK;
2827 * don't clobber our argument
2829 if (strlen(line) >= sizeof (buf)) {
2830 (void) strlcpy(parse_err_msg, gettext("line too long"),
2831 PARSE_ERR_MSG_LEN);
2832 return (GENENT_PARSEERR);
2835 /* replace every tabspace with single space */
2836 replace_tab2space(line);
2837 (void) strcpy(buf, line);
2840 * clear column data
2842 (void) memset((char *)ecol, 0, sizeof (ecol));
2845 * key (col 0)
2847 t = buf;
2848 while (t[0] == ' ')
2849 t++;
2851 if ((s = strchr(t, ' ')) == 0) {
2852 return (GENENT_PARSEERR);
2854 *s++ = 0;
2856 ecol[0].ec_value.ec_value_val = t;
2857 ecol[0].ec_value.ec_value_len = strlen(t)+1;
2858 t = s;
2860 while (t[0] == ' ')
2861 t++;
2864 * mapentry (col 1)
2867 ecol[1].ec_value.ec_value_val = t;
2868 ecol[1].ec_value.ec_value_len = strlen(t)+1;
2870 data.mapname = strdup(databasetype);
2871 data.key = strdup(ecol[0].ec_value.ec_value_val);
2872 data.value = strdup(ecol[1].ec_value.ec_value_val);
2874 if (flags & F_VERBOSE)
2875 (void) fprintf(stdout,
2876 gettext("Adding entry : %s\n"), data.key);
2878 retval = (*cback)(&data, 0);
2880 if (retval == LDAP_ALREADY_EXISTS) {
2881 if (continue_onerror)
2882 (void) fprintf(stderr,
2883 gettext("Entry: %s - already Exists,"
2884 " skipping it.\n"), data.key);
2885 else {
2886 rc = GENENT_CBERR;
2887 (void) fprintf(stderr,
2888 gettext("Entry: %s - already Exists\n"),
2889 data.key);
2891 } else if (retval)
2892 rc = GENENT_CBERR;
2894 free(data.mapname);
2895 free(data.key);
2896 free(data.value);
2897 return (rc);
2900 static void
2901 dump_automount(ns_ldap_result_t *res)
2903 char **value = NULL;
2905 if (res == NULL)
2906 return;
2908 value = __ns_ldap_getAttr(res->entry, "automountKey");
2909 if (value != NULL) {
2910 (void) fprintf(stdout, "%s", value[0]);
2911 value = __ns_ldap_getAttr(res->entry, "automountInformation");
2912 if (value != NULL)
2913 (void) fprintf(stdout, " %s\n", value[0]);
2914 else
2915 (void) fprintf(stdout, "\n");
2921 * /etc/passwd
2925 static int
2926 genent_passwd(char *line, int (*cback)())
2928 char buf[BUFSIZ+1];
2929 char *s, *t;
2930 entry_col ecol[8];
2931 int retval = 1;
2932 char pname[BUFSIZ];
2934 struct passwd data;
2935 int rc = GENENT_OK;
2939 * don't clobber our argument
2941 if (strlen(line) >= sizeof (buf)) {
2942 (void) strlcpy(parse_err_msg, gettext("line too long"),
2943 PARSE_ERR_MSG_LEN);
2944 return (GENENT_PARSEERR);
2946 (void) strcpy(buf, line);
2947 t = buf;
2949 /* ignore empty entries */
2950 if (*t == '\0')
2951 return (GENENT_OK);
2954 * clear column data
2956 (void) memset((char *)ecol, 0, sizeof (ecol));
2959 * name (col 0)
2961 if ((s = strchr(t, ':')) == 0) {
2962 (void) strlcpy(parse_err_msg, gettext("no password"),
2963 PARSE_ERR_MSG_LEN);
2964 return (GENENT_PARSEERR);
2966 *s++ = 0;
2967 ecol[0].ec_value.ec_value_val = t;
2968 ecol[0].ec_value.ec_value_len = strlen(t)+1;
2969 t = s;
2972 * passwd (col 1)
2974 if ((s = strchr(t, ':')) == 0) {
2975 (void) strlcpy(parse_err_msg, gettext("no uid"),
2976 PARSE_ERR_MSG_LEN);
2977 return (GENENT_PARSEERR);
2979 *s++ = 0;
2981 ecol[1].ec_value.ec_value_val = t;
2982 ecol[1].ec_value.ec_value_len = strlen(t)+1;
2984 t = s;
2987 * uid (col 2)
2989 if ((s = strchr(t, ':')) == 0 || s == t) {
2990 (void) strlcpy(parse_err_msg, gettext("no gid"),
2991 PARSE_ERR_MSG_LEN);
2992 return (GENENT_PARSEERR);
2994 *s++ = 0;
2995 ecol[2].ec_value.ec_value_val = t;
2996 ecol[2].ec_value.ec_value_len = strlen(t)+1;
2997 t = s;
3000 * gid (col 3)
3002 if ((s = strchr(t, ':')) == 0 || s == t) {
3003 (void) strlcpy(parse_err_msg, gettext("no gcos"),
3004 PARSE_ERR_MSG_LEN);
3005 return (GENENT_PARSEERR);
3007 *s++ = 0;
3008 ecol[3].ec_value.ec_value_val = t;
3009 ecol[3].ec_value.ec_value_len = strlen(t)+1;
3010 t = s;
3013 * gcos (col 4)
3015 if ((s = strchr(t, ':')) == 0) {
3016 (void) strlcpy(parse_err_msg, gettext("no home"),
3017 PARSE_ERR_MSG_LEN);
3018 return (GENENT_PARSEERR);
3020 *s++ = 0;
3021 ecol[4].ec_value.ec_value_val = t;
3022 ecol[4].ec_value.ec_value_len = strlen(t)+1;
3023 t = s;
3026 * home (col 5)
3028 if ((s = strchr(t, ':')) == 0) {
3029 (void) strlcpy(parse_err_msg, gettext("no shell"),
3030 PARSE_ERR_MSG_LEN);
3031 return (GENENT_PARSEERR);
3033 *s++ = 0;
3034 ecol[5].ec_value.ec_value_val = t;
3035 ecol[5].ec_value.ec_value_len = strlen(t)+1;
3036 t = s;
3039 * shell (col 6)
3041 ecol[6].ec_value.ec_value_val = t;
3042 ecol[6].ec_value.ec_value_len = strlen(t)+1;
3045 * build entry
3047 data.pw_name = strdup(ecol[0].ec_value.ec_value_val);
3049 if (flags & F_PASSWD) {
3050 /* Add {crypt} before passwd entry */
3051 (void) snprintf(pname, sizeof (pname), "{crypt}%s",
3052 ecol[1].ec_value.ec_value_val);
3053 data.pw_passwd = strdup(pname);
3055 else
3056 data.pw_passwd = NULL;
3058 if (ecol[2].ec_value.ec_value_val != NULL &&
3059 ecol[2].ec_value.ec_value_val[0] != '\0') {
3060 data.pw_uid = ascii_to_int(ecol[2].ec_value.ec_value_val);
3061 if (data.pw_uid == (uid_t)-1) {
3062 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3063 gettext("invalid uid : %s"),
3064 ecol[2].ec_value.ec_value_val);
3065 return (GENENT_PARSEERR);
3067 } else
3068 data.pw_uid = (uid_t)-1;
3070 if (ecol[3].ec_value.ec_value_val != NULL &&
3071 ecol[3].ec_value.ec_value_val[0] != '\0') {
3073 data.pw_gid = ascii_to_int(ecol[3].ec_value.ec_value_val);
3074 if (data.pw_gid == (uid_t)-1) {
3075 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3076 gettext("invalid gid : %s"),
3077 ecol[3].ec_value.ec_value_val);
3078 return (GENENT_PARSEERR);
3080 } else
3081 data.pw_gid = (uid_t)-1;
3083 data.pw_age = NULL;
3084 data.pw_comment = NULL;
3085 data.pw_gecos = strdup(ecol[4].ec_value.ec_value_val);
3086 data.pw_dir = strdup(ecol[5].ec_value.ec_value_val);
3087 data.pw_shell = strdup(ecol[6].ec_value.ec_value_val);
3089 if (flags & F_VERBOSE)
3090 (void) fprintf(stdout,
3091 gettext("Adding entry : %s\n"), data.pw_name);
3093 retval = (*cback)(&data, 0);
3095 if (retval == LDAP_ALREADY_EXISTS) {
3096 if (continue_onerror)
3097 (void) fprintf(stderr,
3098 gettext("Entry: %s - already Exists,"
3099 " skipping it.\n"), data.pw_name);
3100 else {
3101 rc = GENENT_CBERR;
3102 (void) fprintf(stderr,
3103 gettext("Entry: %s - already Exists\n"),
3104 data.pw_name);
3106 } else if (retval)
3107 rc = GENENT_CBERR;
3109 free(data.pw_name);
3110 free(data.pw_gecos);
3111 free(data.pw_dir);
3112 free(data.pw_shell);
3113 return (rc);
3117 static void
3118 dump_passwd(ns_ldap_result_t *res)
3120 char **value = NULL;
3122 value = __ns_ldap_getAttr(res->entry, "uid");
3123 if (value == NULL)
3124 return;
3125 else
3126 (void) fprintf(stdout, "%s:", value[0]);
3127 value = __ns_ldap_getAttr(res->entry, "userPassword");
3130 * Don't print the encrypted password, Use x to
3131 * indicate it is in the shadow database.
3133 (void) fprintf(stdout, "x:");
3135 value = __ns_ldap_getAttr(res->entry, "uidNumber");
3136 if (value && value[0])
3137 (void) fprintf(stdout, "%s:", value[0]);
3138 value = __ns_ldap_getAttr(res->entry, "gidNumber");
3139 if (value && value[0])
3140 (void) fprintf(stdout, "%s:", value[0]);
3141 value = __ns_ldap_getAttr(res->entry, "gecos");
3142 if (value == NULL)
3143 (void) fprintf(stdout, ":");
3144 else
3145 (void) fprintf(stdout, "%s:", value[0]);
3146 value = __ns_ldap_getAttr(res->entry, "homeDirectory");
3147 if (value == NULL)
3148 (void) fprintf(stdout, ":");
3149 else
3150 (void) fprintf(stdout, "%s:", value[0]);
3151 value = __ns_ldap_getAttr(res->entry, "loginShell");
3152 if (value == NULL)
3153 (void) fprintf(stdout, "\n");
3154 else
3155 (void) fprintf(stdout, "%s\n", value[0]);
3160 * /etc/shadow
3163 static int
3164 genent_shadow(char *line, int (*cback)())
3166 char buf[BUFSIZ+1];
3167 char *s, *t;
3168 entry_col ecol[9];
3169 char pname[BUFSIZ];
3171 struct spwd data;
3172 int spflag;
3173 int retval;
3177 * don't clobber our argument
3179 if (strlen(line) >= sizeof (buf)) {
3180 (void) strlcpy(parse_err_msg, gettext("line too long"),
3181 PARSE_ERR_MSG_LEN);
3182 return (GENENT_PARSEERR);
3184 (void) strcpy(buf, line);
3185 t = buf;
3187 /* ignore empty entries */
3188 if (*t == '\0')
3189 return (GENENT_OK);
3192 * clear column data
3194 (void) memset((char *)ecol, 0, sizeof (ecol));
3197 * name (col 0)
3199 if ((s = strchr(t, ':')) == 0) {
3200 (void) strlcpy(parse_err_msg, gettext("no uid"),
3201 PARSE_ERR_MSG_LEN);
3202 return (GENENT_PARSEERR);
3204 *s++ = 0;
3205 ecol[0].ec_value.ec_value_val = t;
3206 ecol[0].ec_value.ec_value_len = strlen(t)+1;
3207 t = s;
3210 * passwd (col 1)
3212 if ((s = strchr(t, ':')) == 0) {
3213 (void) strlcpy(parse_err_msg, gettext("Improper format"),
3214 PARSE_ERR_MSG_LEN);
3215 return (GENENT_PARSEERR);
3217 *s++ = 0;
3219 ecol[1].ec_value.ec_value_val = t;
3220 ecol[1].ec_value.ec_value_len = strlen(t)+1;
3222 t = s;
3225 * shadow last change (col 2)
3227 if ((s = strchr(t, ':')) == 0) {
3228 (void) strlcpy(parse_err_msg, gettext("Improper format"),
3229 PARSE_ERR_MSG_LEN);
3230 return (GENENT_PARSEERR);
3232 *s++ = 0;
3233 ecol[2].ec_value.ec_value_val = t;
3234 ecol[2].ec_value.ec_value_len = strlen(t)+1;
3235 t = s;
3238 * shadow min (col 3)
3240 if ((s = strchr(t, ':')) == 0) {
3241 (void) strlcpy(parse_err_msg, gettext("Improper format"),
3242 PARSE_ERR_MSG_LEN);
3243 return (GENENT_PARSEERR);
3245 *s++ = 0;
3246 ecol[3].ec_value.ec_value_val = t;
3247 ecol[3].ec_value.ec_value_len = strlen(t)+1;
3248 t = s;
3251 * shadow max (col 4)
3253 if ((s = strchr(t, ':')) == 0) {
3254 (void) strlcpy(parse_err_msg, gettext("Improper format"),
3255 PARSE_ERR_MSG_LEN);
3256 return (GENENT_PARSEERR);
3258 *s++ = 0;
3259 ecol[4].ec_value.ec_value_val = t;
3260 ecol[4].ec_value.ec_value_len = strlen(t)+1;
3261 t = s;
3264 * shadow warn (col 5)
3266 if ((s = strchr(t, ':')) == 0) {
3267 (void) strlcpy(parse_err_msg, gettext("Improper format"),
3268 PARSE_ERR_MSG_LEN);
3269 return (GENENT_PARSEERR);
3271 *s++ = 0;
3272 ecol[5].ec_value.ec_value_val = t;
3273 ecol[5].ec_value.ec_value_len = strlen(t)+1;
3274 t = s;
3277 * shadow inactive (col 6)
3279 if ((s = strchr(t, ':')) != 0) {
3280 *s++ = 0;
3281 ecol[6].ec_value.ec_value_val = t;
3282 ecol[6].ec_value.ec_value_len = strlen(t)+1;
3283 t = s;
3287 * shadow expire (col 7)
3289 if ((s = strchr(t, ':')) != 0) {
3290 *s++ = 0;
3291 ecol[7].ec_value.ec_value_val = t;
3292 ecol[7].ec_value.ec_value_len = strlen(t)+1;
3293 t = s;
3296 * flag (col 8)
3298 ecol[8].ec_value.ec_value_val = t;
3299 ecol[8].ec_value.ec_value_len = strlen(t)+1;
3303 * build entry
3306 data.sp_namp = strdup(ecol[0].ec_value.ec_value_val);
3308 if (ecol[1].ec_value.ec_value_val != NULL &&
3309 ecol[1].ec_value.ec_value_val[0] != '\0') {
3310 /* Add {crypt} before passwd entry */
3311 (void) snprintf(pname, sizeof (pname), "{crypt}%s",
3312 ecol[1].ec_value.ec_value_val);
3313 data.sp_pwdp = strdup(pname);
3314 } else {
3316 * no password (e.g., deleted by "passwd -d"):
3317 * use the special value NS_LDAP_NO_UNIX_PASSWORD
3318 * instead.
3320 (void) snprintf(pname, sizeof (pname), "{crypt}%s",
3321 NS_LDAP_NO_UNIX_PASSWORD);
3322 data.sp_pwdp = strdup(pname);
3325 if (ecol[2].ec_value.ec_value_val != NULL &&
3326 ecol[2].ec_value.ec_value_val[0] != '\0') {
3328 data.sp_lstchg = ascii_to_int(ecol[2].ec_value.ec_value_val);
3329 if (data.sp_lstchg < -1) {
3330 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3331 gettext("invalid last changed date: %s"),
3332 ecol[2].ec_value.ec_value_val);
3333 return (GENENT_PARSEERR);
3335 } else
3336 data.sp_lstchg = -1;
3338 if (ecol[3].ec_value.ec_value_val != NULL &&
3339 ecol[3].ec_value.ec_value_val[0] != '\0') {
3341 data.sp_min = ascii_to_int(ecol[3].ec_value.ec_value_val);
3342 if (data.sp_min < -1) {
3343 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3344 gettext("invalid sp_min : %s"),
3345 ecol[3].ec_value.ec_value_val);
3346 return (GENENT_PARSEERR);
3348 } else
3349 data.sp_min = -1;
3351 if (ecol[4].ec_value.ec_value_val != NULL &&
3352 ecol[4].ec_value.ec_value_val[0] != '\0') {
3354 data.sp_max = ascii_to_int(ecol[4].ec_value.ec_value_val);
3355 if (data.sp_max < -1) {
3356 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3357 gettext("invalid sp_max : %s"),
3358 ecol[4].ec_value.ec_value_val);
3359 return (GENENT_PARSEERR);
3361 } else
3362 data.sp_max = -1;
3364 if (ecol[5].ec_value.ec_value_val != NULL &&
3365 ecol[5].ec_value.ec_value_val[0] != '\0') {
3367 data.sp_warn = ascii_to_int(ecol[5].ec_value.ec_value_val);
3368 if (data.sp_warn < -1) {
3369 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3370 gettext("invalid sp_warn : %s"),
3371 ecol[5].ec_value.ec_value_val);
3372 return (GENENT_PARSEERR);
3374 } else
3375 data.sp_warn = -1;
3377 if (ecol[6].ec_value.ec_value_val != NULL &&
3378 ecol[6].ec_value.ec_value_val[0] != '\0') {
3380 data.sp_inact = ascii_to_int(ecol[6].ec_value.ec_value_val);
3381 if (data.sp_inact < -1) {
3382 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3383 gettext("invalid sp_inact : %s"),
3384 ecol[6].ec_value.ec_value_val);
3385 return (GENENT_PARSEERR);
3387 } else
3388 data.sp_inact = -1;
3390 if (ecol[7].ec_value.ec_value_val != NULL &&
3391 ecol[7].ec_value.ec_value_val[0] != '\0') {
3393 data.sp_expire = ascii_to_int(ecol[7].ec_value.ec_value_val);
3394 if (data.sp_expire < -1) {
3395 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3396 gettext("invalid login expiry date : %s"),
3397 ecol[7].ec_value.ec_value_val);
3398 return (GENENT_PARSEERR);
3400 } else
3401 data.sp_expire = -1;
3403 if (ecol[8].ec_value.ec_value_val != NULL &&
3404 ecol[8].ec_value.ec_value_val[0] != '\0') {
3407 * data.sp_flag is an unsigned int,
3408 * assign -1 to it, make no sense.
3409 * Use spflag here to avoid lint warning.
3411 spflag = ascii_to_int(ecol[8].ec_value.ec_value_val);
3412 if (spflag < 0) {
3413 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3414 gettext("invalid flag value: %s"),
3415 ecol[8].ec_value.ec_value_val);
3416 return (GENENT_PARSEERR);
3417 } else
3418 data.sp_flag = spflag;
3419 } else
3420 data.sp_flag = 0;
3422 if (flags & F_VERBOSE)
3423 (void) fprintf(stdout,
3424 gettext("Adding entry : %s\n"), data.sp_namp);
3426 retval = (*cback)(&data, 1);
3427 if (retval != NS_LDAP_SUCCESS) {
3428 if (retval == LDAP_NO_SUCH_OBJECT)
3429 (void) fprintf(stdout,
3430 gettext("Cannot add shadow entry (%s), "
3431 "add passwd entry first\n"), data.sp_namp);
3432 if (continue_onerror == 0)
3433 return (GENENT_CBERR);
3436 free(data.sp_namp);
3437 free(data.sp_pwdp);
3438 return (GENENT_OK);
3441 static void
3442 dump_shadow(ns_ldap_result_t *res)
3444 char **value = NULL;
3445 char pnam[256];
3447 value = __ns_ldap_getAttr(res->entry, "uid");
3448 if (value == NULL)
3449 return;
3450 else
3451 (void) fprintf(stdout, "%s:", value[0]);
3452 value = __ns_ldap_getAttr(res->entry, "userPassword");
3453 if (value == NULL)
3454 (void) fprintf(stdout, "*:");
3455 else {
3456 (void) strcpy(pnam, value[0]);
3457 if (strncasecmp(value[0], "{crypt}", 7) == 0) {
3458 if (strcmp(pnam + 7, NS_LDAP_NO_UNIX_PASSWORD) == 0)
3459 (void) fprintf(stdout, ":");
3460 else
3461 (void) fprintf(stdout, "%s:", (pnam+7));
3462 } else
3463 (void) fprintf(stdout, "*:");
3465 value = __ns_ldap_getAttr(res->entry, "shadowLastChange");
3466 if (value == NULL)
3467 (void) fprintf(stdout, ":");
3468 else
3469 (void) fprintf(stdout, "%s:", value[0]);
3470 value = __ns_ldap_getAttr(res->entry, "shadowMin");
3471 if (value == NULL)
3472 (void) fprintf(stdout, ":");
3473 else
3474 (void) fprintf(stdout, "%s:", value[0]);
3475 value = __ns_ldap_getAttr(res->entry, "shadowMax");
3476 if (value == NULL)
3477 (void) fprintf(stdout, ":");
3478 else
3479 (void) fprintf(stdout, "%s:", value[0]);
3481 value = __ns_ldap_getAttr(res->entry, "shadowWarning");
3482 if (value == NULL)
3483 (void) fprintf(stdout, ":");
3484 else
3485 (void) fprintf(stdout, "%s:", value[0]);
3487 value = __ns_ldap_getAttr(res->entry, "shadowInactive");
3488 if (value == NULL)
3489 (void) fprintf(stdout, ":");
3490 else
3491 (void) fprintf(stdout, "%s:", value[0]);
3493 value = __ns_ldap_getAttr(res->entry, "shadowExpire");
3494 if (value == NULL)
3495 (void) fprintf(stdout, ":");
3496 else
3497 (void) fprintf(stdout, "%s:", value[0]);
3499 value = __ns_ldap_getAttr(res->entry, "shadowFlag");
3500 if (value == NULL || value[0] == NULL || strcmp(value[0], "0") == 0)
3501 (void) fprintf(stdout, "\n");
3502 else
3503 (void) fprintf(stdout, "%s\n", value[0]);
3506 static int
3507 genent_bootparams(char *line, int (*cback)())
3509 char buf[BUFSIZ+1];
3510 char *t;
3511 entry_col ecol[2];
3512 int ctr = 0, retval = 1;
3514 struct _ns_bootp data;
3515 char *parameter;
3516 int rc = GENENT_OK;
3519 * don't clobber our argument
3521 if (strlen(line) >= sizeof (buf)) {
3522 (void) strlcpy(parse_err_msg, gettext("line too long"),
3523 PARSE_ERR_MSG_LEN);
3524 return (GENENT_PARSEERR);
3526 (void) strcpy(buf, line);
3529 * clear column data
3531 (void) memset((char *)ecol, 0, sizeof (ecol));
3535 * cname (col 0)
3537 if ((t = strtok(buf, " \t")) == 0) {
3538 (void) strlcpy(parse_err_msg, gettext("no cname"),
3539 PARSE_ERR_MSG_LEN);
3540 return (GENENT_PARSEERR);
3542 ecol[0].ec_value.ec_value_val = t;
3543 ecol[0].ec_value.ec_value_len = strlen(t)+1;
3547 /* build entry */
3548 data.name = strdup(ecol[0].ec_value.ec_value_val);
3551 * name (col 1)
3554 data.param = NULL;
3556 while (t = strtok(NULL, " \t")) {
3559 * don't clobber comment in canonical entry
3563 ecol[1].ec_value.ec_value_val = t;
3564 ecol[1].ec_value.ec_value_len = strlen(t)+1;
3566 ctr++;
3567 parameter = strdup(ecol[1].ec_value.ec_value_val);
3568 if ((data.param = reallocarray(data.param, ctr + 1,
3569 sizeof (char **))) == NULL) {
3570 (void) fprintf(stderr, gettext("out of memory\n"));
3571 exit(1);
3573 data.param[ctr-1] = parameter;
3578 /* End the list of all the aliases by NULL */
3579 if ((data.param = reallocarray(data.param, ctr + 1, sizeof(char **))) ==
3580 NULL) {
3581 (void) fprintf(stderr, gettext("out of memory\n"));
3582 exit(1);
3584 data.param[ctr] = NULL;
3586 if (flags & F_VERBOSE)
3587 (void) fprintf(stdout,
3588 gettext("Adding entry : %s\n"), data.name);
3590 retval = (*cback)(&data, 0);
3592 if (retval == LDAP_ALREADY_EXISTS) {
3593 if (continue_onerror)
3594 (void) fprintf(stderr,
3595 gettext("Entry: %s - already Exists,"
3596 " skipping it.\n"), data.name);
3597 else {
3598 rc = GENENT_CBERR;
3599 (void) fprintf(stderr,
3600 gettext("Entry: %s - already Exists\n"),
3601 data.name);
3603 } else if (retval)
3604 rc = GENENT_CBERR;
3606 free(data.name);
3607 free(data.param);
3609 return (rc);
3614 * Count number of tokens in string which has tokens separated by colons.
3616 * NULL or "" - 0 tokens
3617 * "foo" - 1 token
3618 * "foo:bar" - 2 tokens
3619 * ":bar" - 2 tokens, first empty
3620 * "::" - 3 tokens, all empty
3622 static int
3623 count_tokens(char *string, char delim)
3625 int i = 0;
3626 char *s = string;
3628 if (string == NULL || *string == '\0')
3629 return (0);
3631 /* Count delimiters */
3632 while ((s = strchr(s, delim)) != NULL && *s != '\0') {
3633 i++;
3634 s++;
3637 return (i + 1);
3640 static int
3641 genent_project(char *line, int (*cback)())
3643 char buf[BUFSIZ+1];
3644 char *b = buf;
3645 char *s;
3646 int rc = GENENT_OK, retval;
3647 int index = 0;
3648 struct project data;
3650 (void) memset(&data, 0, sizeof (struct project));
3653 * don't clobber our argument
3655 if (strlen(line) >= sizeof (buf)) {
3656 (void) strlcpy(parse_err_msg, gettext("line too long"),
3657 PARSE_ERR_MSG_LEN);
3658 return (GENENT_PARSEERR);
3661 if (count_tokens(line, ':') != 6) {
3662 (void) strlcpy(parse_err_msg, gettext("Improper format"),
3663 PARSE_ERR_MSG_LEN);
3664 return (GENENT_PARSEERR);
3667 (void) strcpy(buf, line);
3669 s = strsep(&b, ":");
3670 while (s != NULL) {
3671 switch (index) {
3672 /* Project name */
3673 case 0:
3674 if (check_projname(s) != 0) {
3675 (void) strlcpy(parse_err_msg,
3676 gettext("invalid project name"),
3677 PARSE_ERR_MSG_LEN);
3678 return (GENENT_PARSEERR);
3679 } else {
3680 data.pj_name = strdup(s);
3682 break;
3684 /* Project ID */
3685 case 1:
3687 char *endptr = NULL;
3688 int projid = strtoul(s, &endptr, 10);
3690 if (*s == '\0' || strlen(endptr) != 0 || projid < 0 ||
3691 projid > MAXPROJID) {
3692 (void) strlcpy(parse_err_msg,
3693 gettext("invalid project id"),
3694 PARSE_ERR_MSG_LEN);
3695 return (GENENT_PARSEERR);
3696 } else {
3697 data.pj_projid = projid;
3699 break;
3702 /* Project description */
3703 case 2:
3704 if (*s != '\0')
3705 data.pj_comment = strdup(s);
3706 break;
3708 /* Project users */
3709 case 3:
3711 if (*s == '\0')
3712 break;
3714 char *usrlist = strdup(s);
3715 int i = 0;
3716 int usr_count = count_tokens(usrlist, ',');
3717 char *u = strsep(&usrlist, ",");
3719 if (usr_count == 0) {
3720 free(usrlist);
3721 break;
3724 /* +1 to NULL-terminate the array */
3725 data.pj_users = (char **)calloc(usr_count + 1,
3726 sizeof (char *));
3728 while (u != NULL) {
3729 data.pj_users[i++] = strdup(u);
3730 u = strsep(&usrlist, ",");
3733 free(usrlist);
3734 break;
3737 /* Project groups */
3738 case 4:
3740 if (*s == '\0')
3741 break;
3743 char *grouplist = strdup(s);
3744 int i = 0;
3745 int grp_count = count_tokens(grouplist, ',');
3746 char *g = strsep(&grouplist, ",");
3748 if (grp_count == 0) {
3749 free(grouplist);
3750 break;
3753 /* +1 to NULL-terminate the array */
3754 data.pj_groups = (char **)calloc(grp_count + 1,
3755 sizeof (char *));
3757 while (g != NULL) {
3758 data.pj_groups[i++] = strdup(g);
3759 g = strsep(&grouplist, ",");
3762 free(grouplist);
3763 break;
3766 /* Attributes */
3767 case 5:
3768 if (*s != '\0')
3769 data.pj_attr = strdup(s);
3771 break;
3774 /* Next token */
3775 s = strsep(&b, ":");
3776 index++;
3779 if (flags & F_VERBOSE)
3780 (void) fprintf(stdout,
3781 gettext("Adding entry : %s\n"), data.pj_name);
3783 retval = (*cback)(&data, 0);
3785 if (retval == LDAP_ALREADY_EXISTS) {
3786 if (continue_onerror)
3787 (void) fprintf(stderr,
3788 gettext("Entry: %s - already Exists,"
3789 " skipping it.\n"), data.pj_name);
3790 else {
3791 rc = GENENT_CBERR;
3792 (void) fprintf(stderr,
3793 gettext("Entry: %s - already Exists\n"),
3794 data.pj_name);
3796 } else if (retval)
3797 rc = GENENT_CBERR;
3799 /* Clean up */
3800 free(data.pj_name);
3801 free(data.pj_attr);
3802 if (data.pj_users != NULL) {
3803 for (index = 0; data.pj_users[index] != NULL; index++)
3804 free(data.pj_users[index]);
3805 free(data.pj_users);
3807 if (data.pj_groups != NULL) {
3808 for (index = 0; data.pj_groups[index] != NULL; index++)
3809 free(data.pj_groups[index]);
3810 free(data.pj_groups);
3813 return (rc);
3816 static void
3817 dump_project(ns_ldap_result_t *res)
3819 char **value = NULL;
3820 char *endptr = NULL;
3821 int projid;
3823 if (res == NULL || res->entry == NULL)
3824 return;
3826 /* Sanity checking */
3827 value = __ns_ldap_getAttr(res->entry, "SolarisProjectID");
3829 if (value[0] == NULL)
3830 return;
3832 projid = strtoul(value[0], &endptr, 10);
3833 if (*value[0] == '\0' || strlen(endptr) != 0 || projid < 0 ||
3834 projid > MAXPROJID)
3835 return;
3837 value = __ns_ldap_getAttr(res->entry, "SolarisProjectName");
3838 if (value && value[0] && check_projname(value[0]) == 0)
3839 (void) fprintf(stdout, "%s:", value[0]);
3840 else
3841 return;
3843 (void) fprintf(stdout, "%d:", projid);
3845 value = __ns_ldap_getAttr(res->entry, "description");
3846 if (value && value[0])
3847 (void) fprintf(stdout, "%s:", value[0]);
3848 else
3849 (void) fprintf(stdout, ":");
3851 value = __ns_ldap_getAttr(res->entry, "memberUid");
3852 if (value) {
3853 int i;
3854 for (i = 0; value[i] != NULL; i++)
3855 if (value[i+1] != NULL)
3856 (void) fprintf(stdout, "%s,", value[i]);
3857 else
3858 (void) fprintf(stdout, "%s:", value[i]);
3859 } else {
3860 (void) fprintf(stdout, ":");
3863 value = __ns_ldap_getAttr(res->entry, "memberGid");
3864 if (value) {
3865 int i;
3866 for (i = 0; value[i] != NULL; i++)
3867 if (value[i+1] != NULL)
3868 (void) fprintf(stdout, "%s,", value[i]);
3869 else
3870 (void) fprintf(stdout, "%s:", value[i]);
3871 } else {
3872 (void) fprintf(stdout, ":");
3875 value = __ns_ldap_getAttr(res->entry, "SolarisProjectAttr");
3876 if (value && value[0])
3877 (void) fprintf(stdout, "%s\n", value[0]);
3878 else
3879 (void) fprintf(stdout, "\n");
3883 static void
3884 dump_bootparams(ns_ldap_result_t *res)
3886 char **value = NULL;
3887 int attr_count = 0;
3889 value = __ns_ldap_getAttr(res->entry, "cn");
3890 if (value[0] != NULL)
3891 (void) fprintf(stdout, "%s", value[0]);
3892 value = __ns_ldap_getAttr(res->entry, "bootParameter");
3893 if (value != NULL)
3894 while (value[attr_count] != NULL) {
3895 (void) fprintf(stdout, "\t%s", value[attr_count]);
3896 attr_count++;
3898 (void) fprintf(stdout, "\n");
3903 static char *
3904 fget_line_at(struct line_buf *line, int n, FILE *fp)
3906 int c;
3908 line->len = n;
3910 for (;;) {
3911 c = fgetc(fp);
3912 if (c == -1)
3913 break;
3914 if (line->len >= line->alloc)
3915 line_buf_expand(line);
3916 line->str[line->len++] = c;
3918 if (c == '\n')
3919 break;
3922 /* Null Terminate */
3923 if (line->len >= line->alloc)
3924 line_buf_expand(line);
3925 line->str[line->len++] = 0;
3927 /* if no characters are read, return NULL to indicate EOF */
3928 if (line->str[0] == '\0')
3929 return (0);
3931 return (line->str);
3935 * return a line from the file, discarding comments and blank lines
3937 static int
3938 filedbmline_comment(struct line_buf *line, FILE *etcf, int *lineno,
3939 struct file_loc *loc)
3941 int i, len = 0;
3943 loc->offset = ftell(etcf);
3944 for (;;) {
3945 if (fget_line_at(line, len, etcf) == 0)
3946 return (0);
3948 if (lineno)
3949 (*lineno)++;
3951 len = strlen(line->str);
3952 if (len >= 2 &&
3953 line->str[0] != '#' &&
3954 line->str[len-2] == '\\' && line->str[len-1] == '\n') {
3955 line->str[len-2] = 0;
3956 len -= 2;
3957 continue; /* append next line at end */
3960 if (line->str[len-1] == '\n') {
3961 line->str[len-1] = 0;
3962 len -= 1;
3966 * Skip lines where '#' is the first non-blank character.
3968 for (i = 0; i < len; i++) {
3969 if (line->str[i] == '#') {
3970 line->str[i] = '\0';
3971 len = i;
3972 break;
3974 if (line->str[i] != ' ' && line->str[i] != '\t')
3975 break;
3979 * A line with one or more white space characters followed
3980 * by a comment will now be blank. The special case of a
3981 * line with '#' in the first byte will have len == 0.
3983 if (len > 0 && !blankline(line->str))
3984 break;
3986 len = 0;
3987 loc->offset = ftell(etcf);
3990 loc->size = len;
3991 return (1);
3995 * return a line from the file, discarding comments, blanks, and '+' lines
3997 static int
3998 filedbmline_plus(struct line_buf *line, FILE *etcf, int *lineno,
3999 struct file_loc *loc)
4001 int len = 0;
4003 loc->offset = ftell(etcf);
4004 for (;;) {
4005 if (fget_line_at(line, len, etcf) == 0)
4006 return (0);
4008 if (lineno)
4009 (*lineno)++;
4011 len = strlen(line->str);
4012 if (line->str[len-1] == '\n') {
4013 line->str[len-1] = 0;
4014 len -= 1;
4017 if (!blankline(line->str) &&
4018 line->str[0] != '+' && line->str[0] != '-' &&
4019 line->str[0] != '#')
4020 break;
4022 len = 0;
4023 loc->offset = ftell(etcf);
4026 loc->size = len;
4027 return (1);
4031 /* Populating the ttypelist structure */
4033 static struct ttypelist_t ttypelist[] = {
4034 { NS_LDAP_TYPE_HOSTS, genent_hosts, dump_hosts,
4035 filedbmline_comment, "iphost", "cn" },
4036 { NS_LDAP_TYPE_IPNODES, genent_hosts, dump_hosts,
4037 filedbmline_comment, "iphost", "cn" },
4038 { NS_LDAP_TYPE_RPC, genent_rpc, dump_rpc,
4039 filedbmline_comment, "oncrpc", "cn" },
4040 { NS_LDAP_TYPE_PROTOCOLS, genent_protocols, dump_protocols,
4041 filedbmline_comment, "ipprotocol", "cn" },
4042 { NS_LDAP_TYPE_NETWORKS, genent_networks, dump_networks,
4043 filedbmline_comment, "ipnetwork", "ipnetworknumber" },
4044 { NS_LDAP_TYPE_SERVICES, genent_services, dump_services,
4045 filedbmline_comment, "ipservice", "cn" },
4046 { NS_LDAP_TYPE_GROUP, genent_group, dump_group,
4047 filedbmline_plus, "posixgroup", "gidnumber" },
4048 { NS_LDAP_TYPE_NETMASKS, genent_netmasks, dump_netmasks,
4049 filedbmline_comment, "ipnetwork", "ipnetworknumber"},
4050 { NS_LDAP_TYPE_ETHERS, genent_ethers, dump_ethers,
4051 filedbmline_comment, "ieee802Device", "cn" },
4052 { NS_LDAP_TYPE_NETGROUP, genent_netgroup, dump_netgroup,
4053 filedbmline_comment, "nisnetgroup", "cn" },
4054 { NS_LDAP_TYPE_BOOTPARAMS, genent_bootparams, dump_bootparams,
4055 filedbmline_comment, "bootableDevice", "cn" },
4056 { NS_LDAP_TYPE_PUBLICKEY, genent_publickey, NULL /* dump_publickey */,
4057 filedbmline_comment, "niskeyobject", "cn" },
4058 { NS_LDAP_TYPE_PASSWD, genent_passwd, dump_passwd,
4059 filedbmline_plus, "posixaccount", "uid" },
4060 { NS_LDAP_TYPE_SHADOW, genent_shadow, dump_shadow,
4061 filedbmline_plus, "shadowaccount", "uid" },
4062 { NS_LDAP_TYPE_ALIASES, genent_aliases, dump_aliases,
4063 filedbmline_plus, "mailGroup", "cn" },
4064 { NS_LDAP_TYPE_AUTOMOUNT, genent_automount, dump_automount,
4065 filedbmline_comment, "automount", "automountKey" },
4066 { NS_LDAP_TYPE_USERATTR, genent_user_attr, dump_user_attr,
4067 filedbmline_comment, "SolarisUserAttr", "uid" },
4068 { NS_LDAP_TYPE_PROFILE, genent_prof_attr, dump_prof_attr,
4069 filedbmline_comment, "SolarisProfAttr", "cn" },
4070 { NS_LDAP_TYPE_EXECATTR, genent_exec_attr, dump_exec_attr,
4071 filedbmline_comment, "SolarisExecAttr", "cn" },
4072 { NS_LDAP_TYPE_AUTHATTR, genent_auth_attr, dump_auth_attr,
4073 filedbmline_comment, "SolarisAuthAttr", "cn" },
4074 { NS_LDAP_TYPE_PROJECT, genent_project, dump_project,
4075 filedbmline_comment, "SolarisProject", "SolarisProjectName" },
4076 { 0, 0, 0, 0, 0, 0 }
4082 static int lineno = 0;
4084 static void
4085 addfile()
4087 struct line_buf line;
4088 struct file_loc loc;
4090 /* Initializing the Line Buffer */
4091 line_buf_init(&line);
4093 /* Loop through all the lines in the file */
4094 while (tt->filedbmline(&line, etcf, &lineno, &loc)) {
4095 switch ((*(tt->genent))(line.str, addentry)) {
4096 case GENENT_OK:
4097 break;
4098 case GENENT_PARSEERR:
4099 (void) fprintf(stderr,
4100 gettext("parse error: %s (line %d)\n"),
4101 parse_err_msg, lineno);
4102 exit_val = 1;
4103 break;
4104 case GENENT_CBERR:
4105 (void) fprintf(stderr,
4106 gettext("Error while adding line: %s\n"),
4107 line.str);
4108 exit_val = 2;
4109 free(line.str);
4110 return;
4111 case GENENT_ERR:
4112 (void) fprintf(stderr,
4113 gettext("Internal Error while adding line: %s\n"),
4114 line.str);
4115 exit_val = 3;
4116 free(line.str);
4117 return;
4120 free(line.str);
4123 static void
4124 dumptable(char *service)
4127 ns_ldap_result_t *eres = NULL;
4128 ns_ldap_error_t *err = NULL;
4129 int rc = 0, success = 0;
4130 char filter[BUFSIZ];
4131 int done = 0;
4132 void *cookie = NULL;
4134 /* set the appropriate filter */
4135 if (strcmp(tt->ttype, NS_LDAP_TYPE_PROFILE) == 0) {
4137 * prof_attr entries are SolarisProfAttr
4138 * without AUXILIARY SolarisExecAttr
4140 (void) snprintf(filter, sizeof (filter),
4141 "(&(objectclass=%s)(!(objectclass=SolarisExecAttr)))",
4142 tt->objclass);
4143 } else {
4144 (void) snprintf(filter, sizeof (filter),
4145 "(objectclass=%s)", tt->objclass);
4148 if (flags & F_VERBOSE)
4149 (void) fprintf(stdout, gettext("FILTER = %s\n"), filter);
4151 /* Pass cred only if supplied. Cred is not always needed for dump */
4152 if (authority.cred.unix_cred.userID == NULL ||
4153 authority.cred.unix_cred.passwd == NULL)
4154 rc = __ns_ldap_firstEntry(service, filter, tt->sortattr, NULL,
4155 NULL, NULL, NS_LDAP_HARD, &cookie, &eres, &err, NULL);
4156 else
4157 rc = __ns_ldap_firstEntry(service, filter, tt->sortattr, NULL,
4158 NULL, &authority, NS_LDAP_HARD, &cookie, &eres, &err, NULL);
4160 switch (rc) {
4161 case NS_LDAP_SUCCESS:
4162 nent_add++;
4163 success = 1;
4164 if (eres != NULL) {
4165 if (strcmp(databasetype, "publickey") == 0)
4166 dump_publickey(eres, service);
4167 else
4168 (*(tt->dump))(eres);
4170 else
4171 (void) fprintf(stderr, gettext("No entries found.\n"));
4172 break;
4174 case NS_LDAP_OP_FAILED:
4175 exit_val = 2;
4176 (void) fprintf(stderr, gettext("operation failed.\n"));
4177 break;
4179 case NS_LDAP_INVALID_PARAM:
4180 exit_val = 2;
4181 (void) fprintf(stderr,
4182 gettext("invalid parameter(s) passed.\n"));
4183 break;
4185 case NS_LDAP_NOTFOUND:
4186 exit_val = 2;
4187 (void) fprintf(stderr, gettext("entry not found.\n"));
4188 break;
4190 case NS_LDAP_MEMORY:
4191 exit_val = 2;
4192 (void) fprintf(stderr,
4193 gettext("internal memory allocation error.\n"));
4194 break;
4196 case NS_LDAP_CONFIG:
4197 exit_val = 2;
4198 (void) fprintf(stderr,
4199 gettext("LDAP Configuration problem.\n"));
4200 perr(err);
4201 break;
4203 case NS_LDAP_PARTIAL:
4204 exit_val = 2;
4205 (void) fprintf(stderr,
4206 gettext("partial result returned\n"));
4207 perr(err);
4208 break;
4210 case NS_LDAP_INTERNAL:
4211 exit_val = 2;
4212 (void) fprintf(stderr,
4213 gettext("internal LDAP error occured.\n"));
4214 perr(err);
4215 break;
4218 if (eres != NULL) {
4219 (void) __ns_ldap_freeResult(&eres);
4220 eres = NULL;
4223 if (success) {
4224 while (!done) {
4225 rc = __ns_ldap_nextEntry(cookie, &eres, &err);
4226 if (rc != NS_LDAP_SUCCESS || eres == NULL) {
4227 done = 1;
4228 continue;
4231 /* Print the result */
4232 if (eres != NULL) {
4233 if (strcmp(databasetype, "publickey") == 0)
4234 dump_publickey(eres, service);
4235 else
4236 (*(tt->dump))(eres);
4237 (void) __ns_ldap_freeResult(&eres);
4238 eres = NULL;
4245 main(int argc, char **argv)
4247 char *password;
4248 ns_standalone_conf_t standalone_cfg = standaloneDefaults;
4249 int c;
4250 int rc;
4251 int ldaprc;
4252 int authstried = 0;
4253 int op = OP_ADD;
4254 char *ttype, *authmech = 0, *etcfile = 0;
4255 /* Temporary password variable */
4256 char ps[LDAP_MAXNAMELEN];
4257 char filter[BUFSIZ];
4258 void **paramVal = NULL;
4259 ns_auth_t **app;
4260 ns_auth_t **authpp = NULL;
4261 ns_auth_t *authp = NULL;
4262 ns_ldap_error_t *errorp = NULL;
4263 ns_ldap_result_t *resultp;
4264 ns_ldap_entry_t *e;
4265 int flag = 0;
4266 int version1 = 0;
4268 (void) setlocale(LC_ALL, "");
4269 (void) textdomain(TEXT_DOMAIN);
4271 openlog("ldapaddent", LOG_PID, LOG_USER);
4273 inputbasedn = NULL;
4274 authority.cred.unix_cred.passwd = NULL;
4275 authority.cred.unix_cred.userID = NULL;
4276 authority.auth.type = NS_LDAP_AUTH_SIMPLE;
4278 while ((c = getopt(argc, argv, "cdh:N:M:vpf:D:w:j:b:a:P:r:")) != EOF) {
4279 switch (c) {
4280 case 'd':
4281 if (op)
4282 usage(gettext(
4283 "no other option should be specified"));
4284 op = OP_DUMP;
4285 break;
4286 case 'c':
4287 continue_onerror = 1;
4288 break;
4289 case 'v':
4290 flags |= F_VERBOSE;
4291 break;
4292 case 'p':
4293 flags |= F_PASSWD;
4294 break;
4295 case 'M':
4296 standalone_cfg.type = NS_LDAP_SERVER;
4297 standalone_cfg.SA_DOMAIN = optarg;
4298 break;
4299 case 'h':
4300 standalone_cfg.type = NS_LDAP_SERVER;
4301 if (separatePort(optarg,
4302 &standalone_cfg.SA_SERVER,
4303 &standalone_cfg.SA_PORT) > 0) {
4304 exit(1);
4306 break;
4307 case 'P':
4308 standalone_cfg.type = NS_LDAP_SERVER;
4309 authority.hostcertpath = optarg;
4310 break;
4311 case 'N':
4312 standalone_cfg.type = NS_LDAP_SERVER;
4313 standalone_cfg.SA_PROFILE_NAME = optarg;
4314 break;
4315 case 'f':
4316 etcfile = optarg;
4317 break;
4318 case 'D':
4319 authority.cred.unix_cred.userID = strdup(optarg);
4320 break;
4321 case 'w':
4322 if (authority.cred.unix_cred.passwd) {
4323 (void) fprintf(stderr,
4324 gettext("Warning: The -w option is mutually"
4325 " exclusive of -j. -w is ignored.\n"));
4326 break;
4329 if (optarg != NULL &&
4330 optarg[0] == '-' && optarg[1] == '\0') {
4331 /* Ask for a password later */
4332 break;
4335 authority.cred.unix_cred.passwd = strdup(optarg);
4336 break;
4337 case 'j':
4338 if (authority.cred.unix_cred.passwd != NULL) {
4339 (void) fprintf(stderr,
4340 gettext("The -w option is mutually "
4341 "exclusive of -j. -w is ignored.\n"));
4342 free(authority.cred.unix_cred.passwd);
4344 authority.cred.unix_cred.passwd = readPwd(optarg);
4345 if (authority.cred.unix_cred.passwd == NULL) {
4346 exit(1);
4348 break;
4349 case 'b':
4350 inputbasedn = strdup(optarg);
4351 break;
4352 case 'a':
4353 authmech = strdup(optarg);
4354 break;
4355 default:
4356 usage(gettext("Invalid option"));
4360 if (standalone_cfg.type == NS_LDAP_SERVER &&
4361 standalone_cfg.SA_SERVER == NULL) {
4362 (void) fprintf(stderr,
4363 gettext("Please specify an LDAP server you want "
4364 "to connect to. \n"));
4365 exit(1);
4368 if (authmech != NULL) {
4369 if (__ns_ldap_initAuth(authmech, &authority.auth, &errorp) !=
4370 NS_LDAP_SUCCESS) {
4371 if (errorp) {
4372 (void) fprintf(stderr, "%s", errorp->message);
4373 (void) __ns_ldap_freeError(&errorp);
4375 exit(1);
4379 if (authority.auth.saslmech != NS_LDAP_SASL_GSSAPI &&
4380 authority.cred.unix_cred.userID == NULL &&
4381 op != OP_DUMP) {
4382 /* This is not an optional parameter. Exit */
4383 (void) fprintf(stderr,
4384 gettext("DN must be specified unless SASL/GSSAPI is used."
4385 " Use option -D.\n"));
4386 exit(1);
4389 if (authority.auth.saslmech != NS_LDAP_SASL_GSSAPI &&
4390 authority.cred.unix_cred.passwd == NULL &&
4391 (op != OP_DUMP ||
4392 standalone_cfg.type != NS_CACHEMGR &&
4393 authority.cred.unix_cred.userID != NULL)) {
4394 /* If password is not specified, then prompt user for it. */
4395 password = getpassphrase("Enter password:");
4396 (void) strcpy(ps, password);
4397 authority.cred.unix_cred.passwd = strdup(ps);
4400 standalone_cfg.SA_AUTH = authmech == NULL ? NULL : &authority.auth;
4401 standalone_cfg.SA_CERT_PATH = authority.hostcertpath;
4402 standalone_cfg.SA_BIND_DN = authority.cred.unix_cred.userID;
4403 standalone_cfg.SA_BIND_PWD = authority.cred.unix_cred.passwd;
4405 if (__ns_ldap_initStandalone(&standalone_cfg,
4406 &errorp) != NS_LDAP_SUCCESS) {
4407 if (errorp) {
4408 (void) fprintf(stderr, "%s", errorp->message);
4410 exit(1);
4413 if (authmech == NULL) {
4414 ldaprc = __ns_ldap_getParam(NS_LDAP_AUTH_P, (void ***)&authpp,
4415 &errorp);
4416 if (ldaprc != NS_LDAP_SUCCESS ||
4417 (authpp == NULL && op != OP_DUMP)) {
4418 (void) fprintf(stderr,
4419 gettext("No legal authentication method "
4420 "configured.\n"));
4421 (void) fprintf(stderr,
4422 gettext("Provide a legal authentication method "
4423 "using -a option\n"));
4424 exit(1);
4427 /* Use the first authentication method which is not none */
4428 for (app = authpp; *app; app++) {
4429 authp = *app;
4430 if (authp->type != NS_LDAP_AUTH_NONE) {
4431 authstried++;
4432 authority.auth.type = authp->type;
4433 authority.auth.tlstype = authp->tlstype;
4434 authority.auth.saslmech = authp->saslmech;
4435 authority.auth.saslopt = authp->saslopt;
4436 break;
4439 if (authstried == 0 && op != OP_DUMP) {
4440 (void) fprintf(stderr,
4441 gettext("No legal authentication method configured."
4442 "\nProvide a legal authentication method using "
4443 "-a option"));
4444 exit(1);
4446 if (authority.auth.saslmech == NS_LDAP_SASL_GSSAPI &&
4447 authority.cred.unix_cred.passwd != NULL &&
4448 authority.cred.unix_cred.userID != NULL) {
4450 * -a is not specified and the auth method sasl/GSSAPI
4451 * is defined in the configuration of the ldap profile.
4452 * Even -D and -w is provided it's not valid usage.
4453 * Drop them on the floor.
4456 (void) fprintf(stderr,
4457 gettext("The default authentication is "
4458 "sasl/GSSAPI.\n"
4459 "The bind DN and password will be ignored.\n"));
4460 authority.cred.unix_cred.passwd = NULL;
4461 authority.cred.unix_cred.userID = NULL;
4465 ttype = argv[optind++];
4467 if (ttype == NULL) {
4468 usage(gettext("No database type specified"));
4469 exit(1);
4472 if (strncasecmp(ttype, "automount", 9) == 0) {
4473 (void) fprintf(stderr,
4474 gettext("automount is not a valid service for ldapaddent.\n"
4475 "Please use auto_*.\n"
4476 "e.g. auto_home, auto_ws etc.\n "));
4477 exit(1);
4480 for (tt = ttypelist; tt->ttype; tt++) {
4481 if (strcmp(tt->ttype, ttype) == 0)
4482 break;
4483 if (strcmp(tt->ttype, NS_LDAP_TYPE_AUTOMOUNT) == 0 &&
4484 strncmp(ttype, NS_LDAP_TYPE_AUTOMOUNT,
4485 sizeof (NS_LDAP_TYPE_AUTOMOUNT) - 1) == 0)
4486 break;
4489 if (tt->ttype == 0) {
4490 (void) fprintf(stderr,
4491 gettext("database %s not supported;"
4492 " supported databases are:\n"), ttype);
4493 for (tt = ttypelist; tt->ttype; tt++)
4494 (void) fprintf(stderr, gettext("\t%s\n"), tt->ttype);
4495 exit(1);
4498 if (flags & F_VERBOSE)
4499 (void) fprintf(stdout, gettext("SERVICE = %s\n"), tt->ttype);
4501 databasetype = ttype;
4503 if (strcmp(tt->ttype, NS_LDAP_TYPE_AUTOMOUNT) == 0) {
4504 paramVal = NULL;
4505 errorp = NULL;
4506 rc = __ns_ldap_getParam(NS_LDAP_FILE_VERSION_P, &paramVal,
4507 &errorp);
4508 if (paramVal && *paramVal &&
4509 strcasecmp(*paramVal, NS_LDAP_VERSION_1) == 0)
4510 version1 = 1;
4511 if (paramVal)
4512 (void) __ns_ldap_freeParam(&paramVal);
4513 if (errorp)
4514 (void) __ns_ldap_freeError(&errorp);
4517 /* Check if the container exists in first place */
4518 (void) strcpy(&filter[0], "(objectclass=*)");
4520 rc = __ns_ldap_list(databasetype, filter, NULL, (const char **)NULL,
4521 NULL, NS_LDAP_SCOPE_BASE, &resultp, &errorp, NULL, NULL);
4523 /* create a container for auto_* if it does not exist already */
4524 if ((rc == NS_LDAP_NOTFOUND) && (op == OP_ADD) &&
4525 (strcmp(tt->ttype, NS_LDAP_TYPE_AUTOMOUNT) == 0)) {
4526 static char *oclist[] = {NULL, "top", NULL};
4527 if (version1)
4528 oclist[0] = "nisMap";
4529 else
4530 oclist[0] = "automountMap";
4531 e = __s_mk_entry(oclist, 3);
4532 if (e == NULL) {
4533 (void) fprintf(stderr,
4534 gettext("internal memory allocation error.\n"));
4535 exit(1);
4537 if (__s_add_attr(e,
4538 version1 ? "nisMapName" : "automountMapName",
4539 databasetype) != NS_LDAP_SUCCESS) {
4540 (void) fprintf(stderr,
4541 gettext("internal memory allocation error.\n"));
4542 ldap_freeEntry(e);
4543 exit(1);
4546 if (inputbasedn == NULL) {
4547 if (get_basedn(databasetype, &inputbasedn) !=
4548 NS_LDAP_SUCCESS) {
4549 (void) fprintf(stderr,
4550 gettext("Could not obtain basedn\n"));
4551 ldap_freeEntry(e);
4552 exit(1);
4555 if (__ns_ldap_addEntry(databasetype, inputbasedn, e,
4556 &authority, flag, &errorp) != NS_LDAP_SUCCESS) {
4557 (void) fprintf(stderr,
4558 gettext("Could not create container for %s\n"),
4559 databasetype);
4560 ldap_freeEntry(e);
4562 } else if (strcmp(databasetype, "publickey") != 0) {
4563 if (rc == NS_LDAP_NOTFOUND) {
4564 (void) fprintf(stderr,
4565 gettext("Container %s does not exist\n"),
4566 databasetype);
4567 exit(1);
4571 if (op == OP_DUMP) {
4572 if (strcmp(databasetype, "publickey") == 0) {
4573 dumptable("hosts");
4574 dumptable("passwd");
4575 } else {
4576 dumptable(databasetype);
4578 exit(exit_val);
4581 if (etcfile) {
4582 if ((etcf = fopen(etcfile, "r")) == 0) {
4583 (void) fprintf(stderr,
4584 gettext("can't open file %s\n"), etcfile);
4585 exit(1);
4587 } else {
4588 etcfile = "stdin";
4589 etcf = stdin;
4592 if (op == OP_ADD) {
4593 (void) addfile();
4594 (void) fprintf(stdout, gettext("%d entries added\n"), nent_add);
4597 __ns_ldap_cancelStandalone();
4598 /* exit() -> return for make lint */
4599 return (exit_val);
4604 * This is called when service == auto_*.
4605 * It calls __ns_ldap_getSearchDescriptors
4606 * to generate the dn from SSD's base dn.
4607 * If there is no SSD available,
4608 * default base dn will be used
4609 * Only the first baseDN in the SSD is used
4612 static int get_basedn(char *service, char **basedn) {
4613 int rc = NS_LDAP_SUCCESS;
4614 char *dn = NULL;
4615 ns_ldap_search_desc_t **desc = NULL;
4616 ns_ldap_error_t *errp = NULL;
4617 void **paramVal = NULL;
4618 int prepend_automountmapname = FALSE;
4621 * Get auto_* SSD first
4624 if ((rc = __ns_ldap_getSearchDescriptors(
4625 (const char *) service,
4626 &desc, &errp)) == NS_LDAP_SUCCESS &&
4627 desc != NULL) {
4629 if (desc[0] != NULL && desc[0]->basedn != NULL) {
4630 dn = strdup(desc[0]->basedn);
4631 if (dn == NULL) {
4632 (void) __ns_ldap_freeSearchDescriptors
4633 (&desc);
4634 return (NS_LDAP_MEMORY);
4639 /* clean up */
4640 if (desc) (void) __ns_ldap_freeSearchDescriptors(&desc);
4641 if (errp) (void) __ns_ldap_freeError(&errp);
4644 * If no dn is duplicated from auto_* SSD, try automount SSD
4646 if (dn == NULL) {
4647 if ((rc = __ns_ldap_getSearchDescriptors(
4648 "automount", &desc, &errp))
4649 == NS_LDAP_SUCCESS && desc != NULL) {
4651 if (desc[0] != NULL && desc[0]->basedn != NULL) {
4652 dn = strdup(desc[0]->basedn);
4653 if (dn == NULL) {
4654 (void) __ns_ldap_freeSearchDescriptors
4655 (&desc);
4656 return (NS_LDAP_MEMORY);
4658 prepend_automountmapname = TRUE;
4661 /* clean up */
4662 if (desc) (void) __ns_ldap_freeSearchDescriptors(&desc);
4663 if (errp) (void) __ns_ldap_freeError(&errp);
4667 * If no dn is duplicated from auto_* or automount SSD,
4668 * use default DN
4671 if (dn == NULL) {
4672 if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_BASEDN_P,
4673 &paramVal, &errp)) == NS_LDAP_SUCCESS) {
4674 dn = strdup((char *)paramVal[0]);
4675 if (dn == NULL) {
4676 (void) __ns_ldap_freeParam(&paramVal);
4677 return (NS_LDAP_MEMORY);
4679 prepend_automountmapname = TRUE;
4681 if (paramVal) (void) __ns_ldap_freeParam(&paramVal);
4682 if (errp) (void) __ns_ldap_freeError(&errp);
4686 if (dn == NULL) {
4687 return (NS_LDAP_OP_FAILED);
4688 } else {
4690 * If dn is duplicated from
4691 * automount SSD basedn or
4692 * default base dn
4693 * then prepend automountMapName=auto_xxx
4695 if (prepend_automountmapname)
4696 rc = __s_api_prepend_automountmapname_to_dn(
4697 service, &dn, &errp);
4699 if (rc != NS_LDAP_SUCCESS) {
4700 (void) __ns_ldap_freeError(&errp);
4701 free(dn);
4702 return (rc);
4705 *basedn = dn;
4707 return (NS_LDAP_SUCCESS);
4710 static char *
4711 h_errno2str(int h_errno) {
4712 switch (h_errno) {
4713 case HOST_NOT_FOUND:
4714 return ("HOST_NOT_FOUND");
4715 case TRY_AGAIN:
4716 return ("TRY_AGAIN");
4717 case NO_RECOVERY:
4718 return ("NO_RECOVERY");
4719 case NO_DATA:
4720 return ("NO_DATA");
4721 default:
4722 break;
4724 return ("UNKNOWN_ERROR");