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.
This commit is contained in:
David Nugent 1999-02-23 07:15:11 +00:00
parent b48125eaa8
commit 5f12594a29
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=44229
14 changed files with 723 additions and 153 deletions

View File

@ -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}

View File

@ -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 */
}

View File

@ -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));
}

View File

@ -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;

View File

@ -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

View File

@ -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;
@ -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"
}
};

View File

@ -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
{

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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);
if (!PWALTDIR()) {
/*
* Remove mail file
*/
remove(file);
/*
* Remove at jobs
*/
if (getpwuid(uid) == NULL)
rmat(uid);
/*
* 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 ");
/*
* 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;

316
usr.sbin/pw/pw_vpw.c Normal file
View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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 */