nisaddent.c revision cb5caa98562cf06753163f558cbcfe30b8f4673a
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
*
*/
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <ndbm.h>
#include <rpcsvc/nis_dhext.h>
#include <pwd.h>
#include <auth_attr.h>
#include <exec_attr.h>
#include <prof_attr.h>
#include <user_attr.h>
#include <nss_dbdefs.h>
#define NIS_WORLD_MASK(a) (a)
#define NIS_GROUP_MASK(a) (a << 8)
#define NIS_OWNER_MASK(a) (a << 16)
#define NIS_NOBODY_MASK(a) (a << 24)
/* same as in nis_util.c (we really need a .h) */
#define NIS_SRC_DEFAULT 0
#define NIS_SRC_ENV 1
#define NIS_SRC_ARG 2
#define BIGBUF 8192
extern int optind;
extern char *optarg;
extern nis_object nis_default_obj;
extern int nis_default_access_src;
extern char *__nis_quote_key(const char *, char *, int);
extern char *strpbrk_quotes(char *, char *);
extern char *strtok_quotes(char *, char *);
extern char *strchr_quotes(char *, char);
extern char *_strtok_escape(char *, char *, char **); /* from libnsl */
/*
* Temporary files used by merge_file. The 'created' variables
* record whether or not we created the file. An exit routine
* will unlink the files if they were created.
*/
char tmpdirbuf[MAXPATHLEN];
char tmppagbuf[MAXPATHLEN];
int created_dir;
int created_pag;
struct file_loc {
};
struct line_buf {
char *str;
int len;
int alloc;
};
struct ttypelist_t {
char *ttype; /* type tag */
char *ypmap; /* nis map to use */
char *nistbl; /* nis+ table to use */
char *ta_type; /* nis+ table type */
char *clrsrch; /* nis+ search critera to clear table */
int niskeycol; /* nis+ key column */
int filekeycol; /* file key column */
char *filesep; /* chars marking columns in files */
char *(*dbmniskey)(); /* routine to turn dbm key into nis key */
int (*genent)(); /* routine to turn line into nis+ entries */
void (*dump)(); /* routine to print nis+ table */
int (*filedbmline)(); /* routine to turn file line into dbm line */
char *(*fetchdbm)(); /* routine to fetch a nis map line */
void (*printfkeystr)(); /* routine to print keystr for -v */
} *tt;
char *nisdomain;
char ta_name[NIS_MAXNAMELEN];
#define OP_ADD 0
#define OP_REPLACE 1
#define OP_MERGE 2
#define OP_DUMP 3
#define F_VERBOSE 0x1
#define F_PASSWD 0x2
#define F_QUICK 0x4
int exit_val = 0;
unsigned flags = 0;
int oldpubkeymode = 0;
unsigned nent_add = 0;
unsigned nent_del = 0;
int user_attr_keycol[USERATTR_DB_NKEYCOL] = {
};
int exec_attr_keycol[EXECATTR_DB_NKEYCOL] = {
};
#define PARSE_ERR_MSG_LEN 512
static char parse_err_msg [PARSE_ERR_MSG_LEN];
char null_string[] = "";
/* the followings are defined to fix cstyle complain of line too long */
#define ENTRY_COL(c) \
#define OBJ_COL_VAL(i, c) \
/*
* The following is a version of OBJ_COL_VALUE that returns a pointer
* to an empty string, rather than a NULL pointer, if the entry does not
* exist. Involves two derefs but this only a cmd line app so performance
* should not be an issue. The null string is defined as a constant so a new
* copy of it is not created for each macro invocation.
*/
char *nullStr = "";
#define OBJ_COL_VAL_NO_NULL(i, c) \
#define KEYVAL(c) \
/* get either key value or, if it is null, an empty string */
#define OBJ_COL_NAME(c) \
void
usage()
{
" nisaddent [-AM] -d [-t table] type [nisdomain]\n");
exit(1);
}
void
{
} else {
}
exit(1);
}
}
void
{
}
void
{
int toprintlen = 0;
/* has print buffer line been exhausted */
do {
} else {
}
exit(1);
}
}
/* now add new 'toprint' data to buffer */
}
void
{
}
void
{
}
int
int mod;
{
/* ignore unset columns in modified entries */
return (1);
return (0);
return (1);
else
return (0);
}
else
}
int
nis_object *e1;
nis_object *e2;
int mod;
{
int i;
i > 0;
return (0);
return (1);
}
int
entry_inresult(e, r, mod)
nis_object *e;
nis_result *r;
int mod;
{
int i;
return (1);
}
return (0);
}
int
void *udata;
int mod;
{
return (0);
if (mod) {
} else
nent_add++;
else {
"\"%s\"\n", entry);
if (mod)
else
}
return (0);
}
int
void *udata;
int mod;
{
return (1);
return (0);
}
int
{
nent_del++;
else {
}
return (0);
}
/*
* return a string of tab characters that when concatenated with the
* specified string leave the cursor at the beginning of the specified
* column. if the string is too long, then return a single space. the
* specified column must be less than 10.
*/
char *
char *str;
int col;
{
int c, l;
char *p;
for (c = l = 0, p = str; *p; p++) {
if (*p == '\t' || ++l == 8) {
c++;
l = 0;
}
}
if (c < col)
return (" ");
}
char *
{
static char buf[NIS_MAXNAMELEN];
*tmp = '\0';
return (buf);
}
char *
{
int i, numkeycol;
int *keycol;
char *p, *s;
static char buf[NIS_MAXNAMELEN];
buf[0] = 0;
}
for (i = 0; i < numkeycol; i++) {
if (p == NULL) {
break;
}
s = ++p;
}
*p = 0;
return (buf);
}
char *
{
static char buf[NIS_MAXNAMELEN];
return (buf);
}
{
return (key);
}
{
int i;
int numkeycol;
int *keycol;
char *p, *s;
buf[0] = 0;
}
for (i = 0; i < numkeycol; i++) {
continue;
}
*p = 0;
return (key);
}
{
if (mechs) {
goto nomechs;
&algtype) < 0)
goto nomechs;
if (bitlen == 192)
else
} else {
}
return (key);
}
filedbmkey_attr(char *line)
{
int i, j, skip;
int numkeycol;
int *keycol;
char *p = NULL;
char *q = NULL;
char *s = NULL;
s = line;
buf[0] = 0;
}
for (i = 0; i < numkeycol; i++) {
for (j = keycol[i]; j >= 0; j--) {
if (j > 0) {
if (p == NULL) {
return (key);
}
if (skip > 1) {
if ((j = j - skip) <= 0)
j = 1;
}
s = p + skip;
}
}
if (p) {
} else {
if (buf[0] == 0)
break;
}
}
*q = 0;
return (key);
}
char *line;
{
int i;
char *p;
if (mechs) {
char keylen[256];
int bitlen = 0;
/*
* We don't use the private key, but we need to get to
* the algtype
*/
*privkey++ = '\0';
/* Get rid of extra :'s */
if (*privkey == ':')
privkey++;
}
*algtype++ = '\0';
else
algtype = "0";
if (bitlen == 192)
else
} else {
for (i = tt->filekeycol; i >= 0; i--) {
if (i > 0) {
if (p == 0) {
return (key);
}
}
}
if (p)
else
}
return (key);
}
/*
* Note that most of the filedbmkey() code is duplicated in
* filedbmkey_netid() below.
*/
char *line;
{
int i;
char *p;
for (i = tt->filekeycol; i >= 0; i--) {
if (i > 0) {
if (p == 0) {
return (key);
}
}
}
if (p)
else
return (key);
}
/*
* filedbmkey_netid() duplicates filedbmkey() above, but also
* removes trailing dots.
*/
char *line;
{
int i;
char *p;
for (i = tt->filekeycol; i >= 0; i--) {
if (i > 0) {
if (p == 0) {
return (key);
}
}
}
if (p)
else
/* Strip any trailing dot from key */
}
return (key);
}
int
char *line;
{
char *p;
for (p = line; *p; p++)
if (*p != ' ' && *p != '\t')
return (0);
return (1);
}
/*
* Read a line into a line_buf starting at offset 'n'. We expand the
* line_buf when needed. We read until '\n' or EOF. If we don't read
* any characters before EOF we return 0. Otherwise, we return a pointer
* to the string read.
*/
char *
int n;
{
int c;
while (1) {
if (c == -1)
break;
if (c == '\n')
break;
}
/* null terminate */
/* if we read no characters, return NULL to indicate EOF */
return (0);
}
int
int *lineno;
{
int len = 0;
while (1) {
return (0);
if (lineno)
(*lineno)++;
len -= 1;
}
break;
len = 0;
}
return (1);
}
int
int *lineno;
{
int len = 0;
while (1) {
return (0);
if (lineno)
(*lineno)++;
if (len >= 2 &&
len -= 2;
continue; /* append next line at end */
}
len -= 1;
}
break;
len = 0;
}
return (1);
}
int
int *lineno;
{
int len = 0;
while (1) {
return (0);
if (lineno)
(*lineno)++;
len -= 1;
}
break;
len = 0;
}
return (1);
}
char *
{
return (line);
}
return (0);
}
char *
{
return (line);
return (line);
}
}
return (0);
}
char *
{
char *p;
return (0); /* not in file */
exit(1);
}
return (0);
}
/*
* Convert a line into key and content. The key is included
* in the content.
*/
void
char *line;
{
int i;
char *p;
for (i = tt->filekeycol; i >= 0; i--) {
if (i > 0) {
if (p == 0) {
return;
}
}
}
if (p) {
} else {
}
}
/*
* Convert a line into key and content. Unlike filetodbm, the key
* is not included in the content.
*/
void
char *line;
{
int i;
char *p;
for (i = tt->filekeycol; i >= 0; i--) {
if (i > 0) {
if (p == 0) {
return;
}
}
}
if (p) {
} else {
}
}
/*
* Convert a line into key and content. The key is included
* in the content.
*/
void
{
int *keycol;
char *p;
}
for (i = 0; i < numkeycol; i++) {
for (j = keycol[i]; j >= 0; j--) {
if (j > 0) {
if (p == NULL) {
return;
}
if (skip > 1) {
if ((j = j - skip) <= 0)
j = 1;
}
}
}
}
if (p) {
} else {
}
}
void
char *fstr;
{
}
void
char *fstr;
{
}
void
char *fstr;
{
else
}
#define GENENT_OK 0
#define GENENT_PARSEERR 1
#define GENENT_CBERR 2
#define GENENT_ERR 3
/*
* nis+ table: (hosts_tbl) cname, name, addr, comment
* Builds IPv4 entries only, IPv6 entries in hosts are ignored.
*/
int
char *line;
int (*cback)();
void *udata;
{
char *t;
char *cname;
/*
* don't clobber our argument
*/
return (GENENT_PARSEERR);
}
/*
* clear column data
*/
/*
* comment (col 3)
*/
if (t != NULL) {
*t++ = 0;
} else {
}
/*
* addr(col 2)
*/
return (GENENT_PARSEERR);
}
/*
* Ignore IPv6 entries in hosts file, return OK.
*/
return (GENENT_OK);
/*
* cname (col 0)
*/
return (GENENT_PARSEERR);
}
cname = t;
/*
* build entry
*/
if (!cback)
/*
* name (col 1)
*/
do {
/*
* don't clobber comment in canonical entry
*/
continue;
return (GENENT_CBERR);
/*
* only put comment in canonical entry
*/
return (GENENT_OK);
}
/*
* nis+ table: (ipnodes_tbl) cname, name, addr, comment
* Builds both IPv4 and IPv6 entries for ipnodes map.
*/
int
char *line;
int (*cback)();
void *udata;
{
char *t;
char *cname;
/*
* don't clobber our argument
*/
return (GENENT_PARSEERR);
}
/*
* clear column data
*/
/*
* comment (col 3)
*/
if (t != NULL) {
*t++ = 0;
} else {
}
/*
* addr(col 2)
*/
return (GENENT_PARSEERR);
}
/*
* cname (col 0)
*/
return (GENENT_PARSEERR);
}
cname = t;
/*
* build entry
*/
/*
* name (col 1)
*/
do {
/*
* don't clobber comment in canonical entry
*/
continue;
return (GENENT_CBERR);
/*
* only put comment in canonical entry
*/
return (GENENT_OK);
}
/*
* List all of the entries that have the same cname as the passed
* entry.
*/
{
nis_result *res = 0;
char srch[NIS_MAXNAMELEN];
}
return (res);
}
/*
* List all of the entries that have the same cname and address as the passed
* entry.
*/
{
nis_result *res = 0;
char srch[NIS_MAXNAMELEN];
}
return (res);
}
void
{
int i, j;
if (j != i &&
*c0a = 0;
}
}
*c0 = 0;
}
}
}
/*
* nis+ table: (passwd_tbl) name, passwd, uid, gid, gcos, home, shell, shadow
*
*/
int
char *line;
int (*cback)();
void *udata;
{
char *s, *t;
char aname[NIS_MAXNAMELEN];
/*
* don't clobber our argument
*/
return (GENENT_PARSEERR);
}
t = buf;
/* ignore empty entries */
if (*t == '\0')
return (GENENT_OK);
/*
* clear column data
*/
/*
* name (col 0)
*/
if ((s = strchr(t, ':')) == 0) {
return (GENENT_PARSEERR);
}
*s++ = 0;
name = t;
t = s;
/*
* passwd (col 1)
*/
if ((s = strchr(t, ':')) == 0) {
return (GENENT_PARSEERR);
}
*s++ = 0;
#ifndef FOURDOTX
#endif
#ifndef FOURDOTX
}
#endif
t = s;
/*
* uid (col 2)
*/
if ((s = strchr(t, ':')) == 0 || s == t) {
return (GENENT_PARSEERR);
}
*s++ = 0;
t = s;
/*
* gid (col 3)
*/
if ((s = strchr(t, ':')) == 0 || s == t) {
return (GENENT_PARSEERR);
}
*s++ = 0;
t = s;
/*
* gcos (col 4)
*/
if ((s = strchr(t, ':')) == 0) {
return (GENENT_PARSEERR);
}
*s++ = 0;
t = s;
/*
* home (col 5)
*/
if ((s = strchr(t, ':')) == 0) {
return (GENENT_PARSEERR);
}
*s++ = 0;
t = s;
/*
* shell (col 6)
*/
/*
* NIS+ principal name
*/
/*
* build entry
*/
/*
* If access mode did not come from -D option,
* then ignore it.
*/
if (nis_default_access_src != NIS_SRC_ARG)
if (!cback)
/* specify entry by name alone (ignore uid) */
return (GENENT_CBERR);
return (GENENT_OK);
}
void
{
int i;
if (c0 = OBJ_COL_VAL(i, 0)) {
printf("%s:%s:%s:%s:%s:%s:%s\n",
c0,
#ifndef FOURDOTX
"x",
#else
c1,
#endif
}
}
}
int
char *line;
int (*cback)();
void *udata;
{
char *s, *t;
/*
* don't clobber our argument
*/
return (GENENT_PARSEERR);
}
t = buf;
/* ignore empty entries */
if (*t == '\0')
return (GENENT_OK);
/*
* clear column data
*/
/*
* name (col 0)
*/
if ((s = strchr(t, ':')) == 0) {
return (GENENT_PARSEERR);
}
*s++ = 0;
name = t;
t = s;
/*
* passwd (col 1)
*/
if ((s = strchr(t, ':')) == 0) {
return (GENENT_PARSEERR);
}
*s++ = 0;
t = s;
/*
* shadow (col 7)
*/
/*
* NIS+ principal name
*/
/*
* build entry
*/
/*
* If access mode did not come from -D option,
* then ignore it.
*/
if (nis_default_access_src != NIS_SRC_ARG)
if (!cback)
/* specify entry by name alone (ignore uid) */
return (GENENT_CBERR);
return (GENENT_OK);
}
void
{
int i;
if (c0 = OBJ_COL_VAL(i, 0)) {
else
}
}
}
/*
* nis+ table: (ethers_tbl) addr, name, comment
*
*/
int
char *line;
int (*cback)();
void *udata;
{
char *t;
char *name;
/*
* don't clobber our argument
*/
return (GENENT_PARSEERR);
}
/*
* clear column data
*/
/*
* comment (col 2)
*/
if (t) {
*t++ = 0;
} else {
}
/*
* addr(col 0)
*/
return (GENENT_PARSEERR);
}
addr = t;
/*
* name(col 1)
*/
return (GENENT_PARSEERR);
}
name = t;
/*
* build entry
*/
if (!cback)
/* specify entry by addr alone (ignore name) */
return (GENENT_CBERR);
return (GENENT_OK);
}
void
{
int i;
if ((c0 = OBJ_COL_VAL(i, 0)) &&
}
}
}
}
/*
* nis+ table: (group_tbl) name, passwd, gid, members
*
*/
int
char *line;
int (*cback)();
void *udata;
{
char *s, *t;
char *name;
/*
* don't clobber our argument
*/
return (GENENT_PARSEERR);
}
t = buf;
/* ignore empty entries */
if (*t == '\0')
return (GENENT_OK);
/*
* clear column data
*/
/*
* name (col 0)
*/
if ((s = strchr(t, ':')) == 0) {
return (GENENT_PARSEERR);
}
*s++ = 0;
name = t;
t = s;
/*
* passwd (col 1)
*/
if ((s = strchr(t, ':')) == 0) {
return (GENENT_PARSEERR);
}
*s++ = 0;
t = s;
/*
* gid (col 2)
*/
if ((s = strchr(t, ':')) == 0 || s == t) {
return (GENENT_PARSEERR);
}
*s++ = 0;
t = s;
/*
* members (col 3)
*/
/*
* build entry
*/
if (!cback)
return (GENENT_CBERR);
return (GENENT_OK);
}
void
{
int i;
if (c0 = OBJ_COL_VAL(i, 0)) {
}
}
}
/*
* nis+ table: (netmasks_tbl) number, mask, comment
*
*/
int
char *line;
int (*cback)();
void *udata;
{
char *t;
/*
* don't clobber our argument
*/
return (GENENT_PARSEERR);
}
/*
* clear column data
*/
/*
* comment (col 2)
*/
if (t) {
*t++ = 0;
} else {
}
/*
* addr(col 0)
*/
return (GENENT_PARSEERR);
}
addr = t;
/*
* mask (col 1)
*/
return (GENENT_PARSEERR);
}
/*
* build entry
*/
if (!cback)
/* specify entry by addr alone (ignore mask) */
return (GENENT_CBERR);
return (GENENT_OK);
}
void
{
int i;
}
}
}
}
/*
* nis+ table: (networks_tbl) cname, name, addr, comment
*
*/
int
char *line;
int (*cback)();
void *udata;
{
char *t;
char *cname;
/*
* don't clobber our argument
*/
return (GENENT_PARSEERR);
}
/*
* clear column data
*/
/*
* comment (col 3)
*/
if (t) {
*t++ = 0;
} else {
}
/*
* cname(col 0)
*/
return (GENENT_PARSEERR);
}
cname = t;
/*
* number (col 2)
*/
return (GENENT_PARSEERR);
}
/*
* build entry
*/
if (!cback)
/*
* name (col 1)
*/
t = cname;
do {
/*
* don't clobber comment in canonical entry
*/
continue;
return (GENENT_CBERR);
/*
* only put comment in canonical entry
*/
return (GENENT_OK);
}
void
{
int i, j, a;
if (j != i &&
if (a++ > 0)
else
*c0a = 0;
}
}
*c0 = 0;
}
}
}
/*
* nis+ table: (protocols_tbl) cname, name, number, comment
*
*/
int
char *line;
int (*cback)();
void *udata;
{
char *t;
char *cname;
/*
* don't clobber our argument
*/
return (GENENT_PARSEERR);
}
/*
* clear column data
*/
/*
* comment (col 3)
*/
if (t) {
*t++ = 0;
} else {
}
/*
* cname(col 0)
*/
return (GENENT_PARSEERR);
}
cname = t;
/*
* number (col 2)
*/
return (GENENT_PARSEERR);
}
/*
* build entry
*/
if (!cback)
/*
* name (col 1)
*/
t = cname;
do {
/*
* don't clobber comment in canonical entry
*/
continue;
return (GENENT_CBERR);
/*
* only put comment in canonical entry
*/
return (GENENT_OK);
}
void
{
int i, j, a;
if (j != i &&
if (a++ > 0)
else
*c0a = 0;
}
}
*c0 = 0;
}
}
}
/*
* nis+ table: (rpc_tbl) cname, name, number, comment
*
*/
int
char *line;
int (*cback)();
void *udata;
{
char *t;
char *cname;
/*
* don't clobber our argument
*/
return (GENENT_PARSEERR);
}
/*
* clear column data
*/
/*
* comment (col 3)
*/
if (t) {
*t++ = 0;
} else {
}
/*
* cname(col 0)
*/
return (GENENT_PARSEERR);
}
cname = t;
/*
* number (col 2)
*/
return (GENENT_PARSEERR);
}
/*
* build entry
*/
if (!cback)
/*
* name (col 1)
*/
t = cname;
do {
/*
* don't clobber comment in canonical entry
*/
continue;
return (GENENT_CBERR);
/*
* only put comment in canonical entry
*/
return (GENENT_OK);
}
void
{
int i, j, a;
if (j != i &&
if (a++ > 0)
else
*c0a = 0;
}
}
*c0 = 0;
}
}
}
/*
* nis+ table: (services_tbl) cname, name, proto, port, comment
*
*/
int
char *line;
int (*cback)();
void *udata;
{
char *t, *p;
char *cname;
/*
* don't clobber our argument
*/
return (GENENT_PARSEERR);
}
/*
* clear column data
*/
/*
* comment (col 4)
*/
if (t) {
*t++ = 0;
} else {
}
/*
* cname(col 0)
*/
return (GENENT_PARSEERR);
}
cname = t;
/*
* port (col 3)
*/
return (GENENT_PARSEERR);
}
if ((p = strchr(t, '/')) == 0) {
return (GENENT_PARSEERR);
}
*(p++) = 0;
/*
* proto (col 2)
*/
/*
* build entry
*/
if (!cback)
/*
* name (col 1)
*/
t = cname;
do {
/*
* don't clobber comment in canonical entry
*/
continue;
return (GENENT_CBERR);
/*
* only put comment in canonical entry
*/
return (GENENT_OK);
}
/*
* List all of the entries that match the cname, proto, and port
* of the passed entry.
*/
{
nis_result *res = 0;
char srch[NIS_MAXNAMELEN];
}
return (res);
}
void
{
int i, j, a;
if (j != i &&
if (a++ > 0)
else
*c0a = 0;
}
}
*c0 = 0;
}
}
}
char *
{
static char buf[NIS_MAXNAMELEN];
char *p;
} else {
}
return (buf);
}
{
return (key);
}
void
char *fstr;
{
NKEYVAL(2));
else
}
/*
* nis+ table: (cred_tbl) cname, auth_type, auth_name, public_data,
* private_data
*
*/
int
char *line;
int (*cback)();
void *udata;
{
char *t, *p;
int uid;
/*
* don't clobber our argument
*/
return (GENENT_PARSEERR);
}
/*
* clear column data
*/
/*
* auth_name (col 2)
*/
return (GENENT_PARSEERR);
}
/*
* for principal "nobody". We skip it because it does
* not apply to NIS+.
*/
if (strcmp(t, "nobody") == 0)
return (GENENT_OK);
/*
* cname (col 0)
*/
return (GENENT_PARSEERR);
}
return (GENENT_PARSEERR);
}
*(p++) = 0;
extern struct passwd *getpwuid_nisplus_master();
/*
* don't generate entries for uids without passwd entries
* first try it in the regular way, and if that fails, then
* a lookup to the NIS+ Master server to be sure.
*/
"can't map uid %d to username, skipping\n",
uid);
return (GENENT_OK);
}
} else
if (*p != '.')
/*
* XXX complain if domain in netname not same as nisdomain?
*/
/*
* public_data (col 3)
*/
return (GENENT_PARSEERR);
}
if ((p = strchr(t, ':')) == 0) {
return (GENENT_PARSEERR);
}
*(p++) = 0;
/*
* private_data (col 4) and algtype extraction
*/
if (*p == ':')
p++;
t = p;
if (!(t = strchr(t, ':'))) {
if (!oldpubkeymode)
"WARNING: No algtype data found in publickey file, assuming 0\n");
algtype = 0;
} else {
*t = '\0';
t++;
}
/*
* auth_type (col 1)
*/
return (GENENT_PARSEERR);
/*
* build entry
*/
if (!cback)
ta_name);
return (GENENT_CBERR);
return (GENENT_OK);
}
void
{
/*
* If RPCSEC_GSS is configured on this system, a list of
* auth_types needs to be generated to filter entries (since
* dumptable has ignored tt->clrsrch). Otherwise, the
* nis_list has prefiltered out the extra entries in
* dumptable.
*/
if (mechs) {
char *authtype;
MECH_MAXATNAME)) {
sizeof (char *) * (authlistcount + 2));
} else
mcount++;
}
if (authlistcount) {
filter++;
}
}
/*
* If we have a filter list, then we walk
* through it until we find a matching
* auth_type. Otherwise we go on to the next
* result entry.
*/
if (filter) {
int gotit = 0;
authlistcount = 0;
while (authlist[authlistcount]) {
c1) == 0) {
gotit++;
break;
}
}
if (!gotit)
continue;
}
if (!oldpubkeymode) {
else {
char algbuf[MECH_MAXATNAME], *a;
*a = ':';
} else
}
}
}
}
}
int
char *line;
int (*cback)();
void *udata;
{
char *t, *p;
int uid;
/*
* don't clobber our argument
*/
return (GENENT_PARSEERR);
}
/*
* clear column data
*/
/*
* cname (col 0)
*/
return (GENENT_PARSEERR);
}
return (GENENT_PARSEERR);
}
return (GENENT_PARSEERR);
}
*(p++) = 0;
extern struct passwd *getpwuid_nisplus_master();
/*
* don't generate entries for uids without passwd entries
* first try it in the regular way, and if that fails, then
* a lookup to the NIS+ Master server to be sure.
*/
"can't map uid %d to username, skipping\n",
uid);
return (GENENT_OK);
}
} else
uid = 0;
/*
* don't generate LOCAL entries for root
*/
if (uid == 0)
return (GENENT_OK);
if (*p != '.')
/*
* XXX complain if domain in netname not same as nisdomain?
*/
/*
* auth_name (col 2)
*/
return (GENENT_PARSEERR);
}
if ((p = strchr(t, ':')) == 0) {
return (GENENT_PARSEERR);
}
*(p++) = 0;
/*
* public_data (col 3)
*/
/*
* private_data (col 4)
*/
/*
* auth_type (col 1)
*/
/*
* build entry
*/
if (!cback)
return (GENENT_CBERR);
return (GENENT_OK);
}
void
{
int i, j;
if (objdom_len > 0) {
}
}
}
}
char *
{
static char buf[NIS_MAXNAMELEN];
int i;
return (buf);
break;
return (buf);
buf[5+i] = 0;
return (buf);
}
{
return (key);
}
/*
* nis+ table: (mail_aliases) alias, expansion, comments, options
*
* The handling of dbm keys and values for aliases is a little funny
* because the length field in a datum includes the terminating
* null (e.g., "name" would have length 5). The other types of dbm
* files do not include the terminating null.
*/
int
char *line;
int (*cback)();
void *udata;
{
char *t;
/*
* don't clobber our argument
*/
return (GENENT_PARSEERR);
}
/*
* clear column data
*/
/*
* alias(col 0)
*/
return (GENENT_PARSEERR);
}
alias = t;
/*
* expansion (col 1)
*/
return (GENENT_PARSEERR);
}
/*
* skip white space
*/
t += strspn(t, " \t");
if (*t == 0) {
return (GENENT_PARSEERR);
}
/*
* comments (col 2)
*/
/*
* options (col 3)
*/
/*
* build entry
*/
if (!cback)
/* specify entry by alias alone (ignore expansion) */
return (GENENT_CBERR);
return (GENENT_OK);
}
void
{
int i;
}
}
}
{
return (key);
}
char *line;
{
int i;
char *p;
for (i = tt->filekeycol; i >= 0; i--) {
if (i > 0) {
if (p == 0) {
return (key);
}
}
}
if (p)
else
return (key);
}
int
int *lineno;
{
char *p;
int c;
int len = 0;
while (1) {
return (0);
if (lineno)
(*lineno)++;
len -= 1;
}
/*
* A continuation line starts with a space or a tab.
* Continuation lines count even for commented lines.
*/
(c == ' ' || c == '\t')) {
continue;
}
break;
len = 0;
}
*p = ' ';
return (1);
}
/*
* Convert an alias line into key and content. Just like filetodbm_keyvalue
* but the key and data includes the terminating null.
*/
void
char *line;
{
int i;
char *p;
for (i = tt->filekeycol; i >= 0; i--) {
if (i > 0) {
if (p == 0) {
return;
}
}
}
if (p) {
*p++ = '\0'; /* null-terminate key */
} else {
}
}
/*
* key-value
* nis+ table: key, value
*
*/
int
char *line;
int (*cback)();
void *udata;
{
char *t;
/*
* don't clobber our argument
*/
return (GENENT_PARSEERR);
}
/*
* clear column data
*/
/*
* key(col 0)
*/
return (GENENT_PARSEERR);
}
/*
* value (col 1)
*/
t = "";
else
/*
* build entry
*/
if (!cback)
return (GENENT_CBERR);
return (GENENT_OK);
}
void
{
int i, j;
if (c0 = OBJ_COL_VAL(i, 0)) {
}
}
}
}
/*
* nis+ table: (netgroup_tbl) name, group, host, user, domain, comment
*
*/
int
char *line;
int (*cback)();
void *udata;
{
char *t, *p;
/*
* don't clobber our argument
*/
return (GENENT_PARSEERR);
}
/*
* clear column data
*/
/*
* comment (col 5)
*/
if (t) {
*t++ = 0;
} else {
}
/*
* name(col 0)
*/
return (GENENT_OK); /* empty line */
}
/*
* membership list
*/
p = "";
/*
* build entry
*/
if (!cback)
/*
* group (col 1)
* host (col 2)
* user (col 3)
* domain (col 4)
*/
while (*p) {
while (*p == ' ' || *p == '\t')
p++;
if (*p == '\0')
break;
if (*p == '(') {
/*
* group (col 1)
*/
/*
* host (col 2)
*/
p++;
while (*p == ' ' || *p == '\t')
p++;
t = p;
while (*p != ' ' && *p != '\t' && *p != ',')
if (*p == '\0' || *p == ')') {
return (GENENT_PARSEERR);
}
else
p++;
*p++ = 0;
/*
* user (col 3)
*/
while (*p == ' ' || *p == '\t')
p++;
t = p;
while (*p != ' ' && *p != '\t' && *p != ',')
if (*p == '\0' || *p == ')') {
return (GENENT_PARSEERR);
}
else
p++;
*p++ = 0;
/*
* domain (col 4)
*/
while (*p == ' ' || *p == '\t')
p++;
t = p;
while (*p != ' ' && *p != '\t' && *p != ')')
if (*p == '\0' || *p == ',') {
return (GENENT_PARSEERR);
}
else
p++;
*p++ = 0;
} else {
/*
* host (col 2)
*/
/*
* user (col 3)
*/
/*
* domain (col 4)
*/
/*
* group (col 1)
*/
t = p;
while (*p != ' ' && *p != '\t' && *p != '\0')
p++;
if (*p)
*p++ = 0;
}
/*
* XXX should avoid adding duplicates of first entry in
* order to keep from clobbering comment
*/
return (GENENT_CBERR);
/*
* only put comment in first entry
*/
};
return (GENENT_OK);
}
/*
* There is no notion of a canonical entry for netgroup, so
* we can't tell be looking at an entry if it has already
* been handled. So, we keep a table of all of the netgroups
* we have done so far.
*/
#define HASH_SIZE 64
struct hashent {
char *name;
};
int
hash(s)
char *s;
{
int retval = 0;
while (*s)
retval += *s++;
}
int
did_netgroup(s)
char *s;
{
int n;
n = hash(s);
return (1);
}
}
return (0);
}
void
char *s;
{
int n;
if (hp == 0) {
exit(1);
}
exit(1);
}
n = hash(s);
netgroup_table[n] = hp;
}
/*
* List all of the entries that match the name of the passed entry.
*/
{
nis_result *res = 0;
char srch[NIS_MAXNAMELEN];
}
return (res);
}
void
{
int i, j;
if (c1)
else {
}
if (c1a)
else {
}
if (!c5)
*c0a = 0;
}
}
}
*c0 = 0;
}
}
}
void
char *fstr;
{
if (NKEYVAL(1))
else
}
/*
* nis+ table: (timezone_tbl) name, tzone, comment
*
*/
int
char *line;
int (*cback)();
void *udata;
{
char *t;
char *cname;
/*
* don't clobber our argument
*/
return (GENENT_PARSEERR);
}
/*
* clear column data
*/
/*
* comment (col 2)
*/
if (t) {
*t++ = 0;
} else {
}
/*
* tzone (col 1)
*/
return (GENENT_PARSEERR);
}
/*
* name(col 0)
*/
return (GENENT_PARSEERR);
}
/*
* build entry
*/
if (!cback)
return (GENENT_CBERR);
return (GENENT_OK);
}
void
{
int i, j;
}
}
}
}
/*
* genent_attr:
* Generic function for generating entries for all of the *_attr databases.
*/
int
char *line;
int (*cback)();
void *udata;
char *database; /* name of the database */
int ncol; /* number of columns in the database */
char **cnames; /* array of column names */
int nkeycol; /* number of searchable columns that form the id */
int keycol[]; /* array containing indices of searchable columns */
{
int i, j;
char aname[NIS_MAXNAMELEN];
char *s;
char *sep = KV_TOKEN_DELIMIT;
char *lasts;
/*
* don't clobber our argument
*/
return (GENENT_PARSEERR);
}
/*
* setup and clear column data
*/
return (GENENT_ERR);
/* Split up columns */
i = 0;
while (i < ncol) {
if (s == NULL) {
} else {
}
i++;
}
/* build entry */
if (!cback)
/* specify entry by unique identifier */
for (i = 0; i < nkeycol; i++) {
j = keycol[i];
if (i)
}
return (GENENT_CBERR);
return (GENENT_OK);
}
void
int ncol;
{
int i, j;
char *c;
if (c = OBJ_COL_VAL(i, 0)) {
printf("%s", c);
for (j = 1; j < ncol; j++) {
c = OBJ_COL_VAL(i, j);
}
printf("\n");
}
}
}
int
char *line;
int (*cback)();
void *udata;
{
char *cnames[AUTHATTR_DB_NCOL] = {
};
}
void
{
}
int
char *line;
int (*cback)();
void *udata;
{
char *cnames[EXECATTR_DB_NCOL] = {
};
}
void
{
}
int
char *line;
int (*cback)();
void *udata;
{
char *cnames[PROFATTR_DB_NCOL] = {
};
}
void
{
}
int
char *line;
int (*cback)();
void *udata;
{
char *cnames[USERATTR_DB_NCOL] = {
};
}
void
{
}
int
char *line;
int (*cback)();
void *udata;
{
char *cnames[AUDITUSER_DB_NCOL] = {
};
}
void
{
}
struct ttypelist_t ttypelist[] = {
{ "key-value", 0, 0, 0,
0, 0, 0, " \t",
dump_keyvalue, 0,
{ "aliases", "mail.aliases", "mail_aliases.org_dir", "mail_aliases",
0, 0, 0, " \t",
dump_aliases, 0,
{ "bootparams", "bootparams", "bootparams.org_dir", "bootparams_tbl",
0, 0, 0, " \t",
dump_keyvalue, 0,
{ "ethers", "ethers.byaddr", "ethers.org_dir", "ethers_tbl",
0, 0, 0, " \t",
dump_ethers, 0,
{ "group", "group.byname", "group.org_dir", "group_tbl",
0, 0, 0, ":",
dump_group, 0,
{ "hosts", "hosts.byaddr", "hosts.org_dir", "hosts_tbl",
0, 2, 0, " \t",
{ "ipnodes", "ipnodes.byaddr", "ipnodes.org_dir", "ipnodes_tbl",
0, 2, 0, " \t",
{ "netgroup", "netgroup", "netgroup.org_dir", "netgroup_tbl",
0, 0, 0, " \t",
{ "netid", "netid.byname", "cred.org_dir", "cred_tbl",
"auth_type=LOCAL", 0, 0, " \t",
dump_netid, 0,
{ "netmasks", "netmasks.byaddr", "netmasks.org_dir", "netmasks_tbl",
0, 0, 0, " \t",
dump_netmasks, 0,
{ "networks", "networks.byname", "networks.org_dir", "networks_tbl",
0, 0, 0, " \t",
{ "passwd", "passwd.byname", "passwd.org_dir", "passwd_tbl",
0, 0, 0, ":",
dump_passwd, 0,
{ "protocols", "protocols.byname", "protocols.org_dir", "protocols_tbl",
0, 0, 0, " \t",
{"publickey", "publickey.byname", "cred.org_dir", "cred_tbl",
"auth_type=DES", 2, 0, " \t",
{ "rpc", "rpc.bynumber", "rpc.org_dir", "rpc_tbl",
0, 2, 1, " \t",
{ "services", "services.byname", "services.org_dir", "services_tbl",
0, -1, 1, " \t",
#ifndef FOURDOTX
{ "shadow", 0, "passwd.org_dir", "passwd_tbl",
0, 0, 0, ":",
dump_shadow, 0,
#endif
{ "timezone", "timezone.byname", "timezone.org_dir", "timezone_tbl",
0, 0, 1, " \t",
dump_timezone, 0,
{ "auth_attr", "auth_attr.byname", "auth_attr.org_dir", "auth_attr_tbl",
0, 0, 0, ":",
dump_auth_attr, 0,
{ "exec_attr", "exec_attr.byname", "exec_attr.org_dir", "exec_attr_tbl",
0, 0, 0, ":",
dump_exec_attr, 0,
{ "prof_attr", "prof_attr.byname", "prof_attr.org_dir", "prof_attr_tbl",
0, 0, 0, ":",
dump_prof_attr, 0,
{ "user_attr", "user_attr.byname", "user_attr.org_dir", "user_attr_tbl",
0, 0, 0, ":",
dump_user_attr, 0,
{ "audit_user", "audit_user.byname", "audit_user.org_dir",
"audit_user_tbl",
0, 0, 0, ":",
dump_audit_user, 0,
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
/*
* This routine dumps a table entry. If the dump_match routine
* is defined, then we call it to get all of the entries related
* to this one. For example, in the hosts table, we want all
* of the entries for a given address. If the dump_match routine
* returns 0, then the entry will be handled in conjuction with
* another entry and should be ignored now. If the dump_match
* routine is not defined, then we make a nis_result out of
* the entry and then dump it.
*/
int
void *udata;
{
char *line;
if (tt->dump_match) {
if (res) {
}
} else {
}
return (0);
}
/*
* In "quick" mode, we ask the server for all of the entries for
* the table and then call the dump routine to merge entries and
* print them. This only works for small tables or on machines
* with a LOT of swap space. In "normal" mode, we go through
* the entries one by one, calling the dumpcback routine for
* each one. The dumpcback routine will find all of the entries
* related to the current one, merge them, and then print the
* result.
*/
void
{
int i, j;
else {
else
}
} else {
exit(1);
}
}
}
int lineno = 0;
int
putfile()
{
char *p;
case GENENT_OK:
break;
case GENENT_PARSEERR:
exit_val = 2;
break;
default:
return (1);
}
}
return (0);
}
int
{
return (1);
return (0);
}
int
putdbm()
{
char *line;
continue;
case GENENT_OK:
break;
case GENENT_PARSEERR:
exit_val = 2;
break;
default:
return (1);
}
} else {
exit(1);
}
}
return (0);
}
/*
* __nis_form_keys: puts "," as key component separator, as required by
* nis_list etc.
* corrent search key for exec_attr.
*
*/
void
__nis_form_keys(char *keyname)
{
char *p, *s;
s = keyname;
while (s) {
if (p == NULL)
break;
*p = ',';
s = ++p;
}
}
int
int merge;
{
char **p;
"parse error: zero key length (line %d)\n", lineno);
continue;
}
/* if merging, add key/file_offset to dbm file */
if (merge) {
"problem storing %.*s %.*s\n",
return (1);
}
}
}
sizeof (keyname));
/*
* Make sure "," is the separator for multi-component key. E.g.,
* is the correct search key for exec_attr.
*
* __nis_quote_key puts quotes around ",". Is case of multi-
* component key, "," is a separator and should not be in
* quotes (requirement of nis_list etc. Hence __nis_form_keys
* is called after __nis_quote_key.
*/
(void) __nis_form_keys(keyname);
case NIS_BADATTRIBUTE:
lineno);
break;
case NIS_SUCCESS:
case GENENT_OK:
break;
case GENENT_PARSEERR:
exit_val = 2;
break;
default:
return (1);
}
break;
case NIS_NOTFOUND:
case GENENT_OK:
break;
case GENENT_PARSEERR:
exit_val = 2;
break;
default:
return (1);
}
break;
default:
exit(1);
}
}
return (0);
}
int
adddbm()
{
char *line;
continue;
sizeof (keyname));
ta_name);
case NIS_BADATTRIBUTE:
break;
case NIS_SUCCESS:
case GENENT_OK:
break;
case GENENT_PARSEERR:
"parse error: %s (key %.*s)\n",
exit_val = 2;
break;
default:
return (1);
}
break;
case NIS_NOTFOUND:
case GENENT_OK:
break;
case GENENT_PARSEERR:
"parse error: %s (key %.*s)\n",
exit_val = 2;
break;
default:
return (1);
}
break;
default:
exit(1);
}
} else {
exit(1);
}
}
return (0);
}
int
void *udata;
{
char *line;
int ret;
/*
* nis_list requires that the previous entry exists
* to return the next batch of entries. If we remove
* the last entry in a batch, we will not be able to
* get any more entries.
*
* To work around this, we will remember the last entry
* and only remove it after obtaining the next entry.
* deletecback must be called after nis_list completes
* to remove the last entry.
*/
case GENENT_CBERR:
return (0);
case GENENT_OK:
break;
case GENENT_PARSEERR:
"parse error (key %.*s)\n",
exit_val = 2;
return (1);
default:
return (1);
}
}
"Could not clone %s\n", NKEYVAL(0));
exit_val = 2;
return (0);
}
exit_val = 2;
return (0);
}
} else {
}
return (0);
}
return (ret);
}
/*
* The deletecback routine is too slow for large files, so we create
* a dbm file and then use mergedbm instead. An exit routine will
* clean up the temporary files when we exit.
*/
int
{
char lname[NIS_MAXNAMELEN];
char *dbmfile;
/* create dbm file from text file */
if (fp == 0) {
return (1);
}
created_dir = 1;
if (fp == 0) {
return (1);
}
created_pag = 1;
exit(1);
}
if (addfile(1))
return (1);
else
(void*)(fetchfile));
exit(1);
}
/* dbm files will be removed in cleanup, called at exit */
return (0);
}
int
mergedbm()
{
char lname[NIS_MAXNAMELEN];
"Merging of extended Diffie-Hellman keys from NIS(YP) are not supported!\n");
exit(1);
}
if (adddbm())
return (1);
exit(1);
}
return (0);
}
void
cleanup()
{
if (created_dir)
if (created_pag)
}
int
{
*etcfile = 0;
int c;
char rname[NIS_MAXNAMELEN];
char dbmfile[MAXPATHLEN];
/*
* We register an exit routine to clean up any temporary
* files.
*/
switch (c) {
case 'D':
break;
case 'P':
fpath = FOLLOW_PATH;
break;
case 'A':
break;
case 'M':
break;
case 'p':
break;
case 'v':
break;
case 'a':
if (op)
usage();
break;
case 'r':
if (op)
usage();
op = OP_REPLACE;
break;
case 'm':
if (op)
usage();
break;
case 'd':
if (op)
usage();
break;
case 'q':
break;
case 't':
break;
case 'f':
usage();
break;
case 'y':
if (etcfile)
usage();
break;
case 'Y':
if (etcfile)
usage();
break;
case 'o':
break;
default:
usage();
}
}
usage();
usage();
usage();
break;
ttype);
exit(1);
}
exit(1);
}
exit(1);
}
"nisdomain must be fully qualified.\n");
exit(1);
}
} else
usage();
if (!tname)
else
exit(1);
}
exit(1);
}
/*
* Check type of table
*/
exit(1);
}
} else {
/*
* key-value requires two column table
*/
!= 2) {
ta_name);
exit(1);
}
}
dumptable();
}
if (!nis_defaults_init(defstr))
exit(1);
if (ypdomain) {
exit(1);
}
} else if (etcfile) {
exit(1);
}
} else {
etcfile = "stdin";
}
switch (op) {
case OP_MERGE:
printf("merging %s into table %s\n",
break;
case OP_REPLACE:
case OP_ADD:
printf("adding %s to table %s\n",
break;
}
switch (op) {
case OP_REPLACE:
/*
* Handle special case of publickey and RPCSEC_GSS
* being configured on this system.
*/
int mcount = 0;
MECH_MAXATNAME)) {
if (verbose)
"clearing table (auth_type=%s) %s\n",
case NIS_NOTFOUND:
case NIS_SUCCESS:
break;
default:
"can't clear table");
exit(1);
}
}
mcount++;
}
} else {
printf("clearing table (%s) %s\n",
else
}
case NIS_NOTFOUND:
case NIS_SUCCESS:
break;
default:
exit(1);
}
}
if (ypdomain)
putdbm();
else
putfile();
break;
case OP_ADD:
if (ypdomain)
adddbm();
else
addfile(0);
break;
case OP_MERGE:
if (ypdomain)
mergedbm();
else
mergefile();
break;
}
}
return (exit_val);
}