Fix NULL pointer constant issues in cmd
[unleashed.git] / usr / src / cmd / ldap / ns_ldap / ldapaddent.c
blob904a43d3821f5d66615058831f3d569e159f03d3
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 = (char **)realloc(data.h_aliases,
727 ctr * 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 = (char **)realloc(data.h_aliases,
740 (ecol[3].ec_value.ec_value_len != 0 ?
741 ctr + 2 : ctr + 1) * 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 = (char **)realloc(data.r_aliases,
958 ctr * 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 = (char **)realloc(data.r_aliases,
975 (ctr + 1) * 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 = (char **)realloc(data.p_aliases,
1170 ctr * 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 = (char **)realloc(data.p_aliases,
1186 (ctr + 1) * 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 = (char **)realloc(data.n_aliases,
1392 ctr * 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 = (char **)realloc(data.n_aliases,
1408 (ctr + 1) * 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 **)realloc(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 = (char **)realloc(data.s_aliases,
1640 (ctr + 1) * 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 = (char **)realloc(data.member,
2124 (ctr + 1) * 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 = (char **)realloc(
2705 data.triplet,
2706 tripletcount * sizeof (char **))) == NULL) {
2707 (void) fprintf(stderr,
2708 gettext("out of memory\n"));
2709 exit(1);
2711 data.triplet[tripletcount-1] = triplet_tmp;
2712 } else {
2713 (void) strlcpy(parse_err_msg,
2714 gettext("invalid triplet"),
2715 PARSE_ERR_MSG_LEN);
2716 rc = GENENT_PARSEERR;
2718 } else {
2719 /* skip a netgroup if it is added already */
2720 for (i = 0; i < netgcount &&
2721 strcmp(t, data.netgroup[i]); i++)
2723 if (i < netgcount)
2724 continue;
2726 netgcount++;
2727 netg_tmp = strdup(t);
2728 if ((data.netgroup = (char **)realloc(data.netgroup,
2729 netgcount * sizeof (char **))) == NULL) {
2730 (void) fprintf(stderr,
2731 gettext("out of memory\n"));
2732 exit(1);
2734 data.netgroup[netgcount-1] = netg_tmp;
2738 /* End the list with NULL */
2739 if ((data.triplet = (char **)realloc(data.triplet,
2740 (tripletcount + 1) * sizeof (char **))) == NULL) {
2741 (void) fprintf(stderr, gettext("out of memory\n"));
2742 exit(1);
2744 data.triplet[tripletcount] = NULL;
2745 if ((data.netgroup = (char **)realloc(data.netgroup,
2746 (netgcount + 1) * sizeof (char **))) == NULL) {
2747 (void) fprintf(stderr, gettext("out of memory\n"));
2748 exit(1);
2750 data.netgroup[netgcount] = NULL;
2752 if (rc == GENENT_OK) {
2753 if (flags & F_VERBOSE)
2754 (void) fprintf(stdout,
2755 gettext("Adding entry : %s\n"), data.name);
2757 retval = (*cback)(&data, 0);
2759 if (retval == LDAP_ALREADY_EXISTS) {
2760 if (continue_onerror)
2761 (void) fprintf(stderr, gettext(
2762 "Entry: %s - already Exists,"
2763 " skipping it.\n"), data.name);
2764 else {
2765 rc = GENENT_CBERR;
2766 (void) fprintf(stderr,
2767 gettext("Entry: %s - already Exists\n"),
2768 data.name);
2770 } else if (retval)
2771 rc = GENENT_CBERR;
2774 /* release memory allocated by strdup() */
2775 for (i = 0; i < tripletcount; i++) {
2776 free(data.triplet[i]);
2778 for (i = 0; i < netgcount; i++) {
2779 free(data.netgroup[i]);
2782 free(data.name);
2783 free(data.triplet);
2784 free(data.netgroup);
2786 return (rc);
2789 static void
2790 dump_netgroup(ns_ldap_result_t *res)
2792 char **value = NULL;
2793 int attr_count = 0;
2795 value = __ns_ldap_getAttr(res->entry, "cn");
2796 if ((value != NULL) && (value[0] != NULL))
2797 (void) fprintf(stdout, "%s", value[0]);
2798 else
2799 return;
2800 value = __ns_ldap_getAttr(res->entry, "nisNetgroupTriple");
2801 if (value != NULL)
2802 while (value[attr_count] != NULL) {
2803 (void) fprintf(stdout, " %s", value[attr_count]);
2804 attr_count++;
2806 attr_count = 0;
2807 value = __ns_ldap_getAttr(res->entry, "memberNisNetgroup");
2808 if (value != NULL)
2809 while (value[attr_count] != NULL) {
2810 (void) fprintf(stdout, " %s", value[attr_count]);
2811 attr_count++;
2813 (void) fprintf(stdout, "\n");
2817 static int
2818 genent_automount(char *line, int (*cback)())
2820 char buf[BUFSIZ+1];
2821 char *t, *s;
2822 entry_col ecol[2];
2823 struct _ns_automount data;
2824 int retval = 1;
2825 int rc = GENENT_OK;
2828 * don't clobber our argument
2830 if (strlen(line) >= sizeof (buf)) {
2831 (void) strlcpy(parse_err_msg, gettext("line too long"),
2832 PARSE_ERR_MSG_LEN);
2833 return (GENENT_PARSEERR);
2836 /* replace every tabspace with single space */
2837 replace_tab2space(line);
2838 (void) strcpy(buf, line);
2841 * clear column data
2843 (void) memset((char *)ecol, 0, sizeof (ecol));
2846 * key (col 0)
2848 t = buf;
2849 while (t[0] == ' ')
2850 t++;
2852 if ((s = strchr(t, ' ')) == 0) {
2853 return (GENENT_PARSEERR);
2855 *s++ = 0;
2857 ecol[0].ec_value.ec_value_val = t;
2858 ecol[0].ec_value.ec_value_len = strlen(t)+1;
2859 t = s;
2861 while (t[0] == ' ')
2862 t++;
2865 * mapentry (col 1)
2868 ecol[1].ec_value.ec_value_val = t;
2869 ecol[1].ec_value.ec_value_len = strlen(t)+1;
2871 data.mapname = strdup(databasetype);
2872 data.key = strdup(ecol[0].ec_value.ec_value_val);
2873 data.value = strdup(ecol[1].ec_value.ec_value_val);
2875 if (flags & F_VERBOSE)
2876 (void) fprintf(stdout,
2877 gettext("Adding entry : %s\n"), data.key);
2879 retval = (*cback)(&data, 0);
2881 if (retval == LDAP_ALREADY_EXISTS) {
2882 if (continue_onerror)
2883 (void) fprintf(stderr,
2884 gettext("Entry: %s - already Exists,"
2885 " skipping it.\n"), data.key);
2886 else {
2887 rc = GENENT_CBERR;
2888 (void) fprintf(stderr,
2889 gettext("Entry: %s - already Exists\n"),
2890 data.key);
2892 } else if (retval)
2893 rc = GENENT_CBERR;
2895 free(data.mapname);
2896 free(data.key);
2897 free(data.value);
2898 return (rc);
2901 static void
2902 dump_automount(ns_ldap_result_t *res)
2904 char **value = NULL;
2906 if (res == NULL)
2907 return;
2909 value = __ns_ldap_getAttr(res->entry, "automountKey");
2910 if (value != NULL) {
2911 (void) fprintf(stdout, "%s", value[0]);
2912 value = __ns_ldap_getAttr(res->entry, "automountInformation");
2913 if (value != NULL)
2914 (void) fprintf(stdout, " %s\n", value[0]);
2915 else
2916 (void) fprintf(stdout, "\n");
2922 * /etc/passwd
2926 static int
2927 genent_passwd(char *line, int (*cback)())
2929 char buf[BUFSIZ+1];
2930 char *s, *t;
2931 entry_col ecol[8];
2932 int retval = 1;
2933 char pname[BUFSIZ];
2935 struct passwd data;
2936 int rc = GENENT_OK;
2940 * don't clobber our argument
2942 if (strlen(line) >= sizeof (buf)) {
2943 (void) strlcpy(parse_err_msg, gettext("line too long"),
2944 PARSE_ERR_MSG_LEN);
2945 return (GENENT_PARSEERR);
2947 (void) strcpy(buf, line);
2948 t = buf;
2950 /* ignore empty entries */
2951 if (*t == '\0')
2952 return (GENENT_OK);
2955 * clear column data
2957 (void) memset((char *)ecol, 0, sizeof (ecol));
2960 * name (col 0)
2962 if ((s = strchr(t, ':')) == 0) {
2963 (void) strlcpy(parse_err_msg, gettext("no password"),
2964 PARSE_ERR_MSG_LEN);
2965 return (GENENT_PARSEERR);
2967 *s++ = 0;
2968 ecol[0].ec_value.ec_value_val = t;
2969 ecol[0].ec_value.ec_value_len = strlen(t)+1;
2970 t = s;
2973 * passwd (col 1)
2975 if ((s = strchr(t, ':')) == 0) {
2976 (void) strlcpy(parse_err_msg, gettext("no uid"),
2977 PARSE_ERR_MSG_LEN);
2978 return (GENENT_PARSEERR);
2980 *s++ = 0;
2982 ecol[1].ec_value.ec_value_val = t;
2983 ecol[1].ec_value.ec_value_len = strlen(t)+1;
2985 t = s;
2988 * uid (col 2)
2990 if ((s = strchr(t, ':')) == 0 || s == t) {
2991 (void) strlcpy(parse_err_msg, gettext("no gid"),
2992 PARSE_ERR_MSG_LEN);
2993 return (GENENT_PARSEERR);
2995 *s++ = 0;
2996 ecol[2].ec_value.ec_value_val = t;
2997 ecol[2].ec_value.ec_value_len = strlen(t)+1;
2998 t = s;
3001 * gid (col 3)
3003 if ((s = strchr(t, ':')) == 0 || s == t) {
3004 (void) strlcpy(parse_err_msg, gettext("no gcos"),
3005 PARSE_ERR_MSG_LEN);
3006 return (GENENT_PARSEERR);
3008 *s++ = 0;
3009 ecol[3].ec_value.ec_value_val = t;
3010 ecol[3].ec_value.ec_value_len = strlen(t)+1;
3011 t = s;
3014 * gcos (col 4)
3016 if ((s = strchr(t, ':')) == 0) {
3017 (void) strlcpy(parse_err_msg, gettext("no home"),
3018 PARSE_ERR_MSG_LEN);
3019 return (GENENT_PARSEERR);
3021 *s++ = 0;
3022 ecol[4].ec_value.ec_value_val = t;
3023 ecol[4].ec_value.ec_value_len = strlen(t)+1;
3024 t = s;
3027 * home (col 5)
3029 if ((s = strchr(t, ':')) == 0) {
3030 (void) strlcpy(parse_err_msg, gettext("no shell"),
3031 PARSE_ERR_MSG_LEN);
3032 return (GENENT_PARSEERR);
3034 *s++ = 0;
3035 ecol[5].ec_value.ec_value_val = t;
3036 ecol[5].ec_value.ec_value_len = strlen(t)+1;
3037 t = s;
3040 * shell (col 6)
3042 ecol[6].ec_value.ec_value_val = t;
3043 ecol[6].ec_value.ec_value_len = strlen(t)+1;
3046 * build entry
3048 data.pw_name = strdup(ecol[0].ec_value.ec_value_val);
3050 if (flags & F_PASSWD) {
3051 /* Add {crypt} before passwd entry */
3052 (void) snprintf(pname, sizeof (pname), "{crypt}%s",
3053 ecol[1].ec_value.ec_value_val);
3054 data.pw_passwd = strdup(pname);
3056 else
3057 data.pw_passwd = NULL;
3059 if (ecol[2].ec_value.ec_value_val != NULL &&
3060 ecol[2].ec_value.ec_value_val[0] != '\0') {
3061 data.pw_uid = ascii_to_int(ecol[2].ec_value.ec_value_val);
3062 if (data.pw_uid == (uid_t)-1) {
3063 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3064 gettext("invalid uid : %s"),
3065 ecol[2].ec_value.ec_value_val);
3066 return (GENENT_PARSEERR);
3068 } else
3069 data.pw_uid = (uid_t)-1;
3071 if (ecol[3].ec_value.ec_value_val != NULL &&
3072 ecol[3].ec_value.ec_value_val[0] != '\0') {
3074 data.pw_gid = ascii_to_int(ecol[3].ec_value.ec_value_val);
3075 if (data.pw_gid == (uid_t)-1) {
3076 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3077 gettext("invalid gid : %s"),
3078 ecol[3].ec_value.ec_value_val);
3079 return (GENENT_PARSEERR);
3081 } else
3082 data.pw_gid = (uid_t)-1;
3084 data.pw_age = NULL;
3085 data.pw_comment = NULL;
3086 data.pw_gecos = strdup(ecol[4].ec_value.ec_value_val);
3087 data.pw_dir = strdup(ecol[5].ec_value.ec_value_val);
3088 data.pw_shell = strdup(ecol[6].ec_value.ec_value_val);
3090 if (flags & F_VERBOSE)
3091 (void) fprintf(stdout,
3092 gettext("Adding entry : %s\n"), data.pw_name);
3094 retval = (*cback)(&data, 0);
3096 if (retval == LDAP_ALREADY_EXISTS) {
3097 if (continue_onerror)
3098 (void) fprintf(stderr,
3099 gettext("Entry: %s - already Exists,"
3100 " skipping it.\n"), data.pw_name);
3101 else {
3102 rc = GENENT_CBERR;
3103 (void) fprintf(stderr,
3104 gettext("Entry: %s - already Exists\n"),
3105 data.pw_name);
3107 } else if (retval)
3108 rc = GENENT_CBERR;
3110 free(data.pw_name);
3111 free(data.pw_gecos);
3112 free(data.pw_dir);
3113 free(data.pw_shell);
3114 return (rc);
3118 static void
3119 dump_passwd(ns_ldap_result_t *res)
3121 char **value = NULL;
3123 value = __ns_ldap_getAttr(res->entry, "uid");
3124 if (value == NULL)
3125 return;
3126 else
3127 (void) fprintf(stdout, "%s:", value[0]);
3128 value = __ns_ldap_getAttr(res->entry, "userPassword");
3131 * Don't print the encrypted password, Use x to
3132 * indicate it is in the shadow database.
3134 (void) fprintf(stdout, "x:");
3136 value = __ns_ldap_getAttr(res->entry, "uidNumber");
3137 if (value && value[0])
3138 (void) fprintf(stdout, "%s:", value[0]);
3139 value = __ns_ldap_getAttr(res->entry, "gidNumber");
3140 if (value && value[0])
3141 (void) fprintf(stdout, "%s:", value[0]);
3142 value = __ns_ldap_getAttr(res->entry, "gecos");
3143 if (value == NULL)
3144 (void) fprintf(stdout, ":");
3145 else
3146 (void) fprintf(stdout, "%s:", value[0]);
3147 value = __ns_ldap_getAttr(res->entry, "homeDirectory");
3148 if (value == NULL)
3149 (void) fprintf(stdout, ":");
3150 else
3151 (void) fprintf(stdout, "%s:", value[0]);
3152 value = __ns_ldap_getAttr(res->entry, "loginShell");
3153 if (value == NULL)
3154 (void) fprintf(stdout, "\n");
3155 else
3156 (void) fprintf(stdout, "%s\n", value[0]);
3161 * /etc/shadow
3164 static int
3165 genent_shadow(char *line, int (*cback)())
3167 char buf[BUFSIZ+1];
3168 char *s, *t;
3169 entry_col ecol[9];
3170 char pname[BUFSIZ];
3172 struct spwd data;
3173 int spflag;
3174 int retval;
3178 * don't clobber our argument
3180 if (strlen(line) >= sizeof (buf)) {
3181 (void) strlcpy(parse_err_msg, gettext("line too long"),
3182 PARSE_ERR_MSG_LEN);
3183 return (GENENT_PARSEERR);
3185 (void) strcpy(buf, line);
3186 t = buf;
3188 /* ignore empty entries */
3189 if (*t == '\0')
3190 return (GENENT_OK);
3193 * clear column data
3195 (void) memset((char *)ecol, 0, sizeof (ecol));
3198 * name (col 0)
3200 if ((s = strchr(t, ':')) == 0) {
3201 (void) strlcpy(parse_err_msg, gettext("no uid"),
3202 PARSE_ERR_MSG_LEN);
3203 return (GENENT_PARSEERR);
3205 *s++ = 0;
3206 ecol[0].ec_value.ec_value_val = t;
3207 ecol[0].ec_value.ec_value_len = strlen(t)+1;
3208 t = s;
3211 * passwd (col 1)
3213 if ((s = strchr(t, ':')) == 0) {
3214 (void) strlcpy(parse_err_msg, gettext("Improper format"),
3215 PARSE_ERR_MSG_LEN);
3216 return (GENENT_PARSEERR);
3218 *s++ = 0;
3220 ecol[1].ec_value.ec_value_val = t;
3221 ecol[1].ec_value.ec_value_len = strlen(t)+1;
3223 t = s;
3226 * shadow last change (col 2)
3228 if ((s = strchr(t, ':')) == 0) {
3229 (void) strlcpy(parse_err_msg, gettext("Improper format"),
3230 PARSE_ERR_MSG_LEN);
3231 return (GENENT_PARSEERR);
3233 *s++ = 0;
3234 ecol[2].ec_value.ec_value_val = t;
3235 ecol[2].ec_value.ec_value_len = strlen(t)+1;
3236 t = s;
3239 * shadow min (col 3)
3241 if ((s = strchr(t, ':')) == 0) {
3242 (void) strlcpy(parse_err_msg, gettext("Improper format"),
3243 PARSE_ERR_MSG_LEN);
3244 return (GENENT_PARSEERR);
3246 *s++ = 0;
3247 ecol[3].ec_value.ec_value_val = t;
3248 ecol[3].ec_value.ec_value_len = strlen(t)+1;
3249 t = s;
3252 * shadow max (col 4)
3254 if ((s = strchr(t, ':')) == 0) {
3255 (void) strlcpy(parse_err_msg, gettext("Improper format"),
3256 PARSE_ERR_MSG_LEN);
3257 return (GENENT_PARSEERR);
3259 *s++ = 0;
3260 ecol[4].ec_value.ec_value_val = t;
3261 ecol[4].ec_value.ec_value_len = strlen(t)+1;
3262 t = s;
3265 * shadow warn (col 5)
3267 if ((s = strchr(t, ':')) == 0) {
3268 (void) strlcpy(parse_err_msg, gettext("Improper format"),
3269 PARSE_ERR_MSG_LEN);
3270 return (GENENT_PARSEERR);
3272 *s++ = 0;
3273 ecol[5].ec_value.ec_value_val = t;
3274 ecol[5].ec_value.ec_value_len = strlen(t)+1;
3275 t = s;
3278 * shadow inactive (col 6)
3280 if ((s = strchr(t, ':')) != 0) {
3281 *s++ = 0;
3282 ecol[6].ec_value.ec_value_val = t;
3283 ecol[6].ec_value.ec_value_len = strlen(t)+1;
3284 t = s;
3288 * shadow expire (col 7)
3290 if ((s = strchr(t, ':')) != 0) {
3291 *s++ = 0;
3292 ecol[7].ec_value.ec_value_val = t;
3293 ecol[7].ec_value.ec_value_len = strlen(t)+1;
3294 t = s;
3297 * flag (col 8)
3299 ecol[8].ec_value.ec_value_val = t;
3300 ecol[8].ec_value.ec_value_len = strlen(t)+1;
3304 * build entry
3307 data.sp_namp = strdup(ecol[0].ec_value.ec_value_val);
3309 if (ecol[1].ec_value.ec_value_val != NULL &&
3310 ecol[1].ec_value.ec_value_val[0] != '\0') {
3311 /* Add {crypt} before passwd entry */
3312 (void) snprintf(pname, sizeof (pname), "{crypt}%s",
3313 ecol[1].ec_value.ec_value_val);
3314 data.sp_pwdp = strdup(pname);
3315 } else {
3317 * no password (e.g., deleted by "passwd -d"):
3318 * use the special value NS_LDAP_NO_UNIX_PASSWORD
3319 * instead.
3321 (void) snprintf(pname, sizeof (pname), "{crypt}%s",
3322 NS_LDAP_NO_UNIX_PASSWORD);
3323 data.sp_pwdp = strdup(pname);
3326 if (ecol[2].ec_value.ec_value_val != NULL &&
3327 ecol[2].ec_value.ec_value_val[0] != '\0') {
3329 data.sp_lstchg = ascii_to_int(ecol[2].ec_value.ec_value_val);
3330 if (data.sp_lstchg < -1) {
3331 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3332 gettext("invalid last changed date: %s"),
3333 ecol[2].ec_value.ec_value_val);
3334 return (GENENT_PARSEERR);
3336 } else
3337 data.sp_lstchg = -1;
3339 if (ecol[3].ec_value.ec_value_val != NULL &&
3340 ecol[3].ec_value.ec_value_val[0] != '\0') {
3342 data.sp_min = ascii_to_int(ecol[3].ec_value.ec_value_val);
3343 if (data.sp_min < -1) {
3344 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3345 gettext("invalid sp_min : %s"),
3346 ecol[3].ec_value.ec_value_val);
3347 return (GENENT_PARSEERR);
3349 } else
3350 data.sp_min = -1;
3352 if (ecol[4].ec_value.ec_value_val != NULL &&
3353 ecol[4].ec_value.ec_value_val[0] != '\0') {
3355 data.sp_max = ascii_to_int(ecol[4].ec_value.ec_value_val);
3356 if (data.sp_max < -1) {
3357 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3358 gettext("invalid sp_max : %s"),
3359 ecol[4].ec_value.ec_value_val);
3360 return (GENENT_PARSEERR);
3362 } else
3363 data.sp_max = -1;
3365 if (ecol[5].ec_value.ec_value_val != NULL &&
3366 ecol[5].ec_value.ec_value_val[0] != '\0') {
3368 data.sp_warn = ascii_to_int(ecol[5].ec_value.ec_value_val);
3369 if (data.sp_warn < -1) {
3370 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3371 gettext("invalid sp_warn : %s"),
3372 ecol[5].ec_value.ec_value_val);
3373 return (GENENT_PARSEERR);
3375 } else
3376 data.sp_warn = -1;
3378 if (ecol[6].ec_value.ec_value_val != NULL &&
3379 ecol[6].ec_value.ec_value_val[0] != '\0') {
3381 data.sp_inact = ascii_to_int(ecol[6].ec_value.ec_value_val);
3382 if (data.sp_inact < -1) {
3383 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3384 gettext("invalid sp_inact : %s"),
3385 ecol[6].ec_value.ec_value_val);
3386 return (GENENT_PARSEERR);
3388 } else
3389 data.sp_inact = -1;
3391 if (ecol[7].ec_value.ec_value_val != NULL &&
3392 ecol[7].ec_value.ec_value_val[0] != '\0') {
3394 data.sp_expire = ascii_to_int(ecol[7].ec_value.ec_value_val);
3395 if (data.sp_expire < -1) {
3396 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3397 gettext("invalid login expiry date : %s"),
3398 ecol[7].ec_value.ec_value_val);
3399 return (GENENT_PARSEERR);
3401 } else
3402 data.sp_expire = -1;
3404 if (ecol[8].ec_value.ec_value_val != NULL &&
3405 ecol[8].ec_value.ec_value_val[0] != '\0') {
3408 * data.sp_flag is an unsigned int,
3409 * assign -1 to it, make no sense.
3410 * Use spflag here to avoid lint warning.
3412 spflag = ascii_to_int(ecol[8].ec_value.ec_value_val);
3413 if (spflag < 0) {
3414 (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
3415 gettext("invalid flag value: %s"),
3416 ecol[8].ec_value.ec_value_val);
3417 return (GENENT_PARSEERR);
3418 } else
3419 data.sp_flag = spflag;
3420 } else
3421 data.sp_flag = 0;
3423 if (flags & F_VERBOSE)
3424 (void) fprintf(stdout,
3425 gettext("Adding entry : %s\n"), data.sp_namp);
3427 retval = (*cback)(&data, 1);
3428 if (retval != NS_LDAP_SUCCESS) {
3429 if (retval == LDAP_NO_SUCH_OBJECT)
3430 (void) fprintf(stdout,
3431 gettext("Cannot add shadow entry (%s), "
3432 "add passwd entry first\n"), data.sp_namp);
3433 if (continue_onerror == 0)
3434 return (GENENT_CBERR);
3437 free(data.sp_namp);
3438 free(data.sp_pwdp);
3439 return (GENENT_OK);
3442 static void
3443 dump_shadow(ns_ldap_result_t *res)
3445 char **value = NULL;
3446 char pnam[256];
3448 value = __ns_ldap_getAttr(res->entry, "uid");
3449 if (value == NULL)
3450 return;
3451 else
3452 (void) fprintf(stdout, "%s:", value[0]);
3453 value = __ns_ldap_getAttr(res->entry, "userPassword");
3454 if (value == NULL)
3455 (void) fprintf(stdout, "*:");
3456 else {
3457 (void) strcpy(pnam, value[0]);
3458 if (strncasecmp(value[0], "{crypt}", 7) == 0) {
3459 if (strcmp(pnam + 7, NS_LDAP_NO_UNIX_PASSWORD) == 0)
3460 (void) fprintf(stdout, ":");
3461 else
3462 (void) fprintf(stdout, "%s:", (pnam+7));
3463 } else
3464 (void) fprintf(stdout, "*:");
3466 value = __ns_ldap_getAttr(res->entry, "shadowLastChange");
3467 if (value == NULL)
3468 (void) fprintf(stdout, ":");
3469 else
3470 (void) fprintf(stdout, "%s:", value[0]);
3471 value = __ns_ldap_getAttr(res->entry, "shadowMin");
3472 if (value == NULL)
3473 (void) fprintf(stdout, ":");
3474 else
3475 (void) fprintf(stdout, "%s:", value[0]);
3476 value = __ns_ldap_getAttr(res->entry, "shadowMax");
3477 if (value == NULL)
3478 (void) fprintf(stdout, ":");
3479 else
3480 (void) fprintf(stdout, "%s:", value[0]);
3482 value = __ns_ldap_getAttr(res->entry, "shadowWarning");
3483 if (value == NULL)
3484 (void) fprintf(stdout, ":");
3485 else
3486 (void) fprintf(stdout, "%s:", value[0]);
3488 value = __ns_ldap_getAttr(res->entry, "shadowInactive");
3489 if (value == NULL)
3490 (void) fprintf(stdout, ":");
3491 else
3492 (void) fprintf(stdout, "%s:", value[0]);
3494 value = __ns_ldap_getAttr(res->entry, "shadowExpire");
3495 if (value == NULL)
3496 (void) fprintf(stdout, ":");
3497 else
3498 (void) fprintf(stdout, "%s:", value[0]);
3500 value = __ns_ldap_getAttr(res->entry, "shadowFlag");
3501 if (value == NULL || value[0] == NULL || strcmp(value[0], "0") == 0)
3502 (void) fprintf(stdout, "\n");
3503 else
3504 (void) fprintf(stdout, "%s\n", value[0]);
3507 static int
3508 genent_bootparams(char *line, int (*cback)())
3510 char buf[BUFSIZ+1];
3511 char *t;
3512 entry_col ecol[2];
3513 int ctr = 0, retval = 1;
3515 struct _ns_bootp data;
3516 char *parameter;
3517 int rc = GENENT_OK;
3520 * don't clobber our argument
3522 if (strlen(line) >= sizeof (buf)) {
3523 (void) strlcpy(parse_err_msg, gettext("line too long"),
3524 PARSE_ERR_MSG_LEN);
3525 return (GENENT_PARSEERR);
3527 (void) strcpy(buf, line);
3530 * clear column data
3532 (void) memset((char *)ecol, 0, sizeof (ecol));
3536 * cname (col 0)
3538 if ((t = strtok(buf, " \t")) == 0) {
3539 (void) strlcpy(parse_err_msg, gettext("no cname"),
3540 PARSE_ERR_MSG_LEN);
3541 return (GENENT_PARSEERR);
3543 ecol[0].ec_value.ec_value_val = t;
3544 ecol[0].ec_value.ec_value_len = strlen(t)+1;
3548 /* build entry */
3549 data.name = strdup(ecol[0].ec_value.ec_value_val);
3552 * name (col 1)
3555 data.param = NULL;
3557 while (t = strtok(NULL, " \t")) {
3560 * don't clobber comment in canonical entry
3564 ecol[1].ec_value.ec_value_val = t;
3565 ecol[1].ec_value.ec_value_len = strlen(t)+1;
3567 ctr++;
3568 parameter = strdup(ecol[1].ec_value.ec_value_val);
3569 if ((data.param = (char **)realloc(data.param,
3570 (ctr + 1) * sizeof (char **))) == NULL) {
3571 (void) fprintf(stderr, gettext("out of memory\n"));
3572 exit(1);
3574 data.param[ctr-1] = parameter;
3579 /* End the list of all the aliases by NULL */
3580 if ((data.param = (char **)realloc(data.param,
3581 (ctr + 1) * sizeof (char **))) == NULL) {
3582 (void) fprintf(stderr, gettext("out of memory\n"));
3583 exit(1);
3585 data.param[ctr] = NULL;
3587 if (flags & F_VERBOSE)
3588 (void) fprintf(stdout,
3589 gettext("Adding entry : %s\n"), data.name);
3591 retval = (*cback)(&data, 0);
3593 if (retval == LDAP_ALREADY_EXISTS) {
3594 if (continue_onerror)
3595 (void) fprintf(stderr,
3596 gettext("Entry: %s - already Exists,"
3597 " skipping it.\n"), data.name);
3598 else {
3599 rc = GENENT_CBERR;
3600 (void) fprintf(stderr,
3601 gettext("Entry: %s - already Exists\n"),
3602 data.name);
3604 } else if (retval)
3605 rc = GENENT_CBERR;
3607 free(data.name);
3608 free(data.param);
3610 return (rc);
3615 * Count number of tokens in string which has tokens separated by colons.
3617 * NULL or "" - 0 tokens
3618 * "foo" - 1 token
3619 * "foo:bar" - 2 tokens
3620 * ":bar" - 2 tokens, first empty
3621 * "::" - 3 tokens, all empty
3623 static int
3624 count_tokens(char *string, char delim)
3626 int i = 0;
3627 char *s = string;
3629 if (string == NULL || *string == '\0')
3630 return (0);
3632 /* Count delimiters */
3633 while ((s = strchr(s, delim)) != NULL && *s != '\0') {
3634 i++;
3635 s++;
3638 return (i + 1);
3641 static int
3642 genent_project(char *line, int (*cback)())
3644 char buf[BUFSIZ+1];
3645 char *b = buf;
3646 char *s;
3647 int rc = GENENT_OK, retval;
3648 int index = 0;
3649 struct project data;
3651 (void) memset(&data, 0, sizeof (struct project));
3654 * don't clobber our argument
3656 if (strlen(line) >= sizeof (buf)) {
3657 (void) strlcpy(parse_err_msg, gettext("line too long"),
3658 PARSE_ERR_MSG_LEN);
3659 return (GENENT_PARSEERR);
3662 if (count_tokens(line, ':') != 6) {
3663 (void) strlcpy(parse_err_msg, gettext("Improper format"),
3664 PARSE_ERR_MSG_LEN);
3665 return (GENENT_PARSEERR);
3668 (void) strcpy(buf, line);
3670 s = strsep(&b, ":");
3671 while (s != NULL) {
3672 switch (index) {
3673 /* Project name */
3674 case 0:
3675 if (check_projname(s) != 0) {
3676 (void) strlcpy(parse_err_msg,
3677 gettext("invalid project name"),
3678 PARSE_ERR_MSG_LEN);
3679 return (GENENT_PARSEERR);
3680 } else {
3681 data.pj_name = strdup(s);
3683 break;
3685 /* Project ID */
3686 case 1:
3688 char *endptr = NULL;
3689 int projid = strtoul(s, &endptr, 10);
3691 if (*s == '\0' || strlen(endptr) != 0 || projid < 0 ||
3692 projid > MAXPROJID) {
3693 (void) strlcpy(parse_err_msg,
3694 gettext("invalid project id"),
3695 PARSE_ERR_MSG_LEN);
3696 return (GENENT_PARSEERR);
3697 } else {
3698 data.pj_projid = projid;
3700 break;
3703 /* Project description */
3704 case 2:
3705 if (*s != '\0')
3706 data.pj_comment = strdup(s);
3707 break;
3709 /* Project users */
3710 case 3:
3712 if (*s == '\0')
3713 break;
3715 char *usrlist = strdup(s);
3716 int i = 0;
3717 int usr_count = count_tokens(usrlist, ',');
3718 char *u = strsep(&usrlist, ",");
3720 if (usr_count == 0) {
3721 free(usrlist);
3722 break;
3725 /* +1 to NULL-terminate the array */
3726 data.pj_users = (char **)calloc(usr_count + 1,
3727 sizeof (char *));
3729 while (u != NULL) {
3730 data.pj_users[i++] = strdup(u);
3731 u = strsep(&usrlist, ",");
3734 free(usrlist);
3735 break;
3738 /* Project groups */
3739 case 4:
3741 if (*s == '\0')
3742 break;
3744 char *grouplist = strdup(s);
3745 int i = 0;
3746 int grp_count = count_tokens(grouplist, ',');
3747 char *g = strsep(&grouplist, ",");
3749 if (grp_count == 0) {
3750 free(grouplist);
3751 break;
3754 /* +1 to NULL-terminate the array */
3755 data.pj_groups = (char **)calloc(grp_count + 1,
3756 sizeof (char *));
3758 while (g != NULL) {
3759 data.pj_groups[i++] = strdup(g);
3760 g = strsep(&grouplist, ",");
3763 free(grouplist);
3764 break;
3767 /* Attributes */
3768 case 5:
3769 if (*s != '\0')
3770 data.pj_attr = strdup(s);
3772 break;
3775 /* Next token */
3776 s = strsep(&b, ":");
3777 index++;
3780 if (flags & F_VERBOSE)
3781 (void) fprintf(stdout,
3782 gettext("Adding entry : %s\n"), data.pj_name);
3784 retval = (*cback)(&data, 0);
3786 if (retval == LDAP_ALREADY_EXISTS) {
3787 if (continue_onerror)
3788 (void) fprintf(stderr,
3789 gettext("Entry: %s - already Exists,"
3790 " skipping it.\n"), data.pj_name);
3791 else {
3792 rc = GENENT_CBERR;
3793 (void) fprintf(stderr,
3794 gettext("Entry: %s - already Exists\n"),
3795 data.pj_name);
3797 } else if (retval)
3798 rc = GENENT_CBERR;
3800 /* Clean up */
3801 free(data.pj_name);
3802 free(data.pj_attr);
3803 if (data.pj_users != NULL) {
3804 for (index = 0; data.pj_users[index] != NULL; index++)
3805 free(data.pj_users[index]);
3806 free(data.pj_users);
3808 if (data.pj_groups != NULL) {
3809 for (index = 0; data.pj_groups[index] != NULL; index++)
3810 free(data.pj_groups[index]);
3811 free(data.pj_groups);
3814 return (rc);
3817 static void
3818 dump_project(ns_ldap_result_t *res)
3820 char **value = NULL;
3821 char *endptr = NULL;
3822 int projid;
3824 if (res == NULL || res->entry == NULL)
3825 return;
3827 /* Sanity checking */
3828 value = __ns_ldap_getAttr(res->entry, "SolarisProjectID");
3830 if (value[0] == NULL)
3831 return;
3833 projid = strtoul(value[0], &endptr, 10);
3834 if (*value[0] == '\0' || strlen(endptr) != 0 || projid < 0 ||
3835 projid > MAXPROJID)
3836 return;
3838 value = __ns_ldap_getAttr(res->entry, "SolarisProjectName");
3839 if (value && value[0] && check_projname(value[0]) == 0)
3840 (void) fprintf(stdout, "%s:", value[0]);
3841 else
3842 return;
3844 (void) fprintf(stdout, "%d:", projid);
3846 value = __ns_ldap_getAttr(res->entry, "description");
3847 if (value && value[0])
3848 (void) fprintf(stdout, "%s:", value[0]);
3849 else
3850 (void) fprintf(stdout, ":");
3852 value = __ns_ldap_getAttr(res->entry, "memberUid");
3853 if (value) {
3854 int i;
3855 for (i = 0; value[i] != NULL; i++)
3856 if (value[i+1] != NULL)
3857 (void) fprintf(stdout, "%s,", value[i]);
3858 else
3859 (void) fprintf(stdout, "%s:", value[i]);
3860 } else {
3861 (void) fprintf(stdout, ":");
3864 value = __ns_ldap_getAttr(res->entry, "memberGid");
3865 if (value) {
3866 int i;
3867 for (i = 0; value[i] != NULL; i++)
3868 if (value[i+1] != NULL)
3869 (void) fprintf(stdout, "%s,", value[i]);
3870 else
3871 (void) fprintf(stdout, "%s:", value[i]);
3872 } else {
3873 (void) fprintf(stdout, ":");
3876 value = __ns_ldap_getAttr(res->entry, "SolarisProjectAttr");
3877 if (value && value[0])
3878 (void) fprintf(stdout, "%s\n", value[0]);
3879 else
3880 (void) fprintf(stdout, "\n");
3884 static void
3885 dump_bootparams(ns_ldap_result_t *res)
3887 char **value = NULL;
3888 int attr_count = 0;
3890 value = __ns_ldap_getAttr(res->entry, "cn");
3891 if (value[0] != NULL)
3892 (void) fprintf(stdout, "%s", value[0]);
3893 value = __ns_ldap_getAttr(res->entry, "bootParameter");
3894 if (value != NULL)
3895 while (value[attr_count] != NULL) {
3896 (void) fprintf(stdout, "\t%s", value[attr_count]);
3897 attr_count++;
3899 (void) fprintf(stdout, "\n");
3904 static char *
3905 fget_line_at(struct line_buf *line, int n, FILE *fp)
3907 int c;
3909 line->len = n;
3911 for (;;) {
3912 c = fgetc(fp);
3913 if (c == -1)
3914 break;
3915 if (line->len >= line->alloc)
3916 line_buf_expand(line);
3917 line->str[line->len++] = c;
3919 if (c == '\n')
3920 break;
3923 /* Null Terminate */
3924 if (line->len >= line->alloc)
3925 line_buf_expand(line);
3926 line->str[line->len++] = 0;
3928 /* if no characters are read, return NULL to indicate EOF */
3929 if (line->str[0] == '\0')
3930 return (0);
3932 return (line->str);
3936 * return a line from the file, discarding comments and blank lines
3938 static int
3939 filedbmline_comment(struct line_buf *line, FILE *etcf, int *lineno,
3940 struct file_loc *loc)
3942 int i, len = 0;
3944 loc->offset = ftell(etcf);
3945 for (;;) {
3946 if (fget_line_at(line, len, etcf) == 0)
3947 return (0);
3949 if (lineno)
3950 (*lineno)++;
3952 len = strlen(line->str);
3953 if (len >= 2 &&
3954 line->str[0] != '#' &&
3955 line->str[len-2] == '\\' && line->str[len-1] == '\n') {
3956 line->str[len-2] = 0;
3957 len -= 2;
3958 continue; /* append next line at end */
3961 if (line->str[len-1] == '\n') {
3962 line->str[len-1] = 0;
3963 len -= 1;
3967 * Skip lines where '#' is the first non-blank character.
3969 for (i = 0; i < len; i++) {
3970 if (line->str[i] == '#') {
3971 line->str[i] = '\0';
3972 len = i;
3973 break;
3975 if (line->str[i] != ' ' && line->str[i] != '\t')
3976 break;
3980 * A line with one or more white space characters followed
3981 * by a comment will now be blank. The special case of a
3982 * line with '#' in the first byte will have len == 0.
3984 if (len > 0 && !blankline(line->str))
3985 break;
3987 len = 0;
3988 loc->offset = ftell(etcf);
3991 loc->size = len;
3992 return (1);
3996 * return a line from the file, discarding comments, blanks, and '+' lines
3998 static int
3999 filedbmline_plus(struct line_buf *line, FILE *etcf, int *lineno,
4000 struct file_loc *loc)
4002 int len = 0;
4004 loc->offset = ftell(etcf);
4005 for (;;) {
4006 if (fget_line_at(line, len, etcf) == 0)
4007 return (0);
4009 if (lineno)
4010 (*lineno)++;
4012 len = strlen(line->str);
4013 if (line->str[len-1] == '\n') {
4014 line->str[len-1] = 0;
4015 len -= 1;
4018 if (!blankline(line->str) &&
4019 line->str[0] != '+' && line->str[0] != '-' &&
4020 line->str[0] != '#')
4021 break;
4023 len = 0;
4024 loc->offset = ftell(etcf);
4027 loc->size = len;
4028 return (1);
4032 /* Populating the ttypelist structure */
4034 static struct ttypelist_t ttypelist[] = {
4035 { NS_LDAP_TYPE_HOSTS, genent_hosts, dump_hosts,
4036 filedbmline_comment, "iphost", "cn" },
4037 { NS_LDAP_TYPE_IPNODES, genent_hosts, dump_hosts,
4038 filedbmline_comment, "iphost", "cn" },
4039 { NS_LDAP_TYPE_RPC, genent_rpc, dump_rpc,
4040 filedbmline_comment, "oncrpc", "cn" },
4041 { NS_LDAP_TYPE_PROTOCOLS, genent_protocols, dump_protocols,
4042 filedbmline_comment, "ipprotocol", "cn" },
4043 { NS_LDAP_TYPE_NETWORKS, genent_networks, dump_networks,
4044 filedbmline_comment, "ipnetwork", "ipnetworknumber" },
4045 { NS_LDAP_TYPE_SERVICES, genent_services, dump_services,
4046 filedbmline_comment, "ipservice", "cn" },
4047 { NS_LDAP_TYPE_GROUP, genent_group, dump_group,
4048 filedbmline_plus, "posixgroup", "gidnumber" },
4049 { NS_LDAP_TYPE_NETMASKS, genent_netmasks, dump_netmasks,
4050 filedbmline_comment, "ipnetwork", "ipnetworknumber"},
4051 { NS_LDAP_TYPE_ETHERS, genent_ethers, dump_ethers,
4052 filedbmline_comment, "ieee802Device", "cn" },
4053 { NS_LDAP_TYPE_NETGROUP, genent_netgroup, dump_netgroup,
4054 filedbmline_comment, "nisnetgroup", "cn" },
4055 { NS_LDAP_TYPE_BOOTPARAMS, genent_bootparams, dump_bootparams,
4056 filedbmline_comment, "bootableDevice", "cn" },
4057 { NS_LDAP_TYPE_PUBLICKEY, genent_publickey, NULL /* dump_publickey */,
4058 filedbmline_comment, "niskeyobject", "cn" },
4059 { NS_LDAP_TYPE_PASSWD, genent_passwd, dump_passwd,
4060 filedbmline_plus, "posixaccount", "uid" },
4061 { NS_LDAP_TYPE_SHADOW, genent_shadow, dump_shadow,
4062 filedbmline_plus, "shadowaccount", "uid" },
4063 { NS_LDAP_TYPE_ALIASES, genent_aliases, dump_aliases,
4064 filedbmline_plus, "mailGroup", "cn" },
4065 { NS_LDAP_TYPE_AUTOMOUNT, genent_automount, dump_automount,
4066 filedbmline_comment, "automount", "automountKey" },
4067 { NS_LDAP_TYPE_USERATTR, genent_user_attr, dump_user_attr,
4068 filedbmline_comment, "SolarisUserAttr", "uid" },
4069 { NS_LDAP_TYPE_PROFILE, genent_prof_attr, dump_prof_attr,
4070 filedbmline_comment, "SolarisProfAttr", "cn" },
4071 { NS_LDAP_TYPE_EXECATTR, genent_exec_attr, dump_exec_attr,
4072 filedbmline_comment, "SolarisExecAttr", "cn" },
4073 { NS_LDAP_TYPE_AUTHATTR, genent_auth_attr, dump_auth_attr,
4074 filedbmline_comment, "SolarisAuthAttr", "cn" },
4075 { NS_LDAP_TYPE_PROJECT, genent_project, dump_project,
4076 filedbmline_comment, "SolarisProject", "SolarisProjectName" },
4077 { 0, 0, 0, 0, 0, 0 }
4083 static int lineno = 0;
4085 static void
4086 addfile()
4088 struct line_buf line;
4089 struct file_loc loc;
4091 /* Initializing the Line Buffer */
4092 line_buf_init(&line);
4094 /* Loop through all the lines in the file */
4095 while (tt->filedbmline(&line, etcf, &lineno, &loc)) {
4096 switch ((*(tt->genent))(line.str, addentry)) {
4097 case GENENT_OK:
4098 break;
4099 case GENENT_PARSEERR:
4100 (void) fprintf(stderr,
4101 gettext("parse error: %s (line %d)\n"),
4102 parse_err_msg, lineno);
4103 exit_val = 1;
4104 break;
4105 case GENENT_CBERR:
4106 (void) fprintf(stderr,
4107 gettext("Error while adding line: %s\n"),
4108 line.str);
4109 exit_val = 2;
4110 free(line.str);
4111 return;
4112 case GENENT_ERR:
4113 (void) fprintf(stderr,
4114 gettext("Internal Error while adding line: %s\n"),
4115 line.str);
4116 exit_val = 3;
4117 free(line.str);
4118 return;
4121 free(line.str);
4124 static void
4125 dumptable(char *service)
4128 ns_ldap_result_t *eres = NULL;
4129 ns_ldap_error_t *err = NULL;
4130 int rc = 0, success = 0;
4131 char filter[BUFSIZ];
4132 int done = 0;
4133 void *cookie = NULL;
4135 /* set the appropriate filter */
4136 if (strcmp(tt->ttype, NS_LDAP_TYPE_PROFILE) == 0) {
4138 * prof_attr entries are SolarisProfAttr
4139 * without AUXILIARY SolarisExecAttr
4141 (void) snprintf(filter, sizeof (filter),
4142 "(&(objectclass=%s)(!(objectclass=SolarisExecAttr)))",
4143 tt->objclass);
4144 } else {
4145 (void) snprintf(filter, sizeof (filter),
4146 "(objectclass=%s)", tt->objclass);
4149 if (flags & F_VERBOSE)
4150 (void) fprintf(stdout, gettext("FILTER = %s\n"), filter);
4152 /* Pass cred only if supplied. Cred is not always needed for dump */
4153 if (authority.cred.unix_cred.userID == NULL ||
4154 authority.cred.unix_cred.passwd == NULL)
4155 rc = __ns_ldap_firstEntry(service, filter, tt->sortattr, NULL,
4156 NULL, NULL, NS_LDAP_HARD, &cookie, &eres, &err, NULL);
4157 else
4158 rc = __ns_ldap_firstEntry(service, filter, tt->sortattr, NULL,
4159 NULL, &authority, NS_LDAP_HARD, &cookie, &eres, &err, NULL);
4161 switch (rc) {
4162 case NS_LDAP_SUCCESS:
4163 nent_add++;
4164 success = 1;
4165 if (eres != NULL) {
4166 if (strcmp(databasetype, "publickey") == 0)
4167 dump_publickey(eres, service);
4168 else
4169 (*(tt->dump))(eres);
4171 else
4172 (void) fprintf(stderr, gettext("No entries found.\n"));
4173 break;
4175 case NS_LDAP_OP_FAILED:
4176 exit_val = 2;
4177 (void) fprintf(stderr, gettext("operation failed.\n"));
4178 break;
4180 case NS_LDAP_INVALID_PARAM:
4181 exit_val = 2;
4182 (void) fprintf(stderr,
4183 gettext("invalid parameter(s) passed.\n"));
4184 break;
4186 case NS_LDAP_NOTFOUND:
4187 exit_val = 2;
4188 (void) fprintf(stderr, gettext("entry not found.\n"));
4189 break;
4191 case NS_LDAP_MEMORY:
4192 exit_val = 2;
4193 (void) fprintf(stderr,
4194 gettext("internal memory allocation error.\n"));
4195 break;
4197 case NS_LDAP_CONFIG:
4198 exit_val = 2;
4199 (void) fprintf(stderr,
4200 gettext("LDAP Configuration problem.\n"));
4201 perr(err);
4202 break;
4204 case NS_LDAP_PARTIAL:
4205 exit_val = 2;
4206 (void) fprintf(stderr,
4207 gettext("partial result returned\n"));
4208 perr(err);
4209 break;
4211 case NS_LDAP_INTERNAL:
4212 exit_val = 2;
4213 (void) fprintf(stderr,
4214 gettext("internal LDAP error occured.\n"));
4215 perr(err);
4216 break;
4219 if (eres != NULL) {
4220 (void) __ns_ldap_freeResult(&eres);
4221 eres = NULL;
4224 if (success) {
4225 while (!done) {
4226 rc = __ns_ldap_nextEntry(cookie, &eres, &err);
4227 if (rc != NS_LDAP_SUCCESS || eres == NULL) {
4228 done = 1;
4229 continue;
4232 /* Print the result */
4233 if (eres != NULL) {
4234 if (strcmp(databasetype, "publickey") == 0)
4235 dump_publickey(eres, service);
4236 else
4237 (*(tt->dump))(eres);
4238 (void) __ns_ldap_freeResult(&eres);
4239 eres = NULL;
4246 main(int argc, char **argv)
4248 char *password;
4249 ns_standalone_conf_t standalone_cfg = standaloneDefaults;
4250 int c;
4251 int rc;
4252 int ldaprc;
4253 int authstried = 0;
4254 int op = OP_ADD;
4255 char *ttype, *authmech = 0, *etcfile = 0;
4256 /* Temporary password variable */
4257 char ps[LDAP_MAXNAMELEN];
4258 char filter[BUFSIZ];
4259 void **paramVal = NULL;
4260 ns_auth_t **app;
4261 ns_auth_t **authpp = NULL;
4262 ns_auth_t *authp = NULL;
4263 ns_ldap_error_t *errorp = NULL;
4264 ns_ldap_result_t *resultp;
4265 ns_ldap_entry_t *e;
4266 int flag = 0;
4267 int version1 = 0;
4269 (void) setlocale(LC_ALL, "");
4270 (void) textdomain(TEXT_DOMAIN);
4272 openlog("ldapaddent", LOG_PID, LOG_USER);
4274 inputbasedn = NULL;
4275 authority.cred.unix_cred.passwd = NULL;
4276 authority.cred.unix_cred.userID = NULL;
4277 authority.auth.type = NS_LDAP_AUTH_SIMPLE;
4279 while ((c = getopt(argc, argv, "cdh:N:M:vpf:D:w:j:b:a:P:r:")) != EOF) {
4280 switch (c) {
4281 case 'd':
4282 if (op)
4283 usage(gettext(
4284 "no other option should be specified"));
4285 op = OP_DUMP;
4286 break;
4287 case 'c':
4288 continue_onerror = 1;
4289 break;
4290 case 'v':
4291 flags |= F_VERBOSE;
4292 break;
4293 case 'p':
4294 flags |= F_PASSWD;
4295 break;
4296 case 'M':
4297 standalone_cfg.type = NS_LDAP_SERVER;
4298 standalone_cfg.SA_DOMAIN = optarg;
4299 break;
4300 case 'h':
4301 standalone_cfg.type = NS_LDAP_SERVER;
4302 if (separatePort(optarg,
4303 &standalone_cfg.SA_SERVER,
4304 &standalone_cfg.SA_PORT) > 0) {
4305 exit(1);
4307 break;
4308 case 'P':
4309 standalone_cfg.type = NS_LDAP_SERVER;
4310 authority.hostcertpath = optarg;
4311 break;
4312 case 'N':
4313 standalone_cfg.type = NS_LDAP_SERVER;
4314 standalone_cfg.SA_PROFILE_NAME = optarg;
4315 break;
4316 case 'f':
4317 etcfile = optarg;
4318 break;
4319 case 'D':
4320 authority.cred.unix_cred.userID = strdup(optarg);
4321 break;
4322 case 'w':
4323 if (authority.cred.unix_cred.passwd) {
4324 (void) fprintf(stderr,
4325 gettext("Warning: The -w option is mutually"
4326 " exclusive of -j. -w is ignored.\n"));
4327 break;
4330 if (optarg != NULL &&
4331 optarg[0] == '-' && optarg[1] == '\0') {
4332 /* Ask for a password later */
4333 break;
4336 authority.cred.unix_cred.passwd = strdup(optarg);
4337 break;
4338 case 'j':
4339 if (authority.cred.unix_cred.passwd != NULL) {
4340 (void) fprintf(stderr,
4341 gettext("The -w option is mutually "
4342 "exclusive of -j. -w is ignored.\n"));
4343 free(authority.cred.unix_cred.passwd);
4345 authority.cred.unix_cred.passwd = readPwd(optarg);
4346 if (authority.cred.unix_cred.passwd == NULL) {
4347 exit(1);
4349 break;
4350 case 'b':
4351 inputbasedn = strdup(optarg);
4352 break;
4353 case 'a':
4354 authmech = strdup(optarg);
4355 break;
4356 default:
4357 usage(gettext("Invalid option"));
4361 if (standalone_cfg.type == NS_LDAP_SERVER &&
4362 standalone_cfg.SA_SERVER == NULL) {
4363 (void) fprintf(stderr,
4364 gettext("Please specify an LDAP server you want "
4365 "to connect to. \n"));
4366 exit(1);
4369 if (authmech != NULL) {
4370 if (__ns_ldap_initAuth(authmech, &authority.auth, &errorp) !=
4371 NS_LDAP_SUCCESS) {
4372 if (errorp) {
4373 (void) fprintf(stderr, "%s", errorp->message);
4374 (void) __ns_ldap_freeError(&errorp);
4376 exit(1);
4380 if (authority.auth.saslmech != NS_LDAP_SASL_GSSAPI &&
4381 authority.cred.unix_cred.userID == NULL &&
4382 op != OP_DUMP) {
4383 /* This is not an optional parameter. Exit */
4384 (void) fprintf(stderr,
4385 gettext("DN must be specified unless SASL/GSSAPI is used."
4386 " Use option -D.\n"));
4387 exit(1);
4390 if (authority.auth.saslmech != NS_LDAP_SASL_GSSAPI &&
4391 authority.cred.unix_cred.passwd == NULL &&
4392 (op != OP_DUMP ||
4393 standalone_cfg.type != NS_CACHEMGR &&
4394 authority.cred.unix_cred.userID != NULL)) {
4395 /* If password is not specified, then prompt user for it. */
4396 password = getpassphrase("Enter password:");
4397 (void) strcpy(ps, password);
4398 authority.cred.unix_cred.passwd = strdup(ps);
4401 standalone_cfg.SA_AUTH = authmech == NULL ? NULL : &authority.auth;
4402 standalone_cfg.SA_CERT_PATH = authority.hostcertpath;
4403 standalone_cfg.SA_BIND_DN = authority.cred.unix_cred.userID;
4404 standalone_cfg.SA_BIND_PWD = authority.cred.unix_cred.passwd;
4406 if (__ns_ldap_initStandalone(&standalone_cfg,
4407 &errorp) != NS_LDAP_SUCCESS) {
4408 if (errorp) {
4409 (void) fprintf(stderr, "%s", errorp->message);
4411 exit(1);
4414 if (authmech == NULL) {
4415 ldaprc = __ns_ldap_getParam(NS_LDAP_AUTH_P, (void ***)&authpp,
4416 &errorp);
4417 if (ldaprc != NS_LDAP_SUCCESS ||
4418 (authpp == NULL && op != OP_DUMP)) {
4419 (void) fprintf(stderr,
4420 gettext("No legal authentication method "
4421 "configured.\n"));
4422 (void) fprintf(stderr,
4423 gettext("Provide a legal authentication method "
4424 "using -a option\n"));
4425 exit(1);
4428 /* Use the first authentication method which is not none */
4429 for (app = authpp; *app; app++) {
4430 authp = *app;
4431 if (authp->type != NS_LDAP_AUTH_NONE) {
4432 authstried++;
4433 authority.auth.type = authp->type;
4434 authority.auth.tlstype = authp->tlstype;
4435 authority.auth.saslmech = authp->saslmech;
4436 authority.auth.saslopt = authp->saslopt;
4437 break;
4440 if (authstried == 0 && op != OP_DUMP) {
4441 (void) fprintf(stderr,
4442 gettext("No legal authentication method configured."
4443 "\nProvide a legal authentication method using "
4444 "-a option"));
4445 exit(1);
4447 if (authority.auth.saslmech == NS_LDAP_SASL_GSSAPI &&
4448 authority.cred.unix_cred.passwd != NULL &&
4449 authority.cred.unix_cred.userID != NULL) {
4451 * -a is not specified and the auth method sasl/GSSAPI
4452 * is defined in the configuration of the ldap profile.
4453 * Even -D and -w is provided it's not valid usage.
4454 * Drop them on the floor.
4457 (void) fprintf(stderr,
4458 gettext("The default authentication is "
4459 "sasl/GSSAPI.\n"
4460 "The bind DN and password will be ignored.\n"));
4461 authority.cred.unix_cred.passwd = NULL;
4462 authority.cred.unix_cred.userID = NULL;
4466 ttype = argv[optind++];
4468 if (ttype == NULL) {
4469 usage(gettext("No database type specified"));
4470 exit(1);
4473 if (strncasecmp(ttype, "automount", 9) == 0) {
4474 (void) fprintf(stderr,
4475 gettext("automount is not a valid service for ldapaddent.\n"
4476 "Please use auto_*.\n"
4477 "e.g. auto_home, auto_ws etc.\n "));
4478 exit(1);
4481 for (tt = ttypelist; tt->ttype; tt++) {
4482 if (strcmp(tt->ttype, ttype) == 0)
4483 break;
4484 if (strcmp(tt->ttype, NS_LDAP_TYPE_AUTOMOUNT) == 0 &&
4485 strncmp(ttype, NS_LDAP_TYPE_AUTOMOUNT,
4486 sizeof (NS_LDAP_TYPE_AUTOMOUNT) - 1) == 0)
4487 break;
4490 if (tt->ttype == 0) {
4491 (void) fprintf(stderr,
4492 gettext("database %s not supported;"
4493 " supported databases are:\n"), ttype);
4494 for (tt = ttypelist; tt->ttype; tt++)
4495 (void) fprintf(stderr, gettext("\t%s\n"), tt->ttype);
4496 exit(1);
4499 if (flags & F_VERBOSE)
4500 (void) fprintf(stdout, gettext("SERVICE = %s\n"), tt->ttype);
4502 databasetype = ttype;
4504 if (strcmp(tt->ttype, NS_LDAP_TYPE_AUTOMOUNT) == 0) {
4505 paramVal = NULL;
4506 errorp = NULL;
4507 rc = __ns_ldap_getParam(NS_LDAP_FILE_VERSION_P, &paramVal,
4508 &errorp);
4509 if (paramVal && *paramVal &&
4510 strcasecmp(*paramVal, NS_LDAP_VERSION_1) == 0)
4511 version1 = 1;
4512 if (paramVal)
4513 (void) __ns_ldap_freeParam(&paramVal);
4514 if (errorp)
4515 (void) __ns_ldap_freeError(&errorp);
4518 /* Check if the container exists in first place */
4519 (void) strcpy(&filter[0], "(objectclass=*)");
4521 rc = __ns_ldap_list(databasetype, filter, NULL, (const char **)NULL,
4522 NULL, NS_LDAP_SCOPE_BASE, &resultp, &errorp, NULL, NULL);
4524 /* create a container for auto_* if it does not exist already */
4525 if ((rc == NS_LDAP_NOTFOUND) && (op == OP_ADD) &&
4526 (strcmp(tt->ttype, NS_LDAP_TYPE_AUTOMOUNT) == 0)) {
4527 static char *oclist[] = {NULL, "top", NULL};
4528 if (version1)
4529 oclist[0] = "nisMap";
4530 else
4531 oclist[0] = "automountMap";
4532 e = __s_mk_entry(oclist, 3);
4533 if (e == NULL) {
4534 (void) fprintf(stderr,
4535 gettext("internal memory allocation error.\n"));
4536 exit(1);
4538 if (__s_add_attr(e,
4539 version1 ? "nisMapName" : "automountMapName",
4540 databasetype) != NS_LDAP_SUCCESS) {
4541 (void) fprintf(stderr,
4542 gettext("internal memory allocation error.\n"));
4543 ldap_freeEntry(e);
4544 exit(1);
4547 if (inputbasedn == NULL) {
4548 if (get_basedn(databasetype, &inputbasedn) !=
4549 NS_LDAP_SUCCESS) {
4550 (void) fprintf(stderr,
4551 gettext("Could not obtain basedn\n"));
4552 ldap_freeEntry(e);
4553 exit(1);
4556 if (__ns_ldap_addEntry(databasetype, inputbasedn, e,
4557 &authority, flag, &errorp) != NS_LDAP_SUCCESS) {
4558 (void) fprintf(stderr,
4559 gettext("Could not create container for %s\n"),
4560 databasetype);
4561 ldap_freeEntry(e);
4563 } else if (strcmp(databasetype, "publickey") != 0) {
4564 if (rc == NS_LDAP_NOTFOUND) {
4565 (void) fprintf(stderr,
4566 gettext("Container %s does not exist\n"),
4567 databasetype);
4568 exit(1);
4572 if (op == OP_DUMP) {
4573 if (strcmp(databasetype, "publickey") == 0) {
4574 dumptable("hosts");
4575 dumptable("passwd");
4576 } else {
4577 dumptable(databasetype);
4579 exit(exit_val);
4582 if (etcfile) {
4583 if ((etcf = fopen(etcfile, "r")) == 0) {
4584 (void) fprintf(stderr,
4585 gettext("can't open file %s\n"), etcfile);
4586 exit(1);
4588 } else {
4589 etcfile = "stdin";
4590 etcf = stdin;
4593 if (op == OP_ADD) {
4594 (void) addfile();
4595 (void) fprintf(stdout, gettext("%d entries added\n"), nent_add);
4598 __ns_ldap_cancelStandalone();
4599 /* exit() -> return for make lint */
4600 return (exit_val);
4605 * This is called when service == auto_*.
4606 * It calls __ns_ldap_getSearchDescriptors
4607 * to generate the dn from SSD's base dn.
4608 * If there is no SSD available,
4609 * default base dn will be used
4610 * Only the first baseDN in the SSD is used
4613 static int get_basedn(char *service, char **basedn) {
4614 int rc = NS_LDAP_SUCCESS;
4615 char *dn = NULL;
4616 ns_ldap_search_desc_t **desc = NULL;
4617 ns_ldap_error_t *errp = NULL;
4618 void **paramVal = NULL;
4619 int prepend_automountmapname = FALSE;
4622 * Get auto_* SSD first
4625 if ((rc = __ns_ldap_getSearchDescriptors(
4626 (const char *) service,
4627 &desc, &errp)) == NS_LDAP_SUCCESS &&
4628 desc != NULL) {
4630 if (desc[0] != NULL && desc[0]->basedn != NULL) {
4631 dn = strdup(desc[0]->basedn);
4632 if (dn == NULL) {
4633 (void) __ns_ldap_freeSearchDescriptors
4634 (&desc);
4635 return (NS_LDAP_MEMORY);
4640 /* clean up */
4641 if (desc) (void) __ns_ldap_freeSearchDescriptors(&desc);
4642 if (errp) (void) __ns_ldap_freeError(&errp);
4645 * If no dn is duplicated from auto_* SSD, try automount SSD
4647 if (dn == NULL) {
4648 if ((rc = __ns_ldap_getSearchDescriptors(
4649 "automount", &desc, &errp))
4650 == NS_LDAP_SUCCESS && desc != NULL) {
4652 if (desc[0] != NULL && desc[0]->basedn != NULL) {
4653 dn = strdup(desc[0]->basedn);
4654 if (dn == NULL) {
4655 (void) __ns_ldap_freeSearchDescriptors
4656 (&desc);
4657 return (NS_LDAP_MEMORY);
4659 prepend_automountmapname = TRUE;
4662 /* clean up */
4663 if (desc) (void) __ns_ldap_freeSearchDescriptors(&desc);
4664 if (errp) (void) __ns_ldap_freeError(&errp);
4668 * If no dn is duplicated from auto_* or automount SSD,
4669 * use default DN
4672 if (dn == NULL) {
4673 if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_BASEDN_P,
4674 &paramVal, &errp)) == NS_LDAP_SUCCESS) {
4675 dn = strdup((char *)paramVal[0]);
4676 if (dn == NULL) {
4677 (void) __ns_ldap_freeParam(&paramVal);
4678 return (NS_LDAP_MEMORY);
4680 prepend_automountmapname = TRUE;
4682 if (paramVal) (void) __ns_ldap_freeParam(&paramVal);
4683 if (errp) (void) __ns_ldap_freeError(&errp);
4687 if (dn == NULL) {
4688 return (NS_LDAP_OP_FAILED);
4689 } else {
4691 * If dn is duplicated from
4692 * automount SSD basedn or
4693 * default base dn
4694 * then prepend automountMapName=auto_xxx
4696 if (prepend_automountmapname)
4697 rc = __s_api_prepend_automountmapname_to_dn(
4698 service, &dn, &errp);
4700 if (rc != NS_LDAP_SUCCESS) {
4701 (void) __ns_ldap_freeError(&errp);
4702 free(dn);
4703 return (rc);
4706 *basedn = dn;
4708 return (NS_LDAP_SUCCESS);
4711 static char *
4712 h_errno2str(int h_errno) {
4713 switch (h_errno) {
4714 case HOST_NOT_FOUND:
4715 return ("HOST_NOT_FOUND");
4716 case TRY_AGAIN:
4717 return ("TRY_AGAIN");
4718 case NO_RECOVERY:
4719 return ("NO_RECOVERY");
4720 case NO_DATA:
4721 return ("NO_DATA");
4722 default:
4723 break;
4725 return ("UNKNOWN_ERROR");