From 4bf0acc9bcbbd91fb107bcca34f1d2041801fa6c Mon Sep 17 00:00:00 2001 From: brooks Date: Fri, 11 Jan 2013 20:53:28 +0000 Subject: Implement the -N 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 --- usr.bin/xinstall/Makefile | 8 ++++++ usr.bin/xinstall/install.1 | 17 ++++++++++++ usr.bin/xinstall/xinstall.c | 66 ++++++++++++++++++++++++--------------------- 3 files changed, 61 insertions(+), 30 deletions(-) (limited to 'usr.bin/xinstall') diff --git a/usr.bin/xinstall/Makefile b/usr.bin/xinstall/Makefile index e6ff88e..2a2aace 100644 --- a/usr.bin/xinstall/Makefile +++ b/usr.bin/xinstall/Makefile @@ -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 diff --git a/usr.bin/xinstall/install.1 b/usr.bin/xinstall/install.1 index 1c7c415..01b58dc 100644 --- a/usr.bin/xinstall/install.1 +++ b/usr.bin/xinstall/install.1 @@ -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 diff --git a/usr.bin/xinstall/xinstall.c b/usr.bin/xinstall/xinstall.c index 583348a..74f9d20 100644 --- a/usr.bin/xinstall/xinstall.c +++ b/usr.bin/xinstall/xinstall.c @@ -62,6 +62,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include "mtree.h" + /* Bootstrap aid - this doesn't exist in most older releases */ #ifndef MAP_FAILED #define MAP_FAILED ((void *)-1) /* from */ @@ -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 */ } -- cgit v1.1