summaryrefslogtreecommitdiffstats
path: root/gnu/usr.sbin
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>1995-01-31 09:12:52 +0000
committerwpaul <wpaul@FreeBSD.org>1995-01-31 09:12:52 +0000
commit12d39161b860798ddc4628d4e252990024addeba (patch)
tree43a2d00efe05e2a2b93c406604826242afc26879 /gnu/usr.sbin
parentc46e35fcb4e90029a89425459e0c331cfcd0050b (diff)
downloadFreeBSD-src-12d39161b860798ddc4628d4e252990024addeba.zip
FreeBSD-src-12d39161b860798ddc4628d4e252990024addeba.tar.gz
Obtained from: The NYS project
This is a ported/modified version of yppasswd from the NYS yppasswd-0.5 package. This package has code in it from both Olaf Kirch and Theo de Raadt. There are GPL references and BSD-style copyright all over the place... hopefully I won't get flamed into oblivion for commiting this. This program has been modified from the original in the following ways: - Changed the ALLOW_CHFN and ALLOW_CHSH compile-time options into run-time options. - Demolished the password update functions and replaced them with routines to handle FreeBSD-style passwordd databases. It is expected that a seperate master.passwd file will be maintained for use with the NIS maps. yppasswd will have to be told where it is: % yppasswdd -m /var/yp/master.passwd A /var/yp/passwd file will be generated from /var/yp/master.passwd by /var/yp/Makefile. When yppasswdd has finished modifying the master.passwd file, it will invoke /usr/libexec/yppwupdate, which is a script that will run /var/yp/Makefile to generate new maps and push them. Note that there are copies if pw_util.c and pw_copy.c here. This is deliberate: they are *not* identical to the originals. Very similar, yes, but not identical. *sigh*
Diffstat (limited to 'gnu/usr.sbin')
-rw-r--r--gnu/usr.sbin/yppasswdd/Makefile16
-rw-r--r--gnu/usr.sbin/yppasswdd/pw_copy.c108
-rw-r--r--gnu/usr.sbin/yppasswdd/pw_util.c206
-rw-r--r--gnu/usr.sbin/yppasswdd/update.c156
-rw-r--r--gnu/usr.sbin/yppasswdd/yppasswd.h57
-rw-r--r--gnu/usr.sbin/yppasswdd/yppasswd_xdr.c57
-rw-r--r--gnu/usr.sbin/yppasswdd/yppasswdd.892
-rw-r--r--gnu/usr.sbin/yppasswdd/yppasswdd.c205
8 files changed, 897 insertions, 0 deletions
diff --git a/gnu/usr.sbin/yppasswdd/Makefile b/gnu/usr.sbin/yppasswdd/Makefile
new file mode 100644
index 0000000..115c217
--- /dev/null
+++ b/gnu/usr.sbin/yppasswdd/Makefile
@@ -0,0 +1,16 @@
+# @(#)Makefile 8.3 (Berkeley) 4/2/94
+
+PROG= yppasswdd
+MAN8= yppasswdd.8
+
+SRCS= yppasswdd.c yppasswd_xdr.c update.c pw_copy.c pw_util.c
+
+LDADD= -lcrypt
+CFLAGS+=-DCRYPT -I${.CURDIR} -I${.CURDIR}/../../../usr.sbin/vipw \
+ -I${.CURDIR}/../../../usr.bin/chpass
+CFLAGS+=-DVERSION=\"0.5\" -DYPLIBDIR=\"/usr/libexec\" -D_GNU_SOURCE
+
+BINOWN= bin
+BINMODE=555
+
+.include <bsd.prog.mk>
diff --git a/gnu/usr.sbin/yppasswdd/pw_copy.c b/gnu/usr.sbin/yppasswdd/pw_copy.c
new file mode 100644
index 0000000..8eea0cd
--- /dev/null
+++ b/gnu/usr.sbin/yppasswdd/pw_copy.c
@@ -0,0 +1,108 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. 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 the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)pw_copy.c 8.4 (Berkeley) 4/2/94";
+#endif /* not lint */
+
+/*
+ * This module is used to copy the master password file, replacing a single
+ * record, by chpass(1) and passwd(1).
+ */
+
+#include <err.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <pw_util.h>
+#include "pw_copy.h"
+
+extern char *tempname;
+extern char *passfile;
+
+void
+pw_copy(ffd, tfd, pw)
+ int ffd, tfd;
+ struct passwd *pw;
+{
+ FILE *from, *to;
+ int done;
+ char *p, buf[8192];
+
+ if (!(from = fdopen(ffd, "r")))
+ pw_error(passfile, 1, 1);
+ if (!(to = fdopen(tfd, "w")))
+ pw_error(tempname, 1, 1);
+
+ for (done = 0; fgets(buf, sizeof(buf), from);) {
+ if (!strchr(buf, '\n')) {
+ warnx("%s: line too long", passfile);
+ pw_error(NULL, 0, 1);
+ }
+ if (done) {
+ (void)fprintf(to, "%s", buf);
+ if (ferror(to))
+ goto err;
+ continue;
+ }
+ if (!(p = strchr(buf, ':'))) {
+ warnx("%s: corrupted entry", passfile);
+ pw_error(NULL, 0, 1);
+ }
+ *p = '\0';
+ if (strcmp(buf, pw->pw_name)) {
+ *p = ':';
+ (void)fprintf(to, "%s", buf);
+ if (ferror(to))
+ goto err;
+ continue;
+ }
+ (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,
+ pw->pw_dir, pw->pw_shell);
+ done = 1;
+ if (ferror(to))
+ goto err;
+ }
+ if (!done)
+ (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,
+ pw->pw_dir, pw->pw_shell);
+
+ if (ferror(to))
+err: pw_error(NULL, 1, 1);
+ (void)fclose(to);
+}
diff --git a/gnu/usr.sbin/yppasswdd/pw_util.c b/gnu/usr.sbin/yppasswdd/pw_util.c
new file mode 100644
index 0000000..9ca2d16
--- /dev/null
+++ b/gnu/usr.sbin/yppasswdd/pw_util.c
@@ -0,0 +1,206 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. 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 the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)pw_util.c 8.3 (Berkeley) 4/2/94";
+#endif /* not lint */
+
+/*
+ * This file is used by all the "password" programs; vipw(8), chpass(1),
+ * and passwd(1).
+ */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "pw_util.h"
+
+extern char *tempname;
+extern char *passfile;
+
+void
+pw_init()
+{
+ struct rlimit rlim;
+
+ /* Unlimited resource limits. */
+ rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
+ (void)setrlimit(RLIMIT_CPU, &rlim);
+ (void)setrlimit(RLIMIT_FSIZE, &rlim);
+ (void)setrlimit(RLIMIT_STACK, &rlim);
+ (void)setrlimit(RLIMIT_DATA, &rlim);
+ (void)setrlimit(RLIMIT_RSS, &rlim);
+
+ /* Don't drop core (not really necessary, but GP's). */
+ rlim.rlim_cur = rlim.rlim_max = 0;
+ (void)setrlimit(RLIMIT_CORE, &rlim);
+
+ /* Turn off signals. */
+ (void)signal(SIGALRM, SIG_IGN);
+ (void)signal(SIGHUP, SIG_IGN);
+ (void)signal(SIGINT, SIG_IGN);
+ (void)signal(SIGPIPE, SIG_IGN);
+ (void)signal(SIGQUIT, SIG_IGN);
+ (void)signal(SIGTERM, SIG_IGN);
+ (void)signal(SIGTSTP, SIG_IGN);
+ (void)signal(SIGTTOU, SIG_IGN);
+
+ /* Create with exact permissions. */
+ (void)umask(0);
+}
+
+static int lockfd;
+
+int
+pw_lock()
+{
+ /*
+ * If the master password file doesn't exist, the system is hosed.
+ * Might as well try to build one. Set the close-on-exec bit so
+ * that users can't get at the encrypted passwords while editing.
+ * Open should allow flock'ing the file; see 4.4BSD. XXX
+ */
+ lockfd = open(passfile, O_RDONLY, 0);
+ if (lockfd < 0 || fcntl(lockfd, F_SETFD, 1) == -1)
+ err(1, "%s", passfile);
+ if (flock(lockfd, LOCK_EX|LOCK_NB))
+ errx(1, "the password db file is busy");
+ return (lockfd);
+}
+
+int
+pw_tmp()
+{
+ static char path[MAXPATHLEN];
+ int fd;
+ char *p;
+
+ sprintf(path,"%s",passfile);
+ if (p = strrchr(path, '/'))
+ ++p;
+ else
+ p = path;
+ strcpy(p, "pw.XXXXXX");
+ if ((fd = mkstemp(path)) == -1)
+ err(1, "%s", path);
+ tempname = path;
+ return (fd);
+}
+
+int
+pw_mkdb()
+{
+ int pstat;
+ pid_t pid;
+
+ warnx("rebuilding the database...");
+ (void)fflush(stderr);
+ if (!(pid = vfork())) {
+ execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", tempname, NULL);
+ pw_error(_PATH_PWD_MKDB, 1, 1);
+ }
+ pid = waitpid(pid, &pstat, 0);
+ if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0)
+ return (0);
+ warnx("done");
+ return (1);
+}
+
+void
+pw_edit(notsetuid)
+ int notsetuid;
+{
+ int pstat;
+ pid_t pid;
+ char *p, *editor;
+
+ if (!(editor = getenv("EDITOR")))
+ editor = _PATH_VI;
+ if (p = strrchr(editor, '/'))
+ ++p;
+ else
+ p = editor;
+
+ if (!(pid = vfork())) {
+ if (notsetuid) {
+ (void)setgid(getgid());
+ (void)setuid(getuid());
+ }
+ execlp(editor, p, tempname, NULL);
+ _exit(1);
+ }
+ pid = waitpid(pid, (int *)&pstat, 0);
+ if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0)
+ pw_error(editor, 1, 1);
+}
+
+void
+pw_prompt()
+{
+ int c;
+
+ (void)printf("re-edit the password file? [y]: ");
+ (void)fflush(stdout);
+ c = getchar();
+ if (c != EOF && c != '\n')
+ while (getchar() != '\n');
+ if (c == 'n')
+ pw_error(NULL, 0, 0);
+}
+
+void
+pw_error(name, err, eval)
+ char *name;
+ int err, eval;
+{
+ if (err)
+ warn(name);
+
+ warnx("%s: unchanged", passfile);
+ (void)unlink(tempname);
+ exit(eval);
+}
diff --git a/gnu/usr.sbin/yppasswdd/update.c b/gnu/usr.sbin/yppasswdd/update.c
new file mode 100644
index 0000000..69bad95
--- /dev/null
+++ b/gnu/usr.sbin/yppasswdd/update.c
@@ -0,0 +1,156 @@
+/*
+ * yppasswdd
+ * Copyright 1994 Olaf Kirch, <okir@monad.swb.de>
+ *
+ * This program is covered by the GNU General Public License, version 2.
+ * It is provided in the hope that it is useful. However, the author
+ * disclaims ALL WARRANTIES, expressed or implied. See the GPL for details.
+ */
+
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <time.h>
+#include <pwd.h>
+
+#include <syslog.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+#include "yppasswd.h"
+
+char *tempname;
+extern char *passfile, *opassfile;
+extern int *allow_chfn, *allow_chsh;
+
+#define xprt_addr(xprt) (svc_getcaller(xprt)->sin_addr)
+#define xprt_port(xprt) ntohs(svc_getcaller(xprt)->sin_port)
+void reaper( int sig );
+
+/*===============================================================*
+ * Argument validation. Avoid \n... (ouch).
+ * We can't use isprint, because people may use 8bit chars which
+ * aren't recognized as printable in the default locale.
+ *===============================================================*/
+static int
+validate_string(char *str)
+{
+ while (*str && !iscntrl(*str)) str++;
+ return (*str == '\0');
+}
+
+static int
+validate_args(struct xpasswd *pw)
+{
+ return validate_string(pw->pw_passwd)
+ && validate_string(pw->pw_shell)
+ && validate_string(pw->pw_gecos);
+}
+
+/*===============================================================*
+ * The passwd update handler
+ *===============================================================*/
+int *
+yppasswdproc_pwupdate_1(yppasswd *yppw, struct svc_req *rqstp)
+{
+ struct xpasswd *newpw; /* passwd struct passed by the client */
+ struct passwd *pw; /* passwd struct obtained from getpwent() */
+ int chsh = 0, chfn = 0;
+ static int res;
+ char logbuf[255];
+ int pfd, tfd, c;
+
+ newpw = &yppw->newpw;
+ res = 1;
+
+ sprintf( logbuf, "update %.12s (uid=%d) from host %s",
+ yppw->newpw.pw_name,
+ yppw->newpw.pw_uid,
+ inet_ntoa(xprt_addr(rqstp->rq_xprt)));
+
+ if (!validate_args(newpw)) {
+ syslog ( LOG_ALERT, "%s failed", logbuf );
+ syslog ( LOG_ALERT, "Invalid characters in argument. "
+ "Possible spoof attempt?" );
+ return &res;
+ }
+
+ pw_init();
+ pfd = pw_lock();
+ tfd = pw_tmp();
+
+ /* Check if the user exists
+ */
+ if (!(pw = getpwnam(yppw->newpw.pw_name))) {
+ syslog ( LOG_WARNING, "%s failed", logbuf );
+ syslog ( LOG_WARNING, "User not in password file." );
+ return (&res);
+ }
+
+ /* Check the password.
+ */
+ if (strcmp(crypt(yppw->oldpass, pw->pw_passwd), pw->pw_passwd)) {
+ syslog ( LOG_WARNING, "%s rejected", logbuf );
+ syslog ( LOG_WARNING, "Invalid password." );
+ sleep(1);
+ return(&res);
+ }
+
+ /* set the new passwd, shell, and full name
+ */
+ pw->pw_passwd = newpw->pw_passwd;
+
+ if (allow_chsh) {
+ chsh = (strcmp(pw->pw_shell, newpw->pw_shell) != 0);
+ pw->pw_shell = newpw->pw_shell;
+ }
+
+ if (allow_chfn) {
+ chfn = (strcmp(pw->pw_gecos, newpw->pw_gecos) != 0);
+ pw->pw_gecos = newpw->pw_gecos;
+ }
+
+ pw->pw_change = 0;
+ pw_copy(pfd, tfd, pw);
+ if (strcmp(passfile, _PATH_MASTERPASSWD)) {
+ close(pfd);
+ close(tfd);
+ rename(tempname,passfile);
+ }
+ else
+ if (pw_mkdb()) {
+ syslog ( LOG_WARNING, "%s failed to rebuild password database", logbuf );
+ return(&res);
+ }
+
+ /* Fork off process to rebuild NIS passwd.* maps. If the fork
+ * fails, restore old passwd file and return an error.
+ */
+ if ((c = fork()) < 0) {
+ syslog( LOG_ERR, "%s failed", logbuf );
+ syslog( LOG_ERR, "Couldn't fork map update process: %m" );
+ return (&res);
+ }
+ if (c == 0) {
+ execlp(MAP_UPDATE_PATH, MAP_UPDATE, NULL);
+ syslog( LOG_ERR, "Error: couldn't exec map update process: %m" );
+ exit(1);
+ }
+
+ syslog ( LOG_INFO, "%s successful. Password changed.", logbuf );
+ if (chsh || chfn) {
+ syslog ( LOG_INFO, "Shell %schanged (%s), GECOS %schanged (%s).",
+ chsh? "" : "un", newpw->pw_shell,
+ chfn? "" : "un", newpw->pw_gecos );
+ }
+ res = 0;
+
+ return (&res);
+}
diff --git a/gnu/usr.sbin/yppasswdd/yppasswd.h b/gnu/usr.sbin/yppasswdd/yppasswd.h
new file mode 100644
index 0000000..fb85d86
--- /dev/null
+++ b/gnu/usr.sbin/yppasswdd/yppasswd.h
@@ -0,0 +1,57 @@
+/*
+ * yppasswdd
+ * Copyright 1994 Olaf Kirch, <okir@monad.swb.de>
+ *
+ * This program is covered by the GNU General Public License, version 2.
+ * It is provided in the hope that it is useful. However, the author
+ * disclaims ALL WARRANTIES, expressed or implied. See the GPL for details.
+ *
+ * This file was generated automatically by rpcgen from yppasswd.x, and
+ * editied manually.
+ */
+
+#ifndef _YPPASSWD_H_
+#define _YPPASSWD_H_
+
+#define YPPASSWDPROG ((u_long)100009)
+#define YPPASSWDVERS ((u_long)1)
+#define YPPASSWDPROC_UPDATE ((u_long)1)
+
+/*
+ * The password struct passed by the update call. I renamed it to
+ * xpasswd to avoid a type clash with the one defined in <pwd.h>.
+ */
+typedef struct xpasswd {
+ char *pw_name;
+ char *pw_passwd;
+ int pw_uid;
+ int pw_gid;
+ char *pw_gecos;
+ char *pw_dir;
+ char *pw_shell;
+} xpasswd;
+
+/* The updated password information, plus the old password.
+ */
+typedef struct yppasswd {
+ char *oldpass;
+ xpasswd newpw;
+} yppasswd;
+
+/* XDR encoding/decoding routines */
+bool_t xdr_xpasswd (XDR *xdrs, xpasswd *objp);
+bool_t xdr_yppasswd(XDR *xdrs, yppasswd *objp);
+
+/* The server procedure invoked by the main loop. */
+void yppasswdprog_1(struct svc_req *rqstp, SVCXPRT *transp);
+
+/* Password update handler. */
+int * yppasswdproc_pwupdate_1(yppasswd *yppw, struct svc_req *rqstp);
+
+/* This command is forked to rebuild the NIS maps after a successful
+ * update. MAP_UPDATE is used as argv[0].
+ */
+#define MAP_UPDATE "yppwupdate"
+#define MAP_UPDATE_PATH YPLIBDIR "/yppwupdate"
+
+#endif _YPPASSWD_H_
diff --git a/gnu/usr.sbin/yppasswdd/yppasswd_xdr.c b/gnu/usr.sbin/yppasswdd/yppasswd_xdr.c
new file mode 100644
index 0000000..30b55c2
--- /dev/null
+++ b/gnu/usr.sbin/yppasswdd/yppasswd_xdr.c
@@ -0,0 +1,57 @@
+/*
+ * yppasswdd
+ * Copyright 1994 Olaf Kirch, <okir@monad.swb.de>
+ *
+ * This program is covered by the GNU General Public License, version 2.
+ * It is provided in the hope that it is useful. However, the author
+ * disclaims ALL WARRANTIES, expressed or implied. See the GPL for details.
+ *
+ * This file was generated automatically by rpcgen from yppasswd.x, and
+ * editied manually.
+ */
+
+#include <rpc/rpc.h>
+#include "yppasswd.h"
+
+
+bool_t
+xdr_xpasswd(XDR *xdrs, xpasswd *objp)
+{
+ if (!xdr_string(xdrs, &objp->pw_name, ~0)) {
+ return (FALSE);
+ }
+ if (!xdr_string(xdrs, &objp->pw_passwd, ~0)) {
+ return (FALSE);
+ }
+ if (!xdr_int(xdrs, &objp->pw_uid)) {
+ return (FALSE);
+ }
+ if (!xdr_int(xdrs, &objp->pw_gid)) {
+ return (FALSE);
+ }
+ if (!xdr_string(xdrs, &objp->pw_gecos, ~0)) {
+ return (FALSE);
+ }
+ if (!xdr_string(xdrs, &objp->pw_dir, ~0)) {
+ return (FALSE);
+ }
+ if (!xdr_string(xdrs, &objp->pw_shell, ~0)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
+bool_t
+xdr_yppasswd(XDR *xdrs, yppasswd *objp)
+{
+ if (!xdr_string(xdrs, &objp->oldpass, ~0)) {
+ return (FALSE);
+ }
+ if (!xdr_xpasswd(xdrs, &objp->newpw)) {
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+
diff --git a/gnu/usr.sbin/yppasswdd/yppasswdd.8 b/gnu/usr.sbin/yppasswdd/yppasswdd.8
new file mode 100644
index 0000000..24e3dda
--- /dev/null
+++ b/gnu/usr.sbin/yppasswdd/yppasswdd.8
@@ -0,0 +1,92 @@
+.\"
+.\" Copyright 1994 Olaf Kirch, <okir@monad.swb.de>
+.\"
+.\" This program is covered by the GNU General Public License, version 2.
+.\" It is provided in the hope that it is useful. However, the author
+.\" disclaims ALL WARRANTIES, expressed or implied. See the GPL for details.
+.\"
+.TH YPPASSWDD 8 "12 December 1994" "" ""
+.SH NAME
+rpc.yppasswdd \- NIS password update server
+.SH SYNOPSIS
+.B "rpc.yppasswdd [-s]"
+.SH DESCRIPTION
+\fByppasswdd\fP is the RPC server that lets users change their passwords
+in the presence of NIS (a.k.a. YP). It must be run on the NIS master
+server for that NIS domain.
+.P
+When a \fByppasswd(1)\fP client contacts the server, it sends the old user
+password along with the new one. \fByppasswdd\fP will search the system's
+\fB/etc/passwd\fP file for the specified user name, verify that the
+given (old) password matches, and update the entry. If the user
+specified does not exist, or if the password, UID or GID doesn't match
+the information in the password file, the update request is rejected,
+and an error returned to the client.
+.P
+After updating the \fBpasswd\fP file and returning a success notification
+to the client, \fByppasswdd\fP executes the \fBpwupdate\fP script that
+updates the NIS server's \fBpasswd.*\fP maps. This script assumes all
+NIS maps are kept in directories named
+.BI /var/yp/< nisdomain >
+that each contain a \fBMakefile\fP customized for that NIS domain.
+.SH OPTIONS
+The following options are available with \fByppasswdd\fP:
+.IP "\-s"
+When \fByppasswdd\fP is compiled with support for John\ F. Haugh's shadow
+library, this option makes the server use the password functions from the
+\fBlibshadow\fP library instead of the standard ones. See below for a
+brief discussion of shadow support.
+.SH MISCELLANEOUS
+.SS Shadow Passwords
+Using Shadow passwords alongside NIS does not make too much sense, because
+the supposedly inaccesible passwords now become readable through a simple
+invocation of \fBypcat(8)\fP.
+.P
+Shadow support in \fByppasswdd\fP does not mean that it offers a very
+clever solution to this problem, it simply means that it can read and write
+password entries in \fB/etc/shadow\fP. You still have to produce a normal
+NIS map to distribute password information to your NIS clients.
+The \fByp.pwupdate\fP script supplied with
+\fByppasswdd\fP creates a standard \fB/etc/passwd\fP file from
+\fP/etc/shadow\fP using \fBpwunconv(8)\fP and produces the NIS maps from
+that.
+.SS Logging
+\fByppasswdd\fP logs all password update requests to \fBsyslogd(8)\fP's
+auth facility. The logging information includes the originating host's
+IP address and the user name and UID contained in the request. The
+user-supplied password itself is not logged.
+.SS Security
+Unless I've screwed up completely (as I did with versions prior to
+version\ 0.5), \fByppasswdd\fP should be as secure or insecure as any
+program relying on simple password authentication. If you feel that
+this is not enough, you may want to protect \fByppasswdd\fP from outside
+access by using the `securenets' feature of the new \fBportmap(8)\fP
+version\ 3. Better still, use Kerberos.
+.SH COPYRIGHT
+\fByppasswdd\fP is copyright (C) Olaf Kirch. You can use and distribute it
+under the GNU General Public License Version 2. Note that it does \fInot\fP
+contain any code from the shadow password suite. This means that as long as
+you don't use shadow passwords, you won't be affected by the ``no commercial
+use'' policy of the shadow suite.
+.SH FILES
+\fB/usr/sbin/rpc.yppasswdd\fP
+.br
+\fB/usr/lib/yp/pwupdate\fP
+.br
+\fB/etc/passwd\fP
+.br
+\fB/etc/shadow\fP
+.SH SEE ALSO
+.IR passwd(5) ,
+.IR passwd(8) ,
+.IR portmap(8) ,
+.IR pwunconv(8) ,
+.IR yppasswd(1) ,
+.IR ypchsh(1) ,
+.IR ypchfn(1) ,
+.IR ypserv(8) ,
+.IR ypcat(8) .
+.SH AUTHOR
+Olaf Kirch, <okir@monad.swb.de>
+.br
+Charles Lopez, <tjarls@infm.ulst.ac.uk> (shadow support)
diff --git a/gnu/usr.sbin/yppasswdd/yppasswdd.c b/gnu/usr.sbin/yppasswdd/yppasswdd.c
new file mode 100644
index 0000000..1088637
--- /dev/null
+++ b/gnu/usr.sbin/yppasswdd/yppasswdd.c
@@ -0,0 +1,205 @@
+/*
+ * yppasswdd
+ * Copyright 1994 Olaf Kirch, <okir@monad.swb.de>
+ *
+ * This program is covered by the GNU General Public License, version 2.
+ * It is provided in the hope that it is useful. However, the author
+ * disclaims ALL WARRANTIES, expressed or implied. See the GPL for details.
+ */
+
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+#include <termios.h>
+#include <signal.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <stdlib.h>
+#include <syslog.h>
+#include <stdio.h>
+#include <string.h>
+#include <pwd.h>
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+#include "yppasswd.h"
+
+extern char *optarg;
+static char *program_name = "";
+static char *version = "yppsswdd " VERSION;
+char *passfile = _PATH_MASTERPASSWD;
+char *opassfile = NULL;
+int allow_chfn = 0, allow_chsh = 0;
+
+#define xprt_addr(xprt) (svc_getcaller(xprt)->sin_addr)
+#define xprt_port(xprt) ntohs(svc_getcaller(xprt)->sin_port)
+void yppasswdprog_1( struct svc_req *rqstp, SVCXPRT *transp );
+void reaper( int sig );
+
+/*==============================================================*
+ * RPC dispatch function
+ *==============================================================*/
+void
+yppasswdprog_1(struct svc_req *rqstp, SVCXPRT *transp)
+{
+ union {
+ yppasswd yppasswdproc_update_1_arg;
+ } argument;
+ char *result;
+ bool_t (*xdr_argument)(), (*xdr_result)();
+ char *(*local)();
+
+ switch (rqstp->rq_proc) {
+ case NULLPROC:
+ (void)svc_sendreply(transp, xdr_void, (char *)NULL);
+ return;
+
+ case YPPASSWDPROC_UPDATE:
+ xdr_argument = xdr_yppasswd;
+ xdr_result = xdr_int;
+ local = (char *(*)()) yppasswdproc_pwupdate_1;
+ break;
+
+ default:
+ svcerr_noproc(transp);
+ return;
+ }
+ bzero((char *)&argument, sizeof(argument));
+ if (!svc_getargs(transp, xdr_argument, &argument)) {
+ svcerr_decode(transp);
+ return;
+ }
+ result = (*local)(&argument, rqstp);
+ if (result != NULL && !svc_sendreply(transp, xdr_result, result)) {
+ svcerr_systemerr(transp);
+ }
+ if (!svc_freeargs(transp, xdr_argument, &argument)) {
+ (void)fprintf(stderr, "unable to free arguments\n");
+ exit(1);
+ }
+}
+
+static void
+usage(FILE *fp, int n)
+{
+ fprintf (fp, "usage: %s [-m master password file] [-o password file]\n [-h] [-f] [-s] [-v]\n", program_name );
+ exit(n);
+}
+
+void
+reaper( int sig )
+{
+ wait(NULL);
+}
+
+void
+install_reaper( void )
+{
+ struct sigaction act, oact;
+
+ act.sa_handler = reaper;
+ act.sa_mask = 0;
+ act.sa_flags = SA_RESTART;
+ sigaction( SIGCHLD, &act, &oact );
+}
+
+
+int
+main(int argc, char **argv)
+{
+ SVCXPRT *transp;
+ char *sp;
+ int opterr;
+ int c;
+
+ program_name = argv[0];
+ if ((sp = strrchr(program_name, '/')) != NULL) {
+ program_name = ++sp;
+ }
+
+ /* Parse the command line options and arguments. */
+ opterr = 0;
+ while ((c = getopt(argc, argv, "m:o:fshv")) != EOF)
+ switch (c) {
+ case 'm':
+ passfile = strdup(optarg);
+ break;
+ case 'o':
+ opassfile = strdup(optarg);
+ break;
+ case 'f':
+ allow_chfn = 1;
+ break;
+ case 's':
+ allow_chsh = 1;
+ break;
+ case 'h':
+ usage (stdout, 0);
+ break;
+ case 'v':
+ printf("%s\n", version);
+ exit(0);
+ case 0:
+ break;
+ case '?':
+ default:
+ usage(stderr, 1);
+ }
+
+#ifndef RPC_SVC_FG
+ /* We first fork off a child. */
+ if ((c = fork()) > 0)
+ exit(0);
+ if (c < 0) {
+ fprintf(stderr, "yppasswdd: cannot fork: %s\n", strerror(errno));
+ exit(-1);
+ }
+ /* Now we remove ourselves from the foreground. */
+ (void) close(0);
+ (void) close(1);
+ (void) close(2);
+#ifdef TIOCNOTTY
+ if ((c = open("/dev/tty", O_RDWR)) >= 0) {
+ (void) ioctl(c, TIOCNOTTY, (char *) NULL);
+ (void) close(c);
+ }
+#else
+ setsid();
+#endif
+#endif /* not RPC_SVC_FG */
+
+ /* Initialize logging.
+ */
+ openlog ( "yppasswdd", LOG_PID, LOG_AUTH );
+
+ /* Register a signal handler to reap children after they terminated
+ */
+ install_reaper();
+
+ /*
+ * Create the RPC server
+ */
+ (void)pmap_unset(YPPASSWDPROG, YPPASSWDVERS);
+
+ transp = svcudp_create(RPC_ANYSOCK);
+ if (transp == NULL) {
+ (void)fprintf(stderr, "cannot create udp service.\n");
+ exit(1);
+ }
+ if (!svc_register(transp, YPPASSWDPROG, YPPASSWDVERS, yppasswdprog_1,
+ IPPROTO_UDP)) {
+ (void)fprintf(stderr, "unable to register yppaswdd udp service.\n");
+ exit(1);
+ }
+
+ /*
+ * Run the server
+ */
+ svc_run();
+ (void)fprintf(stderr, "svc_run returned\n");
+
+ return 1;
+}
+
OpenPOWER on IntegriCloud