From e3d97c779d907e3556a40a69b84f001d95cf4d6a Mon Sep 17 00:00:00 2001 From: David Nugent Date: Tue, 23 Feb 1999 07:15:11 +0000 Subject: 1) Do not blindly ignore file update errors which may occur due to concurrent updating 2) Add -V , which allows maintaining user/group database in alternate locations other than /etc. --- pw/Makefile | 6 +- pw/edgroup.c | 18 ++-- pw/fileupd.c | 15 +-- pw/grupd.c | 47 ++++++++- pw/pw.8 | 29 +++++- pw/pw.c | 112 ++++++++++++++++++--- pw/pw.h | 4 +- pw/pw_conf.c | 5 +- pw/pw_group.c | 25 +++-- pw/pw_nis.c | 3 +- pw/pw_user.c | 172 +++++++++++++++++--------------- pw/pw_vpw.c | 316 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pw/pwupd.c | 45 +++++++-- pw/pwupd.h | 83 ++++++++++++++- 14 files changed, 725 insertions(+), 155 deletions(-) create mode 100644 pw/pw_vpw.c (limited to 'pw') diff --git a/pw/Makefile b/pw/Makefile index 3425e9c..7b630dd 100644 --- a/pw/Makefile +++ b/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/pw/edgroup.c b/pw/edgroup.c index 6116fa6..649a398 100644 --- a/pw/edgroup.c +++ b/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 @@ -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/pw/fileupd.c b/pw/fileupd.c index fe46480..d76259b 100644 --- a/pw/fileupd.c +++ b/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 @@ -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/pw/grupd.c b/pw/grupd.c index feff430..e36c192 100644 --- a/pw/grupd.c +++ b/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 @@ -36,9 +36,46 @@ static const char rcsid[] = #include #include #include +#include #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/pw/pw.8 b/pw/pw.8 index 3a1a7a8..5de8237 100644 --- a/pw/pw.8 +++ b/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/pw/pw.c b/pw/pw.c index f862cbe..32246f9 100644 --- a/pw/pw.c +++ b/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 #include #include #include +#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 [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; @@ -144,10 +194,29 @@ main(int argc, char *argv[]) if (getarg(&arglist, 'q') != NULL) 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/pw/pw.h b/pw/pw.h index b52891a..16bea61 100644 --- a/pw/pw.h +++ b/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 @@ -34,12 +34,14 @@ #include #include #include +#include #include #include #include #include #include "psdate.h" +#include "pwupd.h" enum _mode { diff --git a/pw/pw_conf.c b/pw/pw_conf.c index 63742a7..dc1bd61 100644 --- a/pw/pw_conf.c +++ b/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 @@ -34,7 +34,6 @@ static const char rcsid[] = #include #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/pw/pw_group.c b/pw/pw_group.c index ce1b230..220a9b1 100644 --- a/pw/pw_group.c +++ b/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 @@ -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/pw/pw_nis.c b/pw/pw_nis.c index fe89685..3b041a8 100644 --- a/pw/pw_nis.c +++ b/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 @@ -34,7 +34,6 @@ static const char rcsid[] = #include #include -#include "pwupd.h" #include "pw.h" static int diff --git a/pw/pw_user.c b/pw/pw_user.c index d339381..635b530 100644 --- a/pw/pw_user.c +++ b/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 @@ -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/pw/pw_vpw.c b/pw/pw_vpw.c new file mode 100644 index 0000000..fca5324 --- /dev/null +++ b/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 +#include +#include +#include + +#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/pw/pwupd.c b/pw/pwupd.c index c42b1fb..8e5fb32 100644 --- a/pw/pwupd.c +++ b/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 @@ -37,19 +37,46 @@ static const char rcsid[] = #include #include #include +#include #include #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/pw/pwupd.h b/pw/pwupd.h index 0bb0389..6695973 100644 --- a/pw/pwupd.h +++ b/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 */ -- cgit v1.2.3-56-ge451