Adds optional NIS passwd file updating and optionally rebuilding

NIS maps.

Suggested by:	Peter Wemm
This commit is contained in:
David Nugent 1997-01-05 07:15:37 +00:00
parent b488c451de
commit f1d684fad9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=21330
8 changed files with 202 additions and 22 deletions

View File

@ -1,7 +1,7 @@
# $Id: Makefile,v 1.1.1.3 1996/12/10 23:58:50 joerg Exp $
# $Id: Makefile,v 1.2 1996/12/17 14:15:33 davidn Exp $
PROG= pw
SRCS= pw.c pw_conf.c pw_user.c pw_group.c pw_log.c \
SRCS= pw.c pw_conf.c pw_user.c pw_group.c pw_log.c pw_nis.c \
grupd.c pwupd.c fileupd.c edgroup.c psdate.c \
bitmap.c cpdir.c rm_r.c

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.4 1996/12/11 00:07:19 joerg Exp $
.\" $Id: pw.8,v 1.5 1996/12/19 15:22:41 davidn Exp $
.\"
.Dd December 9, 1996
.Dt PW 8
@ -52,10 +52,11 @@
.Op Fl h Ar fd
.Op Fl N
.Op Fl P
.Op Fl Y
.Nm pw
.Ar useradd
.Op name|uid
.Op Fl D
.Fl D
.Op Fl C Ar config
.Op Fl q
.Op Fl b Ar dir
@ -68,12 +69,14 @@
.Op Fl i Ar min,max
.Op Fl w Ar method
.Op Fl s Ar shell
.Op Fl y Ar path
.Nm pw
.Ar userdel
.Op name|uid
.Op Fl n Ar name
.Op Fl u Ar uid
.Op Fl r
.Op Fl Y
.Nm pw
.Ar usermod
.Op name|uid
@ -96,6 +99,7 @@
.Op Fl h Ar fd
.Op Fl N
.Op Fl P
.Op Fl Y
.Nm pw
.Ar usershow
.Op name|uid
@ -120,10 +124,12 @@
.Op Fl h Ar fd
.Op Fl N
.Op Fl P
.Op Fl Y
.Nm pw
.Ar groupdel
.Op Fl n Ar name
.Op Fl g Ar gid
.Op Fl Y
.Nm pw
.Ar groupmod
.Op Fl C Ar config
@ -137,6 +143,7 @@
.Op Fl h Ar fd
.Op Fl N
.Op Fl P
.Op Fl Y
.Nm pw
.Ar groupshow
.Op Fl n Ar name
@ -194,7 +201,7 @@ id as an alternative to using the
.Fl g Ar gid
options.
.Pp
The following flags are common to all modes of operation:
The following flags are common to all or most modes of operation:
.Pp
.Bl -tag -width "-G grouplist"
.It Fl C Ar config
@ -224,6 +231,19 @@ of the operation without actually performing it.
You may use the
.Fl P
option to switch between standard passwd and readable formats.
.It Fl Y
Using this option with any of the update modes causes
.Nm pw
to run
.Xr make 1
after changing to the directory
.Pa /var/yp .
This is intended to allow automatic updating of the NIS database files.
If separate passwd and group files are being used by NIS, then use the
.Fl y Ar path
option to specify the location of the NIS passwd database so that pw
will automatically update it concurrently with the system password
databases.
.El
.Pp
.Sh USER OPTIONS
@ -558,6 +578,12 @@ The
method requires that the superuser use
.Xr passwd 1
to render the account accessible with a password.
.It Fl y Ar path
This sets the pathname of the database used by NIS if you are not sharing
the information from
.Pa /etc/master.passwd
directly with NIS.
You should only set this option on NIS servers.
.El
.Pp
The

View File

