summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>1995-08-13 16:12:28 +0000
committerwpaul <wpaul@FreeBSD.org>1995-08-13 16:12:28 +0000
commit34376c5be441a95847ffcd53033e9d5f5f75a5bd (patch)
treecbb25b1f3e9394a0ba6cad7a4dc417448f1fa95f /usr.bin
parenta5c24b2ab93f41e6817b6790c7aec2f58b2e3f8a (diff)
downloadFreeBSD-src-34376c5be441a95847ffcd53033e9d5f5f75a5bd.zip
FreeBSD-src-34376c5be441a95847ffcd53033e9d5f5f75a5bd.tar.gz
Take the ypchfn/ypchsh stuff that was removed from passwd
and graft it into chpass. Chpass can now tell when it's being asked to operate on an NIS user and it displayes the appropriate message in the editor template ("Changing NIS information for foo"). After the changes have been made, chpass will promte the user for his NIS password. If the password is correct, the changes are committed to yppasswdd. Hopefully, this should make NIS more transparent to the end user. Note that even the superuser needs to know a user's password before he can change any NIS information (such is the nature of yppasswdd). Also, changes to the password field are not permitted -- that's what yppasswd is for. (The superuser may specify a new password, but again, he needs to know the user's original password before he can change it.)
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/chpass/Makefile16
-rw-r--r--usr.bin/chpass/chpass.178
-rw-r--r--usr.bin/chpass/chpass.c32
-rw-r--r--usr.bin/chpass/edit.c10
-rw-r--r--usr.bin/chpass/pw_copy.c8
-rw-r--r--usr.bin/chpass/pw_yp.c241
-rw-r--r--usr.bin/chpass/pw_yp.h45
7 files changed, 421 insertions, 9 deletions
diff --git a/usr.bin/chpass/Makefile b/usr.bin/chpass/Makefile
index 7b76f90..e0849bc 100644
--- a/usr.bin/chpass/Makefile
+++ b/usr.bin/chpass/Makefile
@@ -6,14 +6,20 @@ BINOWN= root
BINMODE=4555
.PATH: ${.CURDIR}/../../usr.sbin/pwd_mkdb ${.CURDIR}/../../usr.sbin/vipw
CFLAGS+=-I${.CURDIR}/../../usr.sbin/pwd_mkdb -I${.CURDIR}/../../usr.sbin/vipw
-LINKS= ${BINDIR}/chpass ${BINDIR}/chfn ${BINDIR}/chpass ${BINDIR}/chsh
+LINKS= ${DESTDIR}${BINDIR}/chpass ${DESTDIR}${BINDIR}/chfn
+LINKS+= ${DESTDIR}${BINDIR}/chpass ${DESTDIR}${BINDIR}/chsh
+LINKS+= ${DESTDIR}${BINDIR}/chpass ${DESTDIR}${BINDIR}/ypchpass
+LINKS+= ${DESTDIR}${BINDIR}/chpass ${DESTDIR}${BINDIR}/ypchfn
+LINKS+= ${DESTDIR}${BINDIR}/chpass ${DESTDIR}${BINDIR}/ypchsh
MLINKS= chpass.1 chfn.1 chpass.1 chsh.1
-
+COPTS+=-DYP
+SRCS+= pw_yp.c
+LDADD+=-lrpcsvc -lcrypt
beforeinstall:
- [ ! -e ${DESTDIR}/usr/bin/chpass ] || \
- chflags noschg ${DESTDIR}/usr/bin/chpass
+ [ ! -e ${DESTDIR}${BINDIR}/chpass ] || \
+ chflags noschg ${DESTDIR}${BINDIR}/chpass
afterinstall:
- chflags schg ${DESTDIR}/usr/bin/chpass
+ chflags schg ${DESTDIR}${BINDIR}/chpass
.include <bsd.prog.mk>
diff --git a/usr.bin/chpass/chpass.1 b/usr.bin/chpass/chpass.1
index 534f063..6186c7b 100644
--- a/usr.bin/chpass/chpass.1
+++ b/usr.bin/chpass/chpass.1
@@ -35,7 +35,7 @@
.Dt CHPASS 1
.Os
.Sh NAME
-.Nm chpass
+.Nm chpass, chfn, chsh, ypchpass, ypchfn, ypchsh
.Nd add or change user database information
.Sh SYNOPSIS
chpass
@@ -205,6 +205,72 @@ When the editor terminates, the information is re-read and used to
update the user database itself.
Only the user, or the super-user, may edit the information associated
with the user.
+.Sh NIS INTERACTION
+.Nm Chpass
+can also be used in conjunction with NIS, however some restrictions
+apply.
+Currently,
+.Nm chpass
+can only make changes to the NIS passwd maps through
+.Xr yppasswdd 8 ,
+which only permits changes to a user's password, shell and gecos
+fields. It can not be used to change other user information or to
+add new records to the NIS passwd maps. (Doing that would require
+something such as ypupdated, which is not yet supported.)
+Furthermore,
+.Xr yppasswdd 8
+requires password authentication before it will make any
+changes, even if it receives a request from the super-user.
+.Pp
+As a result, the following restrictions apply when
+.Nm chpass
+is used with NIS:
+.Bl -enum -offset indent
+.It
+.Pa Only the shell and gecos information may be changed.
+All other
+fields are restricted, even when
+.Nm chpass
+is invoked by the super-user, because the
+.Xr yppasswdd 8
+daemon has no support for updating them. While support for
+changing other fields could be added, this would lead to
+compatibility problems with other NIS-capable systems.
+Even though the super-user may supply data for other fields
+while editing an entry, the extra information (other than the
+password -- see below) will be silently discarded.
+.It
+.Pa Password authentication is required.
+.Nm Chpass
+will prompt for the user's NIS password before effecting
+any changes. If the password is invalid, all changes will be
+discarded.
+.It
+.Pa Adding new records to the local
+.Pa password database is discouraged.
+.Nm Chpass
+will allow the administrator to add new records to the
+local password database while NIS is enabled, but this can lead to
+some confusion since the new records are appended to the end of
+the master password file, usually after the special NIS '+' entries.
+The administrator should use
+.Xr vipw 8
+to modify the local password
+file when NIS is running.
+.It
+.Pa Password changes are not permitted.
+Users should use
+.Xr passwd 1
+or
+.Xr yppasswd 1
+to change their NIS passwords. The super-user is allowed to specify
+a new password (even though the ``Password:'' field does not show
+up in the editor template, the super-user may add it back by hand),
+but even the super-user must supply the user's original password
+otherwise
+.Xr yppasswdd 8
+will refuse to update the NIS maps.
+.El
.Sh FILES
.Bl -tag -width /etc/master.passwd -compact
.It Pa /etc/master.passwd
@@ -230,6 +296,16 @@ and
.%A Ken Thompson
.%T "UNIX Password security"
.Re
+.Sh NOTES
+The
+.Xr chfn 1 ,
+.Xr chsh 1 ,
+.Xr ypchpass 1 ,
+.Xr ypchfn 1
+and
+.Xr upchsh 1
+commands are really only links to
+.Nm chpass .
.Sh BUGS
User information should (and eventually will) be stored elsewhere.
.Sh HISTORY
diff --git a/usr.bin/chpass/chpass.c b/usr.bin/chpass/chpass.c
index 086413d..bba8b3d 100644
--- a/usr.bin/chpass/chpass.c
+++ b/usr.bin/chpass/chpass.c
@@ -40,7 +40,7 @@ static char copyright[] =
#ifndef lint
static char sccsid[] = "From: @(#)chpass.c 8.4 (Berkeley) 4/2/94";
static char rcsid[] =
- "$Id: chpass.c,v 1.2 1995/01/14 23:14:25 wollman Exp $";
+ "$Id: chpass.c,v 1.3 1995/05/30 06:29:36 rgrimes Exp $";
#endif /* not lint */
#include <sys/param.h>
@@ -62,6 +62,9 @@ static char rcsid[] =
#include <pw_scan.h>
#include <pw_util.h>
#include "pw_copy.h"
+#ifdef YP
+#include "pw_yp.h"
+#endif
#include "chpass.h"
#include "pathnames.h"
@@ -122,7 +125,6 @@ main(argc, argv)
default:
usage();
}
-
if (op == NEWSH) {
/* protect p_shell -- it thinks NULL is /bin/sh */
if (!arg[0])
@@ -149,6 +151,23 @@ main(argc, argv)
pw->pw_passwd = arg;
}
+#ifdef YP
+ /*
+ * XXX The man page says the data returned by getpwent()
+ * and friends is stored in static buffers that may be
+ * overwritten after successive invokations. Unfortunately,
+ * we need to call getpwent() more than once with NIS
+ * enabled.
+ */
+ pw->pw_name = strdup(pw->pw_name);
+ pw->pw_passwd = strdup(pw->pw_passwd);
+ pw->pw_class = strdup(pw->pw_class);
+ pw->pw_gecos = strdup(pw->pw_gecos);
+ pw->pw_shell = strdup(pw->pw_shell);
+ pw->pw_dir = strdup(pw->pw_dir);
+ _use_yp = use_yp(pw->pw_name);
+#endif /* YP */
+
/*
* The temporary file/file descriptor usage is a little tricky here.
* 1: We start off with two fd's, one for the master password
@@ -185,10 +204,19 @@ main(argc, argv)
tfd = pw_tmp();
}
+#ifdef YP
+ if (_use_yp) {
+ yp_submit(pw);
+ (void)unlink(tempname);
+ } else {
+#endif /* YP */
pw_copy(pfd, tfd, pw);
if (!pw_mkdb())
pw_error((char *)NULL, 0, 1);
+#ifdef YP
+ }
+#endif /* YP */
exit(0);
}
diff --git a/usr.bin/chpass/edit.c b/usr.bin/chpass/edit.c
index 612cb4a..c0f61e0 100644
--- a/usr.bin/chpass/edit.c
+++ b/usr.bin/chpass/edit.c
@@ -52,6 +52,9 @@ static char sccsid[] = "@(#)edit.c 8.3 (Berkeley) 4/2/94";
#include <pw_util.h>
#include "chpass.h"
+#ifdef YP
+#include "pw_yp.h"
+#endif /* YP */
extern char *tempname;
@@ -94,8 +97,13 @@ display(fd, pw)
pw_error(tempname, 1, 1);
(void)fprintf(fp,
- "#Changing user database information for %s.\n", pw->pw_name);
+#ifdef YP
+ "#Changing %s information for %s.\n", _use_yp ? "NIS" : "user database", pw->pw_name);
+ if (!uid && !_use_yp) {
+#else
+ "#Changing user database information for %s.\n", pw->pw_name)
if (!uid) {
+#endif /* YP */
(void)fprintf(fp, "Login: %s\n", pw->pw_name);
(void)fprintf(fp, "Password: %s\n", pw->pw_passwd);
(void)fprintf(fp, "Uid [#]: %d\n", pw->pw_uid);
diff --git a/usr.bin/chpass/pw_copy.c b/usr.bin/chpass/pw_copy.c
index 3db04ed..4a1d9a5 100644
--- a/usr.bin/chpass/pw_copy.c
+++ b/usr.bin/chpass/pw_copy.c
@@ -96,6 +96,14 @@ pw_copy(ffd, tfd, pw)
goto err;
}
if (!done)
+#ifdef YP
+ /* Ultra paranoid: shouldn't happen. */
+ if (getuid()) {
+ warnx("%s: not found in %s -- permission denied",
+ pw->pw_name, _PATH_MASTERPASSWD);
+ pw_error(NULL, 0, 1);
+ } else
+#endif /* YP */
(void)fprintf(to, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n",
pw->pw_name, pw->pw_passwd, pw->pw_uid, pw->pw_gid,
pw->pw_class, pw->pw_change, pw->pw_expire, pw->pw_gecos,
diff --git a/usr.bin/chpass/pw_yp.c b/usr.bin/chpass/pw_yp.c
new file mode 100644
index 0000000..6fd87f5
--- /dev/null
+++ b/usr.bin/chpass/pw_yp.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 1995
+ * Bill Paul <wpaul@ctr.columbia.edu>. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 THE REGENTS 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.
+ *
+ * NIS interface routines for chpass
+ *
+ * Written by Bill Paul <wpaul@ctr.columbia.edu>
+ * Center for Telecommunications Research
+ * Columbia University, New York City
+ *
+ * $Id$
+ */
+
+#ifdef YP
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+#include <time.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <errno.h>
+#include <err.h>
+#include <unistd.h>
+#include <db.h>
+#include <fcntl.h>
+#include <utmp.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <limits.h>
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#include <rpcsvc/yppasswd.h>
+#include <pw_util.h>
+#include "pw_yp.h"
+
+#define PERM_SECURE (S_IRUSR|S_IWUSR)
+HASHINFO openinfo = {
+ 4096, /* bsize */
+ 32, /* ffactor */
+ 256, /* nelem */
+ 2048 * 1024, /* cachesize */
+ NULL, /* hash */
+ 0, /* lorder */
+};
+
+int _use_yp = 0;
+
+/*
+ * Check if the user we're working with is local or in NIS.
+ */
+int use_yp (user)
+char *user;
+{
+ int yp_enabled = 0, user_not_local = 0, exists = 0;
+ DB *dbp;
+ DBT key,data;
+ char bf[UT_NAMESIZE + 2];
+
+ if ((dbp = dbopen(_PATH_MP_DB, O_RDONLY, PERM_SECURE,
+ DB_HASH, &openinfo)) == NULL)
+ errx(1, "error opening database: %s.", _PATH_MP_DB);
+ bf[0] = _PW_KEYYPENABLED;
+ key.data = (u_char *)bf;
+ key.size = 1;
+ if (!(dbp->get)(dbp,&key,&data,0))
+ yp_enabled = 1;
+
+ bf[0] = _PW_KEYBYNAME;
+ bcopy((char *)user, bf + 1, MIN(strlen(user), UT_NAMESIZE));
+ key.data = (u_char *)bf;
+ key.size = strlen(user) + 1;
+ if ((dbp->get)(dbp,&key,&data,0))
+ user_not_local = 1;
+
+ (dbp->close)(dbp);
+
+ if (getpwnam(user) != NULL)
+ exists = 1;
+
+ if (yp_enabled && user_not_local && exists)
+ return(1);
+ else
+ return(0);
+}
+
+/*
+ * Find the name of the NIS master server for this domain
+ * and make sure it's running yppasswdd.
+ */
+static char *get_yp_master(void)
+{
+ char *domain, *mastername;
+ int rval;
+
+ /* Get default NIS domain. */
+
+ if ((rval = yp_get_default_domain(&domain))) {
+ warnx("can't get local NIS domain name: %s",yperr_string(rval));
+ pw_error(NULL, 0, 1);
+ }
+
+ /* Get master server of passwd map. */
+
+ if ((rval = yp_master(domain, "passwd.byname", &mastername))) {
+ warnx("can't get master NIS server: %s", yperr_string(rval));
+ pw_error(NULL, 0, 1);
+ }
+
+ /* Check if yppasswdd is out there. */
+
+ if ((rval = getrpcport(mastername, YPPASSWDPROG, YPPASSWDPROC_UPDATE,
+ IPPROTO_UDP)) == 0) {
+ warnx("yppasswdd not running on NIS master server");
+ pw_error(NULL, 0, 1);
+ }
+
+ /*
+ * Make sure it's on a reserved port.
+ * XXX Might break with yppasswdd servers running on Solaris 2.x.
+ */
+
+ if (rval >= IPPORT_RESERVED) {
+ warnx("yppasswdd server not running on reserved port");
+ pw_error(NULL, 0, 1);
+ }
+
+ /* Everything checks out: return the name of the server. */
+
+ return (mastername);
+}
+/*
+ * Ask the user for his NIS password and submit the new information
+ * to yppasswdd. Note that yppasswdd requires password authentication
+ * and only allows changes to existing records rather than the addition
+ * of new records. (To do actual updates we would need something like
+ * secure RPC and ypupdated, which FreeBSD doesn't have yet.) This means
+ * that the superuser cannot use chpass(1) to add new users records to
+ * the NIS password database.
+ */
+void yp_submit(pw)
+struct passwd *pw;
+{
+ struct yppasswd yppasswd;
+ CLIENT *clnt;
+ char *master, *password, *encpass;
+ int rval, status = 0;
+ struct timeval tv;
+
+ /* Populate the yppasswd structure that gets handed to yppasswdd. */
+ /*
+ * XXX This is done first to work around what looks like a very
+ * strange memory corruption bug: the text fields pointed to
+ * by the members of the 'pw' structure appear to be clobbered
+ * after get_yp_master() returns (in particular, it happens
+ * during getrpcport()). I don't know exactly where the problem
+ * lies: I traced it all the way to gethostbyname(), then gave
+ * up.
+ */
+ yppasswd.newpw.pw_passwd = strdup(pw->pw_passwd);
+ yppasswd.newpw.pw_name = strdup(pw->pw_name);
+ yppasswd.newpw.pw_uid = pw->pw_uid;
+ yppasswd.newpw.pw_gid = pw->pw_gid;
+ yppasswd.newpw.pw_gecos = strdup(pw->pw_gecos);
+ yppasswd.newpw.pw_dir = strdup(pw->pw_dir);
+ yppasswd.newpw.pw_shell = strdup(pw->pw_shell);
+
+ /* Get NIS master server name */
+
+ master = get_yp_master();
+
+ /* Get the user's password for authentication purposes. */
+
+ printf ("Changing NIS information for %s on %s\n",
+ yppasswd.newpw.pw_name, master);
+ encpass = (getpwnam(yppasswd.newpw.pw_name))->pw_passwd;
+ password = getpass("Please enter password: ");
+ if (strncmp(crypt(password, encpass), encpass, strlen(encpass))) {
+ warnx("Password incorrect.");
+ pw_error(NULL, 0, 1);
+ }
+
+ yppasswd.oldpass = password; /* XXX */
+
+ /* Create a handle to yppasswdd. */
+
+ clnt = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp");
+ clnt->cl_auth = authunix_create_default();
+
+ /* Set a timeout and make the RPC call. */
+
+ tv.tv_sec = 20;
+ tv.tv_usec = 0;
+ rval = clnt_call(clnt, YPPASSWDPROC_UPDATE, xdr_yppasswd,
+ (char *)&yppasswd, xdr_int, (char *)&status, &tv);
+
+ /* Call failed: signal the error. */
+
+ if (rval) {
+ warnx("NIS update failed: %s", clnt_sperrno(rval));
+ pw_error(NULL, 0, 1);
+ }
+
+ /* Success. */
+
+ auth_destroy(clnt->cl_auth);
+ clnt_destroy(clnt);
+ warnx("NIS information changed on host %s", master);
+
+ return;
+}
+#endif /* YP */
diff --git a/usr.bin/chpass/pw_yp.h b/usr.bin/chpass/pw_yp.h
new file mode 100644
index 0000000..94c7a74
--- /dev/null
+++ b/usr.bin/chpass/pw_yp.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1995
+ * Bill Paul <wpaul@ctr.columbia.edu>. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 THE REGENTS 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.
+ *
+ * NIS interface routines for chpass
+ *
+ * Written by Bill Paul <wpaul@ctr.columbia.edu>
+ * Center for Telecommunications Research
+ * Columbia University, New York City
+ *
+ * $Id$
+ */
+
+#ifdef YP
+extern int _use_yp;
+void yp_submit __P(( struct passwd * ));
+int use_yp __P(( char * ));
+#endif /* YP */
OpenPOWER on IntegriCloud