diff options
Diffstat (limited to 'usr.sbin/ypbind')
-rw-r--r-- | usr.sbin/ypbind/Makefile | 12 | ||||
-rw-r--r-- | usr.sbin/ypbind/yp_ping.c | 310 | ||||
-rw-r--r-- | usr.sbin/ypbind/yp_ping.h | 5 | ||||
-rw-r--r-- | usr.sbin/ypbind/ypbind.8 | 202 | ||||
-rw-r--r-- | usr.sbin/ypbind/ypbind.c | 1001 |
5 files changed, 0 insertions, 1530 deletions
diff --git a/usr.sbin/ypbind/Makefile b/usr.sbin/ypbind/Makefile deleted file mode 100644 index 8e9a231..0000000 --- a/usr.sbin/ypbind/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# from: @(#)Makefile 5.8 (Berkeley) 7/28/90 -# $FreeBSD$ - -PROG= ypbind -MAN= ypbind.8 -SRCS= ypbind.c yp_ping.c - -CFLAGS+= -DDAEMON - -WARNS?= 2 - -.include <bsd.prog.mk> diff --git a/usr.sbin/ypbind/yp_ping.c b/usr.sbin/ypbind/yp_ping.c deleted file mode 100644 index 1453126..0000000 --- a/usr.sbin/ypbind/yp_ping.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (c) 1996, 1997 - * 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. - */ - -/* - * 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. - * - * 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 - */ - -#if 0 -#ifndef lint -static char *sccsid = "@(#)from: clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro"; -static char *sccsid = "@(#)from: clnt_udp.c 2.2 88/08/01 4.0 RPCSRC"; -#endif -#endif -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * clnt_udp.c, Implements a UDP/IP based, client side RPC. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - -#include <errno.h> -#include <netdb.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <pthread.h> -#include <rpc/rpc.h> -#include <rpc/pmap_clnt.h> -#include <rpc/pmap_prot.h> -#include <rpcsvc/yp.h> -#include <sys/types.h> -#include <sys/poll.h> -#include <sys/socket.h> -#include <sys/signal.h> -#include <sys/ioctl.h> -#include <arpa/inet.h> -#include <net/if.h> - -#include "yp_ping.h" - -/* - * pmap_getport.c - * Client interface to pmap rpc service. - * - * Copyright (C) 1984, Sun Microsystems, Inc. - */ - - -static struct timeval timeout = { 1, 0 }; -static struct timeval tottimeout = { 1, 0 }; - -/* - * Find the mapped port for program,version. - * Calls the pmap service remotely to do the lookup. - * Returns 0 if no map exists. - */ -static u_short -__pmap_getport(struct sockaddr_in *address, u_long program, u_long version, - u_int protocol) -{ - u_short port = 0; - int sock = -1; - register CLIENT *client; - struct pmap parms; - - address->sin_port = htons(PMAPPORT); - - client = clntudp_bufcreate(address, PMAPPROG, - PMAPVERS, timeout, &sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); - if (client != (CLIENT *)NULL) { - parms.pm_prog = program; - parms.pm_vers = version; - parms.pm_prot = protocol; - parms.pm_port = 0; /* not needed or used */ - if (CLNT_CALL(client, PMAPPROC_GETPORT, - (xdrproc_t)xdr_pmap, &parms, - (xdrproc_t)xdr_u_short, &port, - tottimeout) != RPC_SUCCESS){ - rpc_createerr.cf_stat = RPC_PMAPFAILURE; - clnt_geterr(client, &rpc_createerr.cf_error); - } else if (port == 0) { - rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; - } - CLNT_DESTROY(client); - } - if (sock != -1) - (void)close(sock); - address->sin_port = 0; - return (port); -} - -/* - * Transmit to YPPROC_DOMAIN_NONACK, return immediately. - */ -static bool_t * -ypproc_domain_nonack_2_send(domainname *argp, CLIENT *clnt) -{ - static bool_t clnt_res; - struct timeval TIMEOUT = { 0, 0 }; - - memset((char *)&clnt_res, 0, sizeof (clnt_res)); - if (clnt_call(clnt, YPPROC_DOMAIN_NONACK, - (xdrproc_t) xdr_domainname, (caddr_t) argp, - (xdrproc_t) xdr_bool, (caddr_t) &clnt_res, - TIMEOUT) != RPC_SUCCESS) { - return (NULL); - } - return (&clnt_res); -} - -/* - * Receive response from YPPROC_DOMAIN_NONACK asynchronously. - */ -static bool_t * -ypproc_domain_nonack_2_recv(domainname *argp, CLIENT *clnt) -{ - static bool_t clnt_res; - struct timeval TIMEOUT = { 0, 0 }; - - memset((char *)&clnt_res, 0, sizeof (clnt_res)); - if (clnt_call(clnt, YPPROC_DOMAIN_NONACK, - (xdrproc_t) NULL, (caddr_t) argp, - (xdrproc_t) xdr_bool, (caddr_t) &clnt_res, - TIMEOUT) != RPC_SUCCESS) { - return (NULL); - } - return (&clnt_res); -} - -/* - * "We have the machine that goes 'ping!'" -- Monty Python - * - * This function blasts packets at the YPPROC_DOMAIN_NONACK procedures - * of the NIS servers listed in restricted_addrs structure. - * Whoever replies the fastest becomes our chosen server. - * - * Note: THIS IS NOT A BROADCAST OPERATION! We could use clnt_broadcast() - * for this, but that has the following problems: - * - We only get the address of the machine that replied in the - * 'eachresult' callback, and on multi-homed machines this can - * lead to confusion. - * - clnt_broadcast() only transmits to local networks, whereas with - * NIS+ you can have a perfectly good server located anywhere on or - * off the local network. - * - clnt_broadcast() blocks for an arbitrary amount of time which the - * caller can't control -- we want to avoid that. - * - * Also note that this has nothing to do with the NIS_PING procedure used - * for replica updates. - */ - -struct ping_req { - struct sockaddr_in sin; - u_int32_t xid; -}; - -int -__yp_ping(struct in_addr *restricted_addrs, int cnt, char *dom, short *port) -{ - struct timeval tv = { 5, 0 }; - struct ping_req **reqs; - unsigned long i; - int async; - struct sockaddr_in sin, *any = NULL; - struct netbuf addr; - int winner = -1; - u_int32_t xid_seed, xid_lookup; - int sock, dontblock = 1; - CLIENT *clnt; - char *foo = dom; - int validsrvs = 0; - - /* Set up handles. */ - reqs = calloc(1, sizeof(struct ping_req *) * cnt); - xid_seed = time(NULL) ^ getpid(); - - for (i = 0; i < cnt; i++) { - bzero((char *)&sin, sizeof(sin)); - sin.sin_family = AF_INET; - bcopy((char *)&restricted_addrs[i], - (char *)&sin.sin_addr, sizeof(struct in_addr)); - sin.sin_port = htons(__pmap_getport(&sin, YPPROG, - YPVERS, IPPROTO_UDP)); - if (sin.sin_port == 0) - continue; - reqs[i] = calloc(1, sizeof(struct ping_req)); - bcopy((char *)&sin, (char *)&reqs[i]->sin, sizeof(sin)); - any = &reqs[i]->sin; - reqs[i]->xid = xid_seed; - xid_seed++; - validsrvs++; - } - - /* Make sure at least one server was assigned */ - if (!validsrvs) { - free(reqs); - return(-1); - } - - /* Create RPC handle */ - sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - clnt = clntudp_create(any, YPPROG, YPVERS, tv, &sock); - if (clnt == NULL) { - close(sock); - for (i = 0; i < cnt; i++) - if (reqs[i] != NULL) - free(reqs[i]); - free(reqs); - return(-1); - } - clnt->cl_auth = authunix_create_default(); - tv.tv_sec = 0; - - clnt_control(clnt, CLSET_TIMEOUT, (char *)&tv); - async = TRUE; - clnt_control(clnt, CLSET_ASYNC, (char *)&async); - ioctl(sock, FIONBIO, &dontblock); - - /* Transmit */ - for (i = 0; i < cnt; i++) { - if (reqs[i] != NULL) { - clnt_control(clnt, CLSET_XID, (char *)&reqs[i]->xid); - addr.len = sizeof(reqs[i]->sin); - addr.buf = (char *) &reqs[i]->sin; - clnt_control(clnt, CLSET_SVC_ADDR, &addr); - ypproc_domain_nonack_2_send(&foo, clnt); - } - } - - /* Receive reply */ - ypproc_domain_nonack_2_recv(&foo, clnt); - - /* Got a winner -- look him up. */ - clnt_control(clnt, CLGET_XID, (char *)&xid_lookup); - for (i = 0; i < cnt; i++) { - if (reqs[i] != NULL && reqs[i]->xid == xid_lookup) { - winner = i; - *port = reqs[i]->sin.sin_port; - } - } - - /* Shut everything down */ - auth_destroy(clnt->cl_auth); - clnt_destroy(clnt); - close(sock); - - for (i = 0; i < cnt; i++) - if (reqs[i] != NULL) - free(reqs[i]); - free(reqs); - - return(winner); -} diff --git a/usr.sbin/ypbind/yp_ping.h b/usr.sbin/ypbind/yp_ping.h deleted file mode 100644 index 80e6a78..0000000 --- a/usr.sbin/ypbind/yp_ping.h +++ /dev/null @@ -1,5 +0,0 @@ -/* - * $FreeBSD$ - */ - -extern int __yp_ping(struct in_addr *, int, char *, short *); diff --git a/usr.sbin/ypbind/ypbind.8 b/usr.sbin/ypbind/ypbind.8 deleted file mode 100644 index 34ce217..0000000 --- a/usr.sbin/ypbind/ypbind.8 +++ /dev/null @@ -1,202 +0,0 @@ -.\" Copyright (c) 1991, 1993, 1995 -.\" 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. -.\" 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. -.\" -.\" $FreeBSD$ -.\" -.Dd April 9, 1995 -.Dt YPBIND 8 -.Os -.Sh NAME -.Nm ypbind -.Nd "NIS domain binding daemon" -.Sh SYNOPSIS -.Nm -.Op Fl ypset -.Op Fl ypsetme -.Op Fl s -.Op Fl m -.Oo -.Fl S -.Sm off -.Ar domainname , server1 , server2 , ... -.Sm on -.Oc -.Sh DESCRIPTION -The -.Nm -utility is the process that maintains NIS binding information. -At startup, -it searches for an NIS server responsible for serving the system's -default domain (as set by the -.Xr domainname 1 -command) using network broadcasts. -Once it receives a reply, -it will store the address of the server and other -information in a special file located in -.Pa /var/yp/binding . -The NIS routines in the standard C library can then use this file -when processing NIS requests. -There may be several such files -since it is possible for an NIS client to be bound to more than -one domain. -.Pp -After a binding has been established, -.Nm -will send DOMAIN_NONACK requests to the NIS server at one minute -intervals. -If it fails to receive a reply to one of these requests, -.Nm -assumes that the server is no longer running and resumes its network -broadcasts until another binding is established. -The -.Nm -utility will also log warning messages using the -.Xr syslog 3 -facility each time it detects that a server has stopped responding, -as well as when it has bound to a new server. -.Pp -The following options are available: -.Bl -tag -width indent -.It Fl ypset -It is possible to force -.Nm -to bind to a particular NIS server host for a given domain by using the -.Xr ypset 8 -command. -However, -.Nm -refuses YPBINDPROC_SETDOM requests by default since it has no way of -knowing exactly who is sending them. -Using the -.Fl ypset -flag causes -.Nm -to accept YPBINDPROC_SETDOM requests from any host. -This option should only -be used for diagnostic purposes and only for limited periods since allowing -arbitrary users to reset the binding of an NIS client poses a severe -security risk. -.It Fl ypsetme -This is similar to the -.Fl ypset -flag, except that it only permits YPBINDPROC_SETDOM requests to be processed -if they originated from the local host. -.It Fl s -Cause -.Nm -to run in secure mode: it will refuse to bind to any NIS server -that is not running as root (i.e., that is not using privileged -TCP ports). -.It Fl S Xo -.Sm off -.Ar domainname , server1 , server2 , server3 , ... -.Sm on -.Xc -Allow the system administrator to lock -.Nm -to a particular -domain and group of NIS servers. -Up to ten servers can be specified. -There must not be any spaces between the commas in the domain/server -specification. -This option is used to ensure that the system binds -only to one domain and only to one of the specified servers, which -is useful for systems that are both NIS servers and NIS -clients: it provides a way to restrict what machines the system can -bind to without the need for specifying the -.Fl ypset -or -.Fl ypsetme -options, which are often considered to be security holes. -The specified -servers must have valid entries in the local -.Pa /etc/hosts -file. -IP addresses may be specified in place of hostnames. -If -.Nm -cannot make sense out of the arguments, it will ignore -the -.Fl S -flag and continue running normally. -.Pp -Note that -.Nm -will consider the domainname specified with the -.Fl S -flag to be the system default domain. -.It Fl m -Cause -.Nm -to use a 'many-cast' rather than a broadcast for choosing a server -from the restricted mode server list. -In many-cast mode, -.Nm -will transmit directly to the YPPROC_DOMAIN_NONACK procedure of the -servers specified in the restricted list and bind to the server that -responds the fastest. -This mode of operation is useful for NIS clients on remote subnets -where no local NIS servers are available. -The -.Fl m -flag can only be used in conjunction with the -.Fl S -flag above (if used without the -.Fl S -flag, it has no effect). -.El -.Sh NOTES -The -.Nm -utility will not make continuous attempts to keep secondary domains bound. -If a server for a secondary domain fails to respond to a ping, -.Nm -will broadcast for a new server only once before giving up. -If a -client program attempts to reference the unbound domain, -.Nm -will try broadcasting again. -By contrast, -.Nm -will automatically maintain a binding for the default domain whether -client programs reference it ot not. -.Sh FILES -.Bl -tag -width /etc/rc.conf -compact -.It Pa /var/yp/binding/[domainname].[version] -the files used to hold binding information for each NIS domain -.It Pa /etc/rc.conf -system configuration file where the system default domain and -ypbind startup options are specified -.El -.Sh SEE ALSO -.Xr domainname 1 , -.Xr syslog 3 , -.Xr yp 8 , -.Xr ypserv 8 , -.Xr ypset 8 -.Sh AUTHORS -.An Theo de Raadt Aq deraadt@fsa.ca diff --git a/usr.sbin/ypbind/ypbind.c b/usr.sbin/ypbind/ypbind.c deleted file mode 100644 index 0083cf8..0000000 --- a/usr.sbin/ypbind/ypbind.c +++ /dev/null @@ -1,1001 +0,0 @@ -/* - * Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca> - * 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. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/ioctl.h> -#include <sys/signal.h> -#include <sys/socket.h> -#include <sys/file.h> -#include <sys/fcntl.h> -#include <sys/stat.h> -#include <sys/uio.h> -#include <ctype.h> -#include <dirent.h> -#include <err.h> -#include <errno.h> -#include <netdb.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <unistd.h> -#include <rpc/rpc.h> -#include <rpc/xdr.h> -#include <net/if.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <rpc/pmap_clnt.h> -#include <rpc/pmap_prot.h> -#include <rpc/pmap_rmt.h> -#include <rpc/rpc_com.h> -#include <rpcsvc/yp.h> -#include <rpcsvc/ypclnt.h> -#include "yp_ping.h" - -#ifndef BINDINGDIR -#define BINDINGDIR "/var/yp/binding" -#endif - -#ifndef YPBINDLOCK -#define YPBINDLOCK "/var/run/ypbind.lock" -#endif - -struct _dom_binding { - struct _dom_binding *dom_pnext; - char dom_domain[YPMAXDOMAIN + 1]; - struct sockaddr_in dom_server_addr; - long int dom_vers; - int dom_lockfd; - int dom_alive; - int dom_broadcast_pid; - int dom_pipe_fds[2]; - int dom_default; -}; - -#define READFD ypdb->dom_pipe_fds[0] -#define WRITEFD ypdb->dom_pipe_fds[1] -#define BROADFD broad_domain->dom_pipe_fds[1] - -extern bool_t xdr_domainname(), xdr_ypbind_resp(); -extern bool_t xdr_ypreq_key(), xdr_ypresp_val(); -extern bool_t xdr_ypbind_setdom(); - -void checkwork(void); -void *ypbindproc_null_2_yp(SVCXPRT *, void *, CLIENT *); -void *ypbindproc_setdom_2_yp(SVCXPRT *, struct ypbind_setdom *, CLIENT *); -void rpc_received(char *, struct sockaddr_in *, int); -void broadcast(struct _dom_binding *); -int ping(struct _dom_binding *); -int tell_parent(char *, struct sockaddr_in *); -void handle_children(struct _dom_binding *); -void reaper(int); -void terminate(int); -void yp_restricted_mode(char *); -int verify(struct in_addr); - -char *domain_name; -struct _dom_binding *ypbindlist; -static struct _dom_binding *broad_domain; - -#define YPSET_NO 0 -#define YPSET_LOCAL 1 -#define YPSET_ALL 2 -int ypsetmode = YPSET_NO; -int ypsecuremode = 0; -int ppid; - -#define NOT_RESPONDING_HYSTERESIS 10 -static int not_responding_count = 0; - -/* - * Special restricted mode variables: when in restricted mode, only the - * specified restricted_domain will be bound, and only the servers listed - * in restricted_addrs will be used for binding. - */ -#define RESTRICTED_SERVERS 10 -int yp_restricted = 0; -int yp_manycast = 0; -struct in_addr restricted_addrs[RESTRICTED_SERVERS]; - -/* No more than MAX_CHILDREN child broadcasters at a time. */ -#ifndef MAX_CHILDREN -#define MAX_CHILDREN 5 -#endif -/* No more than MAX_DOMAINS simultaneous domains */ -#ifndef MAX_DOMAINS -#define MAX_DOMAINS 200 -#endif -/* RPC timeout value */ -#ifndef FAIL_THRESHOLD -#define FAIL_THRESHOLD 20 -#endif - -/* Number of times to fish for a response froma particular set of hosts */ -#ifndef MAX_RETRIES -#define MAX_RETRIES 30 -#endif - -int retries = 0; -int children = 0; -int domains = 0; -int yplockfd; -fd_set fdsr; - -SVCXPRT *udptransp, *tcptransp; - -void * -ypbindproc_null_2_yp(SVCXPRT *transp, void *argp, CLIENT *clnt) -{ - static char res; - - bzero(&res, sizeof(res)); - return &res; -} - -struct ypbind_resp * -ypbindproc_domain_2_yp(SVCXPRT *transp, domainname *argp, CLIENT *clnt) -{ - static struct ypbind_resp res; - struct _dom_binding *ypdb; - char path[MAXPATHLEN]; - - bzero(&res, sizeof res); - res.ypbind_status = YPBIND_FAIL_VAL; - res.ypbind_resp_u.ypbind_error = YPBIND_ERR_NOSERV; - - if (strchr(*argp, '/')) { - syslog(LOG_WARNING, "Domain name '%s' has embedded slash -- \ -rejecting.", *argp); - return(&res); - } - - for (ypdb = ypbindlist; ypdb; ypdb = ypdb->dom_pnext) { - if (strcmp(ypdb->dom_domain, *argp) == 0) - break; - } - - if (ypdb == NULL) { - if (yp_restricted) { - syslog(LOG_NOTICE, "Running in restricted mode -- request to bind domain \"%s\" rejected.\n", *argp); - return (&res); - } - - if (domains >= MAX_DOMAINS) { - syslog(LOG_WARNING, "domain limit (%d) exceeded", - MAX_DOMAINS); - res.ypbind_resp_u.ypbind_error = YPBIND_ERR_RESC; - return (&res); - } - ypdb = (struct _dom_binding *)malloc(sizeof *ypdb); - if (ypdb == NULL) { - syslog(LOG_WARNING, "malloc: %m"); - res.ypbind_resp_u.ypbind_error = YPBIND_ERR_RESC; - return (&res); - } - bzero(ypdb, sizeof *ypdb); - strncpy(ypdb->dom_domain, *argp, sizeof ypdb->dom_domain); - ypdb->dom_vers = YPVERS; - ypdb->dom_alive = 0; - ypdb->dom_default = 0; - ypdb->dom_lockfd = -1; - sprintf(path, "%s/%s.%ld", BINDINGDIR, - ypdb->dom_domain, ypdb->dom_vers); - unlink(path); - ypdb->dom_pnext = ypbindlist; - ypbindlist = ypdb; - domains++; - } - - if (ping(ypdb)) { - return (&res); - } - - res.ypbind_status = YPBIND_SUCC_VAL; - res.ypbind_resp_u.ypbind_error = 0; /* Success */ - *(u_int32_t *)&res.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr = - ypdb->dom_server_addr.sin_addr.s_addr; - *(u_short *)&res.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port = - ypdb->dom_server_addr.sin_port; - /*printf("domain %s at %s/%d\n", ypdb->dom_domain, - inet_ntoa(ypdb->dom_server_addr.sin_addr), - ntohs(ypdb->dom_server_addr.sin_port));*/ - return (&res); -} - -void * -ypbindproc_setdom_2_yp(SVCXPRT *transp, ypbind_setdom *argp, CLIENT *clnt) -{ - struct sockaddr_in *fromsin, bindsin; - static char *result = NULL; - - if (strchr(argp->ypsetdom_domain, '/')) { - syslog(LOG_WARNING, "Domain name '%s' has embedded slash -- \ -rejecting.", argp->ypsetdom_domain); - return(NULL); - } - fromsin = svc_getcaller(transp); - - switch (ypsetmode) { - case YPSET_LOCAL: - if (fromsin->sin_addr.s_addr != htonl(INADDR_LOOPBACK)) { - svcerr_noprog(transp); - return(NULL); - } - break; - case YPSET_ALL: - break; - case YPSET_NO: - default: - svcerr_noprog(transp); - return(NULL); - } - - if (ntohs(fromsin->sin_port) >= IPPORT_RESERVED) { - svcerr_noprog(transp); - return(NULL); - } - - if (argp->ypsetdom_vers != YPVERS) { - svcerr_noprog(transp); - return(NULL); - } - - bzero(&bindsin, sizeof bindsin); - bindsin.sin_family = AF_INET; - bindsin.sin_addr.s_addr = *(u_int32_t *)argp->ypsetdom_binding.ypbind_binding_addr; - bindsin.sin_port = *(u_short *)argp->ypsetdom_binding.ypbind_binding_port; - rpc_received(argp->ypsetdom_domain, &bindsin, 1); - - return((void *) &result); -} - -void -ypbindprog_2(struct svc_req *rqstp, register SVCXPRT *transp) -{ - union { - domainname ypbindproc_domain_2_arg; - struct ypbind_setdom ypbindproc_setdom_2_arg; - } argument; - struct authunix_parms *creds; - char *result; - bool_t (*xdr_argument)(), (*xdr_result)(); - char *(*local)(); - - switch (rqstp->rq_proc) { - case YPBINDPROC_NULL: - xdr_argument = xdr_void; - xdr_result = xdr_void; - local = (char *(*)()) ypbindproc_null_2_yp; - break; - - case YPBINDPROC_DOMAIN: - xdr_argument = xdr_domainname; - xdr_result = xdr_ypbind_resp; - local = (char *(*)()) ypbindproc_domain_2_yp; - break; - - case YPBINDPROC_SETDOM: - switch (rqstp->rq_cred.oa_flavor) { - case AUTH_UNIX: - creds = (struct authunix_parms *)rqstp->rq_clntcred; - if (creds->aup_uid != 0) { - svcerr_auth(transp, AUTH_BADCRED); - return; - } - break; - default: - svcerr_auth(transp, AUTH_TOOWEAK); - return; - } - - xdr_argument = xdr_ypbind_setdom; - xdr_result = xdr_void; - local = (char *(*)()) ypbindproc_setdom_2_yp; - break; - - default: - svcerr_noproc(transp); - return; - } - bzero(&argument, sizeof(argument)); - if (!svc_getargs(transp, (xdrproc_t)xdr_argument, &argument)) { - svcerr_decode(transp); - return; - } - result = (*local)(transp, &argument, rqstp); - if (result != NULL && - !svc_sendreply(transp, (xdrproc_t)xdr_result, result)) { - svcerr_systemerr(transp); - } - return; -} - -/* Jack the reaper */ -void -reaper(int sig) -{ - int st; - - while (wait3(&st, WNOHANG, NULL) > 0) - children--; -} - -void -terminate(int sig) -{ - struct _dom_binding *ypdb; - char path[MAXPATHLEN]; - - if (ppid != getpid()) - exit(0); - - for (ypdb = ypbindlist; ypdb; ypdb = ypdb->dom_pnext) { - close(ypdb->dom_lockfd); - if (ypdb->dom_broadcast_pid) - kill(ypdb->dom_broadcast_pid, SIGINT); - sprintf(path, "%s/%s.%ld", BINDINGDIR, - ypdb->dom_domain, ypdb->dom_vers); - unlink(path); - } - close(yplockfd); - unlink(YPBINDLOCK); - pmap_unset(YPBINDPROG, YPBINDVERS); - exit(0); -} - -int -main(int argc, char *argv[]) -{ - struct timeval tv; - int i; - DIR *dird; - struct dirent *dirp; - struct _dom_binding *ypdb, *next; - - /* Check that another ypbind isn't already running. */ - if ((yplockfd = (open(YPBINDLOCK, O_RDONLY|O_CREAT, 0444))) == -1) - err(1, "%s", YPBINDLOCK); - - if (flock(yplockfd, LOCK_EX|LOCK_NB) == -1 && errno == EWOULDBLOCK) - errx(1, "another ypbind is already running. Aborting"); - - /* XXX domainname will be overriden if we use restricted mode */ - yp_get_default_domain(&domain_name); - if (domain_name[0] == '\0') - errx(1, "domainname not set. Aborting"); - - for (i = 1; i<argc; i++) { - if (strcmp("-ypset", argv[i]) == 0) - ypsetmode = YPSET_ALL; - else if (strcmp("-ypsetme", argv[i]) == 0) - ypsetmode = YPSET_LOCAL; - else if (strcmp("-s", argv[i]) == 0) - ypsecuremode++; - else if (strcmp("-S", argv[i]) == 0 && argc > i) - yp_restricted_mode(argv[++i]); - else if (strcmp("-m", argv[i]) == 0) - yp_manycast++; - else - errx(1, "unknown option: %s", argv[i]); - } - - /* blow away everything in BINDINGDIR (if it exists) */ - - if ((dird = opendir(BINDINGDIR)) != NULL) { - char path[MAXPATHLEN]; - while ((dirp = readdir(dird)) != NULL) - if (strcmp(dirp->d_name, ".") && - strcmp(dirp->d_name, "..")) { - sprintf(path,"%s/%s",BINDINGDIR,dirp->d_name); - unlink(path); - } - closedir(dird); - } - -#ifdef DAEMON - if (daemon(0,0)) - err(1, "fork"); -#endif - - pmap_unset(YPBINDPROG, YPBINDVERS); - - udptransp = svcudp_create(RPC_ANYSOCK); - if (udptransp == NULL) - errx(1, "cannot create udp service"); - if (!svc_register(udptransp, YPBINDPROG, YPBINDVERS, ypbindprog_2, - IPPROTO_UDP)) - errx(1, "unable to register (YPBINDPROG, YPBINDVERS, udp)"); - - tcptransp = svctcp_create(RPC_ANYSOCK, 0, 0); - if (tcptransp == NULL) - errx(1, "cannot create tcp service"); - - if (!svc_register(tcptransp, YPBINDPROG, YPBINDVERS, ypbindprog_2, - IPPROTO_TCP)) - errx(1, "unable to register (YPBINDPROG, YPBINDVERS, tcp)"); - - /* build initial domain binding, make it "unsuccessful" */ - ypbindlist = (struct _dom_binding *)malloc(sizeof *ypbindlist); - if (ypbindlist == NULL) - errx(1, "malloc"); - bzero(ypbindlist, sizeof *ypbindlist); - strncpy(ypbindlist->dom_domain, domain_name, sizeof ypbindlist->dom_domain); - ypbindlist->dom_vers = YPVERS; - ypbindlist->dom_alive = 0; - ypbindlist->dom_lockfd = -1; - ypbindlist->dom_default = 1; - domains++; - - signal(SIGCHLD, reaper); - signal(SIGTERM, terminate); - - ppid = getpid(); /* Remember who we are. */ - - openlog(argv[0], LOG_PID, LOG_DAEMON); - - /* Kick off the default domain */ - broadcast(ypbindlist); - - while (1) { - fdsr = svc_fdset; - - tv.tv_sec = 60; - tv.tv_usec = 0; - - switch (select(_rpc_dtablesize(), &fdsr, NULL, NULL, &tv)) { - case 0: - checkwork(); - break; - case -1: - if (errno != EINTR) - syslog(LOG_WARNING, "select: %m"); - break; - default: - for (ypdb = ypbindlist; ypdb; ypdb = next) { - next = ypdb->dom_pnext; - if (READFD > 0 && FD_ISSET(READFD, &fdsr)) { - handle_children(ypdb); - if (children == (MAX_CHILDREN - 1)) - checkwork(); - } - } - svc_getreqset(&fdsr); - break; - } - } - - /* NOTREACHED */ - exit(1); -} - -void -checkwork(void) -{ - struct _dom_binding *ypdb; - - for (ypdb = ypbindlist; ypdb; ypdb = ypdb->dom_pnext) - ping(ypdb); -} - -/* The clnt_broadcast() callback mechanism sucks. */ - -/* - * Receive results from broadcaster. Don't worry about passing - * bogus info to rpc_received() -- it can handle it. Note that we - * must be sure to invalidate the dom_pipe_fds descriptors here: - * since descriptors can be re-used, we have to make sure we - * don't mistake one of the RPC descriptors for one of the pipes. - * What's weird is that forgetting to invalidate the pipe descriptors - * doesn't always result in an error (otherwise I would have caught - * the mistake much sooner), even though logically it should. - */ -void -handle_children(struct _dom_binding *ypdb) -{ - char buf[YPMAXDOMAIN + 1]; - struct sockaddr_in addr; - int d = 0, a = 0; - struct _dom_binding *y, *prev = NULL; - char path[MAXPATHLEN]; - - if ((d = read(READFD, &buf, sizeof(buf))) <= 0) - syslog(LOG_WARNING, "could not read from child: %m"); - - if ((a = read(READFD, &addr, sizeof(struct sockaddr_in))) < 0) - syslog(LOG_WARNING, "could not read from child: %m"); - - close(READFD); - FD_CLR(READFD, &fdsr); - FD_CLR(READFD, &svc_fdset); - READFD = WRITEFD = -1; - if (d > 0 && a > 0) - rpc_received(buf, &addr, 0); - else { - for (y = ypbindlist; y; y = y->dom_pnext) { - if (y == ypdb) - break; - prev = y; - } - switch (ypdb->dom_default) { - case 0: - if (prev == NULL) - ypbindlist = y->dom_pnext; - else - prev->dom_pnext = y->dom_pnext; - sprintf(path, "%s/%s.%ld", BINDINGDIR, - ypdb->dom_domain, YPVERS); - close(ypdb->dom_lockfd); - unlink(path); - free(ypdb); - domains--; - return; - case 1: - ypdb->dom_broadcast_pid = 0; - ypdb->dom_alive = 0; - broadcast(ypdb); - return; - default: - break; - } - } - - return; -} - -/* - * Send our dying words back to our parent before we perish. - */ -int -tell_parent(char *dom, struct sockaddr_in *addr) -{ - char buf[YPMAXDOMAIN + 1]; - struct timeval timeout; - fd_set fds; - - timeout.tv_sec = 5; - timeout.tv_usec = 0; - - sprintf(buf, "%s", broad_domain->dom_domain); - if (write(BROADFD, &buf, sizeof(buf)) < 0) - return(1); - - /* - * Stay in sync with parent: wait for it to read our first - * message before sending the second. - */ - - FD_ZERO(&fds); - FD_SET(BROADFD, &fds); - if (select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == -1) - return(1); - if (FD_ISSET(BROADFD, &fds)) { - if (write(BROADFD, addr, sizeof(struct sockaddr_in)) < 0) - return(1); - } else { - return(1); - } - - close(BROADFD); - return (0); -} - -bool_t broadcast_result(out, addr) -bool_t *out; -struct sockaddr_in *addr; -{ - if (retries >= MAX_RETRIES) { - bzero(addr, sizeof(struct sockaddr_in)); - if (tell_parent(broad_domain->dom_domain, addr)) - syslog(LOG_WARNING, "lost connection to parent"); - return (TRUE); - } - - if (yp_restricted && verify(addr->sin_addr)) { - retries++; - syslog(LOG_NOTICE, "NIS server at %s not in restricted mode access list -- rejecting.\n",inet_ntoa(addr->sin_addr)); - return (FALSE); - } else { - if (tell_parent(broad_domain->dom_domain, addr)) - syslog(LOG_WARNING, "lost connection to parent"); - return (TRUE); - } -} - -/* - * The right way to send RPC broadcasts. - * Use the clnt_broadcast() RPC service. Unfortunately, clnt_broadcast() - * blocks while waiting for replies, so we have to fork off separate - * broadcaster processes that do the waiting and then transmit their - * results back to the parent for processing. We also have to remember - * to save the name of the domain we're trying to bind in a global - * variable since clnt_broadcast() provides no way to pass things to - * the 'eachresult' callback function. - */ -void -broadcast(struct _dom_binding *ypdb) -{ - bool_t out = FALSE; - enum clnt_stat stat; - - if (children >= MAX_CHILDREN || ypdb->dom_broadcast_pid) - return; - - if (pipe(ypdb->dom_pipe_fds) < 0) { - syslog(LOG_WARNING, "pipe: %m"); - return; - } - - if (ypdb->dom_vers == -1 && (long)ypdb->dom_server_addr.sin_addr.s_addr) { - if (not_responding_count++ >= NOT_RESPONDING_HYSTERESIS) { - not_responding_count = NOT_RESPONDING_HYSTERESIS; - syslog(LOG_WARNING, "NIS server [%s] for domain \"%s\" not responding", - inet_ntoa(ypdb->dom_server_addr.sin_addr), ypdb->dom_domain); - } - } - - broad_domain = ypdb; - flock(ypdb->dom_lockfd, LOCK_UN); - - switch ((ypdb->dom_broadcast_pid = fork())) { - case 0: - close(READFD); - signal(SIGCHLD, SIG_DFL); - signal(SIGTERM, SIG_DFL); - break; - case -1: - syslog(LOG_WARNING, "fork: %m"); - close(READFD); - close(WRITEFD); - return; - default: - close(WRITEFD); - FD_SET(READFD, &svc_fdset); - children++; - return; - } - - /* Release all locks before doing anything else. */ - while (ypbindlist) { - close(ypbindlist->dom_lockfd); - ypbindlist = ypbindlist->dom_pnext; - } - close(yplockfd); - - /* - * Special 'many-cast' behavior. If we're in restricted mode, - * we have a list of possible server addresses to try. What - * we can do is transmit to each ypserv's YPPROC_DOMAIN_NONACK - * procedure and time the replies. Whoever replies fastest - * gets to be our server. Note that this is not a broadcast - * operation: we transmit uni-cast datagrams only. - */ - if (yp_restricted && yp_manycast) { - short port; - int i; - struct sockaddr_in sin; - - i = __yp_ping(restricted_addrs, yp_restricted, - ypdb->dom_domain, &port); - if (i == -1) { - bzero(&ypdb->dom_server_addr, - sizeof(struct sockaddr_in)); - if (tell_parent(ypdb->dom_domain, - &ypdb->dom_server_addr)) - syslog(LOG_WARNING, "lost connection to parent"); - } else { - bzero(&sin, sizeof(struct sockaddr_in)); - bcopy(&restricted_addrs[i], - &sin.sin_addr, sizeof(struct in_addr)); - sin.sin_family = AF_INET; - sin.sin_port = port; - if (tell_parent(broad_domain->dom_domain, &sin)) - syslog(LOG_WARNING, - "lost connection to parent"); - } - _exit(0); - } - - retries = 0; - - { - char *ptr; - - ptr = ypdb->dom_domain; - stat = clnt_broadcast(YPPROG, YPVERS, YPPROC_DOMAIN_NONACK, - (xdrproc_t)xdr_domainname, &ptr, - (xdrproc_t)xdr_bool, &out, - (resultproc_t)broadcast_result); - } - - if (stat != RPC_SUCCESS) { - bzero(&ypdb->dom_server_addr, - sizeof(struct sockaddr_in)); - if (tell_parent(ypdb->dom_domain, &ypdb->dom_server_addr)) - syslog(LOG_WARNING, "lost connection to parent"); - } - - _exit(0); -} - -/* - * The right way to check if a server is alive. - * Attempt to get a client handle pointing to the server and send a - * YPPROC_DOMAIN. If we can't get a handle or we get a reply of FALSE, - * we invalidate this binding entry and send out a broadcast to try to - * establish a new binding. Note that we treat non-default domains - * specially: once bound, we keep tabs on our server, but if it - * goes away and fails to respond after one round of broadcasting, we - * abandon it until a client specifically references it again. We make - * every effort to keep our default domain bound, however, since we - * need it to keep the system on its feet. - */ -int -ping(struct _dom_binding *ypdb) -{ - bool_t out; - struct timeval interval, timeout; - enum clnt_stat stat; - int rpcsock = RPC_ANYSOCK; - CLIENT *client_handle; - - interval.tv_sec = FAIL_THRESHOLD; - interval.tv_usec = 0; - timeout.tv_sec = FAIL_THRESHOLD; - timeout.tv_usec = 0; - - if (ypdb->dom_broadcast_pid) - return(1); - - if ((client_handle = clntudp_bufcreate(&ypdb->dom_server_addr, - YPPROG, YPVERS, interval, &rpcsock, RPCSMALLMSGSIZE, - RPCSMALLMSGSIZE)) == (CLIENT *)NULL) { - /* Can't get a handle: we're dead. */ - ypdb->dom_alive = 0; - ypdb->dom_vers = -1; - broadcast(ypdb); - return(1); - } - - { - char *ptr; - - ptr = ypdb->dom_domain; - - stat = clnt_call(client_handle, YPPROC_DOMAIN, - (xdrproc_t)xdr_domainname, &ptr, - (xdrproc_t)xdr_bool, &out, timeout); - if (stat != RPC_SUCCESS || out == FALSE) { - ypdb->dom_alive = 0; - ypdb->dom_vers = -1; - clnt_destroy(client_handle); - broadcast(ypdb); - return(1); - } - } - - clnt_destroy(client_handle); - return(0); -} - -void -rpc_received(char *dom, struct sockaddr_in *raddrp, int force) -{ - struct _dom_binding *ypdb, *prev = NULL; - struct iovec iov[2]; - struct ypbind_resp ybr; - char path[MAXPATHLEN]; - int fd; - - /*printf("returned from %s/%d about %s\n", inet_ntoa(raddrp->sin_addr), - ntohs(raddrp->sin_port), dom);*/ - - if (dom == NULL) - return; - - for (ypdb = ypbindlist; ypdb; ypdb = ypdb->dom_pnext) { - if (strcmp(ypdb->dom_domain, dom) == 0) - break; - prev = ypdb; - } - - if (ypdb && force) { - if (ypdb->dom_broadcast_pid) { - kill(ypdb->dom_broadcast_pid, SIGINT); - close(READFD); - FD_CLR(READFD, &fdsr); - FD_CLR(READFD, &svc_fdset); - READFD = WRITEFD = -1; - } - } - - /* if in secure mode, check originating port number */ - if ((ypsecuremode && (ntohs(raddrp->sin_port) >= IPPORT_RESERVED))) { - syslog(LOG_WARNING, "Rejected NIS server on [%s/%d] for domain %s.", - inet_ntoa(raddrp->sin_addr), ntohs(raddrp->sin_port), - dom); - if (ypdb != NULL) { - ypdb->dom_broadcast_pid = 0; - ypdb->dom_alive = 0; - } - return; - } - - if (raddrp->sin_addr.s_addr == (long)0) { - switch (ypdb->dom_default) { - case 0: - if (prev == NULL) - ypbindlist = ypdb->dom_pnext; - else - prev->dom_pnext = ypdb->dom_pnext; - sprintf(path, "%s/%s.%ld", BINDINGDIR, - ypdb->dom_domain, YPVERS); - close(ypdb->dom_lockfd); - unlink(path); - free(ypdb); - domains--; - return; - case 1: - ypdb->dom_broadcast_pid = 0; - ypdb->dom_alive = 0; - broadcast(ypdb); - return; - default: - break; - } - } - - if (ypdb == NULL) { - if (force == 0) - return; - ypdb = (struct _dom_binding *)malloc(sizeof *ypdb); - if (ypdb == NULL) { - syslog(LOG_WARNING, "malloc: %m"); - return; - } - bzero(ypdb, sizeof *ypdb); - strncpy(ypdb->dom_domain, dom, sizeof ypdb->dom_domain); - ypdb->dom_lockfd = -1; - ypdb->dom_default = 0; - ypdb->dom_pnext = ypbindlist; - ypbindlist = ypdb; - } - - /* We've recovered from a crash: inform the world. */ - if (ypdb->dom_vers == -1 && ypdb->dom_server_addr.sin_addr.s_addr) { - if (not_responding_count >= NOT_RESPONDING_HYSTERESIS) { - not_responding_count = 0; - syslog(LOG_WARNING, "NIS server [%s] for domain \"%s\" OK", - inet_ntoa(raddrp->sin_addr), ypdb->dom_domain); - } - } - - bcopy(raddrp, &ypdb->dom_server_addr, - sizeof ypdb->dom_server_addr); - - ypdb->dom_vers = YPVERS; - ypdb->dom_alive = 1; - ypdb->dom_broadcast_pid = 0; - - if (ypdb->dom_lockfd != -1) - close(ypdb->dom_lockfd); - - sprintf(path, "%s/%s.%ld", BINDINGDIR, - ypdb->dom_domain, ypdb->dom_vers); -#ifdef O_SHLOCK - if ((fd = open(path, O_CREAT|O_SHLOCK|O_RDWR|O_TRUNC, 0644)) == -1) { - (void)mkdir(BINDINGDIR, 0755); - if ((fd = open(path, O_CREAT|O_SHLOCK|O_RDWR|O_TRUNC, 0644)) == -1) - return; - } -#else - if ((fd = open(path, O_CREAT|O_RDWR|O_TRUNC, 0644)) == -1) { - (void)mkdir(BINDINGDIR, 0755); - if ((fd = open(path, O_CREAT|O_RDWR|O_TRUNC, 0644)) == -1) - return; - } - flock(fd, LOCK_SH); -#endif - - /* - * ok, if BINDINGDIR exists, and we can create the binding file, - * then write to it.. - */ - ypdb->dom_lockfd = fd; - - iov[0].iov_base = (char *)&(udptransp->xp_port); - iov[0].iov_len = sizeof udptransp->xp_port; - iov[1].iov_base = (char *)&ybr; - iov[1].iov_len = sizeof ybr; - - bzero(&ybr, sizeof ybr); - ybr.ypbind_status = YPBIND_SUCC_VAL; - *(u_int32_t *)&ybr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr = raddrp->sin_addr.s_addr; - *(u_short *)&ybr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port = raddrp->sin_port; - - if (writev(ypdb->dom_lockfd, iov, 2) != iov[0].iov_len + iov[1].iov_len) { - syslog(LOG_WARNING, "write: %m"); - close(ypdb->dom_lockfd); - ypdb->dom_lockfd = -1; - return; - } -} - -/* - * Check address against list of allowed servers. Return 0 if okay, - * 1 if not matched. - */ -int -verify(struct in_addr addr) -{ - int i; - - for (i = 0; i < RESTRICTED_SERVERS; i++) - if (!bcmp(&addr, &restricted_addrs[i], sizeof(struct in_addr))) - return(0); - - return(1); -} - -/* - * Try to set restricted mode. We default to normal mode if we can't - * resolve the specified hostnames. - */ -void -yp_restricted_mode(char *args) -{ - struct hostent *h; - int i = 0; - char *s; - - /* Find the restricted domain. */ - if ((s = strsep(&args, ",")) == NULL) - return; - domain_name = s; - - /* Get the addresses of the servers. */ - while ((s = strsep(&args, ",")) != NULL && i < RESTRICTED_SERVERS) { - if ((h = gethostbyname(s)) == NULL) - return; - bcopy (h->h_addr_list[0], &restricted_addrs[i], - sizeof(struct in_addr)); - i++; - } - - /* ypset and ypsetme not allowed with restricted mode */ - ypsetmode = YPSET_NO; - - yp_restricted = i; - return; -} |