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:
parent
b48125eaa8
commit
5f12594a29
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=44229
@ -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}
|
||||
|
||||
|
@ -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 */
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
112
usr.sbin/pw/pw.c
112
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;
|
||||
@ -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"
|
||||
}
|
||||
};
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
316
usr.sbin/pw/pw_vpw.c
Normal 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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user