Date: Thu, 02 Aug 2012 01:38:14 +0000 From: exxo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r240005 - in soc2012/exxo: . patches Message-ID: <20120802013814.8537F106566C@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: exxo Date: Thu Aug 2 01:38:14 2012 New Revision: 240005 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=240005 Log: Add yp patch and update softnotes Added: soc2012/exxo/patches/yp.patch Modified: soc2012/exxo/softnotes.txt Added: soc2012/exxo/patches/yp.patch ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2012/exxo/patches/yp.patch Thu Aug 2 01:38:14 2012 (r240005) @@ -0,0 +1,2073 @@ +Index: freebsd-head/usr.bin/ypwhich/ypwhich.c +=================================================================== +--- freebsd-head/usr.bin/ypwhich/ypwhich.c (revision 239326) ++++ freebsd-head/usr.bin/ypwhich/ypwhich.c (working copy) +@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$"); + #include <rpc/rpc.h> + #include <rpc/xdr.h> + #include <rpcsvc/yp_prot.h> ++#include <rpcsvc/yp_utils.h> + #include <rpcsvc/ypclnt.h> + + #include <netinet/in.h> +@@ -83,26 +84,68 @@ usage(void) + exit(ERR_USAGE); + } + ++#ifdef INET6 ++# define ADDRSTRLEN INET6_ADDRSTRLEN ++#else ++# define ADDRSTRLEN INET_ADDRSTRLEN ++#endif ++ ++static void ++print_addr(const union ypbf_resp *ypbr, int version) ++{ ++ struct hostent *hent = NULL; ++ char str[ADDRSTRLEN]; ++ int family; ++ size_t len; ++ union { ++ struct in_addr in; ++#ifdef INET6 ++ struct in6_addr in6; ++#endif ++ } ss_addr; ++ ++#ifdef YPBIND_COMPAT_V2 ++ if (version == YPBINDVERS_2) { ++ family = AF_INET; ++ len = sizeof(ss_addr.in); ++ bcopy(&ypbr->ypbf_raddr_v2, &ss_addr, len); ++ } ++ else /* YPBINDVERS */ ++#endif ++ { ++ 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->ypbf_raddr, &ss_addr, len); ++ } ++ hent = gethostbyaddr((char *)&ss_addr, len, family); ++ if (hent) ++ printf("%s\n", hent->h_name); ++ else ++ printf("%s\n", inet_ntop(family, &ss_addr, str, ADDRSTRLEN)); ++} + + /* + * Like yp_bind except can query a specific host + */ + static int +-bind_host(char *dom, struct sockaddr_in *lsin) ++bind_host(char *dom, const char *host) + { +- struct hostent *hent = NULL; +- struct ypbind_resp ypbr; ++ union ypbf_resp ypbr; + struct timeval tv; + CLIENT *client; +- int sock, r; +- struct in_addr ss_addr; ++ int r; ++ int version = YPBINDVERS; + +- sock = RPC_ANYSOCK; + tv.tv_sec = 15; + tv.tv_usec = 0; +- client = clntudp_create(lsin, YPBINDPROG, YPBINDVERS, tv, &sock); ++ client = clnt_create_timed(host, YPBINDPROG, version, "udp", &tv); + if (client == NULL) { +- warnx("can't clntudp_create: %s", yperr_string(YPERR_YPBIND)); ++ warnx("can't clnt_create_timed: %s", yperr_string(YPERR_YPBIND)); + return (YPERR_YPBIND); + } + +@@ -110,28 +153,31 @@ bind_host(char *dom, struct sockaddr_in + tv.tv_usec = 0; + r = clnt_call(client, YPBINDPROC_DOMAIN, + (xdrproc_t)xdr_domainname, &dom, +- (xdrproc_t)xdr_ypbind_resp, &ypbr, tv); ++ (xdrproc_t)xdr_ypbind_resp, &ypbr.resp, tv); ++#ifdef YPBIND_COMPAT_V2 ++ if (r == RPC_PROGVERSMISMATCH) { ++ fprintf(stderr, "Warning: %s, fallback in V2 compatibility mode\n", clnt_sperrno(r)); ++ version = YPBINDVERS_2; ++ if (clnt_control(client, CLSET_VERS, &version) == TRUE) ++ r = clnt_call(client, YPBINDPROC_DOMAIN, ++ (xdrproc_t)xdr_domainname, &dom, ++ (xdrproc_t)xdr_ypbind_resp_v2, &ypbr.resp2, tv); /* TODO libc must define YPBIND_COMPAT_V2 */ ++ } ++#endif + if (r != RPC_SUCCESS) { + warnx("can't clnt_call: %s", yperr_string(YPERR_YPBIND)); + clnt_destroy(client); + return (YPERR_YPBIND); + } else { +- if (ypbr.ypbind_status != YPBIND_SUCC_VAL) { ++ if (ypbr.ypbf_rstatus != YPBIND_SUCC_VAL) { + warnx("can't yp_bind: reason: %s", +- ypbinderr_string(ypbr.ypbind_respbody.ypbind_error)); ++ ypbinderr_string(ypbr.ypbf_rerror)); + clnt_destroy(client); + return (r); + } + } + clnt_destroy(client); +- +- ss_addr = ypbr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_addr; +- /*printf("%08x\n", ss_addr);*/ +- hent = gethostbyaddr((char *)&ss_addr, sizeof(ss_addr), AF_INET); +- if (hent) +- printf("%s\n", hent->h_name); +- else +- printf("%s\n", inet_ntoa(ss_addr)); ++ print_addr(&ypbr, version); + return (0); + } + +@@ -141,8 +187,7 @@ main(int argc, char *argv[]) + char *domnam = NULL, *master; + char *map = NULL; + struct ypmaplist *ypml, *y; +- struct hostent *hent; +- struct sockaddr_in lsin; ++ char *host; + int notrans, mode; + int c, r; + u_int i; +@@ -166,38 +211,20 @@ main(int argc, char *argv[]) + mode++; + break; + default: +- usage(); ++ usage(); + } + + if (!domnam) + yp_get_default_domain(&domnam); + + if (mode == 0) { +- switch (argc-optind) { +- case 0: +- bzero(&lsin, sizeof lsin); +- lsin.sin_family = AF_INET; +- lsin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); +- +- if (bind_host(domnam, &lsin)) +- exit(ERR_NOBINDING); +- break; +- case 1: +- bzero(&lsin, sizeof lsin); +- lsin.sin_family = AF_INET; +- if ((lsin.sin_addr.s_addr = inet_addr(argv[optind])) == INADDR_NONE) { +- hent = gethostbyname(argv[optind]); +- if (!hent) +- errx(ERR_NOSUCHHOST, "host %s unknown", argv[optind]); +- bcopy((char *)hent->h_addr_list[0], +- (char *)&lsin.sin_addr, sizeof lsin.sin_addr); +- } +- if (bind_host(domnam, &lsin)) ++ if (argc-optind == 0 || argc-optind == 1) { ++ host = argc-optind ? argv[optind] : "127.0.0.1"; ++ if (bind_host(domnam, host)) + exit(ERR_NOBINDING); +- break; +- default: +- usage(); + } ++ else ++ usage(); + exit(0); + } + +Index: freebsd-head/usr.bin/ypwhich/Makefile +=================================================================== +--- freebsd-head/usr.bin/ypwhich/Makefile (revision 239326) ++++ freebsd-head/usr.bin/ypwhich/Makefile (working copy) +@@ -1,8 +1,15 @@ + # from: @(#)Makefile 5.8 (Berkeley) 7/28/90 + # $FreeBSD$ + ++.include <bsd.own.mk> ++ + PROG= ypwhich + + WARNS?= 2 + ++CFLAGS += -DYPBIND_COMPAT_V2 ++.if ${MK_INET6_SUPPORT} != "no" ++CFLAGS += -DINET6 ++.endif ++ + .include <bsd.prog.mk> +Index: freebsd-head/include/rpcsvc/yp_utils.h +=================================================================== +--- freebsd-head/include/rpcsvc/yp_utils.h (revision 0) ++++ freebsd-head/include/rpcsvc/yp_utils.h (revision 240004) +@@ -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 <rpcsvc/yp_prot.h> or <rpcsvc/yp.h> ++ * 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_ */ +Index: freebsd-head/include/rpcsvc/yp_prot.h +=================================================================== +--- freebsd-head/include/rpcsvc/yp_prot.h (revision 239326) ++++ freebsd-head/include/rpcsvc/yp_prot.h (working copy) +@@ -199,7 +199,7 @@ struct ypresp_maplist { + struct dom_binding { + struct dom_binding *dom_pnext; + char dom_domain[YPMAXDOMAIN + 1]; +- struct sockaddr_in dom_server_addr; ++ struct sockaddr_storage dom_server_addr; /* TODO impact of changing this ? */ + u_short dom_server_port; + int dom_socket; + CLIENT *dom_client; +@@ -222,7 +222,8 @@ struct dom_binding { + */ + + #define YPBINDPROG ((u_long)100007) +-#define YPBINDVERS ((u_long)2) ++#define YPBINDVERS ((u_long)3) ++#define YPBINDVERS_2 ((u_long)2) + #define YPBINDVERS_ORIG ((u_long)1) + + /* ypbind procedure numbers */ +@@ -238,7 +239,13 @@ enum ypbind_resptype { + + /* network order, of course */ + struct ypbind_binding { +- struct in_addr ypbind_binding_addr; ++ sa_family_t ypbind_binding_family; ++ union { ++ struct in_addr in; ++#ifdef INET6 ++ struct in6_addr in6; ++#endif ++ } ypbind_binding_addr; + u_short ypbind_binding_port; + }; + +@@ -254,6 +261,7 @@ struct ypbind_resp { + #define YPBIND_ERR_ERR 1 /* internal error */ + #define YPBIND_ERR_NOSERV 2 /* no bound server for passed domain */ + #define YPBIND_ERR_RESC 3 /* system resource allocation failure */ ++#define YPBIND_ERR_FAMILY 4 /* unsupported family */ + + /* + * Request data structure for ypbind "Set domain" procedure. +@@ -266,6 +274,30 @@ struct ypbind_setdom { + #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 ++ ++struct ypbind_binding_v2 { ++ struct in_addr ypbind_binding_addr; ++ u_short ypbind_binding_port; ++}; ++ ++struct ypbind_resp_v2 { ++ enum ypbind_resptype ypbind_status; ++ union { ++ u_int ypbind_error; ++ struct ypbind_binding_v2 ypbind_bindinfo; ++ } ypbind_respbody; ++}; ++ ++struct ypbind_setdom_v2 { ++ char ypsetdom_domain[YPMAXDOMAIN + 1]; ++ struct ypbind_binding_v2 ypsetdom_binding; ++ u_int ypsetdom_vers; ++}; ++ ++#endif ++ + /* + * YPPUSH PROTOCOL: + * +@@ -317,6 +349,7 @@ bool_t xdr_ypreq_xfr(XDR *, struct ypreq + bool_t xdr_ypresp_val(XDR *, struct ypresp_val *); + bool_t xdr_ypresp_key_val(XDR *, struct ypresp_key_val *); + bool_t xdr_ypbind_resp(XDR *, struct ypbind_resp *); ++bool_t xdr_ypbind_resp_v2(XDR *, struct ypbind_resp_v2 *); + bool_t xdr_ypbind_setdom(XDR *, struct ypbind_setdom *); + bool_t xdr_yp_inaddr(XDR *, struct inaddr *); + bool_t xdr_ypmap_parms(XDR *, struct ypmap_parms *); +Index: freebsd-head/include/rpcsvc/yp.x +=================================================================== +--- freebsd-head/include/rpcsvc/yp.x (revision 239326) ++++ freebsd-head/include/rpcsvc/yp.x (working copy) +@@ -196,7 +196,8 @@ enum ypbind_resptype { + }; + + struct ypbind_binding { +- opaque ypbind_binding_addr[4]; /* In network order */ ++ unsigned char ypbind_binding_family; ++ opaque ypbind_binding_addr[16]; /* In network order */ + opaque ypbind_binding_port[2]; /* In network order */ + }; + +@@ -207,12 +208,12 @@ case YPBIND_SUCC_VAL: + ypbind_binding ypbind_bindinfo; + }; + +-/* Detailed failure reason codes for response field ypbind_error*/ ++/* Detailed failure reason codes for response field ypbind_error */ + + const YPBIND_ERR_ERR = 1; /* Internal error */ + const YPBIND_ERR_NOSERV = 2; /* No bound server for passed domain */ + const YPBIND_ERR_RESC = 3; /* System resource allocation failure */ +- ++const YPBIND_ERR_FAMILY = 4; /* Unsupported family */ + + /* + * Request data structure for ypbind "Set domain" procedure. +@@ -223,6 +224,30 @@ struct ypbind_setdom { + unsigned ypsetdom_vers; + }; + ++/* Backward compatibility for YPBIND protocol version 2 */ ++#ifdef YPBIND_COMPAT_V2 ++ ++const YPBINDVERS_2 = 2; ++ ++struct ypbind_binding_v2 { ++ opaque ypbind_binding_addr[4]; /* In network order */ ++ opaque ypbind_binding_port[2]; /* In network order */ ++}; ++ ++union ypbind_resp_v2 switch (ypbind_resptype ypbind_status) { ++case YPBIND_FAIL_VAL: ++ unsigned ypbind_error; ++case YPBIND_SUCC_VAL: ++ ypbind_binding_v2 ypbind_bindinfo; ++}; ++ ++struct ypbind_setdom_v2 { ++ domainname ypsetdom_domain; ++ ypbind_binding_v2 ypsetdom_binding; ++ unsigned ypsetdom_vers; ++}; ++ ++#endif + + /* + * NIS v1 support for backwards compatibility +@@ -371,7 +396,7 @@ program YPBINDPROG { + + void + YPBINDPROC_SETDOM(ypbind_setdom) = 2; +- } = 2; ++ } = 3; + } = 100007; + + #endif +Index: freebsd-head/usr.sbin/ypbind/yp_ping.c +=================================================================== +--- freebsd-head/usr.sbin/ypbind/yp_ping.c (revision 239326) ++++ freebsd-head/usr.sbin/ypbind/yp_ping.c (working copy) +@@ -103,6 +103,8 @@ __FBSDID("$FreeBSD$"); + */ + + ++#if 0 /* TODO : Does __yp_getport achieve the same result ? */ ++ + static struct timeval timeout = { 1, 0 }; + static struct timeval tottimeout = { 1, 0 }; + +@@ -145,6 +147,7 @@ __pmap_getport(struct sockaddr_in *addre + address->sin_port = 0; + return (port); + } ++#endif + + /* + * Transmit to YPPROC_DOMAIN_NONACK, return immediately. +@@ -207,104 +210,230 @@ ypproc_domain_nonack_2_recv(domainname * + */ + + struct ping_req { +- struct sockaddr_in sin; ++ struct sockaddr_storage sst; + u_int32_t xid; + }; + ++struct transport { ++ CLIENT *clnt; ++ u_int32_t xid_lookup; ++ struct sockaddr_storage *any; ++ int sock; ++ struct netbuf addr; ++}; ++#define V4 0 ++#define V6 1 ++#ifdef INET6 ++# define TSP_LEN (V6 + 1) ++#else ++# define TSP_LEN (V4 + 1) ++#endif ++ ++u_short ++__rpcb_getport(const char *hostname, const char *netid, ++ const rpcprog_t prognum, const rpcvers_t versnum) ++{ ++ struct sockaddr_storage sst; ++ struct netconfig *nconf; ++ struct netbuf svcaddr; ++ u_short port; ++ ++ svcaddr.len = 0; ++ svcaddr.maxlen = sizeof(sst); ++ svcaddr.buf = &sst; ++ if ((nconf = getnetconfigent(netid)) == NULL || ++ !rpcb_getaddr(prognum, versnum, nconf, &svcaddr, hostname)) ++ return (0); ++ switch (svcaddr.len) { ++ case sizeof(struct sockaddr_in) : ++ port = ss_to_sinport(svcaddr.buf); ++ break; ++#ifdef INET6 ++ case sizeof(struct sockaddr_in6) : ++ port = ss_to_sin6port(svcaddr.buf); ++ break; ++#endif ++ default : ++ port = 0; ++ } ++ return (port); /* Network byte order */ ++} ++ ++static u_short ++__yp_getport(const struct sockaddr_storage *host, const char *netid) ++{ ++ char str[ADDRSTRLEN]; ++ int family; ++ char *ptr; ++ ++ if (ss_extract(host, &family, &ptr, 0)) ++ return (0); ++ inet_ntop(family, ptr, str, ADDRSTRLEN); ++ return (__rpcb_getport(str, netid, YPPROG, YPVERS)); ++} ++ ++static int ++rpc_init(struct transport *tsp) ++{ ++ 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) ++ continue; ++#ifdef INET6 ++ if (i == V6) { ++ 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); ++ } ++ 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) ++ 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); ++ ++validtransp; ++ } ++ return (!validtransp); ++} ++ ++static void ++rpc_destroy(struct transport *tsp) ++{ ++ 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; ++ } ++} ++ + int +-__yp_ping(struct in_addr *restricted_addrs, int cnt, char *dom, short *port) ++__yp_ping(struct sockaddr_storage *restricted_addrs, int cnt, char *dom, u_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 n; ++ struct sockaddr_storage *req_addr; + int winner = -1; +- u_int32_t xid_seed, xid_lookup; +- int sock, dontblock = 1; +- CLIENT *clnt; ++ u_int32_t xid_seed; + char *foo = dom; + int validsrvs = 0; ++ u_short yp_port; ++ struct transport tsp[TSP_LEN] = { ++#ifdef INET6 ++ {NULL, 0, NULL, -1}, ++#endif ++ {NULL, 0, NULL, -1} ++ }; + + /* 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) ++ yp_port = __yp_getport(&restricted_addrs[i], CONNLESS_TSP); ++ if (yp_port == 0) + continue; + reqs[i] = calloc(1, sizeof(struct ping_req)); +- bcopy((char *)&sin, (char *)&reqs[i]->sin, sizeof(sin)); +- any = &reqs[i]->sin; ++ req_addr = &reqs[i]->sst; ++ bcopy((char *)&restricted_addrs[i], (char *)req_addr, sizeof(*req_addr)); ++#ifdef INET6 ++ if (ss_family(req_addr) == AF_INET6) { ++ ss_to_sin6port(req_addr) = yp_port; ++ tsp[V6].any = req_addr; ++ } ++ else /* AF_INET */ ++#endif ++ { ++ ss_to_sinport(req_addr) = yp_port; ++ tsp[V4].any = req_addr; ++ } + reqs[i]->xid = xid_seed; + xid_seed++; + validsrvs++; + } + + /* Make sure at least one server was assigned */ +- if (!validsrvs) { +- free(reqs); +- return(-1); +- } ++ if (!validsrvs) ++ goto err; + +- /* 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); ++ /* Create RPC transports ++ * an inet4 transport for any V4 address existing in `reqs' ++ * an inet6 transport for any V6 address existing in `reqs' ++ * otherwise, shutdown ++ * */ ++ if (rpc_init(tsp)) ++ goto err; + + /* Transmit */ +- for (i = 0; i < cnt; i++) { ++ 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); ++ req_addr = &reqs[i]->sst; ++ n = (ss_family(req_addr) == AF_INET ? V4 : V6); ++ clnt_control(tsp[n].clnt, CLSET_XID, (char *)&reqs[i]->xid); ++ tsp[n].addr.buf = (char *) req_addr; ++ clnt_control(tsp[n].clnt, CLSET_SVC_ADDR, &tsp[n].addr); ++ ypproc_domain_nonack_2_send(&foo, tsp[n].clnt); + } +- } + + /* Receive reply */ +- ypproc_domain_nonack_2_recv(&foo, clnt); ++ for (i = 0; i < TSP_LEN; ++i) ++ if (tsp[i].clnt) ++ ypproc_domain_nonack_2_recv(&foo, tsp[i].clnt); ++ ++ /* Get the winner */ ++ for (i = 0; i < TSP_LEN; ++i) ++ if (tsp[i].clnt) ++ clnt_control(tsp[i].clnt, CLGET_XID, (char *)&tsp[i].xid_lookup); + +- /* 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; ++ /* Look him up */ ++ for (i = 0; i < cnt; i++) ++ if (reqs[i] != NULL) { ++ for (n = 0; n < TSP_LEN; ++n) ++ if (reqs[i]->xid == tsp[n].xid_lookup) { ++#ifdef INET6 ++ if (n == V6) ++ *port = ss_to_sin6port(&reqs[i]->sst); /* Network byte order */ ++ else /* V4 */ ++#endif ++ *port = ss_to_sinport(&reqs[i]->sst); ++ winner = i; ++ break; ++ } ++ if (winner > 0) ++ break; + } +- } +- ++ + /* 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]); ++err: ++ rpc_destroy(tsp); ++ if (validsrvs) { ++ for (i = 0; i < cnt; i++) ++ if (reqs[i] != NULL) ++ free(reqs[i]); ++ } + free(reqs); +- + return(winner); + } +Index: freebsd-head/usr.sbin/ypbind/ypbind.c +=================================================================== +--- freebsd-head/usr.sbin/ypbind/ypbind.c (revision 239326) ++++ freebsd-head/usr.sbin/ypbind/ypbind.c (working copy) +@@ -57,11 +57,13 @@ __FBSDID("$FreeBSD$"); + #include <net/if.h> + #include <netinet/in.h> + #include <arpa/inet.h> ++#include <stdarg.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/yp_utils.h> + #include <rpcsvc/ypclnt.h> + #include "yp_ping.h" + +@@ -69,6 +71,10 @@ __FBSDID("$FreeBSD$"); + #define BINDINGDIR "/var/yp/binding" + #endif + ++#if !defined(BINDINGDIR_V2) && defined(YPBIND_COMPAT_V2) ++#define BINDINGDIR_V2 "/var/yp/binding.2" ++#endif ++ + #ifndef YPBINDLOCK + #define YPBINDLOCK "/var/run/ypbind.lock" + #endif +@@ -76,9 +82,12 @@ __FBSDID("$FreeBSD$"); + struct _dom_binding { + struct _dom_binding *dom_pnext; + char dom_domain[YPMAXDOMAIN + 1]; +- struct sockaddr_in dom_server_addr; ++ struct sockaddr_storage dom_server_addr; + long int dom_vers; + int dom_lockfd; ++#ifdef YPBIND_COMPAT_V2 ++ int dom_lockfd_v2; ++#endif + int dom_alive; + int dom_broadcast_pid; + int dom_pipe_fds[2]; +@@ -89,22 +98,26 @@ struct _dom_binding { + #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; +@@ -128,7 +141,7 @@ static int not_responding_count = 0; + #define RESTRICTED_SERVERS 10 + int yp_restricted = 0; + int yp_manycast = 0; +-struct in_addr restricted_addrs[RESTRICTED_SERVERS]; ++struct sockaddr_storage restricted_addrs[RESTRICTED_SERVERS]; + + /* No more than MAX_CHILDREN child broadcasters at a time. */ + #ifndef MAX_CHILDREN +@@ -154,32 +167,160 @@ int domains = 0; + int yplockfd; + fd_set fdsr; + +-SVCXPRT *udptransp, *tcptransp; ++#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) *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120802013814.8537F106566C>