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*
This commit is contained in:
Bill Paul 1995-01-31 09:12:52 +00:00
parent b4a640674a
commit 6c394ac5f9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=6070
8 changed files with 897 additions and 0 deletions

View File

@ -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>

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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_

View File

@ -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);
}

View File

@ -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)

View File

@ -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;
}