summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Nugent <davidn@FreeBSD.org>1997-01-05 07:15:37 +0000
committerDavid Nugent <davidn@FreeBSD.org>1997-01-05 07:15:37 +0000
commit3f5e90cd330e96e54e53d75397bb6bef56153218 (patch)
treea3695319f1002ddb2670e9ddeb2b2bdd63d09e3a
parent9267b33e5ec61946f68b0c8333bca3bceb33385c (diff)
downloadpw-darwin-3f5e90cd330e96e54e53d75397bb6bef56153218.tar.gz
pw-darwin-3f5e90cd330e96e54e53d75397bb6bef56153218.tar.zst
pw-darwin-3f5e90cd330e96e54e53d75397bb6bef56153218.zip
Adds optional NIS passwd file updating and optionally rebuilding
NIS maps. Suggested by: Peter Wemm
-rw-r--r--pw/Makefile4
-rw-r--r--pw/pw.832
-rw-r--r--pw/pw.c56
-rw-r--r--pw/pw.conf.513
-rw-r--r--pw/pw.h7
-rw-r--r--pw/pw_conf.c14
-rw-r--r--pw/pw_nis.c70
-rw-r--r--pw/pw_user.c28
8 files changed, 202 insertions, 22 deletions
diff --git a/pw/Makefile b/pw/Makefile
index ae8ec1e..c752a61 100644
--- a/pw/Makefile
+++ b/pw/Makefile
@@ -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
diff --git a/pw/pw.8 b/pw/pw.8
index f0aa9f7..7b8ebad 100644
--- a/pw/pw.8
+++ b/pw/pw.8
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $Id: pw.8,v 1.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
diff --git a/pw/pw.c b/pw/pw.c
index 96baab4..e9d55cc 100644
--- a/pw/pw.c
+++ b/pw/pw.c
@@ -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"
diff --git a/pw/pw.conf.5 b/pw/pw.conf.5
index 34daeef..4ef6b18 100644
--- a/pw/pw.conf.5
+++ b/pw/pw.conf.5
@@ -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
diff --git a/pw/pw.h b/pw/pw.h
index 7c8cff5..37c4807 100644
--- a/pw/pw.h
+++ b/pw/pw.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: pw.h,v 1.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);
diff --git a/pw/pw_conf.c b/pw/pw_conf.c
index 8a0e644..bf93c2a 100644
--- a/pw/pw_conf.c
+++ b/pw/pw_conf.c
@@ -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;
diff --git a/pw/pw_nis.c b/pw/pw_nis.c
new file mode 100644
index 0000000..781cfdd
--- /dev/null
+++ b/pw/pw_nis.c
@@ -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);
+}
diff --git a/pw/pw_user.c b/pw/pw_user.c
index 14b618f..9f95fee 100644
--- a/pw/pw_user.c
+++ b/pw/pw_user.c
@@ -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
*/