@ -23,10 +23,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: pw.c,v 1.1.1.2 1996/12/09 23:55:20 joerg Exp $
* $Id: pw.c,v 1.1.1.3 1996/12/10 23:58:58 joerg Exp $
*/
#include "pw.h"
#include <paths.h>
#include <sys/wait.h>
static char *progname = "pw";
@ -58,16 +60,16 @@ main(int argc, char *argv[])
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:NP",
"C:qn:u:r",
"C:qn:u:c:d:e:p:g:G:mk:s:w:L:h:FNP",
"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:mk:s:w:L:h:FNPY",
"C:qn:u:FPa",
"C:q"
},
{ /* grp */
"C:qn:g:h:M:pNP",
"C:qn:g:",
"C:qn:g:l:h:FM:m:NP",
"C:qn:g:h:M:pNPY",
"C:qn:g:Y",
"C:qn:g:l:h:FM:m:NPY",
"C:qn:g:FPa",
"C:q"
}
@ -150,7 +152,34 @@ main(int argc, char *argv[])
* Now, let's do the common initialisation
*/
cnf = read_userconfig(getarg(&arglist, 'C') ? getarg(&arglist, 'C')->val : NULL);
return funcs[which] (cnf, mode, &arglist);
ch = funcs[which] (cnf, mode, &arglist);
/*
* If everything went ok, and we've been asked to update
* the NIS maps, then do it now
*/
if (ch == EXIT_SUCCESS && getarg(&arglist, 'Y') != NULL) {
pid_t pid;
fflush(NULL);
if (chdir(_PATH_YP) == -1)
perror("chdir(" _PATH_YP ")");
else if ((pid = fork()) == -1)
perror("fork()");
else if (pid == 0) {
/* Is make anywhere else? */
execlp("/usr/bin/make", "make", NULL);
_exit(1);
} else {
int i;
waitpid(pid, &i, 0);
if ((i = WEXITSTATUS(i)) != 0)
cmderr(ch, "warning: make exited with status %d\n", i);
else
pw_log(cnf, mode, which, "NIS maps updated");
}
}
return ch;
}
static int
@ -225,6 +254,7 @@ cmdhelp(int mode, int which)
"\t-o duplicate uid ok\n"
"\t-L class user class\n"
"\t-h fd read password on fd\n"
"\t-Y update NIS maps\n"
"\t-N no update\n"
" Setting defaults:\n"
"\t-D set user defaults\n"
@ -238,10 +268,12 @@ cmdhelp(int mode, int which)
"\t-u min,max set min,max uids\n"
"\t-i min,max set min,max gids\n"
"\t-w method set default password method\n"
"\t-s shell default shell\n",
"\t-s shell default shell\n"
"\t-y path set NIS passwd file path\n",
"usage: %s userdel [uid|name] [switches]\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: %s usermod [uid|name] [switches]\n"
"\t-C config configuration file\n"
@ -261,6 +293,7 @@ cmdhelp(int mode, int which)
"\t-s shell name of login shell\n"
"\t-w method set new password using method\n"
"\t-h fd read password on fd\n"
"\t-Y update NIS maps\n"
"\t-N no update\n",
"usage: %s usershow [uid|name] [switches]\n"
"\t-n name login name\n"
@ -279,10 +312,12 @@ cmdhelp(int mode, int which)
"\t-g gid group id\n"
"\t-M usr1,usr2 add users as group members\n"
"\t-o duplicate gid ok\n"
"\t-Y update NIS maps\n"
"\t-N no update\n",
"usage: %s groupdel [group|gid] [switches]\n"
"\t-n name group name\n"
"\t-g gid group id\n",
"\t-g gid group id\n"
"\t-Y update NIS maps\n",
"usage: %s groupmod [group|gid] [switches]\n"
"\t-C config configuration file\n"
"\t-q quiet operation\n"
@ -292,6 +327,7 @@ cmdhelp(int mode, int which)
"\t-M usr1,usr2 replaces users as group members\n"
"\t-m usr1,usr2 add users as group members\n"
"\t-l name new group name\n"
"\t-Y update NIS maps\n"
"\t-N no update\n",
"usage: %s groupshow [group|gid] [switches]\n"
"\t-n name group name\n"

View File

