Import rpc.ypupdated.

This program still needs work but does compile and run. It also
needs a man page.
This commit is contained in:
Bill Paul 1997-05-28 15:47:10 +00:00
parent 51251b2b3b
commit 40a5f74d72
8 changed files with 1210 additions and 0 deletions

View File

@ -0,0 +1,35 @@
# $Id: Makefile,v 1.4 1996/06/03 04:48:32 wpaul Exp $
PROG= rpc.ypupdated
SRCS= ypupdate_prot_svc.c ypupdated_main.c \
yp_error.c update.c ypupdated_server.c \
yp_dblookup.c yp_dbwrite.c yp_dbdelete.c yp_dbupdate.c
.PATH: ${.CURDIR}/../ypserv ${.CURDIR}/../../libexec/ypxfr
RPCDIR= ${DESTDIR}/usr/include/rpcsvc
MAN8= yes
CFLAGS+= -I${.CURDIR}/../ypserv -I.
CFLAGS+= -I${.CURDIR}/../../libexec/ypxfr
#CFLAGS+= -DYP
LDADD+= -lrpcsvc
CLEANFILES= ypupdate_prot_svc.c ypupdate_prot.h
RPCGEN= rpcgen -I -C
# We need to remove the 'static' keyword from _rpcsvcstate so that
# ypupdated_main.c can see it.
ypupdate_prot_svc.c: ${RPCDIR}/ypupdate_prot.x ypupdate_prot.h
rm -f ${.TARGET}
${RPCGEN} -m ${RPCDIR}/ypupdate_prot.x | \
sed s/"static int _rpcsvcstate"/"int _rpcsvcstate"/g > ${.TARGET}
ypupdate_prot.h: ${RPCDIR}/ypupdate_prot.x
${RPCGEN} -h -o ${.TARGET} ${RPCDIR}/ypupdate_prot.x
.include <bsd.prog.mk>

View File

