From owner-svn-soc-all@FreeBSD.ORG Thu Aug 2 01:21:01 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id F0AEE106564A for ; Thu, 2 Aug 2012 01:20:58 +0000 (UTC) (envelope-from exxo@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Thu, 02 Aug 2012 01:20:58 +0000 Date: Thu, 02 Aug 2012 01:20:58 +0000 From: exxo@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120802012058.F0AEE106564A@hub.freebsd.org> Cc: Subject: socsvn commit: r240004 - in soc2012/exxo/freebsd-head: include/rpcsvc usr.bin/ypwhich usr.sbin/ypbind X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 02 Aug 2012 01:21:01 -0000 Author: exxo Date: Thu Aug 2 01:20:58 2012 New Revision: 240004 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=240004 Log: ypbind/ypwhich updated, adding yp_utils Added: soc2012/exxo/freebsd-head/include/rpcsvc/yp_utils.h Modified: soc2012/exxo/freebsd-head/include/rpcsvc/yp.x soc2012/exxo/freebsd-head/include/rpcsvc/yp_prot.h soc2012/exxo/freebsd-head/usr.bin/ypwhich/Makefile soc2012/exxo/freebsd-head/usr.bin/ypwhich/ypwhich.c soc2012/exxo/freebsd-head/usr.sbin/ypbind/Makefile soc2012/exxo/freebsd-head/usr.sbin/ypbind/yp_ping.c soc2012/exxo/freebsd-head/usr.sbin/ypbind/yp_ping.h soc2012/exxo/freebsd-head/usr.sbin/ypbind/ypbind.c Modified: soc2012/exxo/freebsd-head/include/rpcsvc/yp.x ============================================================================== --- soc2012/exxo/freebsd-head/include/rpcsvc/yp.x Thu Aug 2 00:00:34 2012 (r240003) +++ soc2012/exxo/freebsd-head/include/rpcsvc/yp.x Thu Aug 2 01:20:58 2012 (r240004) @@ -223,8 +223,6 @@ ypbind_binding ypsetdom_binding; unsigned ypsetdom_vers; }; -%#define ypsetdom_addr ypsetdom_binding.ypbind_binding_addr -%#define ypsetdom_port ypsetdom_binding.ypbind_binding_port /* Backward compatibility for YPBIND protocol version 2 */ #ifdef YPBIND_COMPAT_V2 @@ -249,17 +247,8 @@ unsigned ypsetdom_vers; }; -%#define yprespv2_error ypbind_resp_v2_u.ypbind_error -%#define yprespv2_addr ypbind_resp_v2_u.ypbind_bindinfo.ypbind_binding_addr -%#define yprespv2_port ypbind_resp_v2_u.ypbind_bindinfo.ypbind_binding_port - #endif -%#define ypresp_error ypbind_resp_u.ypbind_error -%#define ypresp_family ypbind_resp_u.ypbind_bindinfo.ypbind_binding_family -%#define ypresp_addr ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr -%#define ypresp_port ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port - /* * NIS v1 support for backwards compatibility */ Modified: soc2012/exxo/freebsd-head/include/rpcsvc/yp_prot.h ============================================================================== --- soc2012/exxo/freebsd-head/include/rpcsvc/yp_prot.h Thu Aug 2 00:00:34 2012 (r240003) +++ soc2012/exxo/freebsd-head/include/rpcsvc/yp_prot.h Thu Aug 2 01:20:58 2012 (r240004) @@ -296,17 +296,8 @@ u_int ypsetdom_vers; }; -#define yprespv2_error ypbind_resp_v2_u.ypbind_error -#define yprespv2_addr ypbind_resp_v2_u.ypbind_bindinfo.ypbind_binding_addr -#define yprespv2_port ypbind_resp_v2_u.ypbind_bindinfo.ypbind_binding_port - #endif -#define ypresp_error ypbind_resp_u.ypbind_error -#define ypresp_family ypbind_resp_u.ypbind_bindinfo.ypbind_binding_family -#define ypresp_addr ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr -#define ypresp_port ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port - /* * YPPUSH PROTOCOL: * Added: soc2012/exxo/freebsd-head/include/rpcsvc/yp_utils.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2012/exxo/freebsd-head/include/rpcsvc/yp_utils.h Thu Aug 2 01:20:58 2012 (r240004) @@ -0,0 +1,109 @@ +/* + * Copyright (c) TODO + * 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. + * + * $FreeBSD: soc2012/exxo/freebsd-head/include/rpcsvc/yp_prot.h 239957 2012-07-31 16:20:04Z exxo $ + */ + +#ifndef _RPCSVC_YP_UTILS_H_ +#define _RPCSVC_YP_UTILS_H_ + +/* YPBIND facilities + * + * This file should be included after or + * It provides facilities to deal with YPBIND protocols + */ + +#define ypresp_status ypbind_status +#define ypsetdom_family ypsetdom_binding.ypbind_binding_family + +#ifdef _RPCSVC_YP_PROT_H_ /* if used with yp_prot.h */ + +# define ypresp_family ypbind_respbody.ypbind_bindinfo.ypbind_binding_family +# define ypresp_error ypbind_respbody.ypbind_error +# define ypresp_addr ypbind_respbody.ypbind_bindinfo.ypbind_binding_addr +# define ypresp_port ypbind_respbody.ypbind_bindinfo.ypbind_binding_port + +#elif defined(_YP_H_RPCGEN) /* if used with yp.h */ + +# define ypsetdom_addr ypsetdom_binding.ypbind_binding_addr +# define ypsetdom_port ypsetdom_binding.ypbind_binding_port + +# define ypresp_family ypbind_resp_u.ypbind_bindinfo.ypbind_binding_family +# define ypresp_error ypbind_resp_u.ypbind_error +# define ypresp_addr ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr +# define ypresp_port ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port +# define ypresp_error_v2 ypbind_resp_v2_u.ypbind_error +# define ypresp_addr_v2 ypbind_resp_v2_u.ypbind_bindinfo.ypbind_binding_addr +# define ypresp_port_v2 ypbind_resp_v2_u.ypbind_bindinfo.ypbind_binding_port + +#endif + +union ypbf_resp { + struct { + enum ypbind_resptype status; + u_int error; + } header; + struct ypbind_resp resp; +#ifdef YPBIND_COMPAT_V2 + struct ypbind_resp_v2 resp2; +#endif +}; +#define ypbf_rstatus header.status +#define ypbf_rerror header.error +#define ypbf_rfamily resp.ypresp_family +#define ypbf_raddr resp.ypresp_addr +#define ypbf_rport resp.ypresp_port +#ifdef YPBIND_COMPAT_V2 +# ifdef _RPCSVC_YP_PROT_H_ /* yp_prot.h */ +# define ypbf_raddr_v2 resp2.ypresp_addr +# define ypbf_rport_v2 resp2.ypresp_port +# elif defined(_YP_H_RPCGEN) /* yp.h */ +# define ypbf_raddr_v2 resp2.ypresp_addr_v2 +# define ypbf_rport_v2 resp2.ypresp_port_v2 +# endif +#endif + +union ypbf_setdom { + char ypsetdom_domain[YPMAXDOMAIN + 1]; + struct ypbind_setdom setdom; +#ifdef YPBIND_COMPAT_V2 + struct ypbind_setdom_v2 setdom2; +#endif +}; +#define ypbf_sdomain ypsetdom_domain +#define ypbf_sfamily setdom.ypsetdom_family +#define ypbf_saddr setdom.ypsetdom_addr +#define ypbf_sport setdom.ypsetdom_port +#define ypbf_svers setdom.ypsetdom_vers +#ifdef YPBIND_COMPAT_V2 +# define ypbf_saddr_v2 setdom2.ypsetdom_addr +# define ypbf_sport_v2 setdom2.ypsetdom_port +# define ypbf_svers_v2 setdom2.ypsetdom_vers +#endif + +#endif /* _RPCSVC_YP_UTILS_H_ */ Modified: soc2012/exxo/freebsd-head/usr.bin/ypwhich/Makefile ============================================================================== --- soc2012/exxo/freebsd-head/usr.bin/ypwhich/Makefile Thu Aug 2 00:00:34 2012 (r240003) +++ soc2012/exxo/freebsd-head/usr.bin/ypwhich/Makefile Thu Aug 2 01:20:58 2012 (r240004) @@ -7,8 +7,9 @@ WARNS?= 2 +CFLAGS += -DYPBIND_COMPAT_V2 .if ${MK_INET6_SUPPORT} != "no" -CFLAGS+= -DINET6 -DYPBIND_COMPAT_V2 +CFLAGS += -DINET6 .endif .include Modified: soc2012/exxo/freebsd-head/usr.bin/ypwhich/ypwhich.c ============================================================================== --- soc2012/exxo/freebsd-head/usr.bin/ypwhich/ypwhich.c Thu Aug 2 00:00:34 2012 (r240003) +++ soc2012/exxo/freebsd-head/usr.bin/ypwhich/ypwhich.c Thu Aug 2 01:20:58 2012 (r240004) @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -83,24 +84,6 @@ exit(ERR_USAGE); } -union ypb_resp { - struct { - enum ypbind_resptype status; - u_int error; - } header; - struct ypbind_resp resp; -#ifdef YPBIND_COMPAT_V2 - struct ypbind_resp_v2 resp2; -#endif -}; -#define ypb_status header.status -#define ypb_error header.error -#define ypb_family resp.ypbind_respbody.ypbind_bindinfo.ypbind_binding_family -#define ypb_addr resp.ypbind_respbody.ypbind_bindinfo.ypbind_binding_addr -#ifdef YPBIND_COMPAT_V2 -# define ypb_addr_v2 resp2.ypbind_respbody.ypbind_bindinfo.ypbind_binding_addr -#endif - #ifdef INET6 # define ADDRSTRLEN INET6_ADDRSTRLEN #else @@ -108,7 +91,7 @@ #endif static void -print_addr(const union ypb_resp *ypbr, int version) +print_addr(const union ypbf_resp *ypbr, int version) { struct hostent *hent = NULL; char str[ADDRSTRLEN]; @@ -125,19 +108,19 @@ if (version == YPBINDVERS_2) { family = AF_INET; len = sizeof(ss_addr.in); - bcopy(&ypbr->ypb_addr_v2, &ss_addr, len); + bcopy(&ypbr->ypbf_raddr_v2, &ss_addr, len); } else /* YPBINDVERS */ #endif { - family = ypbr->ypb_family; + family = ypbr->ypbf_rfamily; #ifdef INET6 if (family == AF_INET6) len = sizeof(ss_addr.in6); else /* AF_INET */ #endif len = sizeof(ss_addr.in); - bcopy(&ypbr->ypb_addr, &ss_addr, len); + bcopy(&ypbr->ypbf_raddr, &ss_addr, len); } hent = gethostbyaddr((char *)&ss_addr, len, family); if (hent) @@ -152,7 +135,7 @@ static int bind_host(char *dom, const char *host) { - union ypb_resp ypbr; + union ypbf_resp ypbr; struct timeval tv; CLIENT *client; int r; @@ -186,9 +169,9 @@ clnt_destroy(client); return (YPERR_YPBIND); } else { - if (ypbr.ypb_status != YPBIND_SUCC_VAL) { + if (ypbr.ypbf_rstatus != YPBIND_SUCC_VAL) { warnx("can't yp_bind: reason: %s", - ypbinderr_string(ypbr.ypb_error)); + ypbinderr_string(ypbr.ypbf_rerror)); clnt_destroy(client); return (r); } Modified: soc2012/exxo/freebsd-head/usr.sbin/ypbind/Makefile ============================================================================== --- soc2012/exxo/freebsd-head/usr.sbin/ypbind/Makefile Thu Aug 2 00:00:34 2012 (r240003) +++ soc2012/exxo/freebsd-head/usr.sbin/ypbind/Makefile Thu Aug 2 01:20:58 2012 (r240004) @@ -1,11 +1,16 @@ # from: @(#)Makefile 5.8 (Berkeley) 7/28/90 # $FreeBSD$ +.include + PROG= ypbind MAN= ypbind.8 SRCS= ypbind.c yp_ping.c -CFLAGS+= -DDAEMON +CFLAGS += -DDAEMON -DYPBIND_COMPAT_V2 +.if ${MK_INET6_SUPPORT} != "no" +CFLAGS += -DINET6 +.endif WARNS?= 2 Modified: soc2012/exxo/freebsd-head/usr.sbin/ypbind/yp_ping.c ============================================================================== --- soc2012/exxo/freebsd-head/usr.sbin/ypbind/yp_ping.c Thu Aug 2 00:00:34 2012 (r240003) +++ soc2012/exxo/freebsd-head/usr.sbin/ypbind/yp_ping.c Thu Aug 2 01:20:58 2012 (r240004) @@ -275,36 +275,36 @@ static int rpc_init(struct transport *tsp) { - static timeval timenull; + static struct timeval timenull; int async = TRUE; int dontblock = 1; int validtransp = 0; int i; for (i = 0; i < TSP_LEN; ++i) { - if (tsp[i]->any == NULL) + if (tsp[i].any == NULL) continue; #ifdef INET6 if (i == V6) { - tsp[i]->sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); - tsp[i]->addr.len = sizeof(struct sockaddr_in6); + tsp[i].sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); + tsp[i].addr.len = sizeof(struct sockaddr_in6); } else /* V4 */ #endif { - tsp[i]->sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); - tsp[i]->addr.len = sizeof(struct sockaddr_in); + tsp[i].sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + tsp[i].addr.len = sizeof(struct sockaddr_in); } - if (tsp[i]->sock < 0) + if (tsp[i].sock < 0) return (1); - tsp[i]->addr.buf = tsp[i]->any; - tsp[i]->clnt = clnt_dg_create(tsp[i]->sock, &tsp[i]->addr, YPPROG, YPVERS, 0, 0); - if (tsp[i]->clnt == NULL) + tsp[i].addr.buf = tsp[i].any; + tsp[i].clnt = clnt_dg_create(tsp[i].sock, &tsp[i].addr, YPPROG, YPVERS, 0, 0); + if (tsp[i].clnt == NULL) return (1); - tsp[i]->clnt->cl_auth = authsys_create_default(); - clnt_control(tsp[i]->clnt, CLSET_TIMEOUT, (char *)&timenull); - clnt_control(tsp[i]->clnt, CLSET_ASYNC, (char *)&async); - ioctl(tsp[i]->sock, FIONBIO, &dontblock); + tsp[i].clnt->cl_auth = authsys_create_default(); + clnt_control(tsp[i].clnt, CLSET_TIMEOUT, (char *)&timenull); + clnt_control(tsp[i].clnt, CLSET_ASYNC, (char *)&async); + ioctl(tsp[i].sock, FIONBIO, &dontblock); ++validtransp; } return (!validtransp); @@ -316,16 +316,16 @@ int i; for (i = 0; i < TSP_LEN; ++i) { - if (tsp[i]->clnt) { - auth_destroy(tsp[i]->clnt->cl_auth); - clnt_destroy(tsp[i]->clnt); - tsp[i]->clnt = NULL; - } - tsp[i]->xid_lookup = 0; - tsp[i]->any = NULL; - close(tsp[i]->sock); - tsp[i]->sock = -1; - tsp[i]->addr.buf = NULL; + if (tsp[i].clnt) { + auth_destroy(tsp[i].clnt->cl_auth); + clnt_destroy(tsp[i].clnt); + tsp[i].clnt = NULL; + } + tsp[i].xid_lookup = 0; + tsp[i].any = NULL; + close(tsp[i].sock); + tsp[i].sock = -1; + tsp[i].addr.buf = NULL; } } Modified: soc2012/exxo/freebsd-head/usr.sbin/ypbind/yp_ping.h ============================================================================== --- soc2012/exxo/freebsd-head/usr.sbin/ypbind/yp_ping.h Thu Aug 2 00:00:34 2012 (r240003) +++ soc2012/exxo/freebsd-head/usr.sbin/ypbind/yp_ping.h Thu Aug 2 01:20:58 2012 (r240004) @@ -14,8 +14,8 @@ #define ss_family(x) (((struct sockaddr *) x)->sa_family) #define ss_to_sinaddr(x) ((char *) &((struct sockaddr_in *) x)->sin_addr) #define ss_to_sin6addr(x) ((char *) &((struct sockaddr_in6 *) x)->sin6_addr) -#define ss_to_sinport(x) ((u_short) ((struct sockaddr_in *) x)->sin_port) -#define ss_to_sin6port(x) ((u_short) ((struct sockaddr_in6 *) x)->sin6_port) +#define ss_to_sinport(x) (((struct sockaddr_in *) x)->sin_port) +#define ss_to_sin6port(x) (((struct sockaddr_in6 *) x)->sin6_port) static inline int ss_extract(const struct sockaddr_storage *ss, int *family, char **addr, size_t *len) Modified: soc2012/exxo/freebsd-head/usr.sbin/ypbind/ypbind.c ============================================================================== --- soc2012/exxo/freebsd-head/usr.sbin/ypbind/ypbind.c Thu Aug 2 00:00:34 2012 (r240003) +++ soc2012/exxo/freebsd-head/usr.sbin/ypbind/ypbind.c Thu Aug 2 01:20:58 2012 (r240004) @@ -57,11 +57,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include "yp_ping.h" @@ -80,7 +82,7 @@ struct _dom_binding { struct _dom_binding *dom_pnext; char dom_domain[YPMAXDOMAIN + 1]; - struct sockaddr_storage dom_server_addr; /* TODO */ + struct sockaddr_storage dom_server_addr; long int dom_vers; int dom_lockfd; #ifdef YPBIND_COMPAT_V2 @@ -96,22 +98,26 @@ #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_domainname(); extern bool_t xdr_ypreq_key(), xdr_ypresp_val(); -extern bool_t xdr_ypbind_setdom(); +extern bool_t xdr_ypbind_setdom(), xdr_ypbind_setdom_v2(); +extern bool_t xdr_ypbind_resp(), xdr_ypbind_resp_v2(); +void *ypbindproc_null(SVCXPRT *, void *, const rpcvers_t); +void *ypbindproc_setdom(SVCXPRT *, const union ypbf_setdom *, const rpcvers_t); +char *ypbindproc_domain(SVCXPRT *, domainname *, const rpcvers_t); +void ypbindprog(struct svc_req *, register SVCXPRT *); +void reaper(int); +void terminate(int); 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 handle_children(struct _dom_binding *); +int tell_parent(char *, const struct sockaddr_storage *); +bool_t broadcast_result(bool_t *, const struct netbuf *, const struct netconfig *); 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 rpc_received(char *, const struct sockaddr_storage *, int); +int verify(const struct sockaddr_storage *); void yp_restricted_mode(char *); -int verify(struct in_addr); char *domain_name; struct _dom_binding *ypbindlist; @@ -155,38 +161,166 @@ #define MAX_RETRIES 30 #endif -#define CLOSE_LKS 1 -#define FREE_DOMB 2 - int retries = 0; int children = 0; int domains = 0; int yplockfd; fd_set fdsr; +#define CLOSE_LKS 1 +#define FREE_DOMB 2 + +static int +create_domb_file(const struct _dom_binding *ypdb, const char *binding_dir) +{ + char path[MAXPATHLEN]; + int fd; + + sprintf(path, "%s/%s.%ld", binding_dir, + 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(binding_dir, 0755); + if ((fd = open(path, O_CREAT|O_SHLOCK|O_RDWR|O_TRUNC, 0644)) == -1) + return (-1); + } +#else + if ((fd = open(path, O_CREAT|O_RDWR|O_TRUNC, 0644)) == -1) { + (void)mkdir(binding_dir, 0755); + if ((fd = open(path, O_CREAT|O_RDWR|O_TRUNC, 0644)) == -1) + return (-1); + } + flock(fd, LOCK_SH); +#endif + return (fd); +} + +static void +register_domb(struct _dom_binding *ypdb, const struct sockaddr_storage *addr) +{ + struct iovec iov[2]; + struct ypbind_resp ybr; + int family; + u_short port; + + if (ypdb->dom_lockfd != -1) + close(ypdb->dom_lockfd); + + ypdb->dom_lockfd = create_domb_file(ypdb, BINDINGDIR); + if (ypdb->dom_lockfd == -1) + return; + + port = __rpcb_getport("127.0.0.1", CONNLESS_TSP, YPBINDPROG, YPBINDVERS); + iov[0].iov_base = (char *)&port; + iov[0].iov_len = sizeof(port); + iov[1].iov_base = (char *)&ybr; + iov[1].iov_len = sizeof(ybr); + + family = ss_family(addr); + bzero(&ybr, sizeof(ybr)); + ybr.ypresp_status = YPBIND_SUCC_VAL; + ybr.ypresp_family = family; + *(u_short *)&ybr.ypresp_port = *ss_getport(addr); +#ifdef INET6 + if (family == AF_INET6) + bcopy(ss_to_sin6addr(addr), (char *) ybr.ypresp_addr, sizeof(struct in6_addr)); + else +#endif + bcopy(ss_to_sinaddr(addr), (char *) ybr.ypresp_addr, sizeof(struct in_addr)); + + 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; + } +} + +#ifdef YPBIND_COMPAT_V2 +static void +register_domb_v2(struct _dom_binding *ypdb, const struct sockaddr_storage *addr) +{ + struct iovec iov[2]; + struct ypbind_resp_v2 ybr; + int family; + u_short port; + + if (ypdb->dom_lockfd_v2 != -1) + close(ypdb->dom_lockfd_v2); + + ypdb->dom_lockfd_v2 = create_domb_file(ypdb, BINDINGDIR_V2); + if (ypdb->dom_lockfd_v2 == -1) + return; + + port = __rpcb_getport("127.0.0.1", CONNLESS_TSP, YPBINDPROG, YPBINDVERS_2); + iov[0].iov_base = (char *)&port; + iov[0].iov_len = sizeof(port); + iov[1].iov_base = (char *)&ybr; + iov[1].iov_len = sizeof(ybr); + + family = ss_family(addr); + bzero(&ybr, sizeof(ybr)); + if (family != AF_INET) { /* AF_INET6 is not supported in version 2 */ + ybr.ypresp_status = YPBIND_FAIL_VAL; + ybr.ypresp_error_v2 = YPBIND_ERR_FAMILY; + } + else { + ybr.ypresp_status = YPBIND_SUCC_VAL; + bcopy(ss_to_sinaddr(addr), (char *) ybr.ypresp_addr_v2, sizeof(struct in_addr)); + *(u_short *)&ybr.ypresp_port_v2 = ss_to_sinport(addr); + } + + if (writev(ypdb->dom_lockfd_v2, iov, 2) != iov[0].iov_len + iov[1].iov_len) { + syslog(LOG_WARNING, "write: %m"); + close(ypdb->dom_lockfd_v2); + ypdb->dom_lockfd_v2 = -1; + } +} +#endif + +static void +unregister_domb(struct _dom_binding *ypdb, unsigned char mode) +{ + char path[MAXPATHLEN]; + + sprintf(path, "%s/%s.%ld", BINDINGDIR, + ypdb->dom_domain, YPVERS); + if ( (mode & CLOSE_LKS)) + close(ypdb->dom_lockfd); + unlink(path); +#ifdef YPBIND_COMPAT_V2 + sprintf(path, "%s/%s.%ld", BINDINGDIR_V2, + ypdb->dom_domain, YPVERS); + if ( (mode & CLOSE_LKS)) + close(ypdb->dom_lockfd_v2); + unlink(path); +#endif + if ( (mode & FREE_DOMB)) { + free(ypdb); + domains--; + } +} + void * -ypbindproc_null_2_yp(SVCXPRT *transp, void *argp, CLIENT *clnt) +ypbindproc_null(SVCXPRT *transp, void *argp, const rpcvers_t version) { - static char res; + static const char res; - bzero(&res, sizeof(res)); - return &res; + return ((void *) &res); } -struct ypbind_resp * -ypbindproc_domain_2_yp(SVCXPRT *transp, domainname *argp, CLIENT *clnt) +char * +ypbindproc_domain(SVCXPRT *transp, domainname *argp, const rpcvers_t version) { - static struct ypbind_resp res; + static union ypbf_resp res; struct _dom_binding *ypdb; + int family; - bzero(&res, sizeof res); - res.ypbind_status = YPBIND_FAIL_VAL; - res.ypbind_resp_u.ypbind_error = YPBIND_ERR_NOSERV; + res.ypbf_rstatus = YPBIND_FAIL_VAL; + res.ypbf_rerror = YPBIND_ERR_NOSERV; if (strchr(*argp, '/')) { - syslog(LOG_WARNING, "Domain name '%s' has embedded slash -- \ -rejecting.", *argp); - return(&res); + syslog(LOG_WARNING, "Domain name '%s' has embedded slash -- rejecting.", *argp); + return((char *) &res); } for (ypdb = ypbindlist; ypdb; ypdb = ypdb->dom_pnext) { @@ -197,20 +331,19 @@ if (ypdb == NULL) { if (yp_restricted) { syslog(LOG_NOTICE, "Running in restricted mode -- request to bind domain \"%s\" rejected.\n", *argp); - return (&res); + return ((char *) &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); + syslog(LOG_WARNING, "domain limit (%d) exceeded", MAX_DOMAINS); + res.ypbf_rerror = YPBIND_ERR_RESC; + return ((char *) &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); + res.ypbf_rerror = YPBIND_ERR_RESC; + return ((char *) &res); } bzero(ypdb, sizeof *ypdb); strncpy(ypdb->dom_domain, *argp, sizeof ypdb->dom_domain); @@ -227,111 +360,186 @@ domains++; } - if (ping(ypdb)) { - return (&res); - } + if (ping(ypdb)) + return ((char *) &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); + res.ypbf_rstatus = YPBIND_SUCC_VAL; + res.ypbf_rerror = 0; /* Success */ + family = ss_family(&ypdb->dom_server_addr); +#ifdef YPBIND_COMPAT_V2 + if (version == YPBINDVERS_2) { + if (family != AF_INET) { /* AF_INET6 is not supported in version 2 */ + res.ypbf_rstatus = YPBIND_FAIL_VAL; + res.ypbf_rerror = YPBIND_ERR_FAMILY; + } + else { + bcopy(ss_to_sinaddr(&ypdb->dom_server_addr), (char *) res.ypbf_raddr_v2, sizeof(struct in_addr)); + *(u_short *)&res.ypbf_rport_v2 = ss_to_sinport(&ypdb->dom_server_addr); + } + } + else +#endif + { + res.ypbf_rfamily = family; + *(u_short *)&res.ypbf_rport = *ss_getport(&ypdb->dom_server_addr); +#ifdef INET6 + if (family == AF_INET6) + bcopy(ss_to_sin6addr(&ypdb->dom_server_addr), (char *) res.ypbf_raddr, sizeof(struct in6_addr)); + else +#endif + bcopy(ss_to_sinaddr(&ypdb->dom_server_addr), (char *) res.ypbf_raddr, sizeof(struct in_addr)); + } + return ((char *) &res); } -void * -ypbindproc_setdom_2_yp(SVCXPRT *transp, ypbind_setdom *argp, CLIENT *clnt) +static int +is_loopback(const char *buf, size_t len) { - struct sockaddr_in *fromsin, bindsin; - static char *result = NULL; + int ret = 0; - 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); - } + switch (len) { + case sizeof(struct sockaddr_in) : + if (((struct sockaddr_in *) buf)->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) + ret = 1; break; - case YPSET_ALL: +#ifdef INET6 + case sizeof(struct sockaddr_in6) : + if (IN6_IS_ADDR_LOOPBACK(&((struct sockaddr_in6 *) buf)->sin6_addr)) + ret = 1; break; - case YPSET_NO: - default: - svcerr_noprog(transp); - return(NULL); +#endif + default : + ret = -1; } + return (ret); +} - if (ntohs(fromsin->sin_port) >= IPPORT_RESERVED) { - svcerr_noprog(transp); - return(NULL); - } +void * +ypbindproc_setdom(SVCXPRT *transp, const union ypbf_setdom *argp, const rpcvers_t version) +{ + struct sockaddr_storage bindaddr; + static char *result = NULL; + struct netbuf *addr; + int r; - if (argp->ypsetdom_vers != YPVERS) { - svcerr_noprog(transp); - return(NULL); + struct sockaddr_in * const sin = (struct sockaddr_in *) &bindaddr; +#ifdef INET6 + struct sockaddr_in6 * const sin6 = (struct sockaddr_in6 *) &bindaddr; +#endif + + if (strchr(argp->ypbf_sdomain, '/')) { + syslog(LOG_WARNING, "Domain name '%s' has embedded slash -- rejecting.", argp->ypbf_sdomain); + return (NULL); + } + addr = svc_getrpccaller(transp); + r = is_loopback(addr->buf, addr->len); + if (r < 0) { + syslog(LOG_WARNING, "Query from an unsupported address -- rejecting."); + return (NULL); } + if ((ypsetmode == YPSET_LOCAL && r == 0) || ypsetmode != YPSET_ALL) + goto err; + + /* It's ok to consider addr.buf as a sockaddr_storage structure + * ss_* macros never deal with its real representation */ + if (ntohs(*ss_getport(addr->buf)) >= IPPORT_RESERVED) + goto err; - 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); + bzero(&bindaddr, sizeof(bindaddr)); +#ifdef YPBIND_COMPAT_V2 + if (version == YPBINDVERS_2) { + if (argp->ypbf_svers_v2 != YPVERS) + goto err; + + sin->sin_family = AF_INET; + sin->sin_len = sizeof(struct sockaddr_in); + bcopy(argp->ypbf_saddr_v2, &sin->sin_addr, sizeof(struct in_addr)); + sin->sin_port = *(u_short *)&argp->ypbf_sport_v2; + } + else +#endif + { + if (argp->ypbf_svers != YPVERS) + goto err; + + switch (argp->ypbf_sfamily) { + case AF_INET : + sin->sin_family = AF_INET; + sin->sin_len = sizeof(struct sockaddr_in); + bcopy(argp->ypbf_saddr, &sin->sin_addr, sizeof(struct in_addr)); + sin->sin_port = *(u_short *)&argp->ypbf_sport; + break; +#ifdef INET6 + case AF_INET6 : + sin6->sin6_family = AF_INET6; + sin6->sin6_len = sizeof(struct sockaddr_in6); + bcopy(argp->ypbf_saddr, &sin6->sin6_addr, sizeof(struct in6_addr)); + sin6->sin6_port = *(u_short *)&argp->ypbf_sport; + break; +#endif + default : + syslog(LOG_WARNING, "Request an unsupported family -- rejecting."); + return (NULL); + } + } + rpc_received((char *) argp->ypbf_sdomain, &bindaddr, 1); return((void *) &result); + +err: + svcerr_noprog(transp); + return (NULL); } void -ypbindprog_2(struct svc_req *rqstp, register SVCXPRT *transp) +ypbindprog(struct svc_req *rqstp, register SVCXPRT *transp) { + typedef char *(*funcptr)(); union { - domainname ypbindproc_domain_2_arg; - struct ypbind_setdom ypbindproc_setdom_2_arg; + domainname domain; + union ypbf_setdom setdom_arg; } argument; - struct authunix_parms *creds; + struct authsys_parms *creds; char *result; + const rpcvers_t version = rqstp->rq_vers; bool_t (*xdr_argument)(), (*xdr_result)(); - char *(*local)(); + funcptr local; switch (rqstp->rq_proc) { case YPBINDPROC_NULL: xdr_argument = xdr_void; xdr_result = xdr_void; - local = (char *(*)()) ypbindproc_null_2_yp; + local = (funcptr) ypbindproc_null; break; case YPBINDPROC_DOMAIN: xdr_argument = xdr_domainname; - xdr_result = xdr_ypbind_resp; - local = (char *(*)()) ypbindproc_domain_2_yp; + if (version == YPBINDVERS_2) + xdr_result = xdr_ypbind_resp_v2; + else + xdr_result = xdr_ypbind_resp; + local = (funcptr) ypbindproc_domain; break; case YPBINDPROC_SETDOM: switch (rqstp->rq_cred.oa_flavor) { - case AUTH_UNIX: - creds = (struct authunix_parms *)rqstp->rq_clntcred; + case AUTH_SYS: + creds = (struct authsys_parms *) rqstp->rq_clntcred; if (creds->aup_uid != 0) { svcerr_auth(transp, AUTH_BADCRED); return; } break; default: - svcerr_auth(transp, AUTH_TOOWEAK); + svcerr_weakauth(transp); return; } - - xdr_argument = xdr_ypbind_setdom; + if (version == YPBINDVERS_2) + xdr_argument = xdr_ypbind_setdom_v2; + else + xdr_argument = xdr_ypbind_setdom; xdr_result = xdr_void; - local = (char *(*)()) ypbindproc_setdom_2_yp; + local = (funcptr) ypbindproc_setdom; break; default: @@ -343,7 +551,7 @@ svcerr_decode(transp); return; } - result = (*local)(transp, &argument, rqstp); + result = (*local)(transp, &argument, version); if (result != NULL && !svc_sendreply(transp, (xdrproc_t)xdr_result, result)) { svcerr_systemerr(transp); @@ -402,136 +610,6 @@ va_end(args); } -static int -create_domb_file(const struct _dom_binding *ypdb, const char *binding_dir) -{ - char path[MAXPATHLEN]; - int fd; - - sprintf(path, "%s/%s.%ld", binding_dir, - 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(binding_dir, 0755); - if ((fd = open(path, O_CREAT|O_SHLOCK|O_RDWR|O_TRUNC, 0644)) == -1) - return (-1); - } -#else - if ((fd = open(path, O_CREAT|O_RDWR|O_TRUNC, 0644)) == -1) { - (void)mkdir(binding_dir, 0755); - if ((fd = open(path, O_CREAT|O_RDWR|O_TRUNC, 0644)) == -1) - return (-1); - } - flock(fd, LOCK_SH); -#endif - return (fd); -} - -static void -register_domb(struct _dom_binding *ypdb, const struct sockaddr_storage *addr) -{ - struct iovec iov[2]; - struct ypbind_resp ybr; - int family; - u_short port; - - if (ypdb->dom_lockfd != -1) - close(ypdb->dom_lockfd); - - ypdb->dom_lockfd = create_domb_file(ypdb, BINDINGDIR); - if (ypdb->dom_lockfd == -1) - return; - - port = __rpcb_getport("127.0.0.1", CONNLESS_TSP, YPBINDPROG, YPBINDVERS); - iov[0].iov_base = (char *)&port - iov[0].iov_len = sizeof(port); - iov[1].iov_base = (char *)&ybr; - iov[1].iov_len = sizeof(ybr); - - family = ss_family(addr); - bzero(&ybr, sizeof(ybr)); - ybr.ypbind_status = YPBIND_SUCC_VAL; - ybr.ypresp_family = family; - *(u_short *)&ybr.ypresp_port = *ss_getport(addr); -#ifdef INET6 - if (family == AF_INET6) - bcopy(ss_to_sin6addr(addr), (char *) ybr.ypresp_addr, sizeof(struct in6_addr)); - else -#endif - bcopy(ss_to_sinaddr(addr), (char *) ybr.ypresp_addr, sizeof(struct in_addr)); - - 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; - } -} - -#ifdef YPBIND_COMPAT_V2 -static void -register_domb_v2(struct _dom_binding *ypdb, const struct sockaddr_storage *addr) -{ - struct iovec iov[2]; - struct ypbind_resp_v2 ybr; - int family; - u_short port; - - if (ypdb->dom_lockfd_v2 != -1) - close(ypdb->dom_lockfd_v2); - - ypdb->dom_lockfd_v2 = create_domb_file(ypdb, BINDINGDIR_V2); - if (ypdb->dom_lockfd_v2 == -1) - return; - - port = __rpcb_getport("127.0.0.1", CONNLESS_TSP, YPBINDPROG, YPBINDVERS_2); - iov[0].iov_base = (char *)&port - iov[0].iov_len = sizeof(port); - iov[1].iov_base = (char *)&ybr; - iov[1].iov_len = sizeof(ybr); - - family = ss_family(addr); - bzero(&ybr, sizeof(ybr)); - if (family != AF_INET) { /* AF_INET6 is not supported in version 2 */ - ybr2.ypbind_status = YPBIND_FAIL_VAL; - ybr2.yprespv2_error = YPBIND_ERR_FAMILY; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***