@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $Id: pw.conf.5,v 1.1.1.3 1996/12/10 23:58:59 joerg Exp $
.\" $Id: pw.conf.5,v 1.2 1997/01/05 04:05:22 davidn Exp $
.\"
.Dd December 9, 1996
.Dt PW.CONF 5
@ -66,6 +66,8 @@ affects passwords generated for new users
reuse gaps in uid sequences
.It reusegids
reuse gaps in gid sequences
.It nispasswd
path to the NIS passwd database
.It skeleton
where to obtain default home contents
.It newmail
@ -146,12 +148,19 @@ previous user or group deletions.
Note that if the default group is not specified using the
.Ar defaultgroup
keyword,
.Xr pw 8
Xr pw 8
will create a new group for the user and attempt to keep the new
user's uid and gid the same.
If the new user's uid is currently in use as a group id, then the next
available group id is chosen instead.
.Pp
On NIS servers which maintain a separate passwd database to
.Pa /etc/master.passwd ,
this option allows the additional file to be concurrently updated
as user records are added, modified or removed.
If blank or set to 'no', no additional database is updated.
An absolute pathname must be used.
.Pp
The
.Ar skeleton
keyword nominates a directory from which the contents of a user's

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.2 1996/12/19 15:22:42 davidn Exp $
* $Id: pw.h,v 1.3 1996/12/21 15:35:42 davidn Exp $
*/
#include <stdio.h>
@ -72,6 +72,7 @@ struct userconf
int default_password; /* Default password for new users? */
int reuse_uids; /* Reuse uids? */
int reuse_gids; /* Reuse gids? */
char *nispasswd; /* Path to NIS version of the passwd file */
char *dotdir; /* Where to obtain skeleton files */
char *newmail; /* Mail to send to new accounts */
char *logfile; /* Where to log changes */
@ -108,6 +109,10 @@ int delpwent(struct passwd * pwd);
int chgpwent(char const * login, struct passwd * pwd);
int fmtpwent(char *buf, struct passwd * pwd);
int addnispwent(const char *path, struct passwd *pwd);
int delnispwent(const char *path, const char *login);
int chgnispwent(const char *path, const char *login, struct passwd *pwd);
int addgrent(struct group * grp);
int delgrent(struct group * grp);
int chggrent(char const * login, struct group * grp);

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: pw_conf.c,v 1.1.1.2 1996/12/10 23:59:00 joerg Exp $
* $Id: pw_conf.c,v 1.2 1996/12/21 15:35:42 davidn Exp $
*/
#include <string.h>
@ -40,6 +40,7 @@ enum {
_UC_DEFAULTPWD,
_UC_REUSEUID,
_UC_REUSEGID,
_UC_NISPASSWD,
_UC_DOTDIR,
_UC_NEWMAIL,
_UC_LOGFILE,
@ -81,6 +82,7 @@ static struct userconf config =
0, /* Default password for new users? (nologin) */
0, /* Reuse uids? */
0, /* Reuse gids? */
NULL, /* NIS version of the passwd file */
"/usr/share/skel", /* Where to obtain skeleton files */
NULL, /* Mail to send to new accounts */
"/var/log/userlog", /* Where to log changes */
@ -103,6 +105,7 @@ static char const *comments[_UC_FIELDS] =
"\n# Password for new users? no=nologin yes=loginid none=blank random=random\n",
"\n# Reuse gaps in uid sequence? (yes or no)\n",
"\n# Reuse gaps in gid sequence? (yes or no)\n",
"\n# Path to the NIS passwd file (blank or 'no' for none)\n",
"\n# Obtain default dotfiles from this directory\n",
"\n# Mail this file to new user (/etc/newuser.msg or no)\n",
"\n# Log add/change/remove information in this file\n",
@ -127,6 +130,7 @@ static char const *kwds[] =
"defaultpasswd",
"reuseuids",
"reusegids",
"nispasswd",
"skeleton",
"newmail",
"logfile",
@ -266,6 +270,10 @@ read_userconfig(char const * file)
case _UC_REUSEGID:
config.reuse_gids = boolean_val(q, 0);
break;
case _UC_NISPASSWD:
config.nispasswd = (q == NULL || !boolean_val(q, 1))
? NULL : newstr(q);
break;
case _UC_DOTDIR:
config.dotdir = (q == NULL || !boolean_val(q, 1))
? NULL : newstr(q);
@ -384,6 +392,10 @@ write_userconfig(char const * file)
case _UC_REUSEGID:
val = boolean_str(config.reuse_gids);
break;
case _UC_NISPASSWD:
val = config.nispasswd ? config.nispasswd : "";
quote = 0;
break;
case _UC_DOTDIR:
val = config.dotdir ? config.dotdir : boolean_str(0);
break;

70
usr.sbin/pw/pw_nis.c Normal file
View File

@ -0,0 +1,70 @@
/*-
* 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.
*
* $Id$
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "pwupd.h"
#include "pw.h"
static int
pw_nisupdate(const char * path, struct passwd * pwd, char const * user, int mode)
{
char pfx[32];
char pwbuf[PWBUFSZ];
int l = sprintf(pfx, "%s:", user);
/*
* Update the passwd file first
*/
if (pwd == NULL)
*pwbuf = '\0';
else
fmtpwentry(pwbuf, pwd, PWF_MASTER);
return fileupdate(path, 0600, pwbuf, pfx, l, mode) != 0;
}
int
addnispwent(const char *path, struct passwd * pwd)
{
return pw_nisupdate(path, pwd, pwd->pw_name, UPD_CREATE);
}
int
chgnispwent(const char *path, char const * login, struct passwd * pwd)
{
return pw_nisupdate(path, pwd, login, UPD_REPLACE);
}
int
delnispwent(const char *path, const char *login)
{
return pw_nisupdate(path, NULL, login, UPD_DELETE);
}

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: pw_user.c,v 1.10 1996/12/30 11:52:34 davidn Exp $
* $Id: pw_user.c,v 1.11 1997/01/03 04:42:18 davidn Exp $
*/
#include <unistd.h>
@ -87,6 +87,7 @@ static void rmskey(char const * name);
int
pw_user(struct userconf * cnf, int mode, struct cargs * args)
{
int r, r1;
char *p = NULL;
struct carg *a_name;
struct carg *a_uid;
@ -191,6 +192,9 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
if ((arg = getarg(args, 'e')) != NULL)
cnf->expire_days = atoi(arg->val);
if ((arg = getarg(args, 'y')) != NULL)
cnf->nispasswd = arg->val;
if ((arg = getarg(args, 'p')) != NULL && arg->val)
cnf->password_days = atoi(arg->val);
@ -332,6 +336,10 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
if (!delpwent(pwd))
cmderr(EX_IOERR, "Error updating passwd file: %s\n", strerror(errno));
if (cnf->nispasswd && *cnf->nispasswd=='/' && !delnispwent(cnf->nispasswd, a_name->val))
perror("WARNING: NIS passwd update");
editgroups(a_name->val, NULL);
pw_log(cnf, mode, W_USER, "%s(%ld) account removed", a_name->val, (long) uid);
@ -498,11 +506,25 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
if (getarg(args, 'N') != NULL)
return print_user(pwd, getarg(args, 'P') != NULL);
if ((mode == M_ADD && !addpwent(pwd)) ||
(mode == M_UPDATE && !chgpwent(a_name->val, pwd))) {
r = r1 = 1;
if (mode == M_ADD) {
r = addpwent(pwd);
if (r && cnf->nispasswd && *cnf->nispasswd=='/')
r1 = addnispwent(cnf->nispasswd, pwd);
} else if (mode == M_UPDATE) {
r = chgpwent(a_name->val, pwd);
if (r && cnf->nispasswd && *cnf->nispasswd=='/')
r1 = chgnispwent(cnf->nispasswd, a_name->val, pwd);
}
if (!r) {
perror("password update");
return EX_IOERR;
} else if (!r1) {
perror("WARNING: NIS password update");
/* Keep on trucking */
}
/*
* Ok, user is created or changed - now edit group file
*/