@ -0,0 +1,362 @@
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user or with the express written consent of
* Sun Microsystems, Inc.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
#ifndef lint
static char sccsid[] = "@(#)update.c 1.2 91/03/11 Copyr 1986 Sun Micro";
#endif
/*
* Copyright (C) 1986, 1989, Sun Microsystems, Inc.
*/
/*
* Administrative tool to add a new user to the publickey database
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <rpc/rpc.h>
#include <rpc/key_prot.h>
#ifdef YP
#include <rpcsvc/yp_prot.h>
#include <rpcsvc/ypclnt.h>
#include <sys/wait.h>
#include <netdb.h>
#endif /* YP */
#include <pwd.h>
#include <string.h>
#include <sys/resource.h>
#include <stdlib.h>
#include "ypupdated_extern.h"
#ifdef YP
#define MAXMAPNAMELEN 256
#else
#define YPOP_CHANGE 1 /* change, do not add */
#define YPOP_INSERT 2 /* add, do not change */
#define YPOP_DELETE 3 /* delete this entry */
#define YPOP_STORE 4 /* add, or change */
#endif
extern char *getpass();
extern char *malloc();
#ifdef YP
static char *basename();
static char SHELL[] = "/bin/sh";
static char YPDBPATH[]="/var/yp"; /* This is defined but not used! */
static char PKMAP[] = "publickey.byname";
static char UPDATEFILE[] = "updaters";
static char PKFILE[] = "/etc/publickey";
#endif /* YP */
#ifdef YP
static int _openchild __P(( char *, FILE **, FILE ** ));
/*
* Determine if requester is allowed to update the given map,
* and update it if so. Returns the yp status, which is zero
* if there is no access violation.
*/
mapupdate(requester, mapname, op, keylen, key, datalen, data)
char *requester;
char *mapname;
u_int op;
u_int keylen;
char *key;
u_int datalen;
char *data;
{
char updater[MAXMAPNAMELEN + 40];
FILE *childargs;
FILE *childrslt;
#ifdef WEXITSTATUS
int status;
#else
union wait status;
#endif
pid_t pid;
u_int yperrno;
#ifdef DEBUG
printf("%s %s\n", key, data);
#endif
(void)sprintf(updater, "make -s -f %s/%s %s", YPDBPATH, /* !!! */
UPDATEFILE, mapname);
pid = _openchild(updater, &childargs, &childrslt);
if (pid < 0) {
return (YPERR_YPERR);
}
/*
* Write to child
*/
(void)fprintf(childargs, "%s\n", requester);
(void)fprintf(childargs, "%u\n", op);
(void)fprintf(childargs, "%u\n", keylen);
(void)fwrite(key, (int)keylen, 1, childargs);
(void)fprintf(childargs, "\n");
(void)fprintf(childargs, "%u\n", datalen);
(void)fwrite(data, (int)datalen, 1, childargs);
(void)fprintf(childargs, "\n");
(void)fclose(childargs);
/*
* Read from child
*/
(void)fscanf(childrslt, "%d", &yperrno);
(void)fclose(childrslt);
(void)wait(&status);
#ifdef WEXITSTATUS
if (WEXITSTATUS(status) != 0) {
#else
if (status.w_retcode != 0) {
#endif
return (YPERR_YPERR);
}
return (yperrno);
}
/*
* returns pid, or -1 for failure
*/
static
_openchild(command, fto, ffrom)
char *command;
FILE **fto;
FILE **ffrom;
{
int i;
pid_t pid;
int pdto[2];
int pdfrom[2];
char *com;
struct rlimit rl;
if (pipe(pdto) < 0) {
goto error1;
}
if (pipe(pdfrom) < 0) {
goto error2;
}
#ifdef VFORK
switch (pid = vfork()) {
#else
switch (pid = fork()) {
#endif
case -1:
goto error3;
case 0:
/*
* child: read from pdto[0], write into pdfrom[1]
*/
(void)close(0);
(void)dup(pdto[0]);
(void)close(1);
(void)dup(pdfrom[1]);
getrlimit(RLIMIT_NOFILE, &rl);
for (i = rl.rlim_max - 1; i >= 3; i--) {
(void) close(i);
}
com = malloc((unsigned) strlen(command) + 6);
if (com == NULL) {
_exit(~0);
}
(void)sprintf(com, "exec %s", command);
execl(SHELL, basename(SHELL), "-c", com, NULL);
_exit(~0);
default:
/*
* parent: write into pdto[1], read from pdfrom[0]
*/
*fto = fdopen(pdto[1], "w");
(void)close(pdto[0]);
*ffrom = fdopen(pdfrom[0], "r");
(void)close(pdfrom[1]);
break;
}
return (pid);
/*
* error cleanup and return
*/
error3:
(void)close(pdfrom[0]);
(void)close(pdfrom[1]);
error2:
(void)close(pdto[0]);
(void)close(pdto[1]);
error1:
return (-1);
}
static char *
basename(path)
char *path;
{
char *p;
p = strrchr(path, '/');
if (p == NULL) {
return (path);
} else {
return (p + 1);
}
}
#else /* YP */
#ifdef foo
#define ERR_ACCESS 1
#define ERR_MALLOC 2
#define ERR_READ 3
#define ERR_WRITE 4
#define ERR_DBASE 5
#define ERR_KEY 6
extern char *malloc();
#endif
static int match __P(( char * , char * ));
/*
* Determine if requester is allowed to update the given map,
* and update it if so. Returns the status, which is zero
* if there is no access violation. This function updates
* the local file and then shuts up.
*/
int
localupdate(name, filename, op, keylen, key, datalen, data)
char *name; /* Name of the requestor */
char *filename;
u_int op;
u_int keylen; /* Not used */
char *key;
u_int datalen; /* Not used */
char *data;
{
char line[256];
FILE *rf;
FILE *wf;
char *tmpname;
int err;
/*
* Check permission
*/
if (strcmp(name, key) != 0) {
return (ERR_ACCESS);
}
if (strcmp(name, "nobody") == 0) {
/*
* Can't change "nobody"s key.
*/
return (ERR_ACCESS);
}
/*
* Open files
*/
tmpname = malloc(strlen(filename) + 4);
if (tmpname == NULL) {
return (ERR_MALLOC);
}
sprintf(tmpname, "%s.tmp", filename);
rf = fopen(filename, "r");
if (rf == NULL) {
return (ERR_READ);
}
wf = fopen(tmpname, "w");
if (wf == NULL) {
return (ERR_WRITE);
}
err = -1;
while (fgets(line, sizeof (line), rf)) {
if (err < 0 && match(line, name)) {
switch (op) {
case YPOP_INSERT:
err = ERR_KEY;
break;
case YPOP_STORE:
case YPOP_CHANGE:
fprintf(wf, "%s %s\n", key, data);
err = 0;
break;
case YPOP_DELETE:
/* do nothing */
err = 0;
break;
}
} else {
fputs(line, wf);
}
}
if (err < 0) {
switch (op) {
case YPOP_CHANGE:
case YPOP_DELETE:
err = ERR_KEY;
break;
case YPOP_INSERT:
case YPOP_STORE:
err = 0;
fprintf(wf, "%s %s\n", key, data);
break;
}
}
fclose(wf);
fclose(rf);
if (err == 0) {
if (rename(tmpname, filename) < 0) {
return (ERR_DBASE);
}
} else {
if (unlink(tmpname) < 0) {
return (ERR_DBASE);
}
}
return (err);
}
static int
match(line, name)
char *line;
char *name;
{
int len;
len = strlen(name);
return (strncmp(line, name, len) == 0 &&
(line[len] == ' ' || line[len] == '\t'));
}
#endif /* !YP */

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 1995, 1996
* 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 Bill Paul 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: yp_dbdelete.c,v 1.1 1996/12/26 05:43:03 wpaul Exp wpaul $
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>
#include <db.h>
#include <sys/stat.h>
#include <errno.h>
#include <paths.h>
#include <rpcsvc/yp.h>
#include "ypxfr_extern.h"
#ifndef lint
static const char rcsid[] = "$Id: yp_dbdelete.c,v 1.1 1996/12/26 05:43:03 wpaul Exp wpaul $";
#endif
int yp_del_record(dbp,key)
DB *dbp;
DBT *key;
{
int rval;
if ((rval = (dbp->del)(dbp,key,0))) {
switch(rval) {
case 1:
return(YP_FALSE);
break;
case -1:
default:
(void)(dbp->close)(dbp);
return(YP_BADDB);
break;
}
}
return(YP_TRUE);
}

View File

@ -0,0 +1,155 @@
/*
* Copyright (c) 1996
* 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 Bill Paul 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: yp_dbupdate.c,v 1.1 1996/12/26 06:00:13 wpaul Exp $
*/
#include <sys/fcntl.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <db.h>
#include <unistd.h>
struct dom_binding {};
#include <rpcsvc/ypclnt.h>
#include <rpcsvc/ypupdate_prot.h>
#include "ypxfr_extern.h"
#include "ypupdated_extern.h"
#ifndef lint
static const char rcsid[] = "$Id: yp_dbupdate.c,v 1.1 1996/12/26 06:00:13 wpaul Exp $";
#endif
static int yp_domake(map, domain)
char *map;
char *domain;
{
int pid;
switch((pid = fork())) {
case 0:
execlp(MAP_UPDATE_PATH, MAP_UPDATE, map, domain, NULL);
yp_error("couldn't exec map update process: %s",
strerror(errno));
exit(1);
break;
case -1:
yp_error("fork() failed: %s", strerror(errno));
return(YPERR_YPERR);
break;
default:
children++;
break;
}
return(0);
}
int ypmap_update(netname, map, op, keylen, keyval, datlen, datval)
char *netname;
char *map;
unsigned int op;
unsigned int keylen;
char *keyval;
unsigned int datlen;
char *datval;
{
DB *dbp;
DBT key = { NULL, 0 }, data = { NULL, 0 };
char *yp_last = "YP_LAST_MODIFIED";
char yplastbuf[YPMAXRECORD];
char *domptr;
int rval = 0;
if ((domptr = strchr(netname, '@')) == NULL)
return(ERR_ACCESS);
domptr++;
dbp = yp_open_db_rw(domptr, map, O_RDWR);
if (dbp == NULL)
return(ERR_DBASE);
key.data = keyval;
key.size = keylen;
data.data = datval;
data.size = datlen;
switch(op) {
case YPOP_DELETE: /* delete this entry */
rval = yp_del_record(dbp, &key);
if (rval == YP_TRUE)
rval = 0;
break;
case YPOP_INSERT: /* add, do not change */
rval = yp_put_record(dbp, &key, &data, 0);
if (rval == YP_TRUE)
rval = 0;
break;
case YPOP_STORE: /* add, or change */
rval = yp_put_record(dbp, &key, &data, 1);
if (rval == YP_TRUE)
rval = 0;
break;
case YPOP_CHANGE: /* change, do not add */
if (yp_get_record(domptr, map, &key, &data, 0) != YP_TRUE) {
rval = ERR_KEY;
break;
}
rval = yp_put_record(dbp, &key, &data, 1);
if (rval == YP_TRUE)
rval = 0;
break;
default:
yp_error("unknown update command: (%d)", op);
}
if (rval) {
(void)(dbp->close)(dbp);
return(rval);
}
snprintf(yplastbuf, sizeof(yplastbuf), "%lu", time(NULL));
key.data = yp_last;
key.size = strlen(yp_last);
data.data = (char *)&yplastbuf;
data.size = strlen(yplastbuf);
if (yp_put_record(dbp, &key, &data, 1) != YP_TRUE) {
yp_error("failed to update timestamp in %s/%s", domptr, map);
(void)(dbp->close)(dbp);
return(ERR_DBASE);
}
(void)(dbp->close)(dbp);
return(yp_domake(map, domptr));
}

33
usr.sbin/rpc.ypupdated/ypupdate Executable file
View File

@ -0,0 +1,33 @@
#!/bin/sh
#
# This script is invoked by rpc.ypupdatedd to propagate NIS maps
# after the master map databases have been modified. It expects
# to be passed two arguments: the name of the map that was updated
# and the name of the domain where the map resides.
# These are passed to /var/yp/Makefile.
#
# Comment out the LOG=yes line to disable logging.
#
# $Id: yppwupdate,v 1.3 1996/06/05 06:13:09 wpaul Exp $
#
LOG=yes
LOGFILE=/var/yp/ypupdate.log
umask 077
if [ ! -f $LOGFILE ];
then
/usr/bin/touch $LOGFILE
echo "# Edit /usr/libexec/yppwupdate to disable" >> $LOGFILE
echo "# logging to this file from yppasswdd." >> $LOGFILE
echo -n "# Log started on: " >> $LOGFILE
/bin/date >> $LOGFILE
fi
if [ ! $LOG ];
then
cd /var/yp/$2; /usr/bin/make -f ../Makefile $1 2>&1
else
cd /var/yp/$2; /usr/bin/make -f ../Makefile $1 >> $LOGFILE
fi

View File

@ -0,0 +1,29 @@
#include <db.h>
#define YPOP_CHANGE 1 /* change, do not add */
#define YPOP_INSERT 2 /* add, do not change */
#define YPOP_DELETE 3 /* delete this entry */
#define YPOP_STORE 4 /* add, or change */
#define ERR_ACCESS 1
#define ERR_MALLOC 2
#define ERR_READ 3
#define ERR_WRITE 4
#define ERR_DBASE 5
#define ERR_KEY 6
#ifndef YPLIBDIR
#define YPLIBDIR "/usr/libexec/"
#endif
#ifndef MAP_UPPATE
#define MAP_UPDATE "ypupdate"
#endif
#define MAP_UPDATE_PATH YPLIBDIR MAP_UPDATE
extern int children;
extern void ypu_prog_1 __P(( struct svc_req *, register SVCXPRT * ));
extern int localupdate __P(( char *, char *, u_int, u_int, char *, u_int, char * ));
extern int ypmap_update __P(( char *, char *, u_int, u_int, char *, u_int, char * ));
extern int yp_del_record __P(( DB *, DBT * ));

View File

@ -0,0 +1,288 @@
/*
* Copyright (c) 1995, 1996
* 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 Bill Paul 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: ypupdated_main.c,v 1.1 1996/12/25 19:31:28 wpaul Exp wpaul $
*/
#include "ypupdate_prot.h"
#include <stdio.h>
#include <stdlib.h> /* getenv, exit */
#include <rpc/pmap_clnt.h> /* for pmap_unset */
#include <string.h> /* strcmp */
#include <signal.h>
#include <sys/ttycom.h> /* TIOCNOTTY */
#ifdef __cplusplus
#include <sysent.h> /* getdtablesize, open */
#endif /* __cplusplus */
#include <memory.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <syslog.h>
#include <sys/wait.h>
#include <errno.h>
#include <err.h>
#include <stdlib.h>
#include <unistd.h>
#include "ypupdated_extern.h"
#include "yp_extern.h"
#ifndef SIG_PF
#define SIG_PF void(*)(int)
#endif
#ifdef DEBUG
#define RPC_SVC_FG
#endif
#define _RPCSVC_CLOSEDOWN 120
#ifndef lint
static const char rcsid[] = "$Id: ypupdated_main.c,v 1.1 1996/12/25 19:31:28 wpaul Exp wpaul $";
#endif /* not lint */
int _rpcpmstart; /* Started by a port monitor ? */
static int _rpcfdtype;
/* Whether Stream or Datagram ? */
/* States a server can be in wrt request */
#define _IDLE 0
#define _SERVED 1
#define _SERVING 2
extern int _rpcsvcstate; /* Set when a request is serviced */
char *progname = "rpc.ypupdated";
char *yp_dir = "/var/yp/";
static
void _msgout(char* msg)
{
#ifdef RPC_SVC_FG
if (_rpcpmstart)
syslog(LOG_ERR, msg);
else
(void) fprintf(stderr, "%s\n", msg);
#else
syslog(LOG_ERR, msg);
#endif
}
static void
closedown(int sig)
{
if (_rpcsvcstate == _IDLE) {
extern fd_set svc_fdset;
static int size;
int i, openfd;
if (_rpcfdtype == SOCK_DGRAM)
exit(0);
if (size == 0) {
size = getdtablesize();
}
for (i = 0, openfd = 0; i < size && openfd < 2; i++)
if (FD_ISSET(i, &svc_fdset))
openfd++;
if (openfd <= 1)
exit(0);
}
if (_rpcsvcstate == _SERVED)
_rpcsvcstate = _IDLE;
(void) signal(SIGALRM, (SIG_PF) closedown);
(void) alarm(_RPCSVC_CLOSEDOWN/2);
}
static void
ypupdated_svc_run()
{
#ifdef FD_SETSIZE
fd_set readfds;
#else
int readfds;
#endif /* def FD_SETSIZE */
extern int forked;
int pid;
int fd_setsize = _rpc_dtablesize();
/* Establish the identity of the parent ypupdated process. */
pid = getpid();
for (;;) {
#ifdef FD_SETSIZE
readfds = svc_fdset;
#else
readfds = svc_fds;
#endif /* def FD_SETSIZE */
switch (select(fd_setsize, &readfds, NULL, NULL,
(struct timeval *)0)) {
case -1:
if (errno == EINTR) {
continue;
}
perror("svc_run: - select failed");
return;
case 0:
continue;
default:
svc_getreqset(&readfds);
if (forked && pid != getpid())
exit(0);
}
}
}
static void reaper(sig)
int sig;
{
int status;
if (sig == SIGHUP) {
#ifdef foo
load_securenets();
#endif
return;
}
if (sig == SIGCHLD) {
while (wait3(&status, WNOHANG, NULL) > 0)
children--;
} else {
(void) pmap_unset(YPU_PROG, YPU_VERS);
exit(0);
}
}
void usage()
{
fprintf(stderr, "%s [-p path]\n", progname);
exit(0);
}
main(argc, argv)
int argc;
char *argv[];
{
register SVCXPRT *transp = NULL;
int sock;
int proto = 0;
struct sockaddr_in saddr;
int asize = sizeof (saddr);
int ch;
while ((ch = getopt(argc, argv, "p:h")) != EOF) {
switch(ch) {
case 'p':
yp_dir = optarg;
break;
default:
usage();
break;
}
}
#ifdef foo
load_securenets();
#endif
if (svc_auth_reg(AUTH_DES, _svcauth_des) == -1) {
yp_error("failed to register AUTH_DES flavor");
exit(1);
}
if (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {
int ssize = sizeof (int);
if (saddr.sin_family != AF_INET)
exit(1);
if (getsockopt(0, SOL_SOCKET, SO_TYPE,
(char *)&_rpcfdtype, &ssize) == -1)
exit(1);
sock = 0;
_rpcpmstart = 1;
proto = 0;
openlog("rpc.ypupdatedd", LOG_PID, LOG_DAEMON);
} else {
#ifndef RPC_SVC_FG
if (daemon(0,0)) {
err(1, "cannot fork");
}
openlog("rpc.ypupdated", LOG_PID, LOG_DAEMON);
#endif
sock = RPC_ANYSOCK;
(void) pmap_unset(YPU_PROG, YPU_VERS);
}
if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_DGRAM)) {
transp = svcudp_create(sock);
if (transp == NULL) {
_msgout("cannot create udp service.");
exit(1);
}
if (!_rpcpmstart)
proto = IPPROTO_UDP;
if (!svc_register(transp, YPU_PROG, YPU_VERS, ypu_prog_1, proto)) {
_msgout("unable to register (YPU_PROG, YPU_VERS, udp).");
exit(1);
}
}
if ((_rpcfdtype == 0) || (_rpcfdtype == SOCK_STREAM)) {
transp = svctcp_create(sock, 0, 0);
if (transp == NULL) {
_msgout("cannot create tcp service.");
exit(1);
}
if (!_rpcpmstart)
proto = IPPROTO_TCP;
if (!svc_register(transp, YPU_PROG, YPU_VERS, ypu_prog_1, proto)) {
_msgout("unable to register (YPU_PROG, YPU_VERS, tcp).");
exit(1);
}
}
if (transp == (SVCXPRT *)NULL) {
_msgout("could not create a handle");
exit(1);
}
if (_rpcpmstart) {
(void) signal(SIGALRM, (SIG_PF) closedown);
(void) alarm(_RPCSVC_CLOSEDOWN/2);
}
(void) signal(SIGPIPE, SIG_IGN);
(void) signal(SIGCHLD, (SIG_PF) reaper);
(void) signal(SIGTERM, (SIG_PF) reaper);
(void) signal(SIGINT, (SIG_PF) reaper);
(void) signal(SIGHUP, (SIG_PF) reaper);
ypupdated_svc_run();
_msgout("svc_run returned");
exit(1);
/* NOTREACHED */
}

View File

@ -0,0 +1,236 @@
/*
* Copyright (c) 1995, 1996
* 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 Bill Paul 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.
*
* ypupdate server implementation
*
* Written by Bill Paul <wpaul@ctr.columbia.edu>
* Center for Telecommunications Research
* Columbia University, New York City
*
* $Id: ypupdated_server.c,v 1.3 1996/12/26 06:06:05 wpaul Exp wpaul $
*/
#include <stdio.h>
#include <rpc/rpc.h>
#include <rpc/auth_des.h>
#include <rpc/key_prot.h>
#include <sys/param.h>
#include <sys/cdefs.h>
#include <rpcsvc/yp.h>
#include "ypupdate_prot.h"
#include "ypupdated_extern.h"
#include "yp_extern.h"
#include "ypxfr_extern.h"
#ifndef lint
static const char rcsid[] = "$Id: ypupdated_server.c,v 1.3 1996/12/26 06:06:05 wpaul Exp wpaul $";
#endif
int children = 0;
int forked = 0;
/*
* Try to avoid spoofing: if a client chooses to use a very large
* window and then tries a bunch of randomly chosen encrypted timestamps,
* there's a chance he might stumble onto a valid combination.
* We therefore reject any RPCs with a window size larger than a preset
* value.
*/
#ifndef WINDOW
#define WINDOW (60*60)
#endif
static enum auth_stat yp_checkauth(svcreq)
struct svc_req *svcreq;
{
struct authdes_cred *des_cred;
switch (svcreq->rq_cred.oa_flavor) {
case AUTH_DES:
des_cred = (struct authdes_cred *) svcreq->rq_clntcred;
if (des_cred->adc_fullname.window > WINDOW) {
yp_error("warning: client-specified window size \
was too large -- possible spoof attempt");
return(AUTH_BADCRED);
}
return(AUTH_OK);
break;
case AUTH_UNIX:
case AUTH_NONE:
yp_error("warning: client didn't use DES authentication");
return(AUTH_TOOWEAK);
break;
default:
yp_error("client used unknown auth flavor");
return(AUTH_REJECTEDCRED);
break;
}
}
unsigned int *ypu_change_1_svc(args, svcreq)
struct ypupdate_args *args;
struct svc_req *svcreq;
{
struct authdes_cred *des_cred;
static int res;
char *netname;
enum auth_stat astat;
res = 0;
astat = yp_checkauth(svcreq);
if (astat != AUTH_OK) {
svcerr_auth(svcreq->rq_xprt, astat);
return(&res);
}
des_cred = (struct authdes_cred *) svcreq->rq_clntcred;
netname = des_cred->adc_fullname.name;
res = localupdate(netname, "/etc/publickey", YPOP_CHANGE,
args->key.yp_buf_len, args->key.yp_buf_val,
args->datum.yp_buf_len, args->datum.yp_buf_val);
if (res)
return (&res);
res = ypmap_update(netname, args->mapname, YPOP_CHANGE,
args->key.yp_buf_len, args->key.yp_buf_val,
args->datum.yp_buf_len, args->datum.yp_buf_val);
return (&res);
}
unsigned int *ypu_insert_1_svc(args, svcreq)
struct ypupdate_args *args;
struct svc_req *svcreq;
{
struct authdes_cred *des_cred;
static int res;
char *netname;
enum auth_stat astat;
res = 0;
astat = yp_checkauth(svcreq);
if (astat != AUTH_OK) {
svcerr_auth(svcreq->rq_xprt, astat);
return(&res);
}
des_cred = (struct authdes_cred *) svcreq->rq_clntcred;
netname = des_cred->adc_fullname.name;
res = localupdate(netname, "/etc/publickey", YPOP_INSERT,
args->key.yp_buf_len, args->key.yp_buf_val,
args->datum.yp_buf_len, args->datum.yp_buf_val);
if (res)
return (&res);
res = ypmap_update(netname, args->mapname, YPOP_INSERT,
args->key.yp_buf_len, args->key.yp_buf_val,
args->datum.yp_buf_len, args->datum.yp_buf_val);
return (&res);
}
unsigned int *ypu_delete_1_svc(args, svcreq)
struct ypdelete_args *args;
struct svc_req *svcreq;
{
struct authdes_cred *des_cred;
static int res;
char *netname;
enum auth_stat astat;
res = 0;
astat = yp_checkauth(svcreq);
if (astat != AUTH_OK) {
svcerr_auth(svcreq->rq_xprt, astat);
return(&res);
}
des_cred = (struct authdes_cred *) svcreq->rq_clntcred;
netname = des_cred->adc_fullname.name;
res = localupdate(netname, "/etc/publickey", YPOP_DELETE,
args->key.yp_buf_len, args->key.yp_buf_val,
0, NULL);
if (res)
return (&res);
res = ypmap_update(netname, args->mapname, YPOP_DELETE,
args->key.yp_buf_len, args->key.yp_buf_val,
0, NULL);
return (&res);
}
unsigned int *ypu_store_1_svc(args, svcreq)
struct ypupdate_args *args;
struct svc_req *svcreq;
{
struct authdes_cred *des_cred;
static int res;
char *netname;
enum auth_stat astat;
res = 0;
astat = yp_checkauth(svcreq);
if (astat != AUTH_OK) {
svcerr_auth(svcreq->rq_xprt, astat);
return(&res);
}
des_cred = (struct authdes_cred *) svcreq->rq_clntcred;
netname = des_cred->adc_fullname.name;
res = localupdate(netname, "/etc/publickey", YPOP_STORE,
args->key.yp_buf_len, args->key.yp_buf_val,
args->datum.yp_buf_len, args->datum.yp_buf_val);
if (res)
return (&res);
res = ypmap_update(netname, args->mapname, YPOP_STORE,
args->key.yp_buf_len, args->key.yp_buf_val,
args->datum.yp_buf_len, args->datum.yp_buf_val);
return (&res);
}