summaryrefslogtreecommitdiffstats
path: root/usr.sbin/pw
diff options
context:
space:
mode:
authordavidn <davidn@FreeBSD.org>1999-02-23 07:15:11 +0000
committerdavidn <davidn@FreeBSD.org>1999-02-23 07:15:11 +0000
commitaea1f6bc3cb4963dbd48dcd9f051919520f70f2b (patch)
treeb3bd7501edb165799eda61bf2ac5d8202c789a5d /usr.sbin/pw
parentf6416f79a6b9a2eb5c485e8af421d3d570a95d25 (diff)
downloadFreeBSD-src-aea1f6bc3cb4963dbd48dcd9f051919520f70f2b.zip
FreeBSD-src-aea1f6bc3cb4963dbd48dcd9f051919520f70f2b.tar.gz
1) Do not blindly ignore file update errors which may occur due to concurrent
updating 2) Add -V <etcdir>, which allows maintaining user/group database in alternate locations other than /etc.
Diffstat (limited to 'usr.sbin/pw')
-rw-r--r--usr.sbin/pw/Makefile6
-rw-r--r--usr.sbin/pw/edgroup.c18
-rw-r--r--usr.sbin/pw/fileupd.c15
-rw-r--r--usr.sbin/pw/grupd.c47
-rw-r--r--usr.sbin/pw/pw.829
-rw-r--r--usr.sbin/pw/pw.c112
-rw-r--r--usr.sbin/pw/pw.h4
-rw-r--r--usr.sbin/pw/pw_conf.c5
-rw-r--r--usr.sbin/pw/pw_group.c25
-rw-r--r--usr.sbin/pw/pw_nis.c3
-rw-r--r--usr.sbin/pw/pw_user.c172
-rw-r--r--usr.sbin/pw/pw_vpw.c316
-rw-r--r--usr.sbin/pw/pwupd.c45
-rw-r--r--usr.sbin/pw/pwupd.h83
14 files changed, 725 insertions, 155 deletions
diff --git a/usr.sbin/pw/Makefile b/usr.sbin/pw/Makefile
index 3425e9c..7b630dd 100644
--- a/usr.sbin/pw/Makefile
+++ b/usr.sbin/pw/Makefile
@@ -1,7 +1,7 @@
-# $Id: Makefile,v 1.5 1997/02/22 16:12:17 peter Exp $
+# $Id: Makefile,v 1.6 1998/09/19 22:42:12 obrien Exp $
PROG= pw
-SRCS= pw.c pw_conf.c pw_user.c pw_group.c pw_log.c pw_nis.c \
+SRCS= pw.c pw_conf.c pw_user.c pw_group.c pw_log.c pw_nis.c pw_vpw.c \
grupd.c pwupd.c fileupd.c edgroup.c psdate.c \
bitmap.c cpdir.c rm_r.c
@@ -9,7 +9,7 @@ MAN5= pw.conf.5
MAN8= pw.8
#RND= -DUSE_MD5RAND
-CFLAGS+= -Wall $(CDB) $(RND)
+CFLAGS+= -W -Wall $(CDB) $(RND)
LDADD= -lcrypt
DPADD= ${LIBCRYPT}
diff --git a/usr.sbin/pw/edgroup.c b/usr.sbin/pw/edgroup.c
index 6116fa6..649a398 100644
--- a/usr.sbin/pw/edgroup.c
+++ b/usr.sbin/pw/edgroup.c
@@ -26,7 +26,7 @@
#ifndef lint
static const char rcsid[] =
- "$Id: edgroup.c,v 1.5 1997/10/10 06:23:30 charnier Exp $";
+ "$Id: edgroup.c,v 1.6 1998/07/16 17:18:22 nate Exp $";
#endif /* not lint */
#include <stdio.h>
@@ -55,14 +55,18 @@ isingroup(char const * name, char **mem)
return -1;
}
-static char groupfile[] = _PATH_GROUP;
-static char grouptmp[] = _PATH_GROUP ".new";
-
int
editgroups(char *name, char **groups)
{
int rc = 0;
int infd;
+ char groupfile[MAXPATHLEN];
+ char grouptmp[MAXPATHLEN];
+
+ strncpy(groupfile, getgrpath(_GROUP), MAXPATHLEN - 5);
+ groupfile[MAXPATHLEN - 5] = '\0';
+ strcpy(grouptmp, groupfile);
+ strcat(grouptmp, ".new");
if ((infd = open(groupfile, O_RDWR | O_CREAT, 0644)) != -1) {
FILE *infp;
@@ -172,9 +176,9 @@ editgroups(char *name, char **groups)
*/
struct passwd *pwd;
- setpwent();
- while ((pwd = getpwent()) != NULL && pwd->pw_gid != grp.gr_gid);
- endpwent();
+ SETPWENT();
+ while ((pwd = GETPWENT()) != NULL && (gid_t)pwd->pw_gid != (gid_t)grp.gr_gid);
+ ENDPWENT();
if (pwd == NULL) /* No members at all */
continue; /* Drop the group */
}
diff --git a/usr.sbin/pw/fileupd.c b/usr.sbin/pw/fileupd.c
index fe46480..d76259b 100644
--- a/usr.sbin/pw/fileupd.c
+++ b/usr.sbin/pw/fileupd.c
@@ -26,7 +26,7 @@
#ifndef lint
static const char rcsid[] =
- "$Id: fileupd.c,v 1.5 1997/10/10 06:23:31 charnier Exp $";
+ "$Id: fileupd.c,v 1.6 1998/07/16 17:18:24 nate Exp $";
#endif /* not lint */
#include <stdio.h>
@@ -175,16 +175,11 @@ fileupdate(char const * filename, mode_t fmode, char const * newline, char const
* corrupted the original file
* Unfortunately, it will lose the inode
* and hence the lock.
- *
- * The implications of this is that this invocation of pw
- * won't have the file locked and concurrent copies
- * of pw, vipw etc could clobber what this one is doing.
- *
- * It should probably just return an error instead
- * of going on like nothing is wrong.
*/
- if (fflush(infp) == EOF || ferror(infp))
- rc = rename(file, filename) == 0;
+ if (fflush(infp) == EOF || ferror(infp)) {
+ rc = errno; /* Preserve errno for return */
+ rename(file, filename);
+ }
else
ftruncate(infd, ftell(infp));
}
diff --git a/usr.sbin/pw/grupd.c b/usr.sbin/pw/grupd.c
index feff430..e36c192 100644
--- a/usr.sbin/pw/grupd.c
+++ b/usr.sbin/pw/grupd.c
@@ -26,7 +26,7 @@
#ifndef lint
static const char rcsid[] =
- "$Id$";
+ "$Id: grupd.c,v 1.5 1997/10/10 06:23:32 charnier Exp $";
#endif /* not lint */
#include <stdio.h>
@@ -36,9 +36,46 @@ static const char rcsid[] =
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/param.h>
#include "pwupd.h"
+static char * grpath = _PATH_PWD;
+
+int
+setgrdir(const char * dir)
+{
+ if (dir == NULL)
+ return -1;
+ else {
+ char * d = malloc(strlen(dir)+1);
+ if (d == NULL)
+ return -1;
+ grpath = strcpy(d, dir);
+ }
+ return 0;
+}
+
+char *
+getgrpath(const char * file)
+{
+ static char pathbuf[MAXPATHLEN];
+
+ snprintf(pathbuf, sizeof pathbuf, "%s/%s", grpath, file);
+ return pathbuf;
+}
+
+int
+grdb(char *arg,...)
+{
+ /*
+ * This is a stub for now, but maybe eventually be functional
+ * if ever an indexed version of /etc/groups is implemented.
+ */
+ arg=arg;
+ return 0;
+}
+
int
fmtgrentry(char **buf, int * buflen, struct group * grp, int type)
{
@@ -96,7 +133,7 @@ gr_update(struct group * grp, char const * group, int mode)
int grbuflen = 0;
char *grbuf = NULL;
- endgrent();
+ ENDGRENT();
l = snprintf(pfx, sizeof pfx, "%s:", group);
/*
@@ -104,8 +141,10 @@ gr_update(struct group * grp, char const * group, int mode)
*/
if (grp != NULL && fmtgrentry(&grbuf, &grbuflen, grp, PWF_PASSWD) == -1)
l = -1;
- else
- l = fileupdate(_PATH_GROUP, 0644, grbuf, pfx, l, mode);
+ else {
+ if ((l = fileupdate(getgrpath(_GROUP), 0644, grbuf, pfx, l, mode)) != 0)
+ l = grdb(NULL) == 0;
+ }
if (grbuf != NULL)
free(grbuf);
return l;
diff --git a/usr.sbin/pw/pw.8 b/usr.sbin/pw/pw.8
index 3a1a7a8..5de8237 100644
--- a/usr.sbin/pw/pw.8
+++ b/usr.sbin/pw/pw.8
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $Id: pw.8,v 1.14 1998/08/31 04:49:04 jkoshy Exp $
+.\" $Id: pw.8,v 1.15 1998/09/18 04:45:43 jkoshy Exp $
.\"
.Dd December 9, 1996
.Dt PW 8
@@ -32,6 +32,7 @@
.Nd create, remove, modify & display system users and groups
.Sh SYNOPSIS
.Nm pw
+.Op Fl V Ar etcdir
.Ar useradd
.Op name|uid
.Op Fl C Ar config
@@ -54,6 +55,7 @@
.Op Fl P
.Op Fl Y
.Nm pw
+.Op Fl V Ar etcdir
.Ar useradd
.Op name|uid
.Fl D
@@ -71,6 +73,7 @@
.Op Fl s Ar shell
.Op Fl y Ar path
.Nm pw
+.Op Fl V Ar etcdir
.Ar userdel
.Op name|uid
.Op Fl n Ar name
@@ -78,6 +81,7 @@
.Op Fl r
.Op Fl Y
.Nm pw
+.Op Fl V Ar etcdir
.Ar usermod
.Op name|uid
.Op Fl C Ar config
@@ -101,6 +105,7 @@
.Op Fl P
.Op Fl Y
.Nm pw
+.Op Fl V Ar etcdir
.Ar usershow
.Op name|uid
.Op Fl n Ar name
@@ -109,10 +114,12 @@
.Op Fl P
.Op Fl a
.Nm pw
+.Op Fl V Ar etcdir
.Ar usernext
.Op Fl C Ar config
.Op Fl q
.Nm pw
+.Op Fl V Ar etcdir
.Ar groupadd
.Op group|gid
.Op Fl C Ar config
@@ -126,12 +133,14 @@
.Op Fl P
.Op Fl Y
.Nm pw
+.Op Fl V Ar etcdir
.Ar groupdel
.Op group|gid
.Op Fl n Ar name
.Op Fl g Ar gid
.Op Fl Y
.Nm pw
+.Op Fl V Ar etcdir
.Ar groupmod
.Op group|gid
.Op Fl C Ar config
@@ -147,6 +156,7 @@
.Op Fl P
.Op Fl Y
.Nm pw
+.Op Fl V Ar etcdir
.Ar groupshow
.Op group|gid
.Op Fl n Ar name
@@ -155,6 +165,7 @@
.Op Fl P
.Op Fl a
.Nm pw
+.Op Fl V Ar etcdir
.Ar groupnext
.Op Fl C Ar config
.Op Fl q
@@ -208,9 +219,23 @@ id as an alternative to using the
.Fl g Ar gid
options.
.Pp
-The following flags are common to most modes of operation;
+The following flags are common to most or all modes of operation;
.Pp
.Bl -tag -width "-G grouplist"
+.It Fl V Ar etcdir
+This flag sets an alternate location for the password, group and configuration files,
+and may be used to maintain a user/group database in an alternate location.
+If this switch is specified, the system
+.Pa /etc/pw.conf
+will not be sourced for default configuration data, but the file pw.conf in the
+specified directory will be used instead (or none, if it does not exist).
+The
+.Fl C
+flag may be used to override this behaviour.
+As an exception to the general rule where options must follow the operation
+type, the
+.Fl V
+flag may be used on the command line before the operation keyword.
.It Fl C Ar config
By default,
.Nm
diff --git a/usr.sbin/pw/pw.c b/usr.sbin/pw/pw.c
index f862cbe..32246f9 100644
--- a/usr.sbin/pw/pw.c
+++ b/usr.sbin/pw/pw.c
@@ -26,14 +26,14 @@
#ifndef lint
static const char rcsid[] =
- "$Id: pw.c,v 1.10 1998/08/04 22:31:26 nate Exp $";
+ "$Id: pw.c,v 1.11 1999/01/08 10:52:38 davidn Exp $";
#endif /* not lint */
-#include "pw.h"
#include <err.h>
#include <fcntl.h>
#include <paths.h>
#include <sys/wait.h>
+#include "pw.h"
const char *Modes[] = {"add", "del", "mod", "show", "next", NULL};
const char *Which[] = {"user", "group", NULL};
@@ -46,6 +46,40 @@ static const char *Combo2[] = {
"addgroup", "delgroup", "modgroup", "showgroup", "nextgroup",
NULL};
+struct pwf PWF =
+{
+ 0,
+ setpwent,
+ endpwent,
+ getpwent,
+ getpwuid,
+ getpwnam,
+ pwdb,
+ setgrent,
+ endgrent,
+ getgrent,
+ getgrgid,
+ getgrnam,
+ grdb
+
+};
+struct pwf VPWF =
+{
+ 1,
+ vsetpwent,
+ vendpwent,
+ vgetpwent,
+ vgetpwuid,
+ vgetpwnam,
+ vpwdb,
+ vsetgrent,
+ vendgrent,
+ vgetgrent,
+ vgetgrgid,
+ vgetgrnam,
+ vgrdb
+};
+
static struct cargs arglist;
static int getindex(const char *words[], const char *word);
@@ -58,23 +92,24 @@ main(int argc, char *argv[])
int ch;
int mode = -1;
int which = -1;
+ char *config = NULL;
struct userconf *cnf;
static const char *opts[W_NUM][M_NUM] =
{
{ /* user */
- "C:qn:u:c:d:e:p:g:G:mk:s:oL:i:w:h:Db:NPy:Y",
- "C:qn:u:rY",
- "C:qn:u:c:d:e:p:g:G:ml:k:s:w:L:h:FNPY",
- "C:qn:u:FPa",
- "C:q"
+ "VC:qn:u:c:d:e:p:g:G:mk:s:oL:i:w:h:Db:NPy:Y",
+ "VC:qn:u:rY",
+ "VC:qn:u:c:d:e:p:g:G:ml:k:s:w:L:h:FNPY",
+ "VC:qn:u:FPa",
+ "VC:q"
},
{ /* grp */
- "C:qn:g:h:M:pNPY",
- "C:qn:g:Y",
- "C:qn:g:l:h:FM:m:NPY",
- "C:qn:g:FPa",
- "C:q"
+ "VC:qn:g:h:M:pNPY",
+ "VC:qn:g:Y",
+ "VC:qn:g:l:h:FM:m:NPY",
+ "VC:qn:g:FPa",
+ "VC:q"
}
};
@@ -91,10 +126,25 @@ main(int argc, char *argv[])
* Break off the first couple of words to determine what exactly
* we're being asked to do
*/
- while (argc > 1 && *argv[1] != '-') {
+ while (argc > 1) {
int tmp;
- if ((tmp = getindex(Modes, argv[1])) != -1)
+ if (*argv[1] == '-') {
+ /*
+ * Special case, allow pw -V<dir> <operation> [args] for scripts etc.
+ */
+ if (argv[1][1] == 'V') {
+ optarg = &argv[1][2];
+ if (*optarg == '\0') {
+ optarg = argv[2];
+ ++argv;
+ --argc;
+ }
+ addarg(&arglist, 'V', optarg);
+ }
+ break;
+ }
+ else if ((tmp = getindex(Modes, argv[1])) != -1)
mode = tmp;
else if ((tmp = getindex(Which, argv[1])) != -1)
which = tmp;
@@ -145,9 +195,28 @@ main(int argc, char *argv[])
freopen("/dev/null", "w", stderr);
/*
+ * Set our base working path if not overridden
+ */
+
+ config = getarg(&arglist, 'C') ? getarg(&arglist, 'C')->val : NULL;
+
+ if (getarg(&arglist, 'V') != NULL) {
+ char * etcpath = getarg(&arglist, 'V')->val;
+ if (*etcpath) {
+ if (config == NULL) { /* Only override config location if -C not specified */
+ config = malloc(MAXPATHLEN);
+ snprintf(config, MAXPATHLEN, "%s/pw.conf", etcpath);
+ }
+ memcpy(&PWF, &VPWF, sizeof PWF);
+ setpwdir(etcpath);
+ setgrdir(etcpath);
+ }
+ }
+
+ /*
* Now, let's do the common initialisation
*/
- cnf = read_userconfig(getarg(&arglist, 'C') ? getarg(&arglist, 'C')->val : NULL);
+ cnf = read_userconfig(config);
ch = funcs[which] (cnf, mode, &arglist);
@@ -215,6 +284,7 @@ cmdhelp(int mode, int which)
{
{
"usage: pw useradd [name] [switches]\n"
+ "\t-V etcdir alternate /etc location\n"
"\t-C config configuration file\n"
"\t-q quiet operation\n"
" Adding users:\n"
@@ -234,7 +304,8 @@ cmdhelp(int mode, int which)
"\t-Y update NIS maps\n"
"\t-N no update\n"
" Setting defaults:\n"
- "\t-D set user defaults\n"
+ "\t-V etcdir alternate /etc location\n"
+ "\t-D set user defaults\n"
"\t-b dir default home root dir\n"
"\t-e period default expiry period\n"
"\t-p period default password change period\n"
@@ -248,11 +319,13 @@ cmdhelp(int mode, int which)
"\t-s shell default shell\n"
"\t-y path set NIS passwd file path\n",
"usage: pw userdel [uid|name] [switches]\n"
+ "\t-V etcdir alternate /etc location\n"
"\t-n name login name\n"
"\t-u uid user id\n"
"\t-Y update NIS maps\n"
"\t-r remove home & contents\n",
"usage: pw usermod [uid|name] [switches]\n"
+ "\t-V etcdir alternate /etc location\n"
"\t-C config configuration file\n"
"\t-q quiet operation\n"
"\t-F force add if no user\n"
@@ -273,16 +346,19 @@ cmdhelp(int mode, int which)
"\t-Y update NIS maps\n"
"\t-N no update\n",
"usage: pw usershow [uid|name] [switches]\n"
+ "\t-V etcdir alternate /etc location\n"
"\t-n name login name\n"
"\t-u uid user id\n"
"\t-F force print\n"
"\t-P prettier format\n"
"\t-a print all users\n",
"usage: pw usernext [switches]\n"
+ "\t-V etcdir alternate /etc location\n"
"\t-C config configuration file\n"
},
{
"usage: pw groupadd [group|gid] [switches]\n"
+ "\t-V etcdir alternate /etc location\n"
"\t-C config configuration file\n"
"\t-q quiet operation\n"
"\t-n group group name\n"
@@ -292,10 +368,12 @@ cmdhelp(int mode, int which)
"\t-Y update NIS maps\n"
"\t-N no update\n",
"usage: pw groupdel [group|gid] [switches]\n"
+ "\t-V etcdir alternate /etc location\n"
"\t-n name group name\n"
"\t-g gid group id\n"
"\t-Y update NIS maps\n",
"usage: pw groupmod [group|gid] [switches]\n"
+ "\t-V etcdir alternate /etc location\n"
"\t-C config configuration file\n"
"\t-q quiet operation\n"
"\t-F force add if not exists\n"
@@ -307,12 +385,14 @@ cmdhelp(int mode, int which)
"\t-Y update NIS maps\n"
"\t-N no update\n",
"usage: pw groupshow [group|gid] [switches]\n"
+ "\t-V etcdir alternate /etc location\n"
"\t-n name group name\n"
"\t-g gid group id\n"
"\t-F force print\n"
"\t-P prettier format\n"
"\t-a print all accounting groups\n",
"usage: pw groupnext [switches]\n"
+ "\t-V etcdir alternate /etc location\n"
"\t-C config configuration file\n"
}
};
diff --git a/usr.sbin/pw/pw.h b/usr.sbin/pw/pw.h
index b52891a..16bea61 100644
--- a/usr.sbin/pw/pw.h
+++ b/usr.sbin/pw/pw.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: pw.h,v 1.6 1997/02/22 16:12:27 peter Exp $
+ * $Id: pw.h,v 1.7 1997/10/10 06:23:35 charnier Exp $
*/
#include <stdio.h>
@@ -34,12 +34,14 @@
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/param.h>
#include <pwd.h>
#include <grp.h>
#include <sys/queue.h>
#include <sysexits.h>
#include "psdate.h"
+#include "pwupd.h"
enum _mode
{
diff --git a/usr.sbin/pw/pw_conf.c b/usr.sbin/pw/pw_conf.c
index 63742a7..dc1bd61 100644
--- a/usr.sbin/pw/pw_conf.c
+++ b/usr.sbin/pw/pw_conf.c
@@ -26,7 +26,7 @@
#ifndef lint
static const char rcsid[] =
- "$Id$";
+ "$Id: pw_conf.c,v 1.7 1997/10/10 06:23:36 charnier Exp $";
#endif /* not lint */
#include <string.h>
@@ -34,7 +34,6 @@ static const char rcsid[] =
#include <fcntl.h>
#include "pw.h"
-#include "pwupd.h"
#define debugging 0
@@ -310,7 +309,7 @@ read_userconfig(char const * file)
break;
case _UC_DEFAULTGROUP:
q = unquote(q);
- config.default_group = (q == NULL || !boolean_val(q, 1) || getgrnam(q) == NULL)
+ config.default_group = (q == NULL || !boolean_val(q, 1) || GETGRNAM(q) == NULL)
? NULL : newstr(q);
break;
case _UC_EXTRAGROUPS:
diff --git a/usr.sbin/pw/pw_group.c b/usr.sbin/pw/pw_group.c
index ce1b230..220a9b1 100644
--- a/usr.sbin/pw/pw_group.c
+++ b/usr.sbin/pw/pw_group.c
@@ -26,7 +26,7 @@
#ifndef lint
static const char rcsid[] =
- "$Id$";
+ "$Id: pw_group.c,v 1.7 1997/10/10 06:23:36 charnier Exp $";
#endif /* not lint */
#include <ctype.h>
@@ -36,7 +36,6 @@ static const char rcsid[] =
#include "pw.h"
#include "bitmap.h"
-#include "pwupd.h"
static int print_group(struct group * grp, int pretty);
@@ -76,10 +75,10 @@ pw_group(struct userconf * cnf, int mode, struct cargs * args)
if (mode == M_PRINT && getarg(args, 'a')) {
int pretty = getarg(args, 'P') != NULL;
- setgrent();
- while ((grp = getgrent()) != NULL)
+ SETGRENT();
+ while ((grp = GETGRENT()) != NULL)
print_group(grp, pretty);
- endgrent();
+ ENDGRENT();
return EXIT_SUCCESS;
}
if (a_gid == NULL) {
@@ -91,11 +90,11 @@ pw_group(struct userconf * cnf, int mode, struct cargs * args)
a_name = NULL;
}
}
- grp = (a_name != NULL) ? getgrnam(a_name->val) : getgrgid((gid_t) atoi(a_gid->val));
+ grp = (a_name != NULL) ? GETGRNAM(a_name->val) : GETGRGID((gid_t) atoi(a_gid->val));
if (mode == M_UPDATE || mode == M_DELETE || mode == M_PRINT) {
if (a_name == NULL && grp == NULL) /* Try harder */
- grp = getgrgid(atoi(a_gid->val));
+ grp = GETGRGID(atoi(a_gid->val));
if (grp == NULL) {
if (mode == M_PRINT && getarg(args, 'F')) {
@@ -212,7 +211,7 @@ pw_group(struct userconf * cnf, int mode, struct cargs * args)
}
for (p = strtok(arg->val, ", \t"); p != NULL; p = strtok(NULL, ", \t")) {
int j;
- if ((pwd = getpwnam(p)) == NULL) {
+ if ((pwd = GETPWNAM(p)) == NULL) {
if (!isdigit(*p) || (pwd = getpwuid((uid_t) atoi(p))) == NULL)
errx(EX_NOUSER, "user `%s' does not exist", p);
}
@@ -237,7 +236,7 @@ pw_group(struct userconf * cnf, int mode, struct cargs * args)
return EX_IOERR;
}
/* grp may have been invalidated */
- if ((grp = getgrnam(a_name->val)) == NULL)
+ if ((grp = GETGRNAM(a_name->val)) == NULL)
errx(EX_SOFTWARE, "group disappeared during update");
pw_log(cnf, mode, W_GROUP, "%s(%ld)", grp->gr_name, (long) grp->gr_gid);
@@ -262,7 +261,7 @@ gr_gidpolicy(struct userconf * cnf, struct cargs * args)
if (a_gid != NULL) {
gid = (gid_t) atol(a_gid->val);
- if ((grp = getgrgid(gid)) != NULL && getarg(args, 'o') == NULL)
+ if ((grp = GETGRGID(gid)) != NULL && getarg(args, 'o') == NULL)
errx(EX_DATAERR, "gid `%ld' has already been allocated", (long) grp->gr_gid);
} else {
struct bitmap bm;
@@ -281,11 +280,11 @@ gr_gidpolicy(struct userconf * cnf, struct cargs * args)
/*
* Now, let's fill the bitmap from the password file
*/
- setgrent();
- while ((grp = getgrent()) != NULL)
+ SETGRENT();
+ while ((grp = GETGRENT()) != NULL)
if (grp->gr_gid >= (int) cnf->min_gid && grp->gr_gid <= (int) cnf->max_gid)
bm_setbit(&bm, grp->gr_gid - cnf->min_gid);
- endgrent();
+ ENDGRENT();
/*
* Then apply the policy, with fallback to reuse if necessary
diff --git a/usr.sbin/pw/pw_nis.c b/usr.sbin/pw/pw_nis.c
index fe89685..3b041a8 100644
--- a/usr.sbin/pw/pw_nis.c
+++ b/usr.sbin/pw/pw_nis.c
@@ -26,7 +26,7 @@
#ifndef lint
static const char rcsid[] =
- "$Id$";
+ "$Id: pw_nis.c,v 1.4 1997/10/10 06:23:38 charnier Exp $";
#endif /* not lint */
#include <stdio.h>
@@ -34,7 +34,6 @@ static const char rcsid[] =
#include <string.h>
#include <sys/types.h>
-#include "pwupd.h"
#include "pw.h"
static int
diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c
index d339381..635b530 100644
--- a/usr.sbin/pw/pw_user.c
+++ b/usr.sbin/pw/pw_user.c
@@ -22,11 +22,12 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
+ *
*/
#ifndef lint
static const char rcsid[] =
- "$Id: pw_user.c,v 1.25 1999/01/04 14:07:53 billf Exp $";
+ "$Id: pw_user.c,v 1.26 1999/02/08 21:26:44 des Exp $";
#endif /* not lint */
#include <ctype.h>
@@ -46,7 +47,6 @@ static const char rcsid[] =
#endif
#include "pw.h"
#include "bitmap.h"
-#include "pwupd.h"
#if (MAXLOGNAME-1) > UT_NAMESIZE
#define LOGNAMESIZE UT_NAMESIZE
@@ -215,8 +215,8 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
if ((arg = getarg(args, 'g')) != NULL) {
p = arg->val;
- if ((grp = getgrnam(p)) == NULL) {
- if (!isdigit(*p) || (grp = getgrgid((gid_t) atoi(p))) == NULL)
+ if ((grp = GETGRNAM(p)) == NULL) {
+ if (!isdigit(*p) || (grp = GETGRGID((gid_t) atoi(p))) == NULL)
errx(EX_NOUSER, "group `%s' does not exist", p);
}
cnf->default_group = newstr(grp->gr_name);
@@ -228,8 +228,8 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
int i = 0;
for (p = strtok(arg->val, ", \t"); p != NULL; p = strtok(NULL, ", \t")) {
- if ((grp = getgrnam(p)) == NULL) {
- if (!isdigit(*p) || (grp = getgrgid((gid_t) atoi(p))) == NULL)
+ if ((grp = GETGRNAM(p)) == NULL) {
+ if (!isdigit(*p) || (grp = GETGRGID((gid_t) atoi(p))) == NULL)
errx(EX_NOUSER, "group `%s' does not exist", p);
}
if (extendarray(&cnf->groups, &cnf->numgroups, i + 2) != -1)
@@ -272,14 +272,14 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
if (mode == M_PRINT && getarg(args, 'a')) {
int pretty = getarg(args, 'P') != NULL;
- setpwent();
- while ((pwd = getpwent()) != NULL)
+ SETPWENT();
+ while ((pwd = GETPWENT()) != NULL)
print_user(pwd, pretty);
- endpwent();
+ ENDPWENT();
return EXIT_SUCCESS;
}
if ((a_name = getarg(args, 'n')) != NULL)
- pwd = getpwnam(pw_checkname((u_char *)a_name->val, 0));
+ pwd = GETPWNAM(pw_checkname((u_char *)a_name->val, 0));
a_uid = getarg(args, 'u');
if (a_uid == NULL) {
@@ -303,7 +303,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
*/
if (mode == M_UPDATE || mode == M_DELETE || mode == M_PRINT) {
if (a_name == NULL && pwd == NULL) /* Try harder */
- pwd = getpwuid(atoi(a_uid->val));
+ pwd = GETPWUID(atoi(a_uid->val));
if (pwd == NULL) {
if (mode == M_PRINT && getarg(args, 'F')) {
@@ -329,19 +329,21 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
if (strcmp(pwd->pw_name, "root") == 0)
errx(EX_DATAERR, "cannot remove user 'root'");
- /*
- * Remove skey record from /etc/skeykeys
- */
+ if (!PWALTDIR()) {
+ /*
+ * Remove skey record from /etc/skeykeys
+ */
- rmskey(pwd->pw_name);
+ rmskey(pwd->pw_name);
- /*
- * Remove crontabs
- */
- sprintf(file, "/var/cron/tabs/%s", pwd->pw_name);
- if (access(file, F_OK) == 0) {
- sprintf(file, "crontab -u %s -r", pwd->pw_name);
- system(file);
+ /*
+ * Remove crontabs
+ */
+ sprintf(file, "/var/cron/tabs/%s", pwd->pw_name);
+ if (access(file, F_OK) == 0) {
+ sprintf(file, "crontab -u %s -r", pwd->pw_name);
+ system(file);
+ }
}
/*
* Save these for later, since contents of pwd may be
@@ -361,26 +363,28 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
pw_log(cnf, mode, W_USER, "%s(%ld) account removed", a_name->val, (long) uid);
- /*
- * Remove mail file
- */
- remove(file);
-
- /*
- * Remove at jobs
- */
- if (getpwuid(uid) == NULL)
- rmat(uid);
-
- /*
- * Remove home directory and contents
- */
- if (getarg(args, 'r') != NULL && *home == '/' && getpwuid(uid) == NULL) {
- if (stat(home, &st) != -1) {
- rm_r(home, uid);
- pw_log(cnf, mode, W_USER, "%s(%ld) home '%s' %sremoved",
- a_name->val, (long) uid, home,
- stat(home, &st) == -1 ? "" : "not completely ");
+ if (!PWALTDIR()) {
+ /*
+ * Remove mail file
+ */
+ remove(file);
+
+ /*
+ * Remove at jobs
+ */
+ if (getpwuid(uid) == NULL)
+ rmat(uid);
+
+ /*
+ * Remove home directory and contents
+ */
+ if (getarg(args, 'r') != NULL && *home == '/' && getpwuid(uid) == NULL) {
+ if (stat(home, &st) != -1) {
+ rm_r(home, uid);
+ pw_log(cnf, mode, W_USER, "%s(%ld) home '%s' %sremoved",
+ a_name->val, (long) uid, home,
+ stat(home, &st) == -1 ? "" : "not completely ");
+ }
}
}
return EXIT_SUCCESS;
@@ -403,7 +407,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
warnx("WARNING: account `%s' will have a uid of 0 (superuser access!)", pwd->pw_name);
}
if ((arg = getarg(args, 'g')) != NULL && pwd->pw_uid != 0) /* Already checked this */
- pwd->pw_gid = (gid_t) getgrnam(cnf->default_group)->gr_gid;
+ pwd->pw_gid = (gid_t) GETGRNAM(cnf->default_group)->gr_gid;
if ((arg = getarg(args, 'p')) != NULL) {
if (*arg->val == '\0' || strcmp(arg->val, "0") == 0)
@@ -449,7 +453,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
} else {
if (a_name == NULL) /* Required */
errx(EX_DATAERR, "login name required");
- else if ((pwd = getpwnam(a_name->val)) != NULL) /* Exists */
+ else if ((pwd = GETPWNAM(a_name->val)) != NULL) /* Exists */
errx(EX_DATAERR, "login name `%s' already exists", a_name->val);
/*
@@ -550,10 +554,10 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
editgroups(pwd->pw_name, cnf->groups);
/* pwd may have been invalidated */
- if ((pwd = getpwnam(a_name->val)) == NULL)
+ if ((pwd = GETPWNAM(a_name->val)) == NULL)
errx(EX_NOUSER, "user '%s' disappeared during update", a_name->val);
- grp = getgrgid(pwd->pw_gid);
+ grp = GETGRGID(pwd->pw_gid);
pw_log(cnf, mode, W_USER, "%s(%ld):%s(%d):%s:%s:%s",
pwd->pw_name, (long) pwd->pw_uid,
grp ? grp->gr_name : "unknown", (long) (grp ? grp->gr_gid : -1),
@@ -567,30 +571,32 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
if (mode == M_ADD) {
FILE *fp;
- sprintf(line, "%s/%s", _PATH_MAILDIR, pwd->pw_name);
- close(open(line, O_RDWR | O_CREAT, 0600)); /* Preserve contents &
- * mtime */
- chown(line, pwd->pw_uid, pwd->pw_gid);
+ if (!PWALTDIR()) {
+ sprintf(line, "%s/%s", _PATH_MAILDIR, pwd->pw_name);
+ close(open(line, O_RDWR | O_CREAT, 0600)); /* Preserve contents &
+ * mtime */
+ chown(line, pwd->pw_uid, pwd->pw_gid);
- /*
- * Send mail to the new user as well, if we are asked to
- */
- if (cnf->newmail && *cnf->newmail && (fp = fopen(cnf->newmail, "r")) != NULL) {
- FILE *pfp = popen(_PATH_SENDMAIL " -t", "w");
+ /*
+ * Send mail to the new user as well, if we are asked to
+ */
+ if (cnf->newmail && *cnf->newmail && (fp = fopen(cnf->newmail, "r")) != NULL) {
+ FILE *pfp = popen(_PATH_SENDMAIL " -t", "w");
- if (pfp == NULL)
- warn("sendmail");
- else {
- fprintf(pfp, "From: root\n" "To: %s\n" "Subject: Welcome!\n\n", pwd->pw_name);
- while (fgets(line, sizeof(line), fp) != NULL) {
- /* Do substitutions? */
- fputs(line, pfp);
+ if (pfp == NULL)
+ warn("sendmail");
+ else {
+ fprintf(pfp, "From: root\n" "To: %s\n" "Subject: Welcome!\n\n", pwd->pw_name);
+ while (fgets(line, sizeof(line), fp) != NULL) {
+ /* Do substitutions? */
+ fputs(line, pfp);
+ }
+ pclose(pfp);
+ pw_log(cnf, mode, W_USER, "%s(%ld) new user mail sent",
+ pwd->pw_name, (long) pwd->pw_uid);
}
- pclose(pfp);
- pw_log(cnf, mode, W_USER, "%s(%ld) new user mail sent",
- pwd->pw_name, (long) pwd->pw_uid);
+ fclose(fp);
}
- fclose(fp);
}
}
/*
@@ -598,7 +604,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
* that this also `works' for editing users if -m is used, but
* existing files will *not* be overwritten.
*/
- if (getarg(args, 'm') != NULL && pwd->pw_dir && *pwd->pw_dir == '/' && pwd->pw_dir[1]) {
+ if (!PWALTDIR() && getarg(args, 'm') != NULL && pwd->pw_dir && *pwd->pw_dir == '/' && pwd->pw_dir[1]) {
copymkdir(pwd->pw_dir, cnf->dotdir, 0755, pwd->pw_uid, pwd->pw_gid);
pw_log(cnf, mode, W_USER, "%s(%ld) home %s made",
pwd->pw_name, (long) pwd->pw_uid, pwd->pw_dir);
@@ -620,7 +626,7 @@ pw_uidpolicy(struct userconf * cnf, struct cargs * args)
if (a_uid != NULL) {
uid = (uid_t) atol(a_uid->val);
- if ((pwd = getpwuid(uid)) != NULL && getarg(args, 'o') == NULL)
+ if ((pwd = GETPWUID(uid)) != NULL && getarg(args, 'o') == NULL)
errx(EX_DATAERR, "uid `%ld' has already been allocated", (long) pwd->pw_uid);
} else {
struct bitmap bm;
@@ -640,11 +646,11 @@ pw_uidpolicy(struct userconf * cnf, struct cargs * args)
/*
* Now, let's fill the bitmap from the password file
*/
- setpwent();
- while ((pwd = getpwent()) != NULL)
- if (pwd->pw_uid >= (int) cnf->min_uid && pwd->pw_uid <= (int) cnf->max_uid)
+ SETPWENT();
+ while ((pwd = GETPWENT()) != NULL)
+ if (pwd->pw_uid >= (uid_t) cnf->min_uid && pwd->pw_uid <= (uid_t) cnf->max_uid)
bm_setbit(&bm, pwd->pw_uid - cnf->min_uid);
- endpwent();
+ ENDPWENT();
/*
* Then apply the policy, with fallback to reuse if necessary
@@ -679,15 +685,15 @@ pw_gidpolicy(struct userconf * cnf, struct cargs * args, char *nam, gid_t prefer
/*
* Check the given gid, if any
*/
- setgrent();
+ SETGRENT();
if (a_gid != NULL) {
- if ((grp = getgrnam(a_gid->val)) == NULL) {
+ if ((grp = GETGRNAM(a_gid->val)) == NULL) {
gid = (gid_t) atol(a_gid->val);
- if ((gid == 0 && !isdigit(*a_gid->val)) || (grp = getgrgid(gid)) == NULL)
+ if ((gid == 0 && !isdigit(*a_gid->val)) || (grp = GETGRGID(gid)) == NULL)
errx(EX_NOUSER, "group `%s' is not defined", a_gid->val);
}
gid = grp->gr_gid;
- } else if ((grp = getgrnam(nam)) != NULL && grp->gr_mem[0] == NULL) {
+ } else if ((grp = GETGRNAM(nam)) != NULL && grp->gr_mem[0] == NULL) {
gid = grp->gr_gid; /* Already created? Use it anyway... */
} else {
struct cargs grpargs;
@@ -705,7 +711,7 @@ pw_gidpolicy(struct userconf * cnf, struct cargs * args, char *nam, gid_t prefer
* user's name dups an existing group, then the group add
* function will happily handle that case for us and exit.
*/
- if (getgrgid(prefer) == NULL) {
+ if (GETGRGID(prefer) == NULL) {
sprintf(tmp, "%lu", (unsigned long) prefer);
addarg(&grpargs, 'g', tmp);
}
@@ -718,7 +724,7 @@ pw_gidpolicy(struct userconf * cnf, struct cargs * args, char *nam, gid_t prefer
else
{
pw_group(cnf, M_ADD, &grpargs);
- if ((grp = getgrnam(nam)) != NULL)
+ if ((grp = GETGRNAM(nam)) != NULL)
gid = grp->gr_gid;
}
a_gid = grpargs.lh_first;
@@ -728,7 +734,7 @@ pw_gidpolicy(struct userconf * cnf, struct cargs * args, char *nam, gid_t prefer
a_gid = t;
}
}
- endgrent();
+ ENDGRENT();
return gid;
}
@@ -968,7 +974,7 @@ print_user(struct passwd * pwd, int pretty)
} else {
int j;
char *p;
- struct group *grp = getgrgid(pwd->pw_gid);
+ struct group *grp = GETGRGID(pwd->pw_gid);
char uname[60] = "User &", office[60] = "[None]",
wphone[60] = "[None]", hphone[60] = "[None]";
char acexpire[32] = "[None]", pwexpire[32] = "[None]";
@@ -1016,9 +1022,9 @@ print_user(struct passwd * pwd, int pretty)
uname, pwd->pw_dir, pwd->pw_class,
pwd->pw_shell, office, wphone, hphone,
acexpire, pwexpire);
- setgrent();
+ SETGRENT();
j = 0;
- while ((grp=getgrent()) != NULL)
+ while ((grp=GETGRENT()) != NULL)
{
int i = 0;
while (grp->gr_mem[i] != NULL)
@@ -1031,7 +1037,7 @@ print_user(struct passwd * pwd, int pretty)
++i;
}
}
- endgrent();
+ ENDGRENT();
printf("%s\n", j ? "\n" : "");
}
return EXIT_SUCCESS;
diff --git a/usr.sbin/pw/pw_vpw.c b/usr.sbin/pw/pw_vpw.c
new file mode 100644
index 0000000..fca5324
--- /dev/null
+++ b/usr.sbin/pw/pw_vpw.c
@@ -0,0 +1,316 @@
+/*-
+ * Copyright (C) 1996
+ * David L. Nugent. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DAVID L. NUGENT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL DAVID L. NUGENT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "$Id$";
+#endif /* not lint */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/param.h>
+
+#include "pwupd.h"
+
+static FILE * pwd_fp = NULL;
+
+void
+vendpwent(void)
+{
+ if (pwd_fp != NULL) {
+ fclose(pwd_fp);
+ pwd_fp = NULL;
+ }
+}
+
+void
+vsetpwent(void)
+{
+ vendpwent();
+}
+
+static struct passwd *
+vnextpwent(char const * nam, uid_t uid, int doclose)
+{
+ struct passwd * pw = NULL;
+ static char pwtmp[1024];
+
+ strncpy(pwtmp, getpwpath(_MASTERPASSWD), sizeof pwtmp);
+ pwtmp[sizeof pwtmp - 1] = '\0';
+
+ if (pwd_fp != NULL || (pwd_fp = fopen(pwtmp, "r")) != NULL) {
+ int done = 0;
+
+ static struct passwd pwd;
+
+ while (!done && fgets(pwtmp, sizeof pwtmp, pwd_fp) != NULL)
+ {
+ int i, quickout = 0;
+ char * q;
+ char * p = strchr(pwtmp, '\n');
+
+ if (p == NULL) {
+ while (fgets(pwtmp, sizeof pwtmp, pwd_fp) != NULL && strchr(pwtmp, '\n')==NULL)
+ ; /* Skip long lines */
+ continue;
+ }
+
+ /* skip comments & empty lines */
+ if (*pwtmp =='\n' || *pwtmp == '#')
+ continue;
+
+ i = 0;
+ q = p = pwtmp;
+ bzero(&pwd, sizeof pwd);
+ while (!quickout && (p = strsep(&q, ":\n")) != NULL) {
+ switch (i++)
+ {
+ case 0: /* username */
+ pwd.pw_name = p;
+ if (nam) {
+ if (strcmp(nam, p) == 0)
+ done = 1;
+ else
+ quickout = 1;
+ }
+ break;
+ case 1: /* password */
+ pwd.pw_passwd = p;
+ break;
+ case 2: /* uid */
+ pwd.pw_uid = atoi(p);
+ if (uid != (uid_t)-1) {
+ if (uid == pwd.pw_uid)
+ done = 1;
+ else
+ quickout = 1;
+ }
+ break;
+ case 3: /* gid */
+ pwd.pw_gid = atoi(p);
+ break;
+ case 4: /* class */
+ if (nam == NULL && uid == (uid_t)-1)
+ done = 1;
+ pwd.pw_class = p;
+ break;
+ case 5: /* change */
+ pwd.pw_change = (time_t)atol(p);
+ break;
+ case 6: /* expire */
+ pwd.pw_expire = (time_t)atol(p);
+ break;
+ case 7: /* gecos */
+ pwd.pw_gecos = p;
+ break;
+ case 8: /* directory */
+ pwd.pw_dir = p;
+ break;
+ case 9: /* shell */
+ pwd.pw_shell = p;
+ break;
+ }
+ }
+ }
+ if (doclose)
+ vendpwent();
+ if (done && pwd.pw_name) {
+ pw = &pwd;
+
+ #define CKNULL(s) s = s ? s : ""
+ CKNULL(pwd.pw_passwd);
+ CKNULL(pwd.pw_class);
+ CKNULL(pwd.pw_gecos);
+ CKNULL(pwd.pw_dir);
+ CKNULL(pwd.pw_shell);
+ }
+ }
+ return pw;
+}
+
+struct passwd *
+vgetpwent(void)
+{
+ return vnextpwent(NULL, -1, 0);
+}
+
+struct passwd *
+vgetpwuid(uid_t uid)
+{
+ return vnextpwent(NULL, uid, 1);
+}
+
+struct passwd *
+vgetpwnam(const char * nam)
+{
+ return vnextpwent(nam, -1, 1);
+}
+
+int vpwdb(char *arg, ...)
+{
+ arg=arg;
+ return 0;
+}
+
+
+
+static FILE * grp_fp = NULL;
+
+void
+vendgrent(void)
+{
+ if (grp_fp != NULL) {
+ fclose(grp_fp);
+ grp_fp = NULL;
+ }
+}
+
+int
+vsetgrent(void)
+{
+ vendgrent();
+ return 0;
+}
+
+static struct group *
+vnextgrent(char const * nam, gid_t gid, int doclose)
+{
+ struct group * gr = NULL;
+
+ static char * grtmp = NULL;
+ static int grlen = 0;
+ static char ** mems = NULL;
+ static int memlen = 0;
+
+ extendline(&grtmp, &grlen, MAXPATHLEN);
+ strncpy(grtmp, getgrpath(_GROUP), MAXPATHLEN);
+ grtmp[MAXPATHLEN - 1] = '\0';
+
+ if (grp_fp != NULL || (grp_fp = fopen(grtmp, "r")) != NULL) {
+ int done = 0;
+
+ static struct group grp;
+
+ while (!done && fgets(grtmp, grlen, grp_fp) != NULL)
+ {
+ int i, quickout = 0;
+ int mno = 0;
+ char * q, * p;
+ char * sep = ":\n";
+
+ if ((p = strchr(grtmp, '\n')) == NULL) {
+ int l;
+ extendline(&grtmp, &grlen, grlen + PWBUFSZ);
+ l = strlen(grtmp);
+ if (fgets(grtmp + l, grlen - l, grp_fp) == NULL)
+ break; /* No newline terminator on last line */
+ }
+ /* Skip comments and empty lines */
+ if (*grtmp == '\n' || *grtmp == '#')
+ continue;
+ i = 0;
+ q = p = grtmp;
+ bzero(&grp, sizeof grp);
+ extendarray(&mems, &memlen, 200);
+ while (!quickout && (p = strsep(&q, sep)) != NULL) {
+ switch (i++)
+ {
+ case 0: /* groupname */
+ grp.gr_name = p;
+ if (nam) {
+ if (strcmp(nam, p) == 0)
+ done = 1;
+ else
+ quickout = 1;
+ }
+ break;
+ case 1: /* password */
+ grp.gr_passwd = p;
+ break;
+ case 2: /* gid */
+ grp.gr_gid = atoi(p);
+ if (gid != (gid_t)-1) {
+ if (gid == (gid_t)grp.gr_gid)
+ done = 1;
+ else
+ quickout = 1;
+ } else if (nam == NULL)
+ done = 1;
+ break;
+ case 3:
+ q = p;
+ sep = ",\n";
+ break;
+ default:
+ if (*p) {
+ extendarray(&mems, &memlen, mno + 2);
+ mems[mno++] = p;
+ }
+ break;
+ }
+ }
+ grp.gr_mem = mems;
+ mems[mno] = NULL;
+ }
+ if (doclose)
+ vendgrent();
+ if (done && grp.gr_name) {
+ gr = &grp;
+
+ CKNULL(grp.gr_passwd);
+ }
+ }
+ return gr;
+}
+
+struct group *
+vgetgrent(void)
+{
+ return vnextgrent(NULL, -1, 0);
+}
+
+
+struct group *
+vgetgrgid(gid_t gid)
+{
+ return vnextgrent(NULL, gid, 1);
+}
+
+struct group *
+vgetgrnam(const char * nam)
+{
+ return vnextgrent(nam, -1, 1);
+}
+
+int
+vgrdb(char *arg, ...)
+{
+ arg=arg;
+ return 0;
+}
+
diff --git a/usr.sbin/pw/pwupd.c b/usr.sbin/pw/pwupd.c
index c42b1fb..8e5fb32 100644
--- a/usr.sbin/pw/pwupd.c
+++ b/usr.sbin/pw/pwupd.c
@@ -26,7 +26,7 @@
#ifndef lint
static const char rcsid[] =
- "$Id: pwupd.c,v 1.6 1997/10/10 06:23:41 charnier Exp $";
+ "$Id: pwupd.c,v 1.7 1998/02/11 23:31:24 wosch Exp $";
#endif /* not lint */
#include <stdio.h>
@@ -37,19 +37,46 @@ static const char rcsid[] =
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/param.h>
#include <sys/wait.h>
#include "pwupd.h"
#define HAVE_PWDB_C 1
-static int
+static char pathpwd[] = _PATH_PWD;
+static char * pwpath = pathpwd;
+
+int
+setpwdir(const char * dir)
+{
+ if (dir == NULL)
+ return -1;
+ else {
+ char * d = malloc(strlen(dir)+1);
+ if (d == NULL)
+ return -1;
+ pwpath = strcpy(d, dir);
+ }
+ return 0;
+}
+
+char *
+getpwpath(char const * file)
+{
+ static char pathbuf[MAXPATHLEN];
+
+ snprintf(pathbuf, sizeof pathbuf, "%s/%s", pwpath, file);
+ return pathbuf;
+}
+
+int
pwdb(char *arg,...)
{
int i = 0;
pid_t pid;
va_list ap;
- char *args[8];
+ char *args[10];
args[i++] = _PATH_PWD_MKDB;
va_start(ap, arg);
@@ -57,7 +84,11 @@ pwdb(char *arg,...)
args[i++] = arg;
arg = va_arg(ap, char *);
}
- args[i++] = _PATH_MASTERPASSWD;
+ if (pwpath != pathpwd) {
+ args[i++] = "-d";
+ args[i++] = pwpath;
+ }
+ args[i++] = getpwpath(_MASTERPASSWD);
args[i] = NULL;
if ((pid = fork()) == -1) /* Error (errno set) */
@@ -108,7 +139,7 @@ pw_update(struct passwd * pwd, char const * user, int mode)
{
int rc = 0;
- endpwent();
+ ENDPWENT();
/*
* First, let's check the see if the database is alright
@@ -130,14 +161,14 @@ pw_update(struct passwd * pwd, char const * user, int mode)
*pwbuf = '\0';
else
fmtpwentry(pwbuf, pwd, PWF_PASSWD);
- if ((rc = fileupdate(_PATH_PASSWD, 0644, pwbuf, pfx, l, mode)) != 0) {
+ if ((rc = fileupdate(getpwpath(_PASSWD), 0644, pwbuf, pfx, l, mode)) != 0) {
/*
* Then the master.passwd file
*/
if (pwd != NULL)
fmtpwentry(pwbuf, pwd, PWF_MASTER);
- if ((rc = fileupdate(_PATH_MASTERPASSWD, 0644, pwbuf, pfx, l, mode)) != 0)
+ if ((rc = fileupdate(getpwpath(_MASTERPASSWD), 0644, pwbuf, pfx, l, mode)) != 0)
rc = pwdb(NULL) == 0;
}
}
diff --git a/usr.sbin/pw/pwupd.h b/usr.sbin/pw/pwupd.h
index 0bb0389..6695973 100644
--- a/usr.sbin/pw/pwupd.h
+++ b/usr.sbin/pw/pwupd.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: pwupd.h,v 1.4 1997/02/22 16:12:31 peter Exp $
*/
#ifndef _PWUPD_H_
@@ -54,6 +54,57 @@ enum pwdfmttype
PWF_MASTER /* MASTER format with password */
};
+struct pwf
+{
+ int _altdir;
+ void (*_setpwent)(void);
+ void (*_endpwent)(void);
+ struct passwd * (*_getpwent)(void);
+ struct passwd * (*_getpwuid)(uid_t uid);
+ struct passwd * (*_getpwnam)(const char * nam);
+ int (*_pwdb)(char *arg, ...);
+ int (*_setgrent)(void);
+ void (*_endgrent)(void);
+ struct group * (*_getgrent)(void);
+ struct group * (*_getgrgid)(gid_t gid);
+ struct group * (*_getgrnam)(const char * nam);
+ int (*_grdb)(char *arg, ...);
+};
+
+extern struct pwf PWF;
+extern struct pwf VPWF;
+
+#define SETPWENT() PWF._setpwent()
+#define ENDPWENT() PWF._endpwent()
+#define GETPWENT() PWF._getpwent()
+#define GETPWUID(uid) PWF._getpwuid(uid)
+#define GETPWNAM(nam) PWF._getpwnam(nam)
+#define PWDB(args) PWF._pwdb(args)
+
+#define SETGRENT() PWF._setgrent()
+#define ENDGRENT() PWF._endgrent()
+#define GETGRENT() PWF._getgrent()
+#define GETGRGID(gid) PWF._getgrgid(gid)
+#define GETGRNAM(nam) PWF._getgrnam(nam)
+#define GRDB(args) PWF._grdb(args)
+
+#define PWALTDIR() PWF._altdir
+#ifndef _PATH_PWD
+#define _PATH_PWD "/etc"
+#endif
+#ifndef _GROUP
+#define _GROUP "group"
+#endif
+#ifndef _PASSWD
+#define _PASSWD "passwd"
+#endif
+#ifndef _MASTERPASSWD
+#define _MASTERPASSWD "master.passwd"
+#endif
+#ifndef _GROUP
+#define _GROUP "group"
+#endif
+
__BEGIN_DECLS
int addpwent __P((struct passwd * pwd));
int delpwent __P((struct passwd * pwd));
@@ -61,21 +112,45 @@ int chgpwent __P((char const * login, struct passwd * pwd));
int fmtpwent __P((char *buf, struct passwd * pwd));
int fmtpwentry __P((char *buf, struct passwd * pwd, int type));
+int setpwdir __P((const char * dir));
+char * getpwpath __P((char const * file));
+int pwdb __P((char *arg, ...));
+
int addgrent __P((struct group * grp));
int delgrent __P((struct group * grp));
int chggrent __P((char const * name, struct group * grp));
int fmtgrent __P((char **buf, int * buflen, struct group * grp));
int fmtgrentry __P((char **buf, int * buflen, struct group * grp, int type));
int editgroups __P((char *name, char **groups));
-__END_DECLS
-#define PWBUFSZ 1024
+int setgrdir __P((const char * dir));
+char * getgrpath __P((const char *file));
+int grdb __P((char *arg, ...));
+
+void vsetpwent __P((void));
+void vendpwent __P((void));
+struct passwd * vgetpwent __P((void));
+struct passwd * vgetpwuid __P((uid_t uid));
+struct passwd * vgetpwnam __P((const char * nam));
+struct passwd * vgetpwent __P((void));
+int vpwdb __P((char *arg, ...));
+
+int vsetgrent __P((void));
+void vendgrent __P((void));
+struct group * vgetgrent __P((void));
+struct group * vgetgrgid __P((gid_t gid));
+struct group * vgetgrnam __P((const char * nam));
+struct group * vgetgrent __P((void));
+int vgrdb __P((char *arg, ...));
+int vsetgrent __P((void));
+void vendgrent __P((void));
-__BEGIN_DECLS
void copymkdir __P((char const * dir, char const * skel, mode_t mode, uid_t uid, gid_t gid));
void rm_r __P((char const * dir, uid_t uid));
int extendline __P((char **buf, int *buflen, int needed));
int extendarray __P((char ***buf, int *buflen, int needed));
__END_DECLS
+#define PWBUFSZ 1024
+
#endif /* !_PWUPD_H */
OpenPOWER on IntegriCloud