4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Auxiliary routines to shield off random internet hosts and to report
23 * service requests (verbose mode only) or violations (always).
25 * This code was extensively modifed from a version authored by:
27 * Wietse Venema, Eindhoven University of Technology, The Netherlands
28 * and distributed as "rpcbind 2.1".
30 * Sun was granted permission to use, modify, including make
31 * derivatives of, copy, reproduce and distribute this code.c in both
32 * binary and source forms, directly and indirectly.
34 * Modified for bundling with Solaris and IPv6.
36 * Solaris specific modifcations made are:
38 * Double fork() logging replaced with qsyslog();
39 * Connection refusals are flagged with svcerr_auth(); this
40 * aids in quicker diagnosability of misconfigurations and quicker
41 * failures for /net automounts;
42 * Single function for pmap* and rpcb*;
43 * Local transport checks made using localxprt().
45 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
46 * Use is subject to license terms.
49 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
58 #include <netconfig.h>
61 #include <arpa/inet.h>
62 #include <netinet/in.h>
64 #include <rpc/pmap_prot.h>
65 #include <rpc/rpcb_prot.h>
73 * These are globally visible so that they can be modified by the wrapper's
74 * language extension routines.
76 int allow_severity
= LOG_INFO
;
77 int deny_severity
= LOG_WARNING
;
79 static mutex_t hosts_ctl_lock
= DEFAULTMUTEX
;
82 * "inet_ntoa/inet_pton" for struct sockaddr_gen
85 sgen_toa(struct sockaddr_gen
*addr
, char *buf
, size_t bufsize
)
87 return (inet_ntop(SGFAM(addr
), SGADDRP(addr
), buf
, bufsize
));
95 static const struct proc_map pmapmap
[] = {
96 PMAPPROC_CALLIT
, "callit",
97 PMAPPROC_DUMP
, "dump",
98 PMAPPROC_GETPORT
, "getport",
100 PMAPPROC_UNSET
, "unset",
104 static const struct proc_map rpcbmap
[] = {
106 RPCBPROC_UNSET
, "unset",
107 RPCBPROC_GETADDR
, "getaddr",
108 RPCBPROC_DUMP
, "dump",
109 RPCBPROC_CALLIT
, "callit",
110 RPCBPROC_GETTIME
, "gettime",
111 RPCBPROC_UADDR2TADDR
, "uaddr2taddr",
112 RPCBPROC_TADDR2UADDR
, "taddr2uaddr",
113 RPCBPROC_GETVERSADDR
, "getversaddr",
114 RPCBPROC_INDIRECT
, "indirect",
115 RPCBPROC_GETADDRLIST
, "getaddrlist",
116 RPCBPROC_GETSTAT
, "getstat",
121 * find_procname - map rpcb/pmap procedure number to name
124 find_procname(rpcproc_t procnum
, boolean_t pm
)
127 const struct proc_map
*procp
;
131 nitems
= sizeof (pmapmap
)/sizeof (struct proc_map
);
134 nitems
= sizeof (rpcbmap
)/sizeof (struct proc_map
);
137 for (i
= 0; i
< nitems
; i
++) {
138 if (procp
[i
].code
== procnum
)
139 return (procp
[i
].proc
);
145 * rpcb_log - log request for service
148 rpcb_log(boolean_t verdict
, SVCXPRT
*transp
, rpcproc_t proc
, rpcprog_t prog
,
151 struct netconfig
*conf
;
152 const char *client
= "unknown";
155 char toabuf
[INET6_ADDRSTRLEN
];
156 const char *procname
;
159 * Transform the transport address into something printable.
161 if ((conf
= rpcbind_get_conf(transp
->xp_netid
)) == 0) {
163 "unknown transport (rpcbind_get_conf failed)");
164 } else if (strcmp(conf
->nc_protofmly
, "inet") == 0 ||
165 strcmp(conf
->nc_protofmly
, "inet6") == 0) {
166 client
= sgen_toa(svc_getgencaller(transp
), toabuf
,
168 } else if ((uaddr
= taddr2uaddr(conf
, &(transp
->xp_rtaddr
))) == NULL
) {
169 syslog(LOG_WARNING
, "unknown address (taddr2uaddr failed)");
171 (void) snprintf(buf
, sizeof (buf
), "%s(%s)",
172 conf
->nc_protofmly
, uaddr
);
177 if ((procname
= find_procname(proc
, pm
)) == NULL
) {
178 qsyslog(verdict
? allow_severity
: deny_severity
,
179 "%sconnect from %s to %s-%lu(%lu)",
180 verdict
? "" : "refused ", client
, pm
? "pmap" : "rpcb",
181 (ulong_t
)proc
, (ulong_t
)prog
);
183 qsyslog(verdict
? allow_severity
: deny_severity
,
184 "%sconnect from %s to %s(%lu)", verdict
? "" : "refused ",
185 client
, procname
, (ulong_t
)prog
);
190 * rpcb_check; the rpcbind/portmap access check function.
193 rpcb_check(SVCXPRT
*transp
, rpcproc_t procnum
, boolean_t ispmap
)
195 struct netconfig
*conf
;
196 boolean_t res
= B_TRUE
;
198 if ((conf
= rpcbind_get_conf(transp
->xp_netid
)) == 0) {
200 "rpcbind_get_conf failed: no client address checks");
205 * Require IPv4 for pmap calls; they're not defined for anything else.
207 if (ispmap
&& strcmp(conf
->nc_protofmly
, "inet") != 0) {
209 } else if (strcmp(conf
->nc_protofmly
, "inet") == 0 ||
210 strcmp(conf
->nc_protofmly
, "inet6") == 0) {
211 if (!localxprt(transp
, ispmap
)) {
215 char buf
[INET6_ADDRSTRLEN
];
216 const char *addr_string
=
217 sgen_toa(svc_getgencaller(transp
), buf
,
220 (void) mutex_lock(&hosts_ctl_lock
);
221 if (hosts_ctl("rpcbind", addr_string
,
222 addr_string
, "") == 0)
224 (void) mutex_unlock(&hosts_ctl_lock
);
230 svcerr_auth(transp
, AUTH_FAILED
);
232 if (verboselog
|| !res
)
233 rpcb_log(res
, transp
, procnum
, 0, ispmap
);