1N/A/*
1N/A * CDDL HEADER START
1N/A *
1N/A * The contents of this file are subject to the terms of the
1N/A * Common Development and Distribution License (the "License").
1N/A * You may not use this file except in compliance with the License.
1N/A *
1N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1N/A * or http://www.opensolaris.org/os/licensing.
1N/A * See the License for the specific language governing permissions
1N/A * and limitations under the License.
1N/A *
1N/A * When distributing Covered Code, include this CDDL HEADER in each
1N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1N/A * If applicable, add the following below this CDDL HEADER, with the
1N/A * fields enclosed by brackets "[]" replaced with your own identifying
1N/A * information: Portions Copyright [yyyy] [name of copyright owner]
1N/A *
1N/A * CDDL HEADER END
1N/A */
1N/A/*
1N/A * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
1N/A */
1N/A
1N/A/*
1N/A * ldapaddent.c
1N/A *
1N/A * Utility to add /etc files into LDAP.
1N/A * Can also be used to dump entries from a ldap container in /etc format.
1N/A */
1N/A
1N/A#include <stdio.h>
1N/A#include <stdlib.h>
1N/A#include <libintl.h>
1N/A#include <strings.h>
1N/A#include <sys/param.h>
1N/A#include <ctype.h>
1N/A#include <sys/types.h>
1N/A#include <sys/socket.h>
1N/A#include <netinet/in.h>
1N/A#include <arpa/inet.h>
1N/A#include <locale.h>
1N/A#include <syslog.h>
1N/A
1N/A#undef opaque
1N/A
1N/A#include <nss_dbdefs.h>
1N/A#include <netdb.h>
1N/A#include <rpc/rpcent.h>
1N/A#include <grp.h>
1N/A#include <pwd.h>
1N/A#include <project.h>
1N/A#include <shadow.h>
1N/A#include <sys/systeminfo.h>
1N/A#include "ns_internal.h"
1N/A#include "ldapaddent.h"
1N/A#include "standalone.h"
1N/A
1N/A#define OP_ADD 0
1N/A#define OP_DUMP 3
1N/A
1N/Astatic struct ttypelist_t {
1N/A char *ttype; /* type tag */
1N/A int (*genent)(char *, int(*)());
1N/A /* routine to turn line into ldap entries */
1N/A void (*dump)(ns_ldap_result_t *);
1N/A /* routine to print ldap containers */
1N/A int (*filedbmline)(); /* routine to turn file line into dbm line */
1N/A char *objclass; /* Objectclass for the servicetype */
1N/A char *sortattr; /* Sort attr for enumeration */
1N/A} *tt;
1N/A
1N/Achar parse_err_msg [PARSE_ERR_MSG_LEN];
1N/Aint continue_onerror = 0; /* do not exit on error */
1N/A
1N/Astatic int get_basedn(char *service, char **basedn);
1N/Astatic int check_ipaddr(char *addr, char **newaddr);
1N/Astatic int check_projname(char *addr);
1N/A
1N/Aextern int optind;
1N/Aextern char *optarg;
1N/A
1N/Aextern char *__nis_quote_key(const char *, char *, int);
1N/A
1N/Astatic char *inputbasedn = NULL;
1N/Astatic char *databasetype = NULL;
1N/Astatic int exit_val = 0;
1N/Astatic unsigned nent_add = 0;
1N/Astatic FILE *etcf = 0;
1N/Astatic ns_cred_t authority;
1N/Aunsigned flags = 0;
1N/A
1N/Astatic void
1N/Aperr(ns_ldap_error_t *e)
1N/A{
1N/A if (e)
1N/A (void) fprintf(stderr, "%d: %s\n",
1N/A e->status, e->message);
1N/A}
1N/A
1N/A
1N/Astatic int
1N/Aascii_to_int(char *str)
1N/A{
1N/A int i;
1N/A char *c = str;
1N/A
1N/A if (c == NULL || *c == '\0')
1N/A return (-1);
1N/A
1N/A while (c != '\0' && *c == ' ')
1N/A c++;
1N/A if (*c == '\0')
1N/A return (-1);
1N/A
1N/A for (i = 0; i < strlen(c); i++)
1N/A if (!isdigit(c[i]))
1N/A return (-1);
1N/A
1N/A return (atoi(c));
1N/A}
1N/A
1N/A/*
1N/A * Internet network address interpretation routine.
1N/A * The library routines call this routine to interpret
1N/A * network numbers.
1N/A */
1N/Astatic in_addr_t
1N/Aencode_network(const char *cp)
1N/A{
1N/A in_addr_t val;
1N/A int base;
1N/A ptrdiff_t n;
1N/A char c;
1N/A in_addr_t parts[4], *pp = parts;
1N/A int i;
1N/A
1N/Aagain:
1N/A val = 0; base = 10;
1N/A if (*cp == '0') {
1N/A if (*++cp == 'x' || *cp == 'X')
1N/A base = 16, cp++;
1N/A else
1N/A base = 8;
1N/A }
1N/A while ((c = *cp) != NULL) {
1N/A if (isdigit(c)) {
1N/A if ((c - '0') >= base)
1N/A break;
1N/A val = (val * base) + (c - '0');
1N/A cp++;
1N/A continue;
1N/A }
1N/A if (base == 16 && isxdigit(c)) {
1N/A val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
1N/A cp++;
1N/A continue;
1N/A }
1N/A break;
1N/A }
1N/A if (*cp == '.') {
1N/A if (pp >= parts + 4)
1N/A return ((in_addr_t)-1);
1N/A *pp++ = val, cp++;
1N/A goto again;
1N/A }
1N/A if (*cp && !isspace(*cp))
1N/A return ((in_addr_t)-1);
1N/A *pp++ = val;
1N/A n = pp - parts;
1N/A if (n > 4)
1N/A return ((in_addr_t)-1);
1N/A for (val = 0, i = 0; i < n; i++) {
1N/A val <<= 8;
1N/A val |= parts[i] & 0xff;
1N/A }
1N/A for (/* no init */; i < 4; i++)
1N/A val <<= 8;
1N/A return (val);
1N/A}
1N/A
1N/Astatic void
1N/Areplace_tab2space(char *str)
1N/A{
1N/A int i = 0;
1N/A
1N/A while ((str) && (str[i])) {
1N/A if (str[i] == '\t')
1N/A str[i] = ' ';
1N/A i++;
1N/A }
1N/A}
1N/A
1N/Astatic int
1N/Ablankline(char *line)
1N/A{
1N/A char *p;
1N/A
1N/A for (p = line; *p; p++)
1N/A if (*p != ' ' && *p != '\t')
1N/A return (0);
1N/A return (1);
1N/A}
1N/A
1N/A/*
1N/A * check whether the token <tok> is a triplet,
1N/A * i. e. <tok> := (<hostname>,<username>,<domainname>)
1N/A * where <hostname>, <username>, <domainname> are IA5String
1N/A * <tok> supposes to contain NO spaces and start with '('
1N/A */
1N/Astatic int
1N/Ais_triplet(char *tok)
1N/A{
1N/A char *s;
1N/A return (strchr(++tok, '(') == NULL && /* no more '(' */
1N/A (s = strchr(tok, ')')) != NULL && /* find ')' */
1N/A !*++s && /* ')' ends token */
1N/A (tok = strchr(tok, ',')) != NULL && /* host up to ',' */
1N/A (tok = strchr(++tok, ',')) != NULL && /* user up to ',' */
1N/A strchr(++tok, ',') == NULL); /* no more ',' */
1N/A}
1N/A
1N/Astatic void
1N/Aline_buf_expand(struct line_buf *line)
1N/A{
1N/A line->alloc += BUFSIZ;
1N/A line->str = (char *)realloc(line->str, line->alloc);
1N/A
1N/A if (line->str == NULL) {
1N/A (void) fprintf(stderr,
1N/A gettext("line_buf_expand: out of memory\n"));
1N/A exit(1);
1N/A }
1N/A}
1N/A
1N/Astatic void
1N/Aline_buf_init(struct line_buf *line)
1N/A{
1N/A (void) memset((char *)line, 0, sizeof (*line));
1N/A line_buf_expand(line);
1N/A}
1N/A
1N/Astatic int
1N/A__s_add_attr(ns_ldap_entry_t *e, char *attrname, char *value)
1N/A{
1N/A ns_ldap_attr_t *a;
1N/A char *v;
1N/A
1N/A a = (ns_ldap_attr_t *)calloc(1, sizeof (ns_ldap_attr_t));
1N/A if (a == NULL)
1N/A return (NS_LDAP_MEMORY);
1N/A a->attrname = strdup(attrname);
1N/A if (a->attrname == NULL) {
1N/A free(a);
1N/A return (NS_LDAP_MEMORY);
1N/A }
1N/A a->attrvalue = (char **)calloc(1, sizeof (char **));
1N/A if (a->attrvalue == NULL) {
1N/A free(a->attrname);
1N/A free(a);
1N/A return (NS_LDAP_MEMORY);
1N/A }
1N/A a->value_count = 1;
1N/A a->attrvalue[0] = NULL;
1N/A v = strdup(value);
1N/A if (v == NULL) {
1N/A free(a->attrname);
1N/A free(a->attrvalue);
1N/A free(a);
1N/A return (NS_LDAP_MEMORY);
1N/A }
1N/A a->attrvalue[0] = v;
1N/A e->attr_pair[e->attr_count] = a;
1N/A e->attr_count++;
1N/A return (NS_LDAP_SUCCESS);
1N/A}
1N/A
1N/Astatic int
1N/A__s_add_attrlist(ns_ldap_entry_t *e, char *attrname, char **argv)
1N/A{
1N/A ns_ldap_attr_t *a;
1N/A char *v;
1N/A char **av;
1N/A int i, j;
1N/A
1N/A a = (ns_ldap_attr_t *)calloc(1, sizeof (ns_ldap_attr_t));
1N/A if (a == NULL)
1N/A return (NS_LDAP_MEMORY);
1N/A a->attrname = strdup(attrname);
1N/A if (a->attrname == NULL) {
1N/A free(a);
1N/A return (NS_LDAP_MEMORY);
1N/A }
1N/A
1N/A for (i = 0, av = argv; *av != NULL; av++, i++)
1N/A ;
1N/A
1N/A a->attrvalue = (char **)calloc(i, sizeof (char **));
1N/A
1N/A if (a->attrvalue == NULL) {
1N/A free(a->attrname);
1N/A free(a);
1N/A return (NS_LDAP_MEMORY);
1N/A }
1N/A a->value_count = i;
1N/A for (j = 0; j < i; j++) {
1N/A v = strdup(argv[j]);
1N/A if (v == NULL) {
1N/A free(a->attrname);
1N/A free(a->attrvalue);
1N/A free(a);
1N/A return (NS_LDAP_MEMORY);
1N/A }
1N/A a->attrvalue[j] = v;
1N/A }
1N/A e->attr_pair[e->attr_count] = a;
1N/A e->attr_count++;
1N/A return (NS_LDAP_SUCCESS);
1N/A}
1N/A
1N/Astatic ns_ldap_entry_t *
1N/A__s_mk_entry(char **objclass, int max_attr)
1N/A{
1N/A ns_ldap_entry_t *e;
1N/A e = (ns_ldap_entry_t *)calloc(1, sizeof (ns_ldap_entry_t));
1N/A if (e == NULL)
1N/A return (NULL);
1N/A e->attr_pair = (ns_ldap_attr_t **)calloc(max_attr+1,
1N/A sizeof (ns_ldap_attr_t *));
1N/A if (e->attr_pair == NULL) {
1N/A free(e);
1N/A return (NULL);
1N/A }
1N/A e->attr_count = 0;
1N/A if (__s_add_attrlist(e, "objectClass", objclass) != NS_LDAP_SUCCESS) {
1N/A free(e->attr_pair);
1N/A free(e);
1N/A return (NULL);
1N/A }
1N/A return (e);
1N/A}
1N/A
1N/Astatic void
1N/Aldap_freeEntry(ns_ldap_entry_t *ep)
1N/A{
1N/A int j, k = 0;
1N/A
1N/A if (ep == NULL)
1N/A return;
1N/A
1N/A if (ep->attr_pair == NULL) {
1N/A free(ep);
1N/A return;
1N/A }
1N/A for (j = 0; j < ep->attr_count; j++) {
1N/A if (ep->attr_pair[j] == NULL)
1N/A continue;
1N/A if (ep->attr_pair[j]->attrname)
1N/A free(ep->attr_pair[j]->attrname);
1N/A if (ep->attr_pair[j]->attrvalue) {
1N/A for (k = 0; (k < ep->attr_pair[j]->value_count) &&
1N/A (ep->attr_pair[j]->attrvalue[k]); k++) {
1N/A free(ep->attr_pair[j]->attrvalue[k]);
1N/A }
1N/A free(ep->attr_pair[j]->attrvalue);
1N/A }
1N/A free(ep->attr_pair[j]);
1N/A }
1N/A free(ep->attr_pair);
1N/A free(ep);
1N/A}
1N/A
1N/Astatic int
1N/Aaddentry(void *entry, int mod)
1N/A{
1N/A int result = 0;
1N/A ns_ldap_error_t *eres = NULL;
1N/A int rc = 1;
1N/A
1N/A
1N/A /* adds entry into the LDAP tree */
1N/A if (mod)
1N/A result = __ns_ldap_addTypedEntry(databasetype, inputbasedn,
1N/A entry, 0, &authority, NS_LDAP_FOLLOWREF | NS_LDAP_KEEP_CONN,
1N/A &eres);
1N/A else
1N/A result = __ns_ldap_addTypedEntry(databasetype, inputbasedn,
1N/A entry, 1, &authority, NS_LDAP_FOLLOWREF | NS_LDAP_KEEP_CONN,
1N/A &eres);
1N/A /*
1N/A * Return 0 on success
1N/A * LDAP_ALREADY_EXISTS if entry exists already
1N/A * 1 for all other non-fatal errors.
1N/A * Exit on fatal errors.
1N/A */
1N/A switch (result) {
1N/A case NS_LDAP_SUCCESS:
1N/A nent_add++;
1N/A rc = 0;
1N/A break;
1N/A
1N/A case NS_LDAP_OP_FAILED:
1N/A (void) fprintf(stderr, gettext("operation failed.\n"));
1N/A rc = 1;
1N/A break;
1N/A
1N/A case NS_LDAP_INVALID_PARAM:
1N/A (void) fprintf(stderr,
1N/A gettext("invalid parameter(s) passed.\n"));
1N/A rc = 1;
1N/A break;
1N/A
1N/A case NS_LDAP_NOTFOUND:
1N/A (void) fprintf(stderr, gettext("entry not found.\n"));
1N/A rc = 1;
1N/A break;
1N/A
1N/A case NS_LDAP_MEMORY:
1N/A (void) fprintf(stderr,
1N/A gettext("internal memory allocation error.\n"));
1N/A exit(1);
1N/A break;
1N/A
1N/A case NS_LDAP_CONFIG:
1N/A (void) fprintf(stderr,
1N/A gettext("LDAP Configuration problem.\n"));
1N/A perr(eres);
1N/A exit(1);
1N/A break;
1N/A
1N/A case NS_LDAP_PARTIAL:
1N/A (void) fprintf(stderr,
1N/A gettext("partial result returned\n"));
1N/A perr(eres);
1N/A rc = 1;
1N/A break;
1N/A
1N/A case NS_LDAP_INTERNAL:
1N/A if (eres->status == LDAP_ALREADY_EXISTS ||
1N/A eres->status == LDAP_NO_SUCH_OBJECT)
1N/A rc = eres->status;
1N/A else if (eres->status == LDAP_INSUFFICIENT_ACCESS) {
1N/A (void) fprintf(stderr,
1N/A gettext("The user does not have permission"
1N/A " to add/modify entries\n"));
1N/A perr(eres);
1N/A exit(1);
1N/A } else {
1N/A rc = 1;
1N/A perr(eres);
1N/A }
1N/A break;
1N/A }
1N/A
1N/A if (eres)
1N/A (void) __ns_ldap_freeError(&eres);
1N/A return (rc);
1N/A}
1N/A
1N/A/*
1N/A * usage(char *msg)
1N/A * Display usage message to STDERR.
1N/A */
1N/Astatic void
1N/Ausage(char *msg) {
1N/A
1N/A if (msg)
1N/A (void) fprintf(stderr, "%s\n", msg);
1N/A
1N/A (void) fprintf(stderr, gettext(
1N/A "usage: ldapaddent [-cpv] [-a authenticationMethod] [-b baseDN]\n"
1N/A "-D bindDN [-w bindPassword] [-j passwdFile] [-f filename]\n"
1N/A "database\n"
1N/A "\n"
1N/A "usage: ldapaddent [-cpv] -asasl/GSSAPI [-b baseDN] [-f filename]\n"
1N/A "database\n"
1N/A "\n"
1N/A "usage: ldapaddent -d [-v] [-a authenticationMethod] [-D bindDN]\n"
1N/A "[-w bindPassword] [-j passwdFile] database\n"
1N/A "\n"
1N/A "usage: ldapaddent [-cpv] -h LDAP_server[:serverPort] [-M domainName]\n"
1N/A "[-N profileName] [-P certifPath] [-a authenticationMethod]\n"
1N/A "[-b baseDN] -D bindDN [-w bindPassword] [-f filename]\n"
1N/A "[-j passwdFile] database\n"
1N/A "\n"
1N/A "usage: ldapaddent [-cpv] -h LDAP_server[:serverPort] [-M domainName]\n"
1N/A "[-N profileName] [-P certifPath] -asasl/GSSAPI [-b baseDN]\n"
1N/A "[-f filename] database\n"
1N/A "\n"
1N/A "usage: ldapaddent -d [-v] -h LDAP_server[:serverPort]"
1N/A " [-M domainName]\n"
1N/A "[-N profileName] [-P certifPath] [-a authenticationMethod]\n"
1N/A "[-b baseDN] -D bindDN [-w bindPassword] [-j passwdFile]\n"
1N/A "database\n"));
1N/A exit(1);
1N/A}
1N/A
1N/A/*
1N/A * Determine if the given string is an IP address (IPv4 or IPv6).
1N/A * If so, it's converted to the preferred form (rfc2373) and
1N/A * *newaddr will point to the new address.
1N/A *
1N/A * Returns -2 : inet_ntop error
1N/A * -1 : not an IP address
1N/A * 0 : unsupported IP address (future use)
1N/A * AF_INET : IPv4
1N/A * AF_INET6 : IPv6
1N/A */
1N/Astatic int
1N/Acheck_ipaddr(char *addr, char **newaddr) {
1N/A ipaddr_t addr_ipv4 = 0;
1N/A in6_addr_t addr_ipv6;
1N/A
1N/A /* IPv6 */
1N/A if (inet_pton(AF_INET6, addr, &addr_ipv6) == 1) {
1N/A if (newaddr == NULL)
1N/A return (AF_INET6);
1N/A
1N/A /* Convert IPv4-mapped IPv6 address to IPv4 */
1N/A if (IN6_IS_ADDR_V4MAPPED(&addr_ipv6) ||
1N/A IN6_IS_ADDR_V4COMPAT(&addr_ipv6)) {
1N/A IN6_V4MAPPED_TO_IPADDR(&addr_ipv6, addr_ipv4);
1N/A if ((*newaddr = calloc(1, INET_ADDRSTRLEN)) == NULL) {
1N/A (void) fprintf(stderr,
1N/A gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A if (inet_ntop(AF_INET, &addr_ipv4, *newaddr,
1N/A INET_ADDRSTRLEN))
1N/A return (AF_INET6);
1N/A free(*newaddr);
1N/A return (-2);
1N/A }
1N/A
1N/A /* Processing general IPv6 addresses */
1N/A if ((*newaddr = calloc(1, INET6_ADDRSTRLEN)) == NULL) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A if (inet_ntop(AF_INET6, &addr_ipv6, *newaddr, INET6_ADDRSTRLEN))
1N/A return (AF_INET6);
1N/A free(*newaddr);
1N/A return (-2);
1N/A }
1N/A
1N/A /* Processing IPv4 addresses of the type d.d.d.d. */
1N/A if (inet_pton(AF_INET, addr, &addr_ipv4) == 1) {
1N/A if (newaddr == NULL)
1N/A return (AF_INET);
1N/A if ((*newaddr = calloc(1, INET_ADDRSTRLEN)) == NULL) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A if (inet_ntop(AF_INET, &addr_ipv4, *newaddr, INET_ADDRSTRLEN))
1N/A return (AF_INET);
1N/A free(*newaddr);
1N/A return (-2);
1N/A }
1N/A
1N/A /* Processing IPv4 addresses d.d.d , d.d and d */
1N/A if (inet_addr(addr) != (in_addr_t)-1) {
1N/A if (newaddr == NULL)
1N/A return (AF_INET);
1N/A if ((*newaddr = strdup(addr)) == NULL) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A return (AF_INET);
1N/A }
1N/A
1N/A return (-1);
1N/A}
1N/A
1N/A/*
1N/A * Verifies that project name meets the restrictions defined by project(4).
1N/A */
1N/Astatic int
1N/Acheck_projname(char *addr)
1N/A{
1N/A int i;
1N/A if (addr == NULL || *addr == '\0')
1N/A return (-1);
1N/A
1N/A for (i = 0; i < strlen(addr); i++) {
1N/A if (!isalpha(addr[i]) &&
1N/A !isdigit(addr[i]) &&
1N/A addr[i] != '_' &&
1N/A addr[i] != '-' &&
1N/A addr[i] != '.')
1N/A return (-1);
1N/A }
1N/A
1N/A return (0);
1N/A}
1N/A
1N/Astatic int
1N/Agenent_hosts(char *line, int (*cback)())
1N/A{
1N/A char buf[BUFSIZ+1];
1N/A char *t, *comment;
1N/A entry_col ecol[4];
1N/A char *cname, *pref_addr;
1N/A int ctr = 0, retval = 1;
1N/A int rc = GENENT_OK, af;
1N/A
1N/A struct hostent data;
1N/A char *alias;
1N/A
1N/A /*
1N/A * don't clobber our argument
1N/A */
1N/A if (strlen(line) >= sizeof (buf)) {
1N/A (void) strlcpy(parse_err_msg, gettext("line too long"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A (void) strcpy(buf, line);
1N/A
1N/A /*
1N/A * clear column data
1N/A */
1N/A (void) memset((char *)ecol, 0, sizeof (ecol));
1N/A
1N/A /*
1N/A * comment (col 3)
1N/A * All leading spaces will be deleted from the comment
1N/A */
1N/A ecol[3].ec_value.ec_value_val = "";
1N/A ecol[3].ec_value.ec_value_len = 0;
1N/A comment = t = strchr(buf, '#');
1N/A if (comment) {
1N/A do {
1N/A ++comment;
1N/A } while (*comment != '\0' && isspace(*comment));
1N/A if (*comment != '\0') {
1N/A *--comment = '#';
1N/A ecol[3].ec_value.ec_value_val = strdup(comment);
1N/A ecol[3].ec_value.ec_value_len = strlen(comment)+1;
1N/A }
1N/A
1N/A *t = '\0';
1N/A }
1N/A
1N/A /*
1N/A * addr(col 2)
1N/A */
1N/A if ((t = strtok(buf, " \t")) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no host"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A
1N/A af = check_ipaddr(t, &pref_addr);
1N/A if (af == -2) {
1N/A (void) strlcpy(parse_err_msg, gettext("Internal error"),
1N/A PARSE_ERR_MSG_LEN);
1N/A } else if (af == -1) {
1N/A (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
1N/A gettext("Invalid IP address: %s"), t);
1N/A } else if (flags & F_VERBOSE) {
1N/A if ((strncasecmp(t, pref_addr, strlen(t))) != 0) {
1N/A (void) fprintf(stdout,
1N/A gettext("IP address %s converted to %s\n"),
1N/A t, pref_addr);
1N/A }
1N/A }
1N/A
1N/A if (af < 0) {
1N/A (void) fprintf(stderr, "%s\n", parse_err_msg);
1N/A if (continue_onerror == 0)
1N/A return (GENENT_CBERR);
1N/A else
1N/A return (rc);
1N/A }
1N/A
1N/A ecol[2].ec_value.ec_value_val = pref_addr;
1N/A ecol[2].ec_value.ec_value_len = strlen(pref_addr)+1;
1N/A
1N/A /*
1N/A * cname (col 0)
1N/A */
1N/A if ((t = strtok(NULL, " \t")) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no cname"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A ecol[0].ec_value.ec_value_val = t;
1N/A ecol[0].ec_value.ec_value_len = strlen(t)+1;
1N/A cname = t;
1N/A
1N/A
1N/A /* build entry */
1N/A if ((data.h_addr_list = (char **)calloc(2, sizeof (char **))) == NULL) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A data.h_addr_list[0] = strdup(ecol[2].ec_value.ec_value_val);
1N/A data.h_addr_list[1] = NULL;
1N/A
1N/A free(pref_addr);
1N/A data.h_name = strdup(ecol[0].ec_value.ec_value_val);
1N/A
1N/A /*
1N/A * name (col 1)
1N/A */
1N/A
1N/A data.h_aliases = NULL;
1N/A
1N/A do {
1N/A /*
1N/A * don't clobber comment in canonical entry
1N/A */
1N/A
1N/A /* This call to AddEntry may move out of the loop */
1N/A /* This is because we have to call the function just once */
1N/A if (t != cname && strcasecmp(t, cname) == 0)
1N/A continue;
1N/A if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
1N/A continue;
1N/A
1N/A ecol[1].ec_value.ec_value_val = t;
1N/A ecol[1].ec_value.ec_value_len = strlen(t)+1;
1N/A
1N/A ctr++;
1N/A alias = strdup(ecol[1].ec_value.ec_value_val);
1N/A if ((data.h_aliases = (char **)realloc(data.h_aliases,
1N/A ctr * sizeof (char **))) == NULL) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A data.h_aliases[ctr-1] = alias;
1N/A } while (t = strtok(NULL, " \t"));
1N/A
1N/A /*
1N/A * End the list of all the aliases by NULL
1N/A * If there is some comment, it will be stored as the last entry
1N/A * in the list of the host aliases
1N/A */
1N/A if ((data.h_aliases = (char **)realloc(data.h_aliases,
1N/A (ecol[3].ec_value.ec_value_len != 0 ?
1N/A ctr + 2 : ctr + 1) * sizeof (char **))) == NULL) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A
1N/A if (ecol[3].ec_value.ec_value_len != 0) {
1N/A data.h_aliases[ctr++] = ecol[3].ec_value.ec_value_val;
1N/A }
1N/A data.h_aliases[ctr] = NULL;
1N/A
1N/A if (flags & F_VERBOSE)
1N/A (void) fprintf(stdout,
1N/A gettext("Adding entry : cn=%s+ipHostNumber=%s\n"),
1N/A data.h_name, data.h_addr_list[0]);
1N/A
1N/A retval = (*cback)(&data, 0);
1N/A
1N/A if (ecol[3].ec_value.ec_value_len != 0) {
1N/A free(ecol[3].ec_value.ec_value_val);
1N/A }
1N/A
1N/A if (retval == LDAP_ALREADY_EXISTS) {
1N/A if (continue_onerror)
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: cn=%s+ipHostNumber=%s "
1N/A "already Exists -skipping it\n"),
1N/A data.h_name, data.h_addr_list[0]);
1N/A else {
1N/A rc = GENENT_CBERR;
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: cn=%s+ipHostNumber=%s"
1N/A " already Exists\n"),
1N/A data.h_name, data.h_addr_list[0]);
1N/A }
1N/A } else if (retval)
1N/A rc = GENENT_CBERR;
1N/A
1N/A free(data.h_name);
1N/A free(data.h_aliases);
1N/A free(data.h_addr_list);
1N/A
1N/A return (rc);
1N/A}
1N/A
1N/A
1N/A
1N/Astatic void
1N/Adump_hosts(ns_ldap_result_t *res)
1N/A{
1N/A ns_ldap_attr_t *attrptr = NULL,
1N/A *cn = NULL,
1N/A *iphostnumber = NULL,
1N/A *desc = NULL;
1N/A int i, j;
1N/A char *name; /* host name */
1N/A
1N/A if (res == NULL || res->entry == NULL)
1N/A return;
1N/A for (i = 0; i < res->entry->attr_count; i++) {
1N/A attrptr = res->entry->attr_pair[i];
1N/A if (strcasecmp(attrptr->attrname, "cn") == 0)
1N/A cn = attrptr;
1N/A else if (strcasecmp(attrptr->attrname, "iphostnumber") == 0)
1N/A iphostnumber = attrptr;
1N/A else if (strcasecmp(attrptr->attrname, "description") == 0) {
1N/A desc = attrptr;
1N/A }
1N/A }
1N/A /* sanity check */
1N/A if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL ||
1N/A iphostnumber == NULL || iphostnumber->attrvalue == NULL ||
1N/A iphostnumber->attrvalue[0] == NULL)
1N/A return;
1N/A
1N/A if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL)
1N/A return;
1N/A
1N/A /* ip host/ipnode number */
1N/A if (strlen(iphostnumber->attrvalue[0]) <= INET_ADDRSTRLEN)
1N/A /* IPV4 or IPV6 but <= NET_ADDRSTRLEN */
1N/A (void) fprintf(stdout, "%-18s", iphostnumber->attrvalue[0]);
1N/A else
1N/A /* IPV6 */
1N/A (void) fprintf(stdout, "%-48s", iphostnumber->attrvalue[0]);
1N/A
1N/A /* host/ipnode name */
1N/A (void) fprintf(stdout, "%s ", name);
1N/A
1N/A /* aliases */
1N/A for (j = 0; j < cn->value_count; j++) {
1N/A if (cn->attrvalue[j]) {
1N/A if (strcasecmp(name, cn->attrvalue[j]) == 0)
1N/A /* skip host name */
1N/A continue;
1N/A (void) fprintf(stdout, "%s ", cn->attrvalue[j]);
1N/A }
1N/A }
1N/A
1N/A /* description */
1N/A if (desc != NULL && desc->attrvalue != NULL &&
1N/A desc->attrvalue[0] != NULL) {
1N/A (void) fprintf(stdout, "#%s", desc->attrvalue[0]);
1N/A }
1N/A
1N/A /* end of line */
1N/A (void) fprintf(stdout, "\n");
1N/A}
1N/A
1N/A/*
1N/A * /etc/rpc
1N/A */
1N/A
1N/Astatic int
1N/Agenent_rpc(char *line, int (*cback)())
1N/A{
1N/A char buf[BUFSIZ+1];
1N/A char *t;
1N/A entry_col ecol[4];
1N/A char *cname;
1N/A
1N/A struct rpcent data;
1N/A char *alias;
1N/A int ctr = 0;
1N/A int retval = 1;
1N/A int rc = GENENT_OK;
1N/A
1N/A /*
1N/A * don't clobber our argument
1N/A */
1N/A if (strlen(line) >= sizeof (buf)) {
1N/A (void) strlcpy(parse_err_msg, gettext("line too long"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A (void) strcpy(buf, line);
1N/A
1N/A /*
1N/A * clear column data
1N/A */
1N/A (void) memset((char *)ecol, 0, sizeof (ecol));
1N/A
1N/A /*
1N/A * comment (col 3)
1N/A */
1N/A t = strchr(buf, '#');
1N/A if (t) {
1N/A *t++ = 0;
1N/A ecol[3].ec_value.ec_value_val = t;
1N/A ecol[3].ec_value.ec_value_len = strlen(t)+1;
1N/A } else {
1N/A ecol[3].ec_value.ec_value_val = 0;
1N/A ecol[3].ec_value.ec_value_len = 0;
1N/A }
1N/A
1N/A /*
1N/A * cname(col 0)
1N/A */
1N/A if ((t = strtok(buf, " \t")) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no number"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A ecol[0].ec_value.ec_value_val = t;
1N/A ecol[0].ec_value.ec_value_len = strlen(t)+1;
1N/A cname = t;
1N/A
1N/A /*
1N/A * number (col 2)
1N/A */
1N/A if ((t = strtok(NULL, " \t")) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no number"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A ecol[2].ec_value.ec_value_val = t;
1N/A ecol[2].ec_value.ec_value_len = strlen(t)+1;
1N/A
1N/A
1N/A /*
1N/A * build entry
1N/A */
1N/A
1N/A data.r_name = strdup(ecol[0].ec_value.ec_value_val);
1N/A if (ecol[2].ec_value.ec_value_val != NULL &&
1N/A ecol[2].ec_value.ec_value_val[0] != '\0') {
1N/A
1N/A data.r_number = ascii_to_int(ecol[2].ec_value.ec_value_val);
1N/A if (data.r_number == -1) {
1N/A (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
1N/A gettext("invalid program number: %s"),
1N/A ecol[2].ec_value.ec_value_val);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A } else
1N/A data.r_number = -1;
1N/A
1N/A /*
1N/A * name (col 1)
1N/A */
1N/A t = cname;
1N/A data.r_aliases = NULL;
1N/A do {
1N/A
1N/A /*
1N/A * don't clobber comment in canonical entry
1N/A */
1N/A if (t != cname && strcasecmp(t, cname) == 0)
1N/A continue;
1N/A if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
1N/A continue;
1N/A
1N/A ecol[1].ec_value.ec_value_val = t;
1N/A ecol[1].ec_value.ec_value_len = strlen(t)+1;
1N/A
1N/A ctr++;
1N/A alias = strdup(ecol[1].ec_value.ec_value_val);
1N/A if ((data.r_aliases = (char **)realloc(data.r_aliases,
1N/A ctr * sizeof (char **))) == NULL) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A data.r_aliases[ctr-1] = alias;
1N/A
1N/A
1N/A /*
1N/A * only put comment in canonical entry
1N/A */
1N/A ecol[3].ec_value.ec_value_val = 0;
1N/A ecol[3].ec_value.ec_value_len = 0;
1N/A
1N/A } while (t = strtok(NULL, " \t"));
1N/A
1N/A /* End the list of all the aliases by NULL */
1N/A if ((data.r_aliases = (char **)realloc(data.r_aliases,
1N/A (ctr + 1) * sizeof (char **))) == NULL) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A data.r_aliases[ctr] = NULL;
1N/A
1N/A if (flags & F_VERBOSE)
1N/A (void) fprintf(stdout,
1N/A gettext("Adding entry : %s\n"), data.r_name);
1N/A
1N/A retval = (*cback)(&data, 0);
1N/A
1N/A if (retval == LDAP_ALREADY_EXISTS) {
1N/A if (continue_onerror)
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: %s - already Exists,"
1N/A " skipping it.\n"), data.r_name);
1N/A else {
1N/A rc = GENENT_CBERR;
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: %s - already Exists\n"),
1N/A data.r_name);
1N/A }
1N/A } else if (retval)
1N/A rc = GENENT_CBERR;
1N/A
1N/A free(data.r_name);
1N/A free(data.r_aliases);
1N/A
1N/A return (rc);
1N/A}
1N/A
1N/A
1N/A
1N/Astatic void
1N/Adump_rpc(ns_ldap_result_t *res)
1N/A{
1N/A ns_ldap_attr_t *attrptr = NULL, *cn = NULL, *rpcnumber = NULL;
1N/A int i, j;
1N/A char *name; /* rpc name */
1N/A
1N/A if (res == NULL || res->entry == NULL)
1N/A return;
1N/A for (i = 0; i < res->entry->attr_count; i++) {
1N/A attrptr = res->entry->attr_pair[i];
1N/A if (strcasecmp(attrptr->attrname, "cn") == 0)
1N/A cn = attrptr;
1N/A else if (strcasecmp(attrptr->attrname, "oncRpcNumber") == 0)
1N/A rpcnumber = attrptr;
1N/A }
1N/A /* sanity check */
1N/A if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL ||
1N/A rpcnumber == NULL || rpcnumber->attrvalue == NULL ||
1N/A rpcnumber->attrvalue[0] == NULL)
1N/A return;
1N/A
1N/A if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL)
1N/A return;
1N/A
1N/A /* rpc name */
1N/A if (strlen(name) < 8)
1N/A (void) fprintf(stdout, "%s\t\t", name);
1N/A else
1N/A (void) fprintf(stdout, "%s\t", name);
1N/A
1N/A /* rpc number */
1N/A (void) fprintf(stdout, "%-8s", rpcnumber->attrvalue[0]);
1N/A
1N/A
1N/A /* aliases */
1N/A for (j = 0; j < cn->value_count; j++) {
1N/A if (cn->attrvalue[j]) {
1N/A if (strcasecmp(name, cn->attrvalue[j]) == 0)
1N/A /* skip rpc name */
1N/A continue;
1N/A (void) fprintf(stdout, "%s ", cn->attrvalue[j]);
1N/A }
1N/A }
1N/A
1N/A /* end of line */
1N/A (void) fprintf(stdout, "\n");
1N/A
1N/A}
1N/A
1N/A/*
1N/A * /etc/protocols
1N/A *
1N/A */
1N/A
1N/Astatic int
1N/Agenent_protocols(char *line, int (*cback)())
1N/A{
1N/A char buf[BUFSIZ+1];
1N/A char *t;
1N/A entry_col ecol[4];
1N/A char *cname;
1N/A
1N/A struct protoent data;
1N/A char *alias;
1N/A int ctr = 0;
1N/A int retval = 1;
1N/A int rc = GENENT_OK;
1N/A
1N/A /*
1N/A * don't clobber our argument
1N/A */
1N/A if (strlen(line) >= sizeof (buf)) {
1N/A (void) strlcpy(parse_err_msg, gettext("line too long"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A (void) strcpy(buf, line);
1N/A
1N/A /*
1N/A * clear column data
1N/A */
1N/A (void) memset((char *)ecol, 0, sizeof (ecol));
1N/A
1N/A /*
1N/A * comment (col 3)
1N/A */
1N/A t = strchr(buf, '#');
1N/A if (t) {
1N/A *t++ = 0;
1N/A ecol[3].ec_value.ec_value_val = t;
1N/A ecol[3].ec_value.ec_value_len = strlen(t)+1;
1N/A } else {
1N/A ecol[3].ec_value.ec_value_val = 0;
1N/A ecol[3].ec_value.ec_value_len = 0;
1N/A }
1N/A
1N/A /*
1N/A * cname(col 0)
1N/A */
1N/A if ((t = strtok(buf, " \t")) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no number"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A ecol[0].ec_value.ec_value_val = t;
1N/A ecol[0].ec_value.ec_value_len = strlen(t)+1;
1N/A cname = t;
1N/A
1N/A /*
1N/A * number (col 2)
1N/A */
1N/A if ((t = strtok(NULL, " \t")) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no number"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A ecol[2].ec_value.ec_value_val = t;
1N/A ecol[2].ec_value.ec_value_len = strlen(t)+1;
1N/A
1N/A
1N/A /*
1N/A * build entry
1N/A */
1N/A data.p_name = strdup(ecol[0].ec_value.ec_value_val);
1N/A
1N/A if (ecol[2].ec_value.ec_value_val != NULL &&
1N/A ecol[2].ec_value.ec_value_val[0] != '\0') {
1N/A
1N/A data.p_proto = ascii_to_int(ecol[2].ec_value.ec_value_val);
1N/A if (data.p_proto == -1) {
1N/A (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
1N/A gettext("invalid protocol number: %s"),
1N/A ecol[2].ec_value.ec_value_val);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A } else
1N/A data.p_proto = -1;
1N/A
1N/A /*
1N/A * name (col 1)
1N/A */
1N/A t = cname;
1N/A ctr = 0;
1N/A data.p_aliases = NULL;
1N/A
1N/A do {
1N/A /*
1N/A * don't clobber comment in canonical entry
1N/A */
1N/A if (t != cname && strcasecmp(t, cname) == 0)
1N/A continue;
1N/A if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
1N/A continue;
1N/A
1N/A ecol[1].ec_value.ec_value_val = t;
1N/A ecol[1].ec_value.ec_value_len = strlen(t)+1;
1N/A
1N/A ctr++;
1N/A alias = strdup(ecol[1].ec_value.ec_value_val);
1N/A if ((data.p_aliases = (char **)realloc(data.p_aliases,
1N/A ctr * sizeof (char **))) == NULL) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A data.p_aliases[ctr-1] = alias;
1N/A
1N/A /*
1N/A * only put comment in canonical entry
1N/A */
1N/A ecol[3].ec_value.ec_value_val = 0;
1N/A ecol[3].ec_value.ec_value_len = 0;
1N/A
1N/A } while (t = strtok(NULL, " \t"));
1N/A
1N/A /* End the list of all the aliases by NULL */
1N/A if ((data.p_aliases = (char **)realloc(data.p_aliases,
1N/A (ctr + 1) * sizeof (char **))) == NULL) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A data.p_aliases[ctr] = NULL;
1N/A
1N/A if (flags & F_VERBOSE)
1N/A (void) fprintf(stdout,
1N/A gettext("Adding entry : %s\n"), data.p_name);
1N/A
1N/A retval = (*cback)(&data, 0);
1N/A
1N/A if (retval == LDAP_ALREADY_EXISTS) {
1N/A if (continue_onerror)
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: %s - already Exists,"
1N/A " skipping it.\n"), data.p_name);
1N/A else {
1N/A rc = GENENT_CBERR;
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: %s - already Exists\n"),
1N/A data.p_name);
1N/A }
1N/A } else if (retval)
1N/A rc = GENENT_CBERR;
1N/A
1N/A free(data.p_name);
1N/A free(data.p_aliases);
1N/A
1N/A return (rc);
1N/A}
1N/A
1N/A
1N/Astatic void
1N/Adump_protocols(ns_ldap_result_t *res)
1N/A{
1N/A ns_ldap_attr_t *attrptr = NULL, *cn = NULL, *protocolnumber = NULL;
1N/A int i, j;
1N/A char *name, *cp;
1N/A
1N/A if (res == NULL || res->entry == NULL)
1N/A return;
1N/A for (i = 0; i < res->entry->attr_count; i++) {
1N/A attrptr = res->entry->attr_pair[i];
1N/A if (strcasecmp(attrptr->attrname, "cn") == 0)
1N/A cn = attrptr;
1N/A else if (strcasecmp(attrptr->attrname, "ipProtocolNumber")
1N/A == 0)
1N/A protocolnumber = attrptr;
1N/A }
1N/A /* sanity check */
1N/A if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL ||
1N/A protocolnumber == NULL || protocolnumber->attrvalue == NULL ||
1N/A protocolnumber->attrvalue[0] == NULL)
1N/A return;
1N/A
1N/A if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL)
1N/A return;
1N/A
1N/A /* protocol name */
1N/A if (strlen(name) < 8)
1N/A (void) fprintf(stdout, "%s\t\t", name);
1N/A else
1N/A (void) fprintf(stdout, "%s\t", name);
1N/A
1N/A /* protocol number */
1N/A (void) fprintf(stdout, "%-16s", protocolnumber->attrvalue[0]);
1N/A
1N/A /* aliases */
1N/A for (j = 0; j < cn->value_count; j++) {
1N/A if (cn->attrvalue[j]) {
1N/A if (strcasecmp(name, cn->attrvalue[j]) == 0) {
1N/A if (cn->value_count > 1)
1N/A /* Do not replicate */
1N/A continue;
1N/A /*
1N/A * Replicate name in uppercase as an aliase
1N/A */
1N/A for (cp = cn->attrvalue[j]; *cp; cp++)
1N/A *cp = toupper(*cp);
1N/A }
1N/A (void) fprintf(stdout, "%s ", cn->attrvalue[j]);
1N/A }
1N/A }
1N/A
1N/A /* end of line */
1N/A (void) fprintf(stdout, "\n");
1N/A
1N/A}
1N/A
1N/A
1N/A
1N/A
1N/A
1N/A/*
1N/A * /etc/networks
1N/A *
1N/A */
1N/A
1N/Astatic int
1N/Agenent_networks(char *line, int (*cback)())
1N/A{
1N/A char buf[BUFSIZ+1];
1N/A char *t;
1N/A entry_col ecol[4];
1N/A char *cname;
1N/A
1N/A struct netent data;
1N/A char *alias;
1N/A int ctr = 0;
1N/A int retval = 1;
1N/A int enet;
1N/A int rc = GENENT_OK;
1N/A
1N/A /*
1N/A * don't clobber our argument
1N/A */
1N/A if (strlen(line) >= sizeof (buf)) {
1N/A (void) strlcpy(parse_err_msg, gettext("line too long"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A (void) strcpy(buf, line);
1N/A
1N/A /*
1N/A * clear column data
1N/A */
1N/A (void) memset((char *)ecol, 0, sizeof (ecol));
1N/A
1N/A /*
1N/A * comment (col 3)
1N/A */
1N/A t = strchr(buf, '#');
1N/A if (t) {
1N/A *t++ = 0;
1N/A ecol[3].ec_value.ec_value_val = t;
1N/A ecol[3].ec_value.ec_value_len = strlen(t)+1;
1N/A } else {
1N/A ecol[3].ec_value.ec_value_val = 0;
1N/A ecol[3].ec_value.ec_value_len = 0;
1N/A }
1N/A
1N/A /*
1N/A * cname(col 0)
1N/A */
1N/A if ((t = strtok(buf, " \t")) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no number"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A ecol[0].ec_value.ec_value_val = t;
1N/A ecol[0].ec_value.ec_value_len = strlen(t)+1;
1N/A cname = t;
1N/A
1N/A /*
1N/A * number (col 2)
1N/A */
1N/A if ((t = strtok(NULL, " \t")) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no number"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A ecol[2].ec_value.ec_value_val = t;
1N/A ecol[2].ec_value.ec_value_len = strlen(t)+1;
1N/A
1N/A
1N/A /*
1N/A * build entry
1N/A */
1N/A
1N/A data.n_name = strdup(ecol[0].ec_value.ec_value_val);
1N/A /*
1N/A * data.n_net is an unsigned field,
1N/A * assign -1 to it, make no sense.
1N/A * Use enet here to avoid lint warning.
1N/A */
1N/A enet = encode_network(ecol[2].ec_value.ec_value_val);
1N/A
1N/A if (enet == -1 && continue_onerror == 0) {
1N/A (void) fprintf(stderr, gettext("Invalid network number\n"));
1N/A if (continue_onerror == 0)
1N/A return (GENENT_CBERR);
1N/A } else
1N/A data.n_net = enet;
1N/A
1N/A /*
1N/A * name (col 1)
1N/A */
1N/A t = cname;
1N/A data.n_aliases = NULL;
1N/A
1N/A do {
1N/A /*
1N/A * don't clobber comment in canonical entry
1N/A */
1N/A if (t != cname && strcasecmp(t, cname) == 0)
1N/A continue;
1N/A if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
1N/A continue;
1N/A
1N/A ecol[1].ec_value.ec_value_val = t;
1N/A ecol[1].ec_value.ec_value_len = strlen(t)+1;
1N/A
1N/A ctr++;
1N/A alias = strdup(ecol[1].ec_value.ec_value_val);
1N/A if ((data.n_aliases = (char **)realloc(data.n_aliases,
1N/A ctr * sizeof (char **))) == NULL) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A data.n_aliases[ctr-1] = alias;
1N/A
1N/A /*
1N/A * only put comment in canonical entry
1N/A */
1N/A ecol[3].ec_value.ec_value_val = 0;
1N/A ecol[3].ec_value.ec_value_len = 0;
1N/A
1N/A } while (t = strtok(NULL, " \t"));
1N/A
1N/A /* End the list of all the aliases by NULL */
1N/A if ((data.n_aliases = (char **)realloc(data.n_aliases,
1N/A (ctr + 1) * sizeof (char **))) == NULL) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A data.n_aliases[ctr] = NULL;
1N/A
1N/A if (flags & F_VERBOSE)
1N/A (void) fprintf(stdout,
1N/A gettext("Adding entry : %s\n"), data.n_name);
1N/A
1N/A retval = (*cback)(&data, 0);
1N/A
1N/A if (retval == LDAP_ALREADY_EXISTS) {
1N/A if (continue_onerror)
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: %s - already Exists,"
1N/A " skipping it.\n"), data.n_name);
1N/A else {
1N/A rc = GENENT_CBERR;
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: %s - already Exists\n"),
1N/A data.n_name);
1N/A }
1N/A } else if (retval)
1N/A rc = GENENT_CBERR;
1N/A
1N/A free(data.n_name);
1N/A free(data.n_aliases);
1N/A
1N/A return (rc);
1N/A}
1N/A
1N/A
1N/Astatic void
1N/Adump_networks(ns_ldap_result_t *res)
1N/A{
1N/A ns_ldap_attr_t *attrptr = NULL, *cn = NULL, *networknumber = NULL;
1N/A int i, j;
1N/A char *name;
1N/A
1N/A if (res == NULL || res->entry == NULL)
1N/A return;
1N/A for (i = 0; i < res->entry->attr_count; i++) {
1N/A attrptr = res->entry->attr_pair[i];
1N/A if (strcasecmp(attrptr->attrname, "cn") == 0)
1N/A cn = attrptr;
1N/A else if (strcasecmp(attrptr->attrname, "ipNetworkNumber")
1N/A == 0)
1N/A networknumber = attrptr;
1N/A }
1N/A /* sanity check */
1N/A if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL ||
1N/A networknumber == NULL || networknumber->attrvalue == NULL ||
1N/A networknumber->attrvalue[0] == NULL)
1N/A return;
1N/A
1N/A /*
1N/A * cn can be a MUST attribute(RFC 2307) or MAY attribute(2307bis).
1N/A * If the canonical name can not be found (2307bis), use the 1st
1N/A * value as the official name.
1N/A */
1N/A
1N/A /* network name */
1N/A if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL)
1N/A name = cn->attrvalue[0];
1N/A
1N/A if (strlen(name) < 8)
1N/A (void) fprintf(stdout, "%s\t\t", name);
1N/A else
1N/A (void) fprintf(stdout, "%s\t", name);
1N/A
1N/A /* network number */
1N/A (void) fprintf(stdout, "%-16s", networknumber->attrvalue[0]);
1N/A
1N/A /* aliases */
1N/A for (j = 0; j < cn->value_count; j++) {
1N/A if (cn->attrvalue[j]) {
1N/A if (strcasecmp(name, cn->attrvalue[j]) == 0)
1N/A /* skip name */
1N/A continue;
1N/A (void) fprintf(stdout, "%s ", cn->attrvalue[j]);
1N/A }
1N/A }
1N/A
1N/A /* end of line */
1N/A (void) fprintf(stdout, "\n");
1N/A
1N/A}
1N/A
1N/A
1N/A
1N/A
1N/A/*
1N/A * /etc/services
1N/A *
1N/A */
1N/A
1N/Astatic int
1N/Agenent_services(char *line, int (*cback)())
1N/A{
1N/A char buf[BUFSIZ+1];
1N/A char *t, *p;
1N/A entry_col ecol[5];
1N/A char *cname;
1N/A
1N/A struct servent data;
1N/A char *alias;
1N/A int ctr = 0;
1N/A int retval = 1;
1N/A int rc = GENENT_OK;
1N/A
1N/A /*
1N/A * don't clobber our argument
1N/A */
1N/A if (strlen(line) >= sizeof (buf)) {
1N/A (void) strlcpy(parse_err_msg, gettext("line too long"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A (void) strcpy(buf, line);
1N/A
1N/A /*
1N/A * clear column data
1N/A */
1N/A (void) memset((char *)ecol, 0, sizeof (ecol));
1N/A
1N/A /*
1N/A * comment (col 4)
1N/A */
1N/A t = strchr(buf, '#');
1N/A if (t) {
1N/A *t++ = 0;
1N/A ecol[4].ec_value.ec_value_val = t;
1N/A ecol[4].ec_value.ec_value_len = strlen(t)+1;
1N/A } else {
1N/A ecol[4].ec_value.ec_value_val = 0;
1N/A ecol[4].ec_value.ec_value_len = 0;
1N/A }
1N/A
1N/A /*
1N/A * cname(col 0)
1N/A */
1N/A if ((t = strtok(buf, " \t")) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no port"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A ecol[0].ec_value.ec_value_val = t;
1N/A ecol[0].ec_value.ec_value_len = strlen(t)+1;
1N/A cname = t;
1N/A
1N/A /*
1N/A * port (col 3)
1N/A */
1N/A if ((t = strtok(NULL, " \t")) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no protocol"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A if ((p = strchr(t, '/')) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("bad port/proto"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A *(p++) = 0;
1N/A ecol[3].ec_value.ec_value_val = t;
1N/A ecol[3].ec_value.ec_value_len = strlen(t)+1;
1N/A
1N/A /*
1N/A * proto (col 2)
1N/A */
1N/A ecol[2].ec_value.ec_value_val = p;
1N/A ecol[2].ec_value.ec_value_len = strlen(p)+1;
1N/A
1N/A
1N/A /*
1N/A * build entry
1N/A */
1N/A
1N/A data.s_name = strdup(ecol[0].ec_value.ec_value_val);
1N/A data.s_proto = strdup(ecol[2].ec_value.ec_value_val);
1N/A
1N/A if (ecol[3].ec_value.ec_value_val != NULL &&
1N/A ecol[3].ec_value.ec_value_val[0] != '\0') {
1N/A
1N/A data.s_port = ascii_to_int(ecol[3].ec_value.ec_value_val);
1N/A if (data.s_port == -1) {
1N/A (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
1N/A gettext("invalid port number: %s"),
1N/A ecol[3].ec_value.ec_value_val);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A } else
1N/A data.s_port = -1;
1N/A
1N/A /*
1N/A * name (col 1)
1N/A */
1N/A t = cname;
1N/A data.s_aliases = NULL;
1N/A
1N/A do {
1N/A /*
1N/A * don't clobber comment in canonical entry
1N/A */
1N/A if (t != cname && strcasecmp(t, cname) == 0)
1N/A continue;
1N/A if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
1N/A continue;
1N/A
1N/A ecol[1].ec_value.ec_value_val = t;
1N/A ecol[1].ec_value.ec_value_len = strlen(t)+1;
1N/A
1N/A ctr++;
1N/A alias = strdup(ecol[1].ec_value.ec_value_val);
1N/A if ((data.s_aliases = (char **)realloc(data.s_aliases,
1N/A ctr * sizeof (char **))) == NULL) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A data.s_aliases[ctr-1] = alias;
1N/A
1N/A /*
1N/A * only put comment in canonical entry
1N/A */
1N/A ecol[4].ec_value.ec_value_val = 0;
1N/A ecol[4].ec_value.ec_value_len = 0;
1N/A
1N/A } while (t = strtok(NULL, " \t"));
1N/A
1N/A /* End the list of all the aliases by NULL */
1N/A if ((data.s_aliases = (char **)realloc(data.s_aliases,
1N/A (ctr + 1) * sizeof (char **))) == NULL) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A data.s_aliases[ctr] = NULL;
1N/A
1N/A if (flags & F_VERBOSE)
1N/A (void) fprintf(stdout,
1N/A gettext("Adding entry : %s\n"), line);
1N/A
1N/A retval = (*cback)(&data, 0);
1N/A
1N/A if (retval == LDAP_ALREADY_EXISTS) {
1N/A if (continue_onerror)
1N/A (void) fprintf(stderr, gettext(
1N/A "Entry: cn=%s+ipServiceProtocol=%s"
1N/A " already Exists, skipping it.\n"),
1N/A data.s_name, data.s_proto);
1N/A else {
1N/A rc = GENENT_CBERR;
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: cn=%s+ipServiceProtocol=%s"
1N/A " - already Exists\n"),
1N/A data.s_name, data.s_proto);
1N/A }
1N/A } else if (retval)
1N/A rc = GENENT_CBERR;
1N/A
1N/A free(data.s_name);
1N/A free(data.s_proto);
1N/A free(data.s_aliases);
1N/A
1N/A return (rc);
1N/A}
1N/A
1N/A
1N/A
1N/Astatic void
1N/Adump_services(ns_ldap_result_t *res)
1N/A{
1N/A ns_ldap_attr_t *attrptr = NULL, *cn = NULL, *port = NULL;
1N/A ns_ldap_attr_t *protocol = NULL;
1N/A int i, j, len;
1N/A char *name; /* service name */
1N/A
1N/A /*
1N/A * cn can have multiple values.(service name and its aliases)
1N/A * In order to support RFC 2307, section 5.5, ipserviceprotocol can
1N/A * have multiple values too.
1N/A * The output format should look like
1N/A *
1N/A * test 2345/udp mytest
1N/A * test 2345/tcp mytest
1N/A */
1N/A if (res == NULL || res->entry == NULL)
1N/A return;
1N/A for (i = 0; i < res->entry->attr_count; i++) {
1N/A attrptr = res->entry->attr_pair[i];
1N/A if (strcasecmp(attrptr->attrname, "cn") == 0)
1N/A cn = attrptr;
1N/A else if (strcasecmp(attrptr->attrname, "ipServicePort") == 0)
1N/A port = attrptr;
1N/A else if (strcasecmp(attrptr->attrname,
1N/A "ipServiceProtocol") == 0)
1N/A protocol = attrptr;
1N/A }
1N/A /* sanity check */
1N/A if (cn == NULL || cn->attrvalue == NULL || cn->attrvalue[0] == NULL ||
1N/A port == NULL || port->attrvalue == NULL ||
1N/A port->attrvalue[0] == NULL || protocol == NULL ||
1N/A protocol->attrvalue == NULL || protocol->attrvalue[0] == NULL)
1N/A return;
1N/A
1N/A if ((name = __s_api_get_canonical_name(res->entry, cn, 1)) == NULL)
1N/A return;
1N/A for (i = 0; i < protocol->value_count; i++) {
1N/A if (protocol->attrvalue[i] == NULL)
1N/A return;
1N/A /* service name */
1N/A (void) fprintf(stdout, "%-16s", name);
1N/A
1N/A /* port & protocol */
1N/A (void) fprintf(stdout, "%s/%s%n", port->attrvalue[0],
1N/A protocol->attrvalue[i], &len);
1N/A
1N/A if (len < 8)
1N/A (void) fprintf(stdout, "\t\t");
1N/A else
1N/A (void) fprintf(stdout, "\t");
1N/A
1N/A /* aliases */
1N/A for (j = 0; j < cn->value_count; j++) {
1N/A if (cn->attrvalue[j]) {
1N/A if (strcasecmp(name, cn->attrvalue[j]) == 0)
1N/A /* skip service name */
1N/A continue;
1N/A (void) fprintf(stdout, "%s ", cn->attrvalue[j]);
1N/A }
1N/A }
1N/A
1N/A /* end of line */
1N/A (void) fprintf(stdout, "\n");
1N/A }
1N/A}
1N/A
1N/A
1N/A/*
1N/A * /etc/group
1N/A */
1N/A
1N/Astatic int
1N/Agenent_group(char *line, int (*cback)())
1N/A{
1N/A char buf[BIGBUF+1];
1N/A char *s, *t;
1N/A entry_col ecol[5];
1N/A
1N/A struct group data;
1N/A int ctr = 0;
1N/A int retval = 1;
1N/A int rc = GENENT_OK;
1N/A
1N/A /*
1N/A * don't clobber our argument
1N/A */
1N/A if (strlen(line) >= sizeof (buf)) {
1N/A (void) strlcpy(parse_err_msg, gettext("line too long"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A (void) strcpy(buf, line);
1N/A t = buf;
1N/A
1N/A /* ignore empty entries */
1N/A if (*t == '\0')
1N/A return (GENENT_OK);
1N/A
1N/A /*
1N/A * clear column data
1N/A */
1N/A (void) memset((char *)ecol, 0, sizeof (ecol));
1N/A
1N/A /*
1N/A * name (col 0)
1N/A */
1N/A if ((s = strchr(t, ':')) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no passwd"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A *s++ = 0;
1N/A ecol[0].ec_value.ec_value_val = t;
1N/A ecol[0].ec_value.ec_value_len = strlen(t)+1;
1N/A t = s;
1N/A
1N/A /*
1N/A * passwd (col 1)
1N/A */
1N/A if ((s = strchr(t, ':')) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no gid"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A *s++ = 0;
1N/A ecol[1].ec_value.ec_value_val = t;
1N/A ecol[1].ec_value.ec_value_len = strlen(t)+1;
1N/A t = s;
1N/A
1N/A
1N/A /*
1N/A * gid (col 2)
1N/A */
1N/A if ((s = strchr(t, ':')) == 0 || s == t) {
1N/A (void) strlcpy(parse_err_msg, gettext("no members"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A *s++ = 0;
1N/A ecol[2].ec_value.ec_value_val = t;
1N/A ecol[2].ec_value.ec_value_len = strlen(t)+1;
1N/A t = s;
1N/A
1N/A /*
1N/A * members (col 3)
1N/A */
1N/A ecol[3].ec_value.ec_value_val = t;
1N/A ecol[3].ec_value.ec_value_len = strlen(t)+1;
1N/A
1N/A
1N/A /*
1N/A * build entry
1N/A */
1N/A data.gr_name = strdup(ecol[0].ec_value.ec_value_val);
1N/A data.gr_passwd = strdup(ecol[1].ec_value.ec_value_val);
1N/A if (ecol[2].ec_value.ec_value_val != NULL &&
1N/A ecol[2].ec_value.ec_value_val[0] != '\0') {
1N/A
1N/A data.gr_gid = ascii_to_int(ecol[2].ec_value.ec_value_val);
1N/A if (data.gr_gid == (uid_t)-1) {
1N/A (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
1N/A gettext("invalid group id: %s"),
1N/A ecol[2].ec_value.ec_value_val);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A } else
1N/A data.gr_gid = (uid_t)-1;
1N/A
1N/A data.gr_mem = NULL;
1N/A
1N/A /* Compute maximum amount of members */
1N/A s = t;
1N/A while (s = strchr(s, ',')) {
1N/A s++;
1N/A ctr++;
1N/A }
1N/A
1N/A /* Allocate memory for all members */
1N/A data.gr_mem = calloc(ctr + 2, sizeof (char **));
1N/A if (data.gr_mem == NULL) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A
1N/A ctr = 0;
1N/A while (s = strchr(t, ',')) {
1N/A
1N/A *s++ = 0;
1N/A ecol[3].ec_value.ec_value_val = t;
1N/A t = s;
1N/A /* Send to server only non empty member names */
1N/A if (strlen(ecol[3].ec_value.ec_value_val) != 0)
1N/A data.gr_mem[ctr++] = ecol[3].ec_value.ec_value_val;
1N/A }
1N/A
1N/A /* Send to server only non empty member names */
1N/A if (strlen(t) != 0)
1N/A data.gr_mem[ctr++] = t;
1N/A
1N/A /* Array of members completed, finished by NULL, see calloc() */
1N/A
1N/A if (flags & F_VERBOSE)
1N/A (void) fprintf(stdout,
1N/A gettext("Adding entry : %s\n"), data.gr_name);
1N/A
1N/A retval = (*cback)(&data, 0);
1N/A
1N/A if (retval == LDAP_ALREADY_EXISTS) {
1N/A if (continue_onerror)
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: %s - already Exists,"
1N/A " skipping it.\n"), data.gr_name);
1N/A else {
1N/A rc = GENENT_CBERR;
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: %s - already Exists\n"),
1N/A data.gr_name);
1N/A }
1N/A } else if (retval)
1N/A rc = GENENT_CBERR;
1N/A
1N/A free(data.gr_name);
1N/A free(data.gr_passwd);
1N/A free(data.gr_mem);
1N/A
1N/A return (rc);
1N/A}
1N/A
1N/Astatic void
1N/Adump_group(ns_ldap_result_t *res)
1N/A{
1N/A char **value = NULL;
1N/A char pnam[256];
1N/A int attr_count = 0;
1N/A
1N/A value = __ns_ldap_getAttr(res->entry, "cn");
1N/A if (value && value[0])
1N/A (void) fprintf(stdout, "%s:", value[0]);
1N/A value = __ns_ldap_getAttr(res->entry, "userPassword");
1N/A if (value == NULL || value[0] == NULL)
1N/A (void) fprintf(stdout, "*:");
1N/A else {
1N/A (void) strcpy(pnam, value[0]);
1N/A if (strncasecmp(value[0], "{crypt}", 7) == 0)
1N/A (void) fprintf(stdout, "%s:", (pnam+7));
1N/A else
1N/A (void) fprintf(stdout, "*:");
1N/A }
1N/A value = __ns_ldap_getAttr(res->entry, "gidNumber");
1N/A if (value && value[0])
1N/A (void) fprintf(stdout, "%s:", value[0]);
1N/A
1N/A value = __ns_ldap_getAttr(res->entry, "memberUid");
1N/A if (value != NULL && value[0] != NULL) {
1N/A while (value[attr_count] != NULL) {
1N/A if (value[attr_count+1] == NULL)
1N/A (void) fprintf(stdout, "%s", value[attr_count]);
1N/A else
1N/A (void) fprintf(stdout, "%s,",
1N/A value[attr_count]);
1N/A attr_count++;
1N/A }
1N/A (void) fprintf(stdout, "\n");
1N/A }
1N/A else
1N/A (void) fprintf(stdout, "\n");
1N/A}
1N/A
1N/A
1N/A
1N/A
1N/A
1N/A/*
1N/A * /etc/ethers
1N/A */
1N/A
1N/Astatic int
1N/Agenent_ethers(char *line, int (*cback)())
1N/A{
1N/A char buf[BUFSIZ+1];
1N/A char *t;
1N/A entry_col ecol[3];
1N/A int retval = 1;
1N/A struct _ns_ethers data;
1N/A int rc = GENENT_OK;
1N/A
1N/A /*
1N/A * don't clobber our argument
1N/A */
1N/A if (strlen(line) >= sizeof (buf)) {
1N/A (void) strlcpy(parse_err_msg, gettext("line too long"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A (void) strcpy(buf, line);
1N/A
1N/A /*
1N/A * clear column data
1N/A */
1N/A (void) memset((char *)ecol, 0, sizeof (ecol));
1N/A
1N/A /*
1N/A * comment (col 2)
1N/A */
1N/A t = strchr(buf, '#');
1N/A if (t) {
1N/A *t++ = 0;
1N/A ecol[2].ec_value.ec_value_val = t;
1N/A ecol[2].ec_value.ec_value_len = strlen(t)+1;
1N/A } else {
1N/A ecol[2].ec_value.ec_value_val = 0;
1N/A ecol[2].ec_value.ec_value_len = 0;
1N/A }
1N/A
1N/A /*
1N/A * addr(col 0)
1N/A */
1N/A if ((t = strtok(buf, " \t")) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no name"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A ecol[0].ec_value.ec_value_val = t;
1N/A ecol[0].ec_value.ec_value_len = strlen(t)+1;
1N/A
1N/A /*
1N/A * name(col 1)
1N/A */
1N/A if ((t = strtok(NULL, " \t")) == 0) {
1N/A (void) strlcpy(parse_err_msg,
1N/A gettext("no white space allowed in name"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A ecol[1].ec_value.ec_value_val = t;
1N/A ecol[1].ec_value.ec_value_len = strlen(t)+1;
1N/A
1N/A
1N/A /*
1N/A * build entry
1N/A */
1N/A
1N/A data.ether = strdup(ecol[0].ec_value.ec_value_val);
1N/A data.name = strdup(ecol[1].ec_value.ec_value_val);
1N/A
1N/A
1N/A if (flags & F_VERBOSE)
1N/A (void) fprintf(stdout,
1N/A gettext("Adding entry : %s\n"), data.name);
1N/A
1N/A retval = (*cback)(&data, 0);
1N/A
1N/A if (retval == LDAP_ALREADY_EXISTS) {
1N/A if (continue_onerror)
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: %s - already Exists,"
1N/A " skipping it.\n"), data.name);
1N/A else {
1N/A rc = GENENT_CBERR;
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: %s - already Exists\n"),
1N/A data.name);
1N/A }
1N/A } else if (retval)
1N/A rc = GENENT_CBERR;
1N/A
1N/A free(data.ether);
1N/A free(data.name);
1N/A
1N/A return (rc);
1N/A}
1N/A
1N/A
1N/Astatic void
1N/Adump_ethers(ns_ldap_result_t *res)
1N/A{
1N/A char **value = NULL;
1N/A
1N/A value = __ns_ldap_getAttr(res->entry, "macAddress");
1N/A if (value && value[0])
1N/A (void) fprintf(stdout, "%s", value[0]);
1N/A else
1N/A return;
1N/A value = __ns_ldap_getAttr(res->entry, "cn");
1N/A if (value && value[0])
1N/A (void) fprintf(stdout, " %s\n", value[0]);
1N/A}
1N/A
1N/Astatic int
1N/Agenent_aliases(char *line, int (*cback)())
1N/A{
1N/A char buf[BUFSIZ+1];
1N/A char *t, *aliases;
1N/A char *cname;
1N/A int ctr = 0;
1N/A int retval = 1;
1N/A int i;
1N/A
1N/A struct _ns_alias data;
1N/A char *alias;
1N/A int rc = GENENT_OK;
1N/A
1N/A /*
1N/A * don't clobber our argument
1N/A */
1N/A if (strlen(line) >= sizeof (buf)) {
1N/A (void) strlcpy(parse_err_msg, gettext("line too long"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A
1N/A (void) strcpy(buf, line);
1N/A
1N/A if ((t = strchr(buf, ':')) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no alias name"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A
1N/A t[0] = '\0';
1N/A if (++t == '\0') {
1N/A (void) strlcpy(parse_err_msg, gettext("no alias value"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A
1N/A cname = buf;
1N/A aliases = t;
1N/A
1N/A /* build entry */
1N/A data.alias = strdup(cname);
1N/A if (!data.alias) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A
1N/A data.member = NULL;
1N/A t = strtok(aliases, ",");
1N/A do {
1N/A ctr++;
1N/A while (t[0] == ' ')
1N/A t++;
1N/A alias = strdup(t);
1N/A if ((alias == NULL) ||
1N/A ((data.member = (char **)realloc(data.member,
1N/A (ctr + 1) * sizeof (char **))) == NULL)) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A data.member[ctr-1] = alias;
1N/A
1N/A } while (t = strtok(NULL, ","));
1N/A
1N/A data.member[ctr] = NULL;
1N/A
1N/A if (flags & F_VERBOSE)
1N/A (void) fprintf(stdout,
1N/A gettext("Adding entry : %s\n"), data.alias);
1N/A
1N/A retval = (*cback)(&data, 0);
1N/A
1N/A if (retval == LDAP_ALREADY_EXISTS) {
1N/A if (continue_onerror)
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: %s - already Exists,"
1N/A " skipping it.\n"), data.alias);
1N/A else {
1N/A rc = GENENT_CBERR;
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: %s - already Exists\n"),
1N/A data.alias);
1N/A }
1N/A } else if (retval)
1N/A rc = GENENT_CBERR;
1N/A
1N/A free(data.alias);
1N/A i = 0;
1N/A while (data.member[i])
1N/A free(data.member[i++]);
1N/A free(data.member);
1N/A
1N/A return (rc);
1N/A}
1N/A
1N/A
1N/Astatic void
1N/Adump_aliases(ns_ldap_result_t *res)
1N/A{
1N/A
1N/A char **value = NULL;
1N/A int attr_count = 0;
1N/A
1N/A value = __ns_ldap_getAttr(res->entry, "mail");
1N/A if (value && value[0])
1N/A (void) fprintf(stdout, "%s:", value[0]);
1N/A value = __ns_ldap_getAttr(res->entry, "mgrpRFC822MailMember");
1N/A if (value != NULL)
1N/A while (value[attr_count] != NULL) {
1N/A (void) fprintf(stdout, "%s,", value[attr_count]);
1N/A attr_count++;
1N/A }
1N/A (void) fprintf(stdout, "\n");
1N/A
1N/A}
1N/A
1N/A/*
1N/A * /etc/publickey
1N/A */
1N/A
1N/Astatic char *h_errno2str(int h_errno);
1N/A
1N/Astatic int
1N/Agenent_publickey(char *line, int (*cback)())
1N/A{
1N/A char buf[BUFSIZ+1], tmpbuf[BUFSIZ+1], cname[BUFSIZ+1];
1N/A char *t, *p, *tmppubkey, *tmpprivkey;
1N/A entry_col ecol[3];
1N/A int buflen, uid, retval = 1, errnum = 0;
1N/A struct passwd *pwd;
1N/A char auth_type[BUFSIZ+1], *dot;
1N/A keylen_t keylen;
1N/A algtype_t algtype;
1N/A struct _ns_pubkey data;
1N/A struct hostent *hp;
1N/A struct in_addr in;
1N/A struct in6_addr in6;
1N/A char abuf[INET6_ADDRSTRLEN];
1N/A
1N/A /*
1N/A * don't clobber our argument
1N/A */
1N/A if (strlen(line) >= sizeof (buf)) {
1N/A (void) strlcpy(parse_err_msg, gettext("line too long"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A (void) strcpy(buf, line);
1N/A
1N/A /*
1N/A * clear column data
1N/A */
1N/A (void) memset((char *)ecol, 0, sizeof (ecol));
1N/A
1N/A if ((t = strtok(buf, " \t")) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no cname"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A
1N/A /*
1N/A * Special case: /etc/publickey usually has an entry
1N/A * for principal "nobody". We skip it.
1N/A */
1N/A if (strcmp(t, "nobody") == 0)
1N/A return (GENENT_OK);
1N/A
1N/A /*
1N/A * cname (col 0)
1N/A */
1N/A if (strncmp(t, "unix.", 5)) {
1N/A (void) strlcpy(parse_err_msg, gettext("bad cname"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A (void) strcpy(tmpbuf, &(t[5]));
1N/A if ((p = strchr(tmpbuf, '@')) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("bad cname"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A *(p++) = 0;
1N/A if (isdigit(*tmpbuf)) {
1N/A
1N/A uid = atoi(tmpbuf);
1N/A /*
1N/A * don't generate entries for uids without passwd entries
1N/A */
1N/A if ((pwd = getpwuid(uid)) == 0) {
1N/A (void) fprintf(stderr,
1N/A gettext("can't map uid %d to username, skipping\n"),
1N/A uid);
1N/A return (GENENT_OK);
1N/A }
1N/A (void) strcpy(cname, pwd->pw_name);
1N/A data.hostcred = NS_HOSTCRED_FALSE;
1N/A } else {
1N/A if ((hp = getipnodebyname(tmpbuf, AF_INET6,
1N/A AI_ALL | AI_V4MAPPED, &errnum)) == NULL) {
1N/A (void) fprintf(stderr,
1N/A gettext("can't map hostname %s to hostaddress, "
1N/A "errnum %d %s skipping\n"), tmpbuf, errnum,
1N/A h_errno2str(errnum));
1N/A return (GENENT_OK);
1N/A }
1N/A (void) memcpy((char *)&in6.s6_addr, hp->h_addr_list[0],
1N/A hp->h_length);
1N/A if (IN6_IS_ADDR_V4MAPPED(&in6) ||
1N/A IN6_IS_ADDR_V4COMPAT(&in6)) {
1N/A IN6_V4MAPPED_TO_INADDR(&in6, &in);
1N/A if (inet_ntop(AF_INET, (const void *)&in, abuf,
1N/A INET6_ADDRSTRLEN) == NULL) {
1N/A (void) fprintf(stderr,
1N/A gettext("can't convert IPV4 address of"
1N/A " hostname %s to string, "
1N/A "skipping\n"), tmpbuf);
1N/A return (GENENT_OK);
1N/A }
1N/A } else {
1N/A if (inet_ntop(AF_INET6, (const void *)&in6, abuf,
1N/A INET6_ADDRSTRLEN) == NULL) {
1N/A (void) fprintf(stderr,
1N/A gettext("can't convert IPV6 address of"
1N/A " hostname %s to string, "
1N/A "skipping\n"), tmpbuf);
1N/A return (GENENT_OK);
1N/A }
1N/A }
1N/A data.hostcred = NS_HOSTCRED_TRUE;
1N/A /*
1N/A * tmpbuf could be an alias, use hp->h_name instead.
1N/A * hp->h_name is in FQDN format, so extract 1st field.
1N/A */
1N/A if ((dot = strchr(hp->h_name, '.')) != NULL)
1N/A *dot = '\0';
1N/A (void) snprintf(cname, sizeof (cname),
1N/A "%s+ipHostNumber=%s", hp->h_name, abuf);
1N/A if (dot)
1N/A *dot = '.';
1N/A }
1N/A
1N/A ecol[0].ec_value.ec_value_val = cname;
1N/A ecol[0].ec_value.ec_value_len = strlen(cname)+1;
1N/A
1N/A /*
1N/A * public_data (col 1)
1N/A */
1N/A if ((t = strtok(NULL, " \t")) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no private_data"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A if ((p = strchr(t, ':')) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("bad public_data"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A *(p++) = 0;
1N/A ecol[1].ec_value.ec_value_val = t;
1N/A ecol[1].ec_value.ec_value_len = strlen(t)+1;
1N/A keylen = (strlen(t) / 2) * 8;
1N/A
1N/A /*
1N/A * private_data (col 2) and algtype extraction
1N/A */
1N/A if (*p == ':')
1N/A p++;
1N/A t = p;
1N/A if (!(t = strchr(t, ':'))) {
1N/A (void) fprintf(stderr,
1N/A gettext("WARNING: No algorithm type data found "
1N/A "in publickey file, assuming 0\n"));
1N/A algtype = 0;
1N/A } else {
1N/A *t = '\0';
1N/A t++;
1N/A algtype = atoi(t);
1N/A }
1N/A ecol[2].ec_value.ec_value_val = p;
1N/A ecol[2].ec_value.ec_value_len = strlen(p)+1;
1N/A
1N/A /*
1N/A * auth_type (col 1)
1N/A */
1N/A if (AUTH_DES_KEY(keylen, algtype))
1N/A /*
1N/A * {DES} and {DH192-0} means same thing.
1N/A * However, nisplus(obsolete) uses "DES" and ldap uses
1N/A * "DH192-0" internally.
1N/A * See newkey(1M), __nis_mechalias2authtype() which is
1N/A * called by __nis_keyalg2authtype() and getkey_ldap_g()
1N/A */
1N/A (void) strlcpy(auth_type, "DH192-0", BUFSIZ+1);
1N/A else if (!(__nis_keyalg2authtype(keylen, algtype, auth_type,
1N/A MECH_MAXATNAME))) {
1N/A (void) fprintf(stderr,
1N/A gettext("Could not convert algorithm type to "
1N/A "corresponding auth type string\n"));
1N/A return (GENENT_ERR);
1N/A }
1N/A
1N/A /*
1N/A * build entry
1N/A */
1N/A data.name = strdup(ecol[0].ec_value.ec_value_val);
1N/A if (data.name == NULL) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A
1N/A buflen = sizeof (auth_type) + strlen(ecol[1].ec_value.ec_value_val) + 3;
1N/A if ((tmppubkey = (char *)malloc(buflen)) == NULL) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A (void) snprintf(tmppubkey, buflen, "{%s}%s", auth_type,
1N/A ecol[1].ec_value.ec_value_val);
1N/A data.pubkey = tmppubkey;
1N/A
1N/A buflen = sizeof (auth_type) + strlen(ecol[2].ec_value.ec_value_val) + 3;
1N/A if ((tmpprivkey = (char *)malloc(buflen)) == NULL) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A
1N/A (void) snprintf(tmpprivkey, buflen, "{%s}%s", auth_type,
1N/A ecol[2].ec_value.ec_value_val);
1N/A data.privkey = tmpprivkey;
1N/A
1N/A retval = (*cback)(&data, 1);
1N/A if (retval != NS_LDAP_SUCCESS) {
1N/A if (retval == LDAP_NO_SUCH_OBJECT) {
1N/A if (data.hostcred == NS_HOSTCRED_TRUE)
1N/A (void) fprintf(stdout,
1N/A gettext("Cannot add publickey entry"" (%s),"
1N/A " add host entry first\n"),
1N/A tmpbuf);
1N/A else
1N/A (void) fprintf(stdout,
1N/A gettext("Cannot add publickey entry (%s), "
1N/A "add passwd entry first\n"),
1N/A data.name);
1N/A }
1N/A if (continue_onerror == 0)
1N/A return (GENENT_CBERR);
1N/A }
1N/A
1N/A free(data.name);
1N/A free(data.pubkey);
1N/A free(data.privkey);
1N/A return (GENENT_OK);
1N/A}
1N/A
1N/Astatic void
1N/Adump_publickey(ns_ldap_result_t *res, char *container)
1N/A{
1N/A char **value = NULL;
1N/A char buf[BUFSIZ];
1N/A char domainname[BUFSIZ];
1N/A char *pubptr, *prvptr;
1N/A
1N/A if (res == NULL)
1N/A return;
1N/A
1N/A if (sysinfo(SI_SRPC_DOMAIN, domainname, BUFSIZ) < 0) {
1N/A (void) fprintf(stderr,
1N/A gettext("could not obtain domainname\n"));
1N/A exit(1);
1N/A }
1N/A
1N/A /*
1N/A * Retrieve all the attributes, but don't print
1N/A * until we have all the required ones.
1N/A */
1N/A
1N/A if (strcmp(container, "passwd") == 0)
1N/A value = __ns_ldap_getAttr(res->entry, "uidNumber");
1N/A else
1N/A value = __ns_ldap_getAttr(res->entry, "cn");
1N/A
1N/A if (value && value[0])
1N/A (void) snprintf(buf, sizeof (buf), "unix.%s@%s",
1N/A value[0], domainname);
1N/A else
1N/A return;
1N/A
1N/A value = __ns_ldap_getAttr(res->entry, "nisPublickey");
1N/A if (value != NULL && value[0] != NULL) {
1N/A if ((pubptr = strchr(value[0], '}')) == NULL)
1N/A return;
1N/A }
1N/A
1N/A value = __ns_ldap_getAttr(res->entry, "nisSecretkey");
1N/A if (value != NULL && value[0] != NULL)
1N/A if ((prvptr = strchr(value[0], '}')) == NULL)
1N/A return;
1N/A
1N/A /* print the attributes, algorithm type is always 0 */
1N/A (void) fprintf(stdout, "%s %s:%s:0\n", buf, ++pubptr, ++prvptr);
1N/A}
1N/A
1N/A
1N/A
1N/A/*
1N/A * /etc/netmasks
1N/A */
1N/A
1N/Astatic int
1N/Agenent_netmasks(char *line, int (*cback)())
1N/A{
1N/A char buf[BUFSIZ+1];
1N/A char *t;
1N/A entry_col ecol[3];
1N/A int retval;
1N/A
1N/A struct _ns_netmasks data;
1N/A
1N/A
1N/A /*
1N/A * don't clobber our argument
1N/A */
1N/A if (strlen(line) >= sizeof (buf)) {
1N/A (void) strlcpy(parse_err_msg, gettext("line too long"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A (void) strcpy(buf, line);
1N/A
1N/A /*
1N/A * clear column data
1N/A */
1N/A (void) memset((char *)ecol, 0, sizeof (ecol));
1N/A
1N/A /*
1N/A * comment (col 2)
1N/A */
1N/A t = strchr(buf, '#');
1N/A if (t) {
1N/A *t++ = 0;
1N/A ecol[2].ec_value.ec_value_val = t;
1N/A ecol[2].ec_value.ec_value_len = strlen(t)+1;
1N/A } else {
1N/A ecol[2].ec_value.ec_value_val = 0;
1N/A ecol[2].ec_value.ec_value_len = 0;
1N/A }
1N/A
1N/A /*
1N/A * addr(col 0)
1N/A */
1N/A if ((t = strtok(buf, " \t")) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no mask"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A ecol[0].ec_value.ec_value_val = t;
1N/A ecol[0].ec_value.ec_value_len = strlen(t)+1;
1N/A
1N/A /*
1N/A * mask (col 1)
1N/A */
1N/A if ((t = strtok(NULL, " \t")) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no mask"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A ecol[1].ec_value.ec_value_val = t;
1N/A ecol[1].ec_value.ec_value_len = strlen(t)+1;
1N/A
1N/A /* build entry */
1N/A data.netnumber = ecol[0].ec_value.ec_value_val;
1N/A data.netmask = ecol[1].ec_value.ec_value_val;
1N/A
1N/A if (flags & F_VERBOSE)
1N/A (void) fprintf(stdout,
1N/A gettext("Adding entry : %s\n"), data.netnumber);
1N/A
1N/A retval = (*cback)(&data, 1);
1N/A if (retval != NS_LDAP_SUCCESS) {
1N/A if (retval == LDAP_NO_SUCH_OBJECT)
1N/A (void) fprintf(stdout,
1N/A gettext("Cannot add netmask entry (%s), "
1N/A "add network entry first\n"), data.netnumber);
1N/A if (continue_onerror == 0)
1N/A return (GENENT_CBERR);
1N/A }
1N/A
1N/A return (GENENT_OK);
1N/A}
1N/A
1N/Astatic void
1N/Adump_netmasks(ns_ldap_result_t *res)
1N/A{
1N/A char **value = NULL;
1N/A
1N/A value = __ns_ldap_getAttr(res->entry, "ipNetworkNumber");
1N/A if (value && value[0])
1N/A (void) fprintf(stdout, "%s", value[0]);
1N/A value = __ns_ldap_getAttr(res->entry, "ipNetmaskNumber");
1N/A if (value && value[0])
1N/A (void) fprintf(stdout, " %s\n", value[0]);
1N/A}
1N/A
1N/A
1N/A/*
1N/A * /etc/netgroup
1N/A * column data format is:
1N/A * col 0: netgroup name (or cname)
1N/A * col 1: netgroup member, if this is a triplet
1N/A * col 2: netgroup member, if not a triplet
1N/A * col 3: comment
1N/A */
1N/A
1N/Astatic int
1N/Agenent_netgroup(char *line, int (*cback)())
1N/A{
1N/A char buf[BIGBUF+1]; /* netgroup entries tend to be big */
1N/A char *t;
1N/A char *cname = NULL;
1N/A entry_col ecol[4];
1N/A char *netg_tmp = NULL, *triplet_tmp = NULL;
1N/A int netgcount = 0, tripletcount = 0, retval = 1, i;
1N/A struct _ns_netgroups data;
1N/A int rc = GENENT_OK;
1N/A
1N/A /* don't clobber our argument */
1N/A if (strlen(line) >= sizeof (buf)) {
1N/A (void) strlcpy(parse_err_msg, gettext("line too long"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A (void) strcpy(buf, line);
1N/A
1N/A /* clear column data */
1N/A (void) memset((char *)ecol, 0, sizeof (ecol));
1N/A
1N/A /*
1N/A * process 1st minimal entry, to validate that there is no
1N/A * parsing error.
1N/A * start with comment(col 3)
1N/A */
1N/A t = strchr(buf, '#');
1N/A if (t) {
1N/A *t++ = 0;
1N/A ecol[3].ec_value.ec_value_val = t;
1N/A ecol[3].ec_value.ec_value_len = strlen(t)+1;
1N/A } else {
1N/A ecol[3].ec_value.ec_value_val = "";
1N/A ecol[3].ec_value.ec_value_len = 0;
1N/A }
1N/A
1N/A ecol[1].ec_value.ec_value_val = NULL;
1N/A ecol[2].ec_value.ec_value_val = NULL;
1N/A
1N/A /* cname (col 0) */
1N/A if ((t = strtok(buf, " \t")) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no cname"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A
1N/A ecol[0].ec_value.ec_value_val = t;
1N/A ecol[0].ec_value.ec_value_len = strlen(t)+1;
1N/A cname = t;
1N/A
1N/A /* addr(col 1 and 2) */
1N/A if ((t = strtok(NULL, " \t")) == 0) {
1N/A (void) strlcpy(parse_err_msg,
1N/A gettext("no members for netgroup"), PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A
1N/A if (*t == '(') {
1N/A /* if token starts with '(' it must be a valid triplet */
1N/A if (is_triplet(t)) {
1N/A ecol[1].ec_value.ec_value_val = t;
1N/A ecol[1].ec_value.ec_value_len = strlen(t)+1;
1N/A } else {
1N/A (void) strlcpy(parse_err_msg,
1N/A gettext("invalid triplet"), PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A } else {
1N/A ecol[2].ec_value.ec_value_val = t;
1N/A ecol[2].ec_value.ec_value_len = strlen(t)+1;
1N/A }
1N/A
1N/A /*
1N/A * now build entry.
1N/A * start by clearing entry data
1N/A */
1N/A (void) memset((struct _ns_netgroups *)&data, 0, sizeof (data));
1N/A
1N/A data.name = strdup(ecol[0].ec_value.ec_value_val);
1N/A
1N/A if (ecol[1].ec_value.ec_value_val != NULL) {
1N/A if ((data.triplet = calloc(1, sizeof (char **))) == NULL) {
1N/A (void) fprintf(stderr,
1N/A gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A data.triplet[tripletcount++] =
1N/A strdup(ecol[1].ec_value.ec_value_val);
1N/A } else if (ecol[2].ec_value.ec_value_val != NULL) {
1N/A if ((data.netgroup = calloc(1, sizeof (char **)))
1N/A == NULL) {
1N/A (void) fprintf(stderr,
1N/A gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A data.netgroup[netgcount++] =
1N/A strdup(ecol[2].ec_value.ec_value_val);
1N/A }
1N/A
1N/A /*
1N/A * we now have a valid entry (at least 1 netgroup name and
1N/A * 1 netgroup member), proceed with the rest of the line
1N/A */
1N/A while (rc == GENENT_OK && (t = strtok(NULL, " \t"))) {
1N/A
1N/A /* if next token is equal to netgroup name, ignore */
1N/A if (t != cname && strcasecmp(t, cname) == 0)
1N/A continue;
1N/A if (strcasecmp(t, ecol[0].ec_value.ec_value_val) == 0)
1N/A continue;
1N/A
1N/A if (*t == '(') {
1N/A if (is_triplet(t)) {
1N/A /* skip a triplet if it is added already */
1N/A for (i = 0; i < tripletcount &&
1N/A strcmp(t, data.triplet[i]); i++)
1N/A ;
1N/A if (i < tripletcount)
1N/A continue;
1N/A
1N/A tripletcount++;
1N/A triplet_tmp = strdup(t);
1N/A if ((data.triplet = (char **)realloc(
1N/A data.triplet,
1N/A tripletcount * sizeof (char **))) == NULL) {
1N/A (void) fprintf(stderr,
1N/A gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A data.triplet[tripletcount-1] = triplet_tmp;
1N/A } else {
1N/A (void) strlcpy(parse_err_msg,
1N/A gettext("invalid triplet"),
1N/A PARSE_ERR_MSG_LEN);
1N/A rc = GENENT_PARSEERR;
1N/A }
1N/A } else {
1N/A /* skip a netgroup if it is added already */
1N/A for (i = 0; i < netgcount &&
1N/A strcmp(t, data.netgroup[i]); i++)
1N/A ;
1N/A if (i < netgcount)
1N/A continue;
1N/A
1N/A netgcount++;
1N/A netg_tmp = strdup(t);
1N/A if ((data.netgroup = (char **)realloc(data.netgroup,
1N/A netgcount * sizeof (char **))) == NULL) {
1N/A (void) fprintf(stderr,
1N/A gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A data.netgroup[netgcount-1] = netg_tmp;
1N/A }
1N/A }
1N/A
1N/A /* End the list with NULL */
1N/A if ((data.triplet = (char **)realloc(data.triplet,
1N/A (tripletcount + 1) * sizeof (char **))) == NULL) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A data.triplet[tripletcount] = NULL;
1N/A if ((data.netgroup = (char **)realloc(data.netgroup,
1N/A (netgcount + 1) * sizeof (char **))) == NULL) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A data.netgroup[netgcount] = NULL;
1N/A
1N/A if (rc == GENENT_OK) {
1N/A if (flags & F_VERBOSE)
1N/A (void) fprintf(stdout,
1N/A gettext("Adding entry : %s\n"), data.name);
1N/A
1N/A retval = (*cback)(&data, 0);
1N/A
1N/A if (retval == LDAP_ALREADY_EXISTS) {
1N/A if (continue_onerror)
1N/A (void) fprintf(stderr, gettext(
1N/A "Entry: %s - already Exists,"
1N/A " skipping it.\n"), data.name);
1N/A else {
1N/A rc = GENENT_CBERR;
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: %s - already Exists\n"),
1N/A data.name);
1N/A }
1N/A } else if (retval)
1N/A rc = GENENT_CBERR;
1N/A }
1N/A
1N/A /* release memory allocated by strdup() */
1N/A for (i = 0; i < tripletcount; i++) {
1N/A free(data.triplet[i]);
1N/A }
1N/A for (i = 0; i < netgcount; i++) {
1N/A free(data.netgroup[i]);
1N/A }
1N/A
1N/A free(data.name);
1N/A free(data.triplet);
1N/A free(data.netgroup);
1N/A
1N/A return (rc);
1N/A}
1N/A
1N/Astatic void
1N/Adump_netgroup(ns_ldap_result_t *res)
1N/A{
1N/A char **value = NULL;
1N/A int attr_count = 0;
1N/A
1N/A value = __ns_ldap_getAttr(res->entry, "cn");
1N/A if ((value != NULL) && (value[0] != NULL))
1N/A (void) fprintf(stdout, "%s", value[0]);
1N/A else
1N/A return;
1N/A value = __ns_ldap_getAttr(res->entry, "nisNetgroupTriple");
1N/A if (value != NULL)
1N/A while (value[attr_count] != NULL) {
1N/A (void) fprintf(stdout, " %s", value[attr_count]);
1N/A attr_count++;
1N/A }
1N/A attr_count = 0;
1N/A value = __ns_ldap_getAttr(res->entry, "memberNisNetgroup");
1N/A if (value != NULL)
1N/A while (value[attr_count] != NULL) {
1N/A (void) fprintf(stdout, " %s", value[attr_count]);
1N/A attr_count++;
1N/A }
1N/A (void) fprintf(stdout, "\n");
1N/A
1N/A}
1N/A
1N/Astatic int
1N/Agenent_automount(char *line, int (*cback)())
1N/A{
1N/A char buf[BUFSIZ+1];
1N/A char *t, *s;
1N/A entry_col ecol[2];
1N/A struct _ns_automount data;
1N/A int retval = 1;
1N/A int rc = GENENT_OK;
1N/A
1N/A /*
1N/A * don't clobber our argument
1N/A */
1N/A if (strlen(line) >= sizeof (buf)) {
1N/A (void) strlcpy(parse_err_msg, gettext("line too long"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A
1N/A /* replace every tabspace with single space */
1N/A replace_tab2space(line);
1N/A (void) strcpy(buf, line);
1N/A
1N/A /*
1N/A * clear column data
1N/A */
1N/A (void) memset((char *)ecol, 0, sizeof (ecol));
1N/A
1N/A /*
1N/A * key (col 0)
1N/A */
1N/A t = buf;
1N/A while (t[0] == ' ')
1N/A t++;
1N/A
1N/A if ((s = strchr(t, ' ')) == 0) {
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A *s++ = 0;
1N/A
1N/A ecol[0].ec_value.ec_value_val = t;
1N/A ecol[0].ec_value.ec_value_len = strlen(t)+1;
1N/A t = s;
1N/A
1N/A while (t[0] == ' ')
1N/A t++;
1N/A
1N/A /*
1N/A * mapentry (col 1)
1N/A */
1N/A
1N/A ecol[1].ec_value.ec_value_val = t;
1N/A ecol[1].ec_value.ec_value_len = strlen(t)+1;
1N/A
1N/A data.mapname = strdup(databasetype);
1N/A data.key = strdup(ecol[0].ec_value.ec_value_val);
1N/A data.value = strdup(ecol[1].ec_value.ec_value_val);
1N/A
1N/A if (flags & F_VERBOSE)
1N/A (void) fprintf(stdout,
1N/A gettext("Adding entry : %s\n"), data.key);
1N/A
1N/A retval = (*cback)(&data, 0);
1N/A
1N/A if (retval == LDAP_ALREADY_EXISTS) {
1N/A if (continue_onerror)
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: %s - already Exists,"
1N/A " skipping it.\n"), data.key);
1N/A else {
1N/A rc = GENENT_CBERR;
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: %s - already Exists\n"),
1N/A data.key);
1N/A }
1N/A } else if (retval)
1N/A rc = GENENT_CBERR;
1N/A
1N/A free(data.mapname);
1N/A free(data.key);
1N/A free(data.value);
1N/A return (rc);
1N/A}
1N/A
1N/Astatic void
1N/Adump_automount(ns_ldap_result_t *res)
1N/A{
1N/A char **value = NULL;
1N/A
1N/A if (res == NULL)
1N/A return;
1N/A
1N/A value = __ns_ldap_getAttr(res->entry, "automountKey");
1N/A if (value != NULL) {
1N/A (void) fprintf(stdout, "%s", value[0]);
1N/A value = __ns_ldap_getAttr(res->entry, "automountInformation");
1N/A if (value != NULL)
1N/A (void) fprintf(stdout, " %s\n", value[0]);
1N/A else
1N/A (void) fprintf(stdout, "\n");
1N/A }
1N/A}
1N/A
1N/A
1N/A/*
1N/A * /etc/passwd
1N/A *
1N/A */
1N/A
1N/Astatic int
1N/Agenent_passwd(char *line, int (*cback)())
1N/A{
1N/A char buf[BUFSIZ+1];
1N/A char *s, *t;
1N/A entry_col ecol[8];
1N/A int retval = 1;
1N/A char pname[BUFSIZ];
1N/A
1N/A struct passwd data;
1N/A int rc = GENENT_OK;
1N/A
1N/A
1N/A /*
1N/A * don't clobber our argument
1N/A */
1N/A if (strlen(line) >= sizeof (buf)) {
1N/A (void) strlcpy(parse_err_msg, gettext("line too long"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A (void) strcpy(buf, line);
1N/A t = buf;
1N/A
1N/A /* ignore empty entries */
1N/A if (*t == '\0')
1N/A return (GENENT_OK);
1N/A
1N/A /*
1N/A * clear column data
1N/A */
1N/A (void) memset((char *)ecol, 0, sizeof (ecol));
1N/A
1N/A /*
1N/A * name (col 0)
1N/A */
1N/A if ((s = strchr(t, ':')) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no password"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A *s++ = 0;
1N/A ecol[0].ec_value.ec_value_val = t;
1N/A ecol[0].ec_value.ec_value_len = strlen(t)+1;
1N/A t = s;
1N/A
1N/A /*
1N/A * passwd (col 1)
1N/A */
1N/A if ((s = strchr(t, ':')) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no uid"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A *s++ = 0;
1N/A
1N/A ecol[1].ec_value.ec_value_val = t;
1N/A ecol[1].ec_value.ec_value_len = strlen(t)+1;
1N/A
1N/A t = s;
1N/A
1N/A /*
1N/A * uid (col 2)
1N/A */
1N/A if ((s = strchr(t, ':')) == 0 || s == t) {
1N/A (void) strlcpy(parse_err_msg, gettext("no gid"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A *s++ = 0;
1N/A ecol[2].ec_value.ec_value_val = t;
1N/A ecol[2].ec_value.ec_value_len = strlen(t)+1;
1N/A t = s;
1N/A
1N/A /*
1N/A * gid (col 3)
1N/A */
1N/A if ((s = strchr(t, ':')) == 0 || s == t) {
1N/A (void) strlcpy(parse_err_msg, gettext("no gcos"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A *s++ = 0;
1N/A ecol[3].ec_value.ec_value_val = t;
1N/A ecol[3].ec_value.ec_value_len = strlen(t)+1;
1N/A t = s;
1N/A
1N/A /*
1N/A * gcos (col 4)
1N/A */
1N/A if ((s = strchr(t, ':')) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no home"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A *s++ = 0;
1N/A ecol[4].ec_value.ec_value_val = t;
1N/A ecol[4].ec_value.ec_value_len = strlen(t)+1;
1N/A t = s;
1N/A
1N/A /*
1N/A * home (col 5)
1N/A */
1N/A if ((s = strchr(t, ':')) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no shell"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A *s++ = 0;
1N/A ecol[5].ec_value.ec_value_val = t;
1N/A ecol[5].ec_value.ec_value_len = strlen(t)+1;
1N/A t = s;
1N/A
1N/A /*
1N/A * shell (col 6)
1N/A */
1N/A ecol[6].ec_value.ec_value_val = t;
1N/A ecol[6].ec_value.ec_value_len = strlen(t)+1;
1N/A
1N/A /*
1N/A * build entry
1N/A */
1N/A data.pw_name = strdup(ecol[0].ec_value.ec_value_val);
1N/A
1N/A if (flags & F_PASSWD) {
1N/A /* Add {crypt} before passwd entry */
1N/A (void) snprintf(pname, sizeof (pname), "{crypt}%s",
1N/A ecol[1].ec_value.ec_value_val);
1N/A data.pw_passwd = strdup(pname);
1N/A }
1N/A else
1N/A data.pw_passwd = NULL;
1N/A
1N/A if (ecol[2].ec_value.ec_value_val != NULL &&
1N/A ecol[2].ec_value.ec_value_val[0] != '\0') {
1N/A data.pw_uid = ascii_to_int(ecol[2].ec_value.ec_value_val);
1N/A if (data.pw_uid == (uid_t)-1) {
1N/A (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
1N/A gettext("invalid uid : %s"),
1N/A ecol[2].ec_value.ec_value_val);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A } else
1N/A data.pw_uid = (uid_t)-1;
1N/A
1N/A if (ecol[3].ec_value.ec_value_val != NULL &&
1N/A ecol[3].ec_value.ec_value_val[0] != '\0') {
1N/A
1N/A data.pw_gid = ascii_to_int(ecol[3].ec_value.ec_value_val);
1N/A if (data.pw_gid == (uid_t)-1) {
1N/A (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
1N/A gettext("invalid gid : %s"),
1N/A ecol[3].ec_value.ec_value_val);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A } else
1N/A data.pw_gid = (uid_t)-1;
1N/A
1N/A data.pw_age = NULL;
1N/A data.pw_comment = NULL;
1N/A data.pw_gecos = strdup(ecol[4].ec_value.ec_value_val);
1N/A data.pw_dir = strdup(ecol[5].ec_value.ec_value_val);
1N/A data.pw_shell = strdup(ecol[6].ec_value.ec_value_val);
1N/A
1N/A if (flags & F_VERBOSE)
1N/A (void) fprintf(stdout,
1N/A gettext("Adding entry : %s\n"), data.pw_name);
1N/A
1N/A retval = (*cback)(&data, 0);
1N/A
1N/A if (retval == LDAP_ALREADY_EXISTS) {
1N/A if (continue_onerror)
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: %s - already Exists,"
1N/A " skipping it.\n"), data.pw_name);
1N/A else {
1N/A rc = GENENT_CBERR;
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: %s - already Exists\n"),
1N/A data.pw_name);
1N/A }
1N/A } else if (retval)
1N/A rc = GENENT_CBERR;
1N/A
1N/A free(data.pw_name);
1N/A free(data.pw_gecos);
1N/A free(data.pw_dir);
1N/A free(data.pw_shell);
1N/A return (rc);
1N/A}
1N/A
1N/A
1N/Astatic void
1N/Adump_passwd(ns_ldap_result_t *res)
1N/A{
1N/A char **value = NULL;
1N/A
1N/A value = __ns_ldap_getAttr(res->entry, "uid");
1N/A if (value == NULL)
1N/A return;
1N/A else
1N/A (void) fprintf(stdout, "%s:", value[0]);
1N/A value = __ns_ldap_getAttr(res->entry, "userPassword");
1N/A
1N/A /*
1N/A * Don't print the encrypted password, Use x to
1N/A * indicate it is in the shadow database.
1N/A */
1N/A (void) fprintf(stdout, "x:");
1N/A
1N/A value = __ns_ldap_getAttr(res->entry, "uidNumber");
1N/A if (value && value[0])
1N/A (void) fprintf(stdout, "%s:", value[0]);
1N/A value = __ns_ldap_getAttr(res->entry, "gidNumber");
1N/A if (value && value[0])
1N/A (void) fprintf(stdout, "%s:", value[0]);
1N/A value = __ns_ldap_getAttr(res->entry, "gecos");
1N/A if (value == NULL)
1N/A (void) fprintf(stdout, ":");
1N/A else
1N/A (void) fprintf(stdout, "%s:", value[0]);
1N/A value = __ns_ldap_getAttr(res->entry, "homeDirectory");
1N/A if (value == NULL)
1N/A (void) fprintf(stdout, ":");
1N/A else
1N/A (void) fprintf(stdout, "%s:", value[0]);
1N/A value = __ns_ldap_getAttr(res->entry, "loginShell");
1N/A if (value == NULL)
1N/A (void) fprintf(stdout, "\n");
1N/A else
1N/A (void) fprintf(stdout, "%s\n", value[0]);
1N/A
1N/A}
1N/A
1N/A/*
1N/A * /etc/shadow
1N/A */
1N/A
1N/Astatic int
1N/Agenent_shadow(char *line, int (*cback)())
1N/A{
1N/A char buf[BUFSIZ+1];
1N/A char *s, *t;
1N/A entry_col ecol[9];
1N/A char pname[BUFSIZ];
1N/A
1N/A struct spwd data;
1N/A int spflag;
1N/A int retval;
1N/A
1N/A
1N/A /*
1N/A * don't clobber our argument
1N/A */
1N/A if (strlen(line) >= sizeof (buf)) {
1N/A (void) strlcpy(parse_err_msg, gettext("line too long"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A (void) strcpy(buf, line);
1N/A t = buf;
1N/A
1N/A /* ignore empty entries */
1N/A if (*t == '\0')
1N/A return (GENENT_OK);
1N/A
1N/A /*
1N/A * clear column data
1N/A */
1N/A (void) memset((char *)ecol, 0, sizeof (ecol));
1N/A
1N/A /*
1N/A * name (col 0)
1N/A */
1N/A if ((s = strchr(t, ':')) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no uid"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A *s++ = 0;
1N/A ecol[0].ec_value.ec_value_val = t;
1N/A ecol[0].ec_value.ec_value_len = strlen(t)+1;
1N/A t = s;
1N/A
1N/A /*
1N/A * passwd (col 1)
1N/A */
1N/A if ((s = strchr(t, ':')) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("Improper format"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A *s++ = 0;
1N/A
1N/A ecol[1].ec_value.ec_value_val = t;
1N/A ecol[1].ec_value.ec_value_len = strlen(t)+1;
1N/A
1N/A t = s;
1N/A
1N/A /*
1N/A * shadow last change (col 2)
1N/A */
1N/A if ((s = strchr(t, ':')) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("Improper format"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A *s++ = 0;
1N/A ecol[2].ec_value.ec_value_val = t;
1N/A ecol[2].ec_value.ec_value_len = strlen(t)+1;
1N/A t = s;
1N/A
1N/A /*
1N/A * shadow min (col 3)
1N/A */
1N/A if ((s = strchr(t, ':')) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("Improper format"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A *s++ = 0;
1N/A ecol[3].ec_value.ec_value_val = t;
1N/A ecol[3].ec_value.ec_value_len = strlen(t)+1;
1N/A t = s;
1N/A
1N/A /*
1N/A * shadow max (col 4)
1N/A */
1N/A if ((s = strchr(t, ':')) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("Improper format"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A *s++ = 0;
1N/A ecol[4].ec_value.ec_value_val = t;
1N/A ecol[4].ec_value.ec_value_len = strlen(t)+1;
1N/A t = s;
1N/A
1N/A /*
1N/A * shadow warn (col 5)
1N/A */
1N/A if ((s = strchr(t, ':')) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("Improper format"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A *s++ = 0;
1N/A ecol[5].ec_value.ec_value_val = t;
1N/A ecol[5].ec_value.ec_value_len = strlen(t)+1;
1N/A t = s;
1N/A
1N/A /*
1N/A * shadow inactive (col 6)
1N/A */
1N/A if ((s = strchr(t, ':')) != 0) {
1N/A *s++ = 0;
1N/A ecol[6].ec_value.ec_value_val = t;
1N/A ecol[6].ec_value.ec_value_len = strlen(t)+1;
1N/A t = s;
1N/A }
1N/A
1N/A /*
1N/A * shadow expire (col 7)
1N/A */
1N/A if ((s = strchr(t, ':')) != 0) {
1N/A *s++ = 0;
1N/A ecol[7].ec_value.ec_value_val = t;
1N/A ecol[7].ec_value.ec_value_len = strlen(t)+1;
1N/A t = s;
1N/A
1N/A /*
1N/A * flag (col 8)
1N/A */
1N/A ecol[8].ec_value.ec_value_val = t;
1N/A ecol[8].ec_value.ec_value_len = strlen(t)+1;
1N/A }
1N/A
1N/A /*
1N/A * build entry
1N/A */
1N/A
1N/A data.sp_namp = strdup(ecol[0].ec_value.ec_value_val);
1N/A
1N/A if (ecol[1].ec_value.ec_value_val != NULL &&
1N/A ecol[1].ec_value.ec_value_val[0] != '\0') {
1N/A /* Add {crypt} before passwd entry */
1N/A (void) snprintf(pname, sizeof (pname), "{crypt}%s",
1N/A ecol[1].ec_value.ec_value_val);
1N/A data.sp_pwdp = strdup(pname);
1N/A } else {
1N/A /*
1N/A * no password (e.g., deleted by "passwd -d"):
1N/A * use the special value NS_LDAP_NO_UNIX_PASSWORD
1N/A * instead.
1N/A */
1N/A (void) snprintf(pname, sizeof (pname), "{crypt}%s",
1N/A NS_LDAP_NO_UNIX_PASSWORD);
1N/A data.sp_pwdp = strdup(pname);
1N/A }
1N/A
1N/A if (ecol[2].ec_value.ec_value_val != NULL &&
1N/A ecol[2].ec_value.ec_value_val[0] != '\0') {
1N/A
1N/A data.sp_lstchg = ascii_to_int(ecol[2].ec_value.ec_value_val);
1N/A if (data.sp_lstchg < -1) {
1N/A (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
1N/A gettext("invalid last changed date: %s"),
1N/A ecol[2].ec_value.ec_value_val);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A } else
1N/A data.sp_lstchg = -1;
1N/A
1N/A if (ecol[3].ec_value.ec_value_val != NULL &&
1N/A ecol[3].ec_value.ec_value_val[0] != '\0') {
1N/A
1N/A data.sp_min = ascii_to_int(ecol[3].ec_value.ec_value_val);
1N/A if (data.sp_min < -1) {
1N/A (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
1N/A gettext("invalid sp_min : %s"),
1N/A ecol[3].ec_value.ec_value_val);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A } else
1N/A data.sp_min = -1;
1N/A
1N/A if (ecol[4].ec_value.ec_value_val != NULL &&
1N/A ecol[4].ec_value.ec_value_val[0] != '\0') {
1N/A
1N/A data.sp_max = ascii_to_int(ecol[4].ec_value.ec_value_val);
1N/A if (data.sp_max < -1) {
1N/A (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
1N/A gettext("invalid sp_max : %s"),
1N/A ecol[4].ec_value.ec_value_val);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A } else
1N/A data.sp_max = -1;
1N/A
1N/A if (ecol[5].ec_value.ec_value_val != NULL &&
1N/A ecol[5].ec_value.ec_value_val[0] != '\0') {
1N/A
1N/A data.sp_warn = ascii_to_int(ecol[5].ec_value.ec_value_val);
1N/A if (data.sp_warn < -1) {
1N/A (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
1N/A gettext("invalid sp_warn : %s"),
1N/A ecol[5].ec_value.ec_value_val);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A } else
1N/A data.sp_warn = -1;
1N/A
1N/A if (ecol[6].ec_value.ec_value_val != NULL &&
1N/A ecol[6].ec_value.ec_value_val[0] != '\0') {
1N/A
1N/A data.sp_inact = ascii_to_int(ecol[6].ec_value.ec_value_val);
1N/A if (data.sp_inact < -1) {
1N/A (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
1N/A gettext("invalid sp_inact : %s"),
1N/A ecol[6].ec_value.ec_value_val);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A } else
1N/A data.sp_inact = -1;
1N/A
1N/A if (ecol[7].ec_value.ec_value_val != NULL &&
1N/A ecol[7].ec_value.ec_value_val[0] != '\0') {
1N/A
1N/A data.sp_expire = ascii_to_int(ecol[7].ec_value.ec_value_val);
1N/A if (data.sp_expire < -1) {
1N/A (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
1N/A gettext("invalid login expiry date : %s"),
1N/A ecol[7].ec_value.ec_value_val);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A } else
1N/A data.sp_expire = -1;
1N/A
1N/A if (ecol[8].ec_value.ec_value_val != NULL &&
1N/A ecol[8].ec_value.ec_value_val[0] != '\0') {
1N/A
1N/A /*
1N/A * data.sp_flag is an unsigned int,
1N/A * assign -1 to it, make no sense.
1N/A * Use spflag here to avoid lint warning.
1N/A */
1N/A spflag = ascii_to_int(ecol[8].ec_value.ec_value_val);
1N/A if (spflag < 0) {
1N/A (void) snprintf(parse_err_msg, sizeof (parse_err_msg),
1N/A gettext("invalid flag value: %s"),
1N/A ecol[8].ec_value.ec_value_val);
1N/A return (GENENT_PARSEERR);
1N/A } else
1N/A data.sp_flag = spflag;
1N/A } else
1N/A data.sp_flag = 0;
1N/A
1N/A if (flags & F_VERBOSE)
1N/A (void) fprintf(stdout,
1N/A gettext("Adding entry : %s\n"), data.sp_namp);
1N/A
1N/A retval = (*cback)(&data, 1);
1N/A if (retval != NS_LDAP_SUCCESS) {
1N/A if (retval == LDAP_NO_SUCH_OBJECT)
1N/A (void) fprintf(stdout,
1N/A gettext("Cannot add shadow entry (%s), "
1N/A "add passwd entry first\n"), data.sp_namp);
1N/A if (continue_onerror == 0)
1N/A return (GENENT_CBERR);
1N/A }
1N/A
1N/A free(data.sp_namp);
1N/A free(data.sp_pwdp);
1N/A return (GENENT_OK);
1N/A}
1N/A
1N/Astatic void
1N/Adump_shadow(ns_ldap_result_t *res)
1N/A{
1N/A char **value = NULL;
1N/A char pnam[256];
1N/A
1N/A value = __ns_ldap_getAttr(res->entry, "uid");
1N/A if (value == NULL)
1N/A return;
1N/A else
1N/A (void) fprintf(stdout, "%s:", value[0]);
1N/A value = __ns_ldap_getAttr(res->entry, "userPassword");
1N/A if (value == NULL)
1N/A (void) fprintf(stdout, "*:");
1N/A else {
1N/A (void) strcpy(pnam, value[0]);
1N/A if (strncasecmp(value[0], "{crypt}", 7) == 0) {
1N/A if (strcmp(pnam + 7, NS_LDAP_NO_UNIX_PASSWORD) == 0)
1N/A (void) fprintf(stdout, ":");
1N/A else
1N/A (void) fprintf(stdout, "%s:", (pnam+7));
1N/A } else
1N/A (void) fprintf(stdout, "*:");
1N/A }
1N/A value = __ns_ldap_getAttr(res->entry, "shadowLastChange");
1N/A if (value == NULL)
1N/A (void) fprintf(stdout, ":");
1N/A else
1N/A (void) fprintf(stdout, "%s:", value[0]);
1N/A value = __ns_ldap_getAttr(res->entry, "shadowMin");
1N/A if (value == NULL)
1N/A (void) fprintf(stdout, ":");
1N/A else
1N/A (void) fprintf(stdout, "%s:", value[0]);
1N/A value = __ns_ldap_getAttr(res->entry, "shadowMax");
1N/A if (value == NULL)
1N/A (void) fprintf(stdout, ":");
1N/A else
1N/A (void) fprintf(stdout, "%s:", value[0]);
1N/A
1N/A value = __ns_ldap_getAttr(res->entry, "shadowWarning");
1N/A if (value == NULL)
1N/A (void) fprintf(stdout, ":");
1N/A else
1N/A (void) fprintf(stdout, "%s:", value[0]);
1N/A
1N/A value = __ns_ldap_getAttr(res->entry, "shadowInactive");
1N/A if (value == NULL)
1N/A (void) fprintf(stdout, ":");
1N/A else
1N/A (void) fprintf(stdout, "%s:", value[0]);
1N/A
1N/A value = __ns_ldap_getAttr(res->entry, "shadowExpire");
1N/A if (value == NULL)
1N/A (void) fprintf(stdout, ":");
1N/A else
1N/A (void) fprintf(stdout, "%s:", value[0]);
1N/A
1N/A value = __ns_ldap_getAttr(res->entry, "shadowFlag");
1N/A if (value == NULL || value[0] == NULL || strcmp(value[0], "0") == 0)
1N/A (void) fprintf(stdout, "\n");
1N/A else
1N/A (void) fprintf(stdout, "%s\n", value[0]);
1N/A}
1N/A
1N/Astatic int
1N/Agenent_bootparams(char *line, int (*cback)())
1N/A{
1N/A char buf[BUFSIZ+1];
1N/A char *t;
1N/A entry_col ecol[2];
1N/A int ctr = 0, retval = 1;
1N/A
1N/A struct _ns_bootp data;
1N/A char *parameter;
1N/A int rc = GENENT_OK;
1N/A
1N/A /*
1N/A * don't clobber our argument
1N/A */
1N/A if (strlen(line) >= sizeof (buf)) {
1N/A (void) strlcpy(parse_err_msg, gettext("line too long"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A (void) strcpy(buf, line);
1N/A
1N/A /*
1N/A * clear column data
1N/A */
1N/A (void) memset((char *)ecol, 0, sizeof (ecol));
1N/A
1N/A
1N/A /*
1N/A * cname (col 0)
1N/A */
1N/A if ((t = strtok(buf, " \t")) == 0) {
1N/A (void) strlcpy(parse_err_msg, gettext("no cname"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A ecol[0].ec_value.ec_value_val = t;
1N/A ecol[0].ec_value.ec_value_len = strlen(t)+1;
1N/A
1N/A
1N/A
1N/A /* build entry */
1N/A data.name = strdup(ecol[0].ec_value.ec_value_val);
1N/A
1N/A /*
1N/A * name (col 1)
1N/A */
1N/A
1N/A data.param = NULL;
1N/A
1N/A while (t = strtok(NULL, " \t")) {
1N/A
1N/A /*
1N/A * don't clobber comment in canonical entry
1N/A */
1N/A
1N/A
1N/A ecol[1].ec_value.ec_value_val = t;
1N/A ecol[1].ec_value.ec_value_len = strlen(t)+1;
1N/A
1N/A ctr++;
1N/A parameter = strdup(ecol[1].ec_value.ec_value_val);
1N/A if ((data.param = (char **)realloc(data.param,
1N/A (ctr + 1) * sizeof (char **))) == NULL) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A data.param[ctr-1] = parameter;
1N/A
1N/A }
1N/A
1N/A
1N/A /* End the list of all the aliases by NULL */
1N/A if ((data.param = (char **)realloc(data.param,
1N/A (ctr + 1) * sizeof (char **))) == NULL) {
1N/A (void) fprintf(stderr, gettext("out of memory\n"));
1N/A exit(1);
1N/A }
1N/A data.param[ctr] = NULL;
1N/A
1N/A if (flags & F_VERBOSE)
1N/A (void) fprintf(stdout,
1N/A gettext("Adding entry : %s\n"), data.name);
1N/A
1N/A retval = (*cback)(&data, 0);
1N/A
1N/A if (retval == LDAP_ALREADY_EXISTS) {
1N/A if (continue_onerror)
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: %s - already Exists,"
1N/A " skipping it.\n"), data.name);
1N/A else {
1N/A rc = GENENT_CBERR;
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: %s - already Exists\n"),
1N/A data.name);
1N/A }
1N/A } else if (retval)
1N/A rc = GENENT_CBERR;
1N/A
1N/A free(data.name);
1N/A free(data.param);
1N/A
1N/A return (rc);
1N/A
1N/A}
1N/A
1N/A/*
1N/A * Count number of tokens in string which has tokens separated by colons.
1N/A *
1N/A * NULL or "" - 0 tokens
1N/A * "foo" - 1 token
1N/A * "foo:bar" - 2 tokens
1N/A * ":bar" - 2 tokens, first empty
1N/A * "::" - 3 tokens, all empty
1N/A */
1N/Astatic int
1N/Acount_tokens(char *string, char delim)
1N/A{
1N/A int i = 0;
1N/A char *s = string;
1N/A
1N/A if (string == NULL || *string == '\0')
1N/A return (0);
1N/A
1N/A /* Count delimiters */
1N/A while ((s = strchr(s, delim)) != NULL && *s != '\0') {
1N/A i++;
1N/A s++;
1N/A }
1N/A
1N/A return (i + 1);
1N/A}
1N/A
1N/Astatic int
1N/Agenent_project(char *line, int (*cback)())
1N/A{
1N/A char buf[BUFSIZ+1];
1N/A char *b = buf;
1N/A char *s;
1N/A int rc = GENENT_OK, retval;
1N/A int index = 0;
1N/A struct project data;
1N/A
1N/A (void) memset(&data, 0, sizeof (struct project));
1N/A
1N/A /*
1N/A * don't clobber our argument
1N/A */
1N/A if (strlen(line) >= sizeof (buf)) {
1N/A (void) strlcpy(parse_err_msg, gettext("line too long"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A
1N/A if (count_tokens(line, ':') != 6) {
1N/A (void) strlcpy(parse_err_msg, gettext("Improper format"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A }
1N/A
1N/A (void) strcpy(buf, line);
1N/A
1N/A s = strsep(&b, ":");
1N/A while (s != NULL) {
1N/A switch (index) {
1N/A /* Project name */
1N/A case 0:
1N/A if (check_projname(s) != 0) {
1N/A (void) strlcpy(parse_err_msg,
1N/A gettext("invalid project name"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A } else {
1N/A data.pj_name = strdup(s);
1N/A }
1N/A break;
1N/A
1N/A /* Project ID */
1N/A case 1:
1N/A {
1N/A char *endptr = NULL;
1N/A int projid = strtoul(s, &endptr, 10);
1N/A
1N/A if (*s == '\0' || strlen(endptr) != 0 || projid < 0 ||
1N/A projid > MAXPROJID) {
1N/A (void) strlcpy(parse_err_msg,
1N/A gettext("invalid project id"),
1N/A PARSE_ERR_MSG_LEN);
1N/A return (GENENT_PARSEERR);
1N/A } else {
1N/A data.pj_projid = projid;
1N/A }
1N/A break;
1N/A }
1N/A
1N/A /* Project description */
1N/A case 2:
1N/A if (*s != '\0')
1N/A data.pj_comment = strdup(s);
1N/A break;
1N/A
1N/A /* Project users */
1N/A case 3:
1N/A {
1N/A if (*s == '\0')
1N/A break;
1N/A
1N/A char *usrlist = strdup(s);
1N/A int i = 0;
1N/A int usr_count = count_tokens(usrlist, ',');
1N/A char *u = strsep(&usrlist, ",");
1N/A
1N/A if (usr_count == 0) {
1N/A free(usrlist);
1N/A break;
1N/A }
1N/A
1N/A /* +1 to NULL-terminate the array */
1N/A data.pj_users = (char **)calloc(usr_count + 1,
1N/A sizeof (char *));
1N/A
1N/A while (u != NULL) {
1N/A data.pj_users[i++] = strdup(u);
1N/A u = strsep(&usrlist, ",");
1N/A }
1N/A
1N/A free(usrlist);
1N/A break;
1N/A }
1N/A
1N/A /* Project groups */
1N/A case 4:
1N/A {
1N/A if (*s == '\0')
1N/A break;
1N/A
1N/A char *grouplist = strdup(s);
1N/A int i = 0;
1N/A int grp_count = count_tokens(grouplist, ',');
1N/A char *g = strsep(&grouplist, ",");
1N/A
1N/A if (grp_count == 0) {
1N/A free(grouplist);
1N/A break;
1N/A }
1N/A
1N/A /* +1 to NULL-terminate the array */
1N/A data.pj_groups = (char **)calloc(grp_count + 1,
1N/A sizeof (char *));
1N/A
1N/A while (g != NULL) {
1N/A data.pj_groups[i++] = strdup(g);
1N/A g = strsep(&grouplist, ",");
1N/A }
1N/A
1N/A free(grouplist);
1N/A break;
1N/A }
1N/A
1N/A /* Attributes */
1N/A case 5:
1N/A if (*s != '\0')
1N/A data.pj_attr = strdup(s);
1N/A
1N/A break;
1N/A }
1N/A
1N/A /* Next token */
1N/A s = strsep(&b, ":");
1N/A index++;
1N/A }
1N/A
1N/A if (flags & F_VERBOSE)
1N/A (void) fprintf(stdout,
1N/A gettext("Adding entry : %s\n"), data.pj_name);
1N/A
1N/A retval = (*cback)(&data, 0);
1N/A
1N/A if (retval == LDAP_ALREADY_EXISTS) {
1N/A if (continue_onerror)
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: %s - already Exists,"
1N/A " skipping it.\n"), data.pj_name);
1N/A else {
1N/A rc = GENENT_CBERR;
1N/A (void) fprintf(stderr,
1N/A gettext("Entry: %s - already Exists\n"),
1N/A data.pj_name);
1N/A }
1N/A } else if (retval)
1N/A rc = GENENT_CBERR;
1N/A
1N/A /* Clean up */
1N/A free(data.pj_name);
1N/A free(data.pj_attr);
1N/A if (data.pj_users != NULL) {
1N/A for (index = 0; data.pj_users[index] != NULL; index++)
1N/A free(data.pj_users[index]);
1N/A free(data.pj_users);
1N/A }
1N/A if (data.pj_groups != NULL) {
1N/A for (index = 0; data.pj_groups[index] != NULL; index++)
1N/A free(data.pj_groups[index]);
1N/A free(data.pj_groups);
1N/A }
1N/A
1N/A return (rc);
1N/A}
1N/A
1N/Astatic void
1N/Adump_project(ns_ldap_result_t *res)
1N/A{
1N/A char **value = NULL;
1N/A char *endptr = NULL;
1N/A int projid;
1N/A
1N/A if (res == NULL || res->entry == NULL)
1N/A return;
1N/A
1N/A /* Sanity checking */
1N/A value = __ns_ldap_getAttr(res->entry, "SolarisProjectID");
1N/A
1N/A if (value[0] == NULL)
1N/A return;
1N/A
1N/A projid = strtoul(value[0], &endptr, 10);
1N/A if (*value[0] == '\0' || strlen(endptr) != 0 || projid < 0 ||
1N/A projid > MAXPROJID)
1N/A return;
1N/A
1N/A value = __ns_ldap_getAttr(res->entry, "SolarisProjectName");
1N/A if (value && value[0] && check_projname(value[0]) == 0)
1N/A (void) fprintf(stdout, "%s:", value[0]);
1N/A else
1N/A return;
1N/A
1N/A (void) fprintf(stdout, "%d:", projid);
1N/A
1N/A value = __ns_ldap_getAttr(res->entry, "description");
1N/A if (value && value[0])
1N/A (void) fprintf(stdout, "%s:", value[0]);
1N/A else
1N/A (void) fprintf(stdout, ":");
1N/A
1N/A value = __ns_ldap_getAttr(res->entry, "memberUid");
1N/A if (value) {
1N/A int i;
1N/A for (i = 0; value[i] != NULL; i++)
1N/A if (value[i+1] != NULL)
1N/A (void) fprintf(stdout, "%s,", value[i]);
1N/A else
1N/A (void) fprintf(stdout, "%s:", value[i]);
1N/A } else {
1N/A (void) fprintf(stdout, ":");
1N/A }
1N/A
1N/A value = __ns_ldap_getAttr(res->entry, "memberGid");
1N/A if (value) {
1N/A int i;
1N/A for (i = 0; value[i] != NULL; i++)
1N/A if (value[i+1] != NULL)
1N/A (void) fprintf(stdout, "%s,", value[i]);
1N/A else
1N/A (void) fprintf(stdout, "%s:", value[i]);
1N/A } else {
1N/A (void) fprintf(stdout, ":");
1N/A }
1N/A
1N/A value = __ns_ldap_getAttr(res->entry, "SolarisProjectAttr");
1N/A if (value && value[0])
1N/A (void) fprintf(stdout, "%s\n", value[0]);
1N/A else
1N/A (void) fprintf(stdout, "\n");
1N/A
1N/A}
1N/A
1N/Astatic void
1N/Adump_bootparams(ns_ldap_result_t *res)
1N/A{
1N/A char **value = NULL;
1N/A int attr_count = 0;
1N/A
1N/A value = __ns_ldap_getAttr(res->entry, "cn");
1N/A if (value[0] != NULL)
1N/A (void) fprintf(stdout, "%s", value[0]);
1N/A value = __ns_ldap_getAttr(res->entry, "bootParameter");
1N/A if (value != NULL)
1N/A while (value[attr_count] != NULL) {
1N/A (void) fprintf(stdout, "\t%s", value[attr_count]);
1N/A attr_count++;
1N/A }
1N/A (void) fprintf(stdout, "\n");
1N/A
1N/A
1N/A}
1N/A
1N/Astatic char *
1N/Afget_line_at(struct line_buf *line, int n, FILE *fp)
1N/A{
1N/A int c;
1N/A
1N/A line->len = n;
1N/A
1N/A for (;;) {
1N/A c = fgetc(fp);
1N/A if (c == -1)
1N/A break;
1N/A if (line->len >= line->alloc)
1N/A line_buf_expand(line);
1N/A line->str[line->len++] = c;
1N/A
1N/A if (c == '\n')
1N/A break;
1N/A }
1N/A
1N/A /* Null Terminate */
1N/A if (line->len >= line->alloc)
1N/A line_buf_expand(line);
1N/A line->str[line->len++] = 0;
1N/A
1N/A /* if no characters are read, return NULL to indicate EOF */
1N/A if (line->str[0] == '\0')
1N/A return (0);
1N/A
1N/A return (line->str);
1N/A}
1N/A
1N/A/*
1N/A * return a line from the file, discarding comments and blank lines
1N/A */
1N/Astatic int
1N/Afiledbmline_comment(struct line_buf *line, FILE *etcf, int *lineno,
1N/A struct file_loc *loc)
1N/A{
1N/A int i, len = 0;
1N/A
1N/A loc->offset = ftell(etcf);
1N/A for (;;) {
1N/A if (fget_line_at(line, len, etcf) == 0)
1N/A return (0);
1N/A
1N/A if (lineno)
1N/A (*lineno)++;
1N/A
1N/A len = strlen(line->str);
1N/A if (len >= 2 &&
1N/A line->str[0] != '#' &&
1N/A line->str[len-2] == '\\' && line->str[len-1] == '\n') {
1N/A line->str[len-2] = 0;
1N/A len -= 2;
1N/A continue; /* append next line at end */
1N/A }
1N/A
1N/A if (line->str[len-1] == '\n') {
1N/A line->str[len-1] = 0;
1N/A len -= 1;
1N/A }
1N/A
1N/A /*
1N/A * Skip lines where '#' is the first non-blank character.
1N/A */
1N/A for (i = 0; i < len; i++) {
1N/A if (line->str[i] == '#') {
1N/A line->str[i] = '\0';
1N/A len = i;
1N/A break;
1N/A }
1N/A if (line->str[i] != ' ' && line->str[i] != '\t')
1N/A break;
1N/A }
1N/A
1N/A /*
1N/A * A line with one or more white space characters followed
1N/A * by a comment will now be blank. The special case of a
1N/A * line with '#' in the first byte will have len == 0.
1N/A */
1N/A if (len > 0 && !blankline(line->str))
1N/A break;
1N/A
1N/A len = 0;
1N/A loc->offset = ftell(etcf);
1N/A }
1N/A
1N/A loc->size = len;
1N/A return (1);
1N/A}
1N/A
1N/A/*
1N/A * return a line from the file, discarding comments, blanks, and '+' lines
1N/A */
1N/Astatic int
1N/Afiledbmline_plus(struct line_buf *line, FILE *etcf, int *lineno,
1N/A struct file_loc *loc)
1N/A{
1N/A int len = 0;
1N/A
1N/A loc->offset = ftell(etcf);
1N/A for (;;) {
1N/A if (fget_line_at(line, len, etcf) == 0)
1N/A return (0);
1N/A
1N/A if (lineno)
1N/A (*lineno)++;
1N/A
1N/A len = strlen(line->str);
1N/A if (line->str[len-1] == '\n') {
1N/A line->str[len-1] = 0;
1N/A len -= 1;
1N/A }
1N/A
1N/A if (!blankline(line->str) &&
1N/A line->str[0] != '+' && line->str[0] != '-' &&
1N/A line->str[0] != '#')
1N/A break;
1N/A
1N/A len = 0;
1N/A loc->offset = ftell(etcf);
1N/A }
1N/A
1N/A loc->size = len;
1N/A return (1);
1N/A}
1N/A
1N/A
1N/A/* Populating the ttypelist structure */
1N/A
1N/Astatic struct ttypelist_t ttypelist[] = {
1N/A { NS_LDAP_TYPE_HOSTS, genent_hosts, dump_hosts,
1N/A filedbmline_comment, "iphost", "cn" },
1N/A { NS_LDAP_TYPE_IPNODES, genent_hosts, dump_hosts,
1N/A filedbmline_comment, "iphost", "cn" },
1N/A { NS_LDAP_TYPE_RPC, genent_rpc, dump_rpc,
1N/A filedbmline_comment, "oncrpc", "cn" },
1N/A { NS_LDAP_TYPE_PROTOCOLS, genent_protocols, dump_protocols,
1N/A filedbmline_comment, "ipprotocol", "cn" },
1N/A { NS_LDAP_TYPE_NETWORKS, genent_networks, dump_networks,
1N/A filedbmline_comment, "ipnetwork", "ipnetworknumber" },
1N/A { NS_LDAP_TYPE_SERVICES, genent_services, dump_services,
1N/A filedbmline_comment, "ipservice", "cn" },
1N/A { NS_LDAP_TYPE_GROUP, genent_group, dump_group,
1N/A filedbmline_plus, "posixgroup", "gidnumber" },
1N/A { NS_LDAP_TYPE_NETMASKS, genent_netmasks, dump_netmasks,
1N/A filedbmline_comment, "ipnetwork", "ipnetworknumber"},
1N/A { NS_LDAP_TYPE_ETHERS, genent_ethers, dump_ethers,
1N/A filedbmline_comment, "ieee802Device", "cn" },
1N/A { NS_LDAP_TYPE_NETGROUP, genent_netgroup, dump_netgroup,
1N/A filedbmline_comment, "nisnetgroup", "cn" },
1N/A { NS_LDAP_TYPE_BOOTPARAMS, genent_bootparams, dump_bootparams,
1N/A filedbmline_comment, "bootableDevice", "cn" },
1N/A { NS_LDAP_TYPE_PUBLICKEY, genent_publickey, NULL /* dump_publickey */,
1N/A filedbmline_comment, "niskeyobject", "cn" },
1N/A { NS_LDAP_TYPE_PASSWD, genent_passwd, dump_passwd,
1N/A filedbmline_plus, "posixaccount", "uid" },
1N/A { NS_LDAP_TYPE_SHADOW, genent_shadow, dump_shadow,
1N/A filedbmline_plus, "shadowaccount", "uid" },
1N/A { NS_LDAP_TYPE_ALIASES, genent_aliases, dump_aliases,
1N/A filedbmline_plus, "mailGroup", "cn" },
1N/A { NS_LDAP_TYPE_AUTOMOUNT, genent_automount, dump_automount,
1N/A filedbmline_comment, "automount", "automountKey" },
1N/A { NS_LDAP_TYPE_USERATTR, genent_user_attr, dump_user_attr,
1N/A filedbmline_comment, "SolarisUserAttr", "uid" },
1N/A { NS_LDAP_TYPE_PROFILE, genent_prof_attr, dump_prof_attr,
1N/A filedbmline_comment, "SolarisProfAttr", "cn" },
1N/A { NS_LDAP_TYPE_EXECATTR, genent_exec_attr, dump_exec_attr,
1N/A filedbmline_comment, "SolarisExecAttr", "cn" },
1N/A { NS_LDAP_TYPE_AUTHATTR, genent_auth_attr, dump_auth_attr,
1N/A filedbmline_comment, "SolarisAuthAttr", "cn" },
1N/A { NS_LDAP_TYPE_TNRHDB, genent_tnrhdb, dump_tnrhdb,
1N/A filedbmline_comment, "ipTnetHost", "ipTnetNumber" },
1N/A { NS_LDAP_TYPE_TNRHTP, genent_tnrhtp, dump_tnrhtp,
1N/A filedbmline_comment, "ipTnetTemplate", "ipTnetTemplateName" },
1N/A { NS_LDAP_TYPE_PROJECT, genent_project, dump_project,
1N/A filedbmline_comment, "SolarisProject", "SolarisProjectName" },
1N/A { 0, 0, 0, 0, 0, 0 }
1N/A};
1N/A
1N/A
1N/A
1N/A
1N/Astatic int lineno = 0;
1N/A
1N/Astatic void
1N/Aaddfile()
1N/A{
1N/A struct line_buf line;
1N/A struct file_loc loc;
1N/A
1N/A /* Initializing the Line Buffer */
1N/A line_buf_init(&line);
1N/A
1N/A /* Loop through all the lines in the file */
1N/A while (tt->filedbmline(&line, etcf, &lineno, &loc)) {
1N/A switch ((*(tt->genent))(line.str, addentry)) {
1N/A case GENENT_OK:
1N/A break;
1N/A case GENENT_PARSEERR:
1N/A (void) fprintf(stderr,
1N/A gettext("parse error: %s (line %d)\n"),
1N/A parse_err_msg, lineno);
1N/A exit_val = 1;
1N/A break;
1N/A case GENENT_CBERR:
1N/A (void) fprintf(stderr,
1N/A gettext("Error while adding line: %s\n"),
1N/A line.str);
1N/A exit_val = 2;
1N/A free(line.str);
1N/A return;
1N/A /* NOTREACHED */
1N/A break;
1N/A case GENENT_ERR:
1N/A (void) fprintf(stderr,
1N/A gettext("Internal Error while adding line: %s\n"),
1N/A line.str);
1N/A exit_val = 3;
1N/A free(line.str);
1N/A return;
1N/A /* NOTREACHED */
1N/A break;
1N/A }
1N/A }
1N/A free(line.str);
1N/A}
1N/A
1N/Astatic void
1N/Adumptable(char *service)
1N/A{
1N/A
1N/A ns_ldap_result_t *eres = NULL;
1N/A ns_ldap_error_t *err = NULL;
1N/A int rc = 0, success = 0;
1N/A char filter[BUFSIZ];
1N/A int done = 0;
1N/A void *cookie = NULL;
1N/A
1N/A /* set the appropriate filter */
1N/A if (strcmp(tt->ttype, NS_LDAP_TYPE_PROFILE) == 0) {
1N/A /*
1N/A * prof_attr entries are SolarisProfAttr
1N/A * without AUXILIARY SolarisExecAttr
1N/A */
1N/A (void) snprintf(filter, sizeof (filter),
1N/A "(&(objectclass=%s)(!(objectclass=SolarisExecAttr)))",
1N/A tt->objclass);
1N/A } else if (strcmp(tt->ttype, NS_LDAP_TYPE_TNRHDB) == 0) {
1N/A /*
1N/A * tnrhtp entries are ipTnet entries with SolarisAttrKeyValue
1N/A */
1N/A (void) snprintf(filter, sizeof (filter),
1N/A "(&(objectclass=%s)(SolarisAttrKeyValue=*)))",
1N/A tt->objclass);
1N/A } else {
1N/A (void) snprintf(filter, sizeof (filter),
1N/A "(objectclass=%s)", tt->objclass);
1N/A }
1N/A
1N/A if (flags & F_VERBOSE)
1N/A (void) fprintf(stdout, gettext("FILTER = %s\n"), filter);
1N/A
1N/A /* Pass cred only if supplied. Cred is not always needed for dump */
1N/A if (authority.cred.unix_cred.userID == NULL ||
1N/A authority.cred.unix_cred.passwd == NULL)
1N/A rc = __ns_ldap_firstEntry(service, filter, tt->sortattr, NULL,
1N/A NULL, NULL, NS_LDAP_HARD, &cookie, &eres, &err, NULL);
1N/A else
1N/A rc = __ns_ldap_firstEntry(service, filter, tt->sortattr, NULL,
1N/A NULL, &authority, NS_LDAP_HARD, &cookie, &eres, &err, NULL);
1N/A
1N/A switch (rc) {
1N/A case NS_LDAP_SUCCESS:
1N/A nent_add++;
1N/A success = 1;
1N/A if (eres != NULL) {
1N/A if (strcmp(databasetype, "publickey") == 0)
1N/A dump_publickey(eres, service);
1N/A else
1N/A (*(tt->dump))(eres);
1N/A }
1N/A else
1N/A (void) fprintf(stderr, gettext("No entries found.\n"));
1N/A break;
1N/A
1N/A case NS_LDAP_OP_FAILED:
1N/A exit_val = 2;
1N/A (void) fprintf(stderr, gettext("operation failed.\n"));
1N/A break;
1N/A
1N/A case NS_LDAP_INVALID_PARAM:
1N/A exit_val = 2;
1N/A (void) fprintf(stderr,
1N/A gettext("invalid parameter(s) passed.\n"));
1N/A break;
1N/A
1N/A case NS_LDAP_NOTFOUND:
1N/A exit_val = 2;
1N/A (void) fprintf(stderr, gettext("entry not found.\n"));
1N/A break;
1N/A
1N/A case NS_LDAP_MEMORY:
1N/A exit_val = 2;
1N/A (void) fprintf(stderr,
1N/A gettext("internal memory allocation error.\n"));
1N/A break;
1N/A
1N/A case NS_LDAP_CONFIG:
1N/A exit_val = 2;
1N/A (void) fprintf(stderr,
1N/A gettext("LDAP Configuration problem.\n"));
1N/A perr(err);
1N/A break;
1N/A
1N/A case NS_LDAP_PARTIAL:
1N/A exit_val = 2;
1N/A (void) fprintf(stderr,
1N/A gettext("partial result returned\n"));
1N/A perr(err);
1N/A break;
1N/A
1N/A case NS_LDAP_INTERNAL:
1N/A exit_val = 2;
1N/A (void) fprintf(stderr,
1N/A gettext("internal LDAP error occured.\n"));
1N/A perr(err);
1N/A break;
1N/A }
1N/A
1N/A if (eres != NULL) {
1N/A (void) __ns_ldap_freeResult(&eres);
1N/A eres = NULL;
1N/A }
1N/A
1N/A if (success) {
1N/A while (!done) {
1N/A rc = __ns_ldap_nextEntry(cookie, &eres, &err);
1N/A if (rc != NS_LDAP_SUCCESS || eres == NULL) {
1N/A done = 1;
1N/A continue;
1N/A }
1N/A
1N/A /* Print the result */
1N/A if (eres != NULL) {
1N/A if (strcmp(databasetype, "publickey") == 0)
1N/A dump_publickey(eres, service);
1N/A else
1N/A (*(tt->dump))(eres);
1N/A (void) __ns_ldap_freeResult(&eres);
1N/A eres = NULL;
1N/A }
1N/A }
1N/A }
1N/A}
1N/A
1N/Aint
1N/Amain(int argc, char **argv)
1N/A{
1N/A char *password;
1N/A ns_standalone_conf_t standalone_cfg = standaloneDefaults;
1N/A int c;
1N/A int rc;
1N/A int ldaprc;
1N/A int authstried = 0;
1N/A int op = OP_ADD;
1N/A char *ttype, *authmech = 0, *etcfile = 0;
1N/A /* Temporary password variable */
1N/A char ps[LDAP_MAXNAMELEN];
1N/A char filter[BUFSIZ];
1N/A void **paramVal = NULL;
1N/A ns_auth_t **app;
1N/A ns_auth_t **authpp = NULL;
1N/A ns_auth_t *authp = NULL;
1N/A ns_ldap_error_t *errorp = NULL;
1N/A ns_ldap_result_t *resultp;
1N/A ns_ldap_entry_t *e;
1N/A int flag = 0;
1N/A int version1 = 0;
1N/A
1N/A (void) setlocale(LC_ALL, "");
1N/A (void) textdomain(TEXT_DOMAIN);
1N/A
1N/A openlog("ldapaddent", LOG_PID, LOG_USER);
1N/A
1N/A inputbasedn = NULL;
1N/A authority.cred.unix_cred.passwd = NULL;
1N/A authority.cred.unix_cred.userID = NULL;
1N/A authority.auth.type = NS_LDAP_AUTH_SIMPLE;
1N/A
1N/A while ((c = getopt(argc, argv, "cdh:N:M:vpf:D:w:j:b:a:P:r:")) != EOF) {
1N/A switch (c) {
1N/A case 'd':
1N/A if (op)
1N/A usage(gettext(
1N/A "no other option should be specified"));
1N/A op = OP_DUMP;
1N/A break;
1N/A case 'c':
1N/A continue_onerror = 1;
1N/A break;
1N/A case 'v':
1N/A flags |= F_VERBOSE;
1N/A break;
1N/A case 'p':
1N/A flags |= F_PASSWD;
1N/A break;
1N/A case 'M':
1N/A standalone_cfg.type = NS_LDAP_SERVER;
1N/A standalone_cfg.SA_DOMAIN = optarg;
1N/A break;
1N/A case 'h':
1N/A standalone_cfg.type = NS_LDAP_SERVER;
1N/A if (separatePort(optarg,
1N/A &standalone_cfg.SA_SERVER,
1N/A &standalone_cfg.SA_PORT) > 0) {
1N/A exit(1);
1N/A }
1N/A break;
1N/A case 'P':
1N/A standalone_cfg.type = NS_LDAP_SERVER;
1N/A authority.hostcertpath = optarg;
1N/A break;
1N/A case 'N':
1N/A standalone_cfg.type = NS_LDAP_SERVER;
1N/A standalone_cfg.SA_PROFILE_NAME = optarg;
1N/A break;
1N/A case 'f':
1N/A etcfile = optarg;
1N/A break;
1N/A case 'D':
1N/A authority.cred.unix_cred.userID = strdup(optarg);
1N/A break;
1N/A case 'w':
1N/A if (authority.cred.unix_cred.passwd) {
1N/A (void) fprintf(stderr,
1N/A gettext("Warning: The -w option is mutually"
1N/A " exclusive of -j. -w is ignored.\n"));
1N/A break;
1N/A }
1N/A
1N/A if (optarg != NULL &&
1N/A optarg[0] == '-' && optarg[1] == '\0') {
1N/A /* Ask for a password later */
1N/A break;
1N/A }
1N/A
1N/A authority.cred.unix_cred.passwd = strdup(optarg);
1N/A break;
1N/A case 'j':
1N/A if (authority.cred.unix_cred.passwd != NULL) {
1N/A (void) fprintf(stderr,
1N/A gettext("The -w option is mutually "
1N/A "exclusive of -j. -w is ignored.\n"));
1N/A free(authority.cred.unix_cred.passwd);
1N/A }
1N/A authority.cred.unix_cred.passwd = readPwd(optarg);
1N/A if (authority.cred.unix_cred.passwd == NULL) {
1N/A exit(1);
1N/A }
1N/A break;
1N/A case 'b':
1N/A inputbasedn = strdup(optarg);
1N/A break;
1N/A case 'a':
1N/A authmech = strdup(optarg);
1N/A break;
1N/A default:
1N/A usage(gettext("Invalid option"));
1N/A }
1N/A }
1N/A
1N/A if (standalone_cfg.type == NS_LDAP_SERVER &&
1N/A standalone_cfg.SA_SERVER == NULL) {
1N/A (void) fprintf(stderr,
1N/A gettext("Please specify an LDAP server you want "
1N/A "to connect to. \n"));
1N/A exit(1);
1N/A }
1N/A
1N/A if (authmech != NULL) {
1N/A if (__ns_ldap_initAuth(authmech, &authority.auth, &errorp) !=
1N/A NS_LDAP_SUCCESS) {
1N/A if (errorp) {
1N/A (void) fprintf(stderr, "%s", errorp->message);
1N/A (void) __ns_ldap_freeError(&errorp);
1N/A }
1N/A exit(1);
1N/A }
1N/A }
1N/A
1N/A if (authority.auth.saslmech != NS_LDAP_SASL_GSSAPI &&
1N/A authority.cred.unix_cred.userID == NULL &&
1N/A op != OP_DUMP) {
1N/A /* This is not an optional parameter. Exit */
1N/A (void) fprintf(stderr,
1N/A gettext("DN must be specified unless SASL/GSSAPI is used."
1N/A " Use option -D.\n"));
1N/A exit(1);
1N/A }
1N/A
1N/A if (authority.auth.saslmech != NS_LDAP_SASL_GSSAPI &&
1N/A authority.cred.unix_cred.passwd == NULL &&
1N/A (op != OP_DUMP ||
1N/A standalone_cfg.type != NS_CACHEMGR &&
1N/A authority.cred.unix_cred.userID != NULL)) {
1N/A /* If password is not specified, then prompt user for it. */
1N/A password = getpassphrase("Enter password:");
1N/A (void) strcpy(ps, password);
1N/A authority.cred.unix_cred.passwd = strdup(ps);
1N/A }
1N/A
1N/A standalone_cfg.SA_AUTH = authmech == NULL ? NULL : &authority.auth;
1N/A standalone_cfg.SA_CERT_PATH = authority.hostcertpath;
1N/A standalone_cfg.SA_BIND_DN = authority.cred.unix_cred.userID;
1N/A standalone_cfg.SA_BIND_PWD = authority.cred.unix_cred.passwd;
1N/A
1N/A if (__ns_ldap_initStandalone(&standalone_cfg,
1N/A &errorp) != NS_LDAP_SUCCESS) {
1N/A if (errorp) {
1N/A (void) fprintf(stderr, "%s", errorp->message);
1N/A }
1N/A exit(1);
1N/A }
1N/A
1N/A if (authmech == NULL) {
1N/A ldaprc = __ns_ldap_getParam(NS_LDAP_AUTH_P, (void ***)&authpp,
1N/A &errorp);
1N/A if (ldaprc != NS_LDAP_SUCCESS ||
1N/A (authpp == NULL && op != OP_DUMP)) {
1N/A (void) fprintf(stderr,
1N/A gettext("No legal authentication method "
1N/A "configured.\n"));
1N/A (void) fprintf(stderr,
1N/A gettext("Provide a legal authentication method "
1N/A "using -a option\n"));
1N/A exit(1);
1N/A }
1N/A
1N/A /* Use the first authentication method which is not none */
1N/A for (app = authpp; *app; app++) {
1N/A authp = *app;
1N/A if (authp->type != NS_LDAP_AUTH_NONE) {
1N/A authstried++;
1N/A authority.auth.type = authp->type;
1N/A authority.auth.tlstype = authp->tlstype;
1N/A authority.auth.saslmech = authp->saslmech;
1N/A authority.auth.saslopt = authp->saslopt;
1N/A break;
1N/A }
1N/A }
1N/A if (authstried == 0 && op != OP_DUMP) {
1N/A (void) fprintf(stderr,
1N/A gettext("No legal authentication method configured."
1N/A "\nProvide a legal authentication method using "
1N/A "-a option"));
1N/A exit(1);
1N/A }
1N/A if (authority.auth.saslmech == NS_LDAP_SASL_GSSAPI &&
1N/A authority.cred.unix_cred.passwd != NULL &&
1N/A authority.cred.unix_cred.userID != NULL) {
1N/A /*
1N/A * -a is not specified and the auth method sasl/GSSAPI
1N/A * is defined in the configuration of the ldap profile.
1N/A * Even -D and -w is provided it's not valid usage.
1N/A * Drop them on the floor.
1N/A */
1N/A
1N/A (void) fprintf(stderr,
1N/A gettext("The default authentication is "
1N/A "sasl/GSSAPI.\n"
1N/A "The bind DN and password will be ignored.\n"));
1N/A authority.cred.unix_cred.passwd = NULL;
1N/A authority.cred.unix_cred.userID = NULL;
1N/A }
1N/A }
1N/A
1N/A ttype = argv[optind++];
1N/A
1N/A if (ttype == NULL) {
1N/A usage(gettext("No database type specified"));
1N/A exit(1);
1N/A }
1N/A
1N/A if (strncasecmp(ttype, "automount", 9) == 0) {
1N/A (void) fprintf(stderr,
1N/A gettext("automount is not a valid service for ldapaddent.\n"
1N/A "Please use auto_*.\n"
1N/A "e.g. auto_home, auto_ws etc.\n "));
1N/A exit(1);
1N/A }
1N/A
1N/A for (tt = ttypelist; tt->ttype; tt++) {
1N/A if (strcmp(tt->ttype, ttype) == 0)
1N/A break;
1N/A if (strcmp(tt->ttype, NS_LDAP_TYPE_AUTOMOUNT) == 0 &&
1N/A strncmp(ttype, NS_LDAP_TYPE_AUTOMOUNT,
1N/A sizeof (NS_LDAP_TYPE_AUTOMOUNT) - 1) == 0)
1N/A break;
1N/A }
1N/A
1N/A if (tt->ttype == 0) {
1N/A (void) fprintf(stderr,
1N/A gettext("database %s not supported;"
1N/A " supported databases are:\n"), ttype);
1N/A for (tt = ttypelist; tt->ttype; tt++)
1N/A (void) fprintf(stderr, gettext("\t%s\n"), tt->ttype);
1N/A exit(1);
1N/A }
1N/A
1N/A if (flags & F_VERBOSE)
1N/A (void) fprintf(stdout, gettext("SERVICE = %s\n"), tt->ttype);
1N/A
1N/A databasetype = ttype;
1N/A
1N/A if (strcmp(tt->ttype, NS_LDAP_TYPE_AUTOMOUNT) == 0) {
1N/A paramVal = NULL;
1N/A errorp = NULL;
1N/A rc = __ns_ldap_getParam(NS_LDAP_FILE_VERSION_P, &paramVal,
1N/A &errorp);
1N/A if (paramVal && *paramVal &&
1N/A strcasecmp(*paramVal, NS_LDAP_VERSION_1) == 0)
1N/A version1 = 1;
1N/A if (paramVal)
1N/A (void) __ns_ldap_freeParam(&paramVal);
1N/A if (errorp)
1N/A (void) __ns_ldap_freeError(&errorp);
1N/A }
1N/A
1N/A /* Check if the container exists in first place */
1N/A (void) strcpy(&filter[0], "(objectclass=*)");
1N/A
1N/A rc = __ns_ldap_list(databasetype, filter, NULL, (const char **)NULL,
1N/A NULL, NS_LDAP_SCOPE_BASE, &resultp, &errorp, NULL, NULL);
1N/A
1N/A /* create a container for auto_* if it does not exist already */
1N/A if ((rc == NS_LDAP_NOTFOUND) && (op == OP_ADD) &&
1N/A (strcmp(tt->ttype, NS_LDAP_TYPE_AUTOMOUNT) == 0)) {
1N/A static char *oclist[] = {NULL, "top", NULL};
1N/A if (version1)
1N/A oclist[0] = "nisMap";
1N/A else
1N/A oclist[0] = "automountMap";
1N/A e = __s_mk_entry(oclist, 3);
1N/A if (e == NULL) {
1N/A (void) fprintf(stderr,
1N/A gettext("internal memory allocation error.\n"));
1N/A exit(1);
1N/A }
1N/A if (__s_add_attr(e,
1N/A version1 ? "nisMapName" : "automountMapName",
1N/A databasetype) != NS_LDAP_SUCCESS) {
1N/A (void) fprintf(stderr,
1N/A gettext("internal memory allocation error.\n"));
1N/A ldap_freeEntry(e);
1N/A exit(1);
1N/A }
1N/A
1N/A if (inputbasedn == NULL) {
1N/A if (get_basedn(databasetype, &inputbasedn) !=
1N/A NS_LDAP_SUCCESS) {
1N/A (void) fprintf(stderr,
1N/A gettext("Could not obtain basedn\n"));
1N/A ldap_freeEntry(e);
1N/A exit(1);
1N/A }
1N/A }
1N/A if (__ns_ldap_addEntry(databasetype, inputbasedn, e,
1N/A &authority, flag, &errorp) != NS_LDAP_SUCCESS) {
1N/A (void) fprintf(stderr,
1N/A gettext("Could not create container for %s\n"),
1N/A databasetype);
1N/A ldap_freeEntry(e);
1N/A }
1N/A } else if (strcmp(databasetype, "publickey") != 0) {
1N/A if (rc == NS_LDAP_NOTFOUND) {
1N/A (void) fprintf(stderr,
1N/A gettext("Container %s does not exist\n"),
1N/A databasetype);
1N/A exit(1);
1N/A }
1N/A }
1N/A
1N/A if (op == OP_DUMP) {
1N/A if (strcmp(databasetype, "publickey") == 0) {
1N/A dumptable("hosts");
1N/A dumptable("passwd");
1N/A } else {
1N/A dumptable(databasetype);
1N/A }
1N/A exit(exit_val);
1N/A }
1N/A
1N/A if (etcfile) {
1N/A if ((etcf = fopen(etcfile, "r")) == 0) {
1N/A (void) fprintf(stderr,
1N/A gettext("can't open file %s\n"), etcfile);
1N/A exit(1);
1N/A }
1N/A } else {
1N/A etcfile = "stdin";
1N/A etcf = stdin;
1N/A }
1N/A
1N/A if (op == OP_ADD) {
1N/A (void) addfile();
1N/A (void) fprintf(stdout, gettext("%d entries added\n"), nent_add);
1N/A }
1N/A
1N/A __ns_ldap_cancelStandalone();
1N/A /* exit() -> return for make lint */
1N/A return (exit_val);
1N/A}
1N/A
1N/A
1N/A/*
1N/A * This is called when service == auto_*.
1N/A * It calls __ns_ldap_getSearchDescriptors
1N/A * to generate the dn from SSD's base dn.
1N/A * If there is no SSD available,
1N/A * default base dn will be used
1N/A * Only the first baseDN in the SSD is used
1N/A */
1N/A
1N/Astatic int get_basedn(char *service, char **basedn) {
1N/A int rc = NS_LDAP_SUCCESS;
1N/A char *dn = NULL;
1N/A ns_ldap_search_desc_t **desc = NULL;
1N/A ns_ldap_error_t *errp = NULL;
1N/A void **paramVal = NULL;
1N/A int prepend_automountmapname = FALSE;
1N/A
1N/A /*
1N/A * Get auto_* SSD first
1N/A */
1N/A
1N/A if ((rc = __ns_ldap_getSearchDescriptors(
1N/A (const char *) service,
1N/A &desc, &errp)) == NS_LDAP_SUCCESS &&
1N/A desc != NULL) {
1N/A
1N/A if (desc[0] != NULL && desc[0]->basedn != NULL) {
1N/A dn = strdup(desc[0]->basedn);
1N/A if (dn == NULL) {
1N/A (void) __ns_ldap_freeSearchDescriptors
1N/A (&desc);
1N/A return (NS_LDAP_MEMORY);
1N/A }
1N/A }
1N/A }
1N/A
1N/A /* clean up */
1N/A if (desc) (void) __ns_ldap_freeSearchDescriptors(&desc);
1N/A if (errp) (void) __ns_ldap_freeError(&errp);
1N/A
1N/A /*
1N/A * If no dn is duplicated from auto_* SSD, try automount SSD
1N/A */
1N/A if (dn == NULL) {
1N/A if ((rc = __ns_ldap_getSearchDescriptors(
1N/A "automount", &desc, &errp))
1N/A == NS_LDAP_SUCCESS && desc != NULL) {
1N/A
1N/A if (desc[0] != NULL && desc[0]->basedn != NULL) {
1N/A dn = strdup(desc[0]->basedn);
1N/A if (dn == NULL) {
1N/A (void) __ns_ldap_freeSearchDescriptors
1N/A (&desc);
1N/A return (NS_LDAP_MEMORY);
1N/A }
1N/A prepend_automountmapname = TRUE;
1N/A }
1N/A }
1N/A /* clean up */
1N/A if (desc) (void) __ns_ldap_freeSearchDescriptors(&desc);
1N/A if (errp) (void) __ns_ldap_freeError(&errp);
1N/A }
1N/A
1N/A /*
1N/A * If no dn is duplicated from auto_* or automount SSD,
1N/A * use default DN
1N/A */
1N/A
1N/A if (dn == NULL) {
1N/A if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_BASEDN_P,
1N/A &paramVal, &errp)) == NS_LDAP_SUCCESS) {
1N/A dn = strdup((char *)paramVal[0]);
1N/A if (dn == NULL) {
1N/A (void) __ns_ldap_freeParam(&paramVal);
1N/A return (NS_LDAP_MEMORY);
1N/A }
1N/A prepend_automountmapname = TRUE;
1N/A }
1N/A if (paramVal) (void) __ns_ldap_freeParam(&paramVal);
1N/A if (errp) (void) __ns_ldap_freeError(&errp);
1N/A }
1N/A
1N/A
1N/A if (dn == NULL) {
1N/A return (NS_LDAP_OP_FAILED);
1N/A } else {
1N/A /*
1N/A * If dn is duplicated from
1N/A * automount SSD basedn or
1N/A * default base dn
1N/A * then prepend automountMapName=auto_xxx
1N/A */
1N/A if (prepend_automountmapname)
1N/A rc = __s_api_prepend_automountmapname_to_dn(
1N/A service, &dn, &errp);
1N/A
1N/A if (rc != NS_LDAP_SUCCESS) {
1N/A (void) __ns_ldap_freeError(&errp);
1N/A free(dn);
1N/A return (rc);
1N/A }
1N/A
1N/A *basedn = dn;
1N/A
1N/A return (NS_LDAP_SUCCESS);
1N/A }
1N/A}
1N/Astatic char *
1N/Ah_errno2str(int h_errno) {
1N/A switch (h_errno) {
1N/A case HOST_NOT_FOUND:
1N/A return ("HOST_NOT_FOUND");
1N/A /* NOTREACHED */
1N/A break;
1N/A case TRY_AGAIN:
1N/A return ("TRY_AGAIN");
1N/A /* NOTREACHED */
1N/A break;
1N/A case NO_RECOVERY:
1N/A return ("NO_RECOVERY");
1N/A /* NOTREACHED */
1N/A break;
1N/A case NO_DATA:
1N/A return ("NO_DATA");
1N/A /* NOTREACHED */
1N/A break;
1N/A default:
1N/A break;
1N/A }
1N/A return ("UNKNOWN_ERROR");
1N/A}