1995-01-31 09:12:52 +00:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
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)
|
|
|
|
{
|
1995-02-01 23:27:46 +00:00
|
|
|
fprintf (fp, "usage: %s [-m master password file] [-f] [-s] [-h] [-v]\n", program_name );
|
1995-01-31 09:12:52 +00:00
|
|
|
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;
|
1995-02-01 23:27:46 +00:00
|
|
|
while ((c = getopt(argc, argv, "m:fshv")) != EOF)
|
1995-01-31 09:12:52 +00:00
|
|
|
switch (c) {
|
|
|
|
case 'm':
|
|
|
|
passfile = 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;
|
|
|
|
}
|
|
|
|
|