freebsd-dev/gnu/usr.sbin/ypserv/yp_svc.c
Bill Paul 3670011ae8 Added a new feature from Peter Eriksson's latest release of ypserv (0.13):
register ourselves as an NIS version 1 UDP server to pacify older SunOS 4
ypbinds that seem to insist on having one around. All this does is allow
ypserv to respond to DOMAIN_NONACK requests that are periodically
transmitted by ypbind: the server will not actually work as an NIS v1
server in any other way.

Unlike the mainline code, which implements this as a compile-time
option, this feature can be turned on with the newly-added -k flag
at runtime.

Bunped version number to 0.13. (What the hell.)

Updated the man page to reflect this change, also made a couple of small
edits to reflect the recent changes in the /etc/rc* setup.
1995-04-05 03:23:40 +00:00

412 lines
10 KiB
C

/*
* And thus spoke RPCGEN:
* Please do not edit this file.
* It was generated using rpcgen.
*
* And thus replied Lpd@NannyMUD:
* Who cares? :-) /Peter Eriksson <pen@signum.se>
*
* $Id: yp_svc.c,v 1.1 1995/01/31 08:58:56 wpaul Exp $
*/
#include "system.h"
#include "yp.h"
#include <stdio.h>
#include <stdlib.h>
#include <rpc/pmap_clnt.h>
#include <string.h>
#include <memory.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <syslog.h>
#include <errno.h>
#include <paths.h>
extern int errno;
extern void Perror();
#ifdef __STDC__
#define SIG_PF void(*)(int)
#endif
static void
ypprog_2(struct svc_req *rqstp, register SVCXPRT *transp)
{
union {
domainname ypproc_domain_2_arg;
domainname ypproc_domain_nonack_2_arg;
ypreq_key ypproc_match_2_arg;
ypreq_key ypproc_first_2_arg;
ypreq_key ypproc_next_2_arg;
ypreq_xfr ypproc_xfr_2_arg;
ypreq_nokey ypproc_all_2_arg;
ypreq_nokey ypproc_master_2_arg;
ypreq_nokey ypproc_order_2_arg;
domainname ypproc_maplist_2_arg;
} argument;
char *result;
xdrproc_t __xdr_argument, __xdr_result;
char *(*local)(char *, struct svc_req *);
switch (rqstp->rq_proc) {
case YPPROC_NULL:
__xdr_argument = (xdrproc_t) xdr_void;
__xdr_result = (xdrproc_t) xdr_void;
local = (char *(*)(char *, struct svc_req *)) ypproc_null_2_svc;
break;
case YPPROC_DOMAIN:
__xdr_argument = (xdrproc_t) __xdr_domainname;
__xdr_result = (xdrproc_t) xdr_bool;
local = (char *(*)(char *, struct svc_req *)) ypproc_domain_2_svc;
break;
case YPPROC_DOMAIN_NONACK:
__xdr_argument = (xdrproc_t) __xdr_domainname;
__xdr_result = (xdrproc_t) xdr_bool;
local = (char *(*)(char *, struct svc_req *)) ypproc_domain_nonack_2_svc;
break;
case YPPROC_MATCH:
__xdr_argument = (xdrproc_t) __xdr_ypreq_key;
__xdr_result = (xdrproc_t) __xdr_ypresp_val;
local = (char *(*)(char *, struct svc_req *)) ypproc_match_2_svc;
break;
case YPPROC_FIRST:
#if 0 /* Bug in Sun's yp.x RPC prototype file */
__xdr_argument = (xdrproc_t) __xdr_ypreq_key;
#else
__xdr_argument = (xdrproc_t) __xdr_ypreq_nokey;
#endif
__xdr_result = (xdrproc_t) __xdr_ypresp_key_val;
local = (char *(*)(char *, struct svc_req *)) ypproc_first_2_svc;
break;
case YPPROC_NEXT:
__xdr_argument = (xdrproc_t) __xdr_ypreq_key;
__xdr_result = (xdrproc_t) __xdr_ypresp_key_val;
local = (char *(*)(char *, struct svc_req *)) ypproc_next_2_svc;
break;
case YPPROC_XFR:
__xdr_argument = (xdrproc_t) __xdr_ypreq_xfr;
__xdr_result = (xdrproc_t) __xdr_ypresp_xfr;
local = (char *(*)(char *, struct svc_req *)) ypproc_xfr_2_svc;
break;
case YPPROC_CLEAR:
__xdr_argument = (xdrproc_t) xdr_void;
__xdr_result = (xdrproc_t) xdr_void;
local = (char *(*)(char *, struct svc_req *)) ypproc_clear_2_svc;
break;
case YPPROC_ALL:
__xdr_argument = (xdrproc_t) __xdr_ypreq_nokey;
__xdr_result = (xdrproc_t) __xdr_ypresp_all;
local = (char *(*)(char *, struct svc_req *)) ypproc_all_2_svc;
break;
case YPPROC_MASTER:
__xdr_argument = (xdrproc_t) __xdr_ypreq_nokey;
__xdr_result = (xdrproc_t) __xdr_ypresp_master;
local = (char *(*)(char *, struct svc_req *)) ypproc_master_2_svc;
break;
case YPPROC_ORDER:
__xdr_argument = (xdrproc_t) __xdr_ypreq_nokey;
__xdr_result = (xdrproc_t) __xdr_ypresp_order;
local = (char *(*)(char *, struct svc_req *)) ypproc_order_2_svc;
break;
case YPPROC_MAPLIST:
__xdr_argument = (xdrproc_t) __xdr_domainname;
__xdr_result = (xdrproc_t) __xdr_ypresp_maplist;
local = (char *(*)(char *, struct svc_req *)) ypproc_maplist_2_svc;
break;
default:
svcerr_noproc(transp);
return;
}
(void) memset((char *)&argument, 0, sizeof (argument));
if (!svc_getargs(transp, __xdr_argument, (caddr_t) &argument)) {
svcerr_decode(transp);
return;
}
result = (*local)((char *)&argument, rqstp);
if (result != NULL && !svc_sendreply(transp, __xdr_result, result)) {
svcerr_systemerr(transp);
}
if (!svc_freeargs(transp, __xdr_argument, (caddr_t) &argument)) {
fprintf(stderr, "unable to free arguments");
exit(1);
}
return;
}
#if 0
static void
yppush_xfrrespprog_1(struct svc_req *rqstp, register SVCXPRT *transp)
{
union {
int fill;
} argument;
char *result;
xdrproc_t __xdr_argument, __xdr_result;
char *(*local)(char *, struct svc_req *);
switch (rqstp->rq_proc) {
case YPPUSHPROC_NULL:
__xdr_argument = (xdrproc_t) xdr_void;
__xdr_result = (xdrproc_t) xdr_void;
local = (char *(*)(char *, struct svc_req *)) yppushproc_null_1_svc;
break;
case YPPUSHPROC_XFRRESP:
__xdr_argument = (xdrproc_t) xdr_void;
__xdr_result = (xdrproc_t) __xdr_yppushresp_xfr;
local = (char *(*)(char *, struct svc_req *)) yppushproc_xfrresp_1_svc;
break;
default:
svcerr_noproc(transp);
return;
}
(void) memset((char *)&argument, 0, sizeof (argument));
if (!svc_getargs(transp, __xdr_argument, (caddr_t) &argument)) {
svcerr_decode(transp);
return;
}
result = (*local)((char *)&argument, rqstp);
if (result != NULL && !svc_sendreply(transp, __xdr_result, result)) {
svcerr_systemerr(transp);
}
if (!svc_freeargs(transp, __xdr_argument, (caddr_t) &argument)) {
fprintf(stderr, "unable to free arguments");
exit(1);
}
return;
}
static void
ypbindprog_2(struct svc_req *rqstp, register SVCXPRT *transp)
{
union {
domainname ypbindproc_domain_2_arg;
ypbind_setdom ypbindproc_setdom_2_arg;
} argument;
char *result;
xdrproc_t __xdr_argument, __xdr_result;
char *(*local)(char *, struct svc_req *);
switch (rqstp->rq_proc) {
case YPBINDPROC_NULL:
__xdr_argument = (xdrproc_t) xdr_void;
__xdr_result = (xdrproc_t) xdr_void;
local = (char *(*)(char *, struct svc_req *)) ypbindproc_null_2_svc;
break;
case YPBINDPROC_DOMAIN:
__xdr_argument = (xdrproc_t) __xdr_domainname;
__xdr_result = (xdrproc_t) __xdr_ypbind_resp;
local = (char *(*)(char *, struct svc_req *)) ypbindproc_domain_2_svc;
break;
case YPBINDPROC_SETDOM:
__xdr_argument = (xdrproc_t) __xdr_ypbind_setdom;
__xdr_result = (xdrproc_t) xdr_void;
local = (char *(*)(char *, struct svc_req *)) ypbindproc_setdom_2_svc;
break;
default:
svcerr_noproc(transp);
return;
}
(void) memset((char *)&argument, 0, sizeof (argument));
if (!svc_getargs(transp, __xdr_argument, (caddr_t) &argument)) {
svcerr_decode(transp);
return;
}
result = (*local)((char *)&argument, rqstp);
if (result != NULL && !svc_sendreply(transp, __xdr_result, result)) {
svcerr_systemerr(transp);
}
if (!svc_freeargs(transp, __xdr_argument, (caddr_t) &argument)) {
fprintf(stderr, "unable to free arguments");
exit(1);
}
return;
}
#endif
extern int debug_flag;
extern int dns_flag;
#ifndef _PATH_YP
#define _PATH_YP "/var/yp"
#endif
char *path_ypdb = _PATH_YP;
char *progname;
int main(int argc, char **argv)
{
register SVCXPRT *transp;
int i;
int my_port = -1;
int my_socket;
struct sockaddr_in socket_address;
int result;
int sunos_4_kludge = 0;
progname = strrchr (argv[0], '/');
if (progname == (char *) NULL)
progname = argv[0];
else
progname++;
openlog(progname, LOG_PID, TCPW_FACILITY);
for (i = 1; i < argc && argv[i][0] == '-'; i++)
{
if (strcmp(argv[i], "-debug") == 0 || strcmp(argv[i], "-d") == 0)
debug_flag = 1;
else if (strcmp(argv[i], "-dns") == 0 || strcmp(argv[i], "-b") == 0)
dns_flag = 1;
else if ((argv[i][1] == 'p') && (argv[i][2] >= '0') && (argv[i][2] <= '9'))
my_port = atoi(argv[i] + 2);
else if (strcmp(argv[i], "-k") == 0)
sunos_4_kludge = 1;
else
{
fprintf(stderr, "%s: Unknown command line switch: %s\n",
progname,
argv[i]);
exit(1);
}
}
if (!debug_flag)
if(daemon(0,0))
{
perror("daemon()");
exit (1);
}
if (debug_flag)
Perror("[Welcome to the NYS YP Server, version 0.13]\n");
if (i < argc)
{
path_ypdb = argv[i];
if (debug_flag)
Perror("Using database directory: %s\n", path_ypdb);
}
/* Change current directory to database location */
if (chdir(path_ypdb) < 0)
{
Perror("%s: chdir: %", argv[0], strerror(errno));
exit(1);
}
(void) pmap_unset(YPPROG, YPVERS);
if (sunos_4_kludge)
(void) pmap_unset(YPPROG, 1);
if (my_port >= 0)
{
my_socket = socket (AF_INET, SOCK_DGRAM, 0);
if (my_socket < 0)
{
Perror("%s: can not create UDP: %s",
progname, strerror(errno));
exit (1);
}
socket_address.sin_family = AF_INET;
socket_address.sin_addr.s_addr = htonl (INADDR_ANY);
socket_address.sin_port = htons (my_port);
result = bind (my_socket, (struct sockaddr *) &socket_address,
sizeof (socket_address));
if (result < 0)
{
Perror("%s: can not create UDP: %s",
progname, strerror(errno));
exit (1);
}
}
else
my_socket = RPC_ANYSOCK;
transp = svcudp_create(my_socket);
if (transp == NULL) {
Perror("cannot create udp service.");
exit(1);
}
if (!svc_register(transp, YPPROG, YPVERS, ypprog_2, IPPROTO_UDP)) {
Perror("unable to register (YPPROG, YPVERS, udp).");
exit(1);
}
if (sunos_4_kludge) {
/*
** This is just to make us reply to YP version 1 calls which SunOS 4's
** ypbind seems to insist on finding. If someone _really_ tries to
** use this the they will probably be bitten - _hard_, since I haven't
** got the faintest idea on how the XDR calls for YP version 1 should
** look like. The Domain_NoNack call seems to be compatible though :-)
*/
if (!svc_register(transp, YPPROG, 1, ypprog_2, IPPROTO_UDP)) {
fprintf(stderr, "unable to register (YPPROG, 1, udp).");
exit(1);
}
}
if (my_port >= 0)
{
my_socket = socket (AF_INET, SOCK_STREAM, 0);
if (my_socket < 0)
{
Perror("%s: can not create TCP: %s",
progname, strerror(errno));
exit (1);
}
socket_address.sin_family = AF_INET;
socket_address.sin_addr.s_addr = htonl (INADDR_ANY);
socket_address.sin_port = htons (my_port);
result = bind (my_socket, (struct sockaddr *) &socket_address,
sizeof (socket_address));
if (result < 0)
{
Perror("%s: can not create TCP: %s",
progname, strerror(errno));
exit (1);
}
}
else
my_socket = RPC_ANYSOCK;
transp = svctcp_create(my_socket, 0, 0);
if (transp == NULL) {
Perror("%s: cannot create tcp service\n", progname);
exit(1);
}
if (!svc_register(transp, YPPROG, YPVERS, ypprog_2, IPPROTO_TCP)) {
Perror("%s: unable to register (YPPROG, YPVERS, tcp)\n", progname);
exit(1);
}
svc_run();
Perror("svc_run returned");
exit(1);
/* NOTREACHED */
}