Implement the -N <dbdir> option which allows an alternate passwd and

group file to be used.  This is useful for installing on systems where
a user or group does not currently exist.

Sponsored by:	DARPA, AFRL
Obtained from:	NetBSD
MFC after:	5 days
This commit is contained in:
Brooks Davis 2013-01-11 20:53:28 +00:00
parent 79626055e3
commit a6a1856ea3
3 changed files with 61 additions and 30 deletions

View File

@ -3,6 +3,14 @@
PROG= xinstall
PROGNAME= install
SRCS= xinstall.c getid.c
MAN= install.1
.PATH: ${.CURDIR}/../../contrib/mtree
CFLAGS+= -I${.CURDIR}/../../contrib/mtree
CFLAGS+= -I${.CURDIR}/../../lib/libnetbsd
DPADD+= ${LIBUTIL}
LDADD+= -lutil
.include <bsd.prog.mk>

View File

@ -41,6 +41,7 @@
.Op Fl f Ar flags
.Op Fl g Ar group
.Op Fl m Ar mode
.Op Fl N Ar dbdir
.Op Fl o Ar owner
.Ar file1 file2
.Nm
@ -49,6 +50,7 @@
.Op Fl f Ar flags
.Op Fl g Ar group
.Op Fl m Ar mode
.Op Fl N Ar dbdir
.Op Fl o Ar owner
.Ar file1 ... fileN directory
.Nm
@ -56,6 +58,7 @@
.Op Fl v
.Op Fl g Ar group
.Op Fl m Ar mode
.Op Fl N Ar dbdir
.Op Fl o Ar owner
.Ar directory ...
.Sh DESCRIPTION
@ -124,6 +127,18 @@ The default mode is set to rwxr-xr-x (0755).
The specified mode may be either an octal or symbolic value; see
.Xr chmod 1
for a description of possible mode values.
.It Fl N
Use the user database text file
.Pa master.passwd
and group database text file
.Pa group
from
.Ar dbdir ,
rather than using the results from the system's
.Xr getpwnam 3
and
.Xr getgrnam 3
(and related) library calls.
.It Fl o
Specify an owner.
A numeric UID is allowed.
@ -231,6 +246,8 @@ The default was changed to copy in
.Xr mv 1 ,
.Xr strip 1 ,
.Xr mmap 2 ,
.Xr getgrnam 3 ,
.Xr getpwnam 3 ,
.Xr chown 8
.Sh HISTORY
The

View File

@ -62,6 +62,8 @@ __FBSDID("$FreeBSD$");
#include <sysexits.h>
#include <unistd.h>
#include "mtree.h"
/* Bootstrap aid - this doesn't exist in most older releases */
#ifndef MAP_FAILED
#define MAP_FAILED ((void *)-1) /* from <sys/mman.h> */
@ -74,8 +76,6 @@ __FBSDID("$FreeBSD$");
#define NOCHANGEBITS (UF_IMMUTABLE | UF_APPEND | SF_IMMUTABLE | SF_APPEND)
#define BACKUP_SUFFIX ".old"
static struct passwd *pp;
static struct group *gp;
static gid_t gid;
static uid_t uid;
static int dobackup, docompare, dodir, dopreserve, dostrip, nommap, safecopy,
@ -89,7 +89,7 @@ static int create_newfile(const char *, int, struct stat *);
static int create_tempfile(const char *, char *, size_t);
static void install(const char *, const char *, u_long, u_int);
static void install_dir(char *);
static u_long numeric_id(const char *, const char *);
static int parseid(const char *, id_t *);
static void strip(const char *);
static int trymmap(int);
static void usage(void);
@ -107,7 +107,7 @@ main(int argc, char *argv[])
iflags = 0;
group = owner = NULL;
while ((ch = getopt(argc, argv, "B:bCcdf:g:Mm:o:pSsv")) != -1)
while ((ch = getopt(argc, argv, "B:bCcdf:g:Mm:N:o:pSsv")) != -1)
switch((char)ch) {
case 'B':
suffix = optarg;
@ -143,6 +143,11 @@ main(int argc, char *argv[])
mode = getmode(set, 0);
free(set);
break;
case 'N':
if (!setup_getid(optarg))
err(1, "Unable to use user and group "
"databases in `%s'", optarg);
break;
case 'o':
owner = optarg;
break;
@ -186,18 +191,22 @@ main(int argc, char *argv[])
/* get group and owner id's */
if (group != NULL) {
if ((gp = getgrnam(group)) != NULL)
gid = gp->gr_gid;
else
gid = (gid_t)numeric_id(group, "group");
if (gid_from_group(group, &gid) == -1) {
id_t id;
if (!parseid(group, &id))
errx(1, "unknown group %s", group);
gid = id;
}
} else
gid = (gid_t)-1;
if (owner != NULL) {
if ((pp = getpwnam(owner)) != NULL)
uid = pp->pw_uid;
else
uid = (uid_t)numeric_id(owner, "user");
if (uid_from_user(owner, &uid) == -1) {
id_t id;
if (!parseid(owner, &id))
errx(1, "unknown user %s", owner);
uid = id;
}
} else
uid = (uid_t)-1;
@ -244,23 +253,19 @@ main(int argc, char *argv[])
/* NOTREACHED */
}
static u_long
numeric_id(const char *name, const char *type)
/*
* parseid --
* parse uid or gid from arg into id, returning non-zero if successful
*/
static int
parseid(const char *name, id_t *id)
{
u_long val;
char *ep;
/*
* XXX
* We know that uid_t's and gid_t's are unsigned longs.
*/
char *ep;
errno = 0;
val = strtoul(name, &ep, 10);
if (errno)
err(EX_NOUSER, "%s", name);
if (*ep != '\0')
errx(EX_NOUSER, "unknown %s %s", type, name);
return (val);
*id = (id_t)strtoul(name, &ep, 10);
if (errno || *ep != '\0')
return (0);
return (1);
}
/*
@ -786,10 +791,11 @@ usage(void)
{
(void)fprintf(stderr,
"usage: install [-bCcMpSsv] [-B suffix] [-f flags] [-g group] [-m mode]\n"
" [-o owner] file1 file2\n"
" [-N dbdir] [-o owner] file1 file2\n"
" install [-bCcMpSsv] [-B suffix] [-f flags] [-g group] [-m mode]\n"
" [-o owner] file1 ... fileN directory\n"
" install -d [-v] [-g group] [-m mode] [-o owner] directory ...\n");
" [-N dbdir] [-o owner] file1 ... fileN directory\n"
" install -d [-v] [-g group] [-m mode] [-N dbdir] [-o owner]\n"
" directory ...\n");
exit(EX_USAGE);
/* NOTREACHED */
}