xref: /freebsd/usr.sbin/rpc.lockd/lock_proc.c (revision 2a63c3be158216222d89a073dcbd6a72ee4aab5a)
18360efbdSAlfred Perlstein /*	$NetBSD: lock_proc.c,v 1.7 2000/10/11 20:23:56 is Exp $	*/
2df57947fSPedro F. Giffuni /*-
3df57947fSPedro F. Giffuni  * SPDX-License-Identifier: BSD-4-Clause
4df57947fSPedro F. Giffuni  *
58360efbdSAlfred Perlstein  * Copyright (c) 1995
68360efbdSAlfred Perlstein  *	A.R. Gordon (andrew.gordon@net-tel.co.uk).  All rights reserved.
78360efbdSAlfred Perlstein  *
88360efbdSAlfred Perlstein  * Redistribution and use in source and binary forms, with or without
98360efbdSAlfred Perlstein  * modification, are permitted provided that the following conditions
108360efbdSAlfred Perlstein  * are met:
118360efbdSAlfred Perlstein  * 1. Redistributions of source code must retain the above copyright
128360efbdSAlfred Perlstein  *    notice, this list of conditions and the following disclaimer.
138360efbdSAlfred Perlstein  * 2. Redistributions in binary form must reproduce the above copyright
148360efbdSAlfred Perlstein  *    notice, this list of conditions and the following disclaimer in the
158360efbdSAlfred Perlstein  *    documentation and/or other materials provided with the distribution.
168360efbdSAlfred Perlstein  * 3. All advertising materials mentioning features or use of this software
178360efbdSAlfred Perlstein  *    must display the following acknowledgement:
188360efbdSAlfred Perlstein  *	This product includes software developed for the FreeBSD project
198360efbdSAlfred Perlstein  * 4. Neither the name of the author nor the names of any co-contributors
208360efbdSAlfred Perlstein  *    may be used to endorse or promote products derived from this software
218360efbdSAlfred Perlstein  *    without specific prior written permission.
228360efbdSAlfred Perlstein  *
238360efbdSAlfred Perlstein  * THIS SOFTWARE IS PROVIDED BY ANDREW GORDON AND CONTRIBUTORS ``AS IS'' AND
248360efbdSAlfred Perlstein  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
258360efbdSAlfred Perlstein  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
268360efbdSAlfred Perlstein  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
278360efbdSAlfred Perlstein  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
288360efbdSAlfred Perlstein  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
298360efbdSAlfred Perlstein  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
308360efbdSAlfred Perlstein  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
318360efbdSAlfred Perlstein  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
328360efbdSAlfred Perlstein  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
338360efbdSAlfred Perlstein  * SUCH DAMAGE.
348360efbdSAlfred Perlstein  *
358360efbdSAlfred Perlstein  */
368360efbdSAlfred Perlstein 
378360efbdSAlfred Perlstein #include <sys/cdefs.h>
388360efbdSAlfred Perlstein #ifndef lint
398360efbdSAlfred Perlstein __RCSID("$NetBSD: lock_proc.c,v 1.7 2000/10/11 20:23:56 is Exp $");
408360efbdSAlfred Perlstein #endif
418360efbdSAlfred Perlstein 
428360efbdSAlfred Perlstein #include <sys/param.h>
438360efbdSAlfred Perlstein #include <sys/socket.h>
448360efbdSAlfred Perlstein 
458360efbdSAlfred Perlstein #include <netinet/in.h>
468360efbdSAlfred Perlstein #include <arpa/inet.h>
478360efbdSAlfred Perlstein 
488360efbdSAlfred Perlstein #include <netdb.h>
498360efbdSAlfred Perlstein #include <stdio.h>
508360efbdSAlfred Perlstein #include <string.h>
518360efbdSAlfred Perlstein #include <syslog.h>
52fbdef8fbSStefan Farfeleder #include <unistd.h>
538360efbdSAlfred Perlstein #include <netconfig.h>
548360efbdSAlfred Perlstein 
558360efbdSAlfred Perlstein #include <rpc/rpc.h>
568360efbdSAlfred Perlstein #include <rpcsvc/sm_inter.h>
578360efbdSAlfred Perlstein 
588360efbdSAlfred Perlstein #include "lockd.h"
598360efbdSAlfred Perlstein #include <rpcsvc/nlm_prot.h>
608360efbdSAlfred Perlstein #include "lockd_lock.h"
618360efbdSAlfred Perlstein 
628360efbdSAlfred Perlstein 
638360efbdSAlfred Perlstein #define	CLIENT_CACHE_SIZE	64	/* No. of client sockets cached */
648360efbdSAlfred Perlstein #define	CLIENT_CACHE_LIFETIME	120	/* In seconds */
658360efbdSAlfred Perlstein 
662d914e96SJun Kuriyama #define	getrpcaddr(rqstp)	(struct sockaddr *)(svc_getrpccaller((rqstp)->rq_xprt)->buf)
672d914e96SJun Kuriyama 
68efddf138SAlfred Perlstein static void	log_from_addr(const char *, struct svc_req *);
6933314abeSAlfred Perlstein static void	log_netobj(netobj *obj);
7033314abeSAlfred Perlstein static int	addrcmp(struct sockaddr *, struct sockaddr *);
718360efbdSAlfred Perlstein 
728360efbdSAlfred Perlstein /* log_from_addr ----------------------------------------------------------- */
738360efbdSAlfred Perlstein /*
748360efbdSAlfred Perlstein  * Purpose:	Log name of function called and source address
758360efbdSAlfred Perlstein  * Returns:	Nothing
768360efbdSAlfred Perlstein  * Notes:	Extracts the source address from the transport handle
778360efbdSAlfred Perlstein  *		passed in as part of the called procedure specification
788360efbdSAlfred Perlstein  */
798360efbdSAlfred Perlstein static void
log_from_addr(const char * fun_name,struct svc_req * req)8029df5733SXin LI log_from_addr(const char *fun_name, struct svc_req *req)
818360efbdSAlfred Perlstein {
828360efbdSAlfred Perlstein 	struct sockaddr *addr;
838360efbdSAlfred Perlstein 	char hostname_buf[NI_MAXHOST];
848360efbdSAlfred Perlstein 
858360efbdSAlfred Perlstein 	addr = svc_getrpccaller(req->rq_xprt)->buf;
868360efbdSAlfred Perlstein 	if (getnameinfo(addr , addr->sa_len, hostname_buf, sizeof hostname_buf,
878360efbdSAlfred Perlstein 	    NULL, 0, 0) != 0)
888360efbdSAlfred Perlstein 		return;
898360efbdSAlfred Perlstein 
908360efbdSAlfred Perlstein 	syslog(LOG_DEBUG, "%s from %s", fun_name, hostname_buf);
918360efbdSAlfred Perlstein }
928360efbdSAlfred Perlstein 
93bad584e3SAlfred Perlstein /* log_netobj ----------------------------------------------------------- */
94bad584e3SAlfred Perlstein /*
95bad584e3SAlfred Perlstein  * Purpose:	Log a netobj
96bad584e3SAlfred Perlstein  * Returns:	Nothing
97bad584e3SAlfred Perlstein  * Notes:	This function should only really be called as part of
98bad584e3SAlfred Perlstein  *  		a debug subsystem.
99bad584e3SAlfred Perlstein */
100bad584e3SAlfred Perlstein static void
log_netobj(netobj * obj)10129df5733SXin LI log_netobj(netobj *obj)
102bad584e3SAlfred Perlstein {
103bad584e3SAlfred Perlstein 	char objvalbuffer[(sizeof(char)*2)*MAX_NETOBJ_SZ+2];
104bad584e3SAlfred Perlstein 	char objascbuffer[sizeof(char)*MAX_NETOBJ_SZ+1];
1052663693cSAlfred Perlstein 	unsigned int i, maxlen;
106bad584e3SAlfred Perlstein 	char *tmp1, *tmp2;
107bad584e3SAlfred Perlstein 
108bad584e3SAlfred Perlstein 	/* Notify of potential security attacks */
109bad584e3SAlfred Perlstein 	if (obj->n_len > MAX_NETOBJ_SZ)	{
110bad584e3SAlfred Perlstein 		syslog(LOG_DEBUG, "SOMEONE IS TRYING TO DO SOMETHING NASTY!\n");
111bad584e3SAlfred Perlstein 		syslog(LOG_DEBUG, "netobj too large! Should be %d was %d\n",
112bad584e3SAlfred Perlstein 		    MAX_NETOBJ_SZ, obj->n_len);
113bad584e3SAlfred Perlstein 	}
114bad584e3SAlfred Perlstein 	/* Prevent the security hazard from the buffer overflow */
115bad584e3SAlfred Perlstein 	maxlen = (obj->n_len < MAX_NETOBJ_SZ ? obj->n_len : MAX_NETOBJ_SZ);
116b6ecea30SDon Lewis 	for (i=0, tmp1 = objvalbuffer, tmp2 = objascbuffer; i < maxlen;
117bad584e3SAlfred Perlstein 	    i++, tmp1 +=2, tmp2 +=1) {
118bad584e3SAlfred Perlstein 		sprintf(tmp1,"%02X",*(obj->n_bytes+i));
119bad584e3SAlfred Perlstein 		sprintf(tmp2,"%c",*(obj->n_bytes+i));
120bad584e3SAlfred Perlstein 	}
121bad584e3SAlfred Perlstein 	*tmp1 = '\0';
122bad584e3SAlfred Perlstein 	*tmp2 = '\0';
123bad584e3SAlfred Perlstein 	syslog(LOG_DEBUG,"netobjvals: %s\n",objvalbuffer);
124bad584e3SAlfred Perlstein 	syslog(LOG_DEBUG,"netobjascs: %s\n",objascbuffer);
125bad584e3SAlfred Perlstein }
1268360efbdSAlfred Perlstein /* get_client -------------------------------------------------------------- */
1278360efbdSAlfred Perlstein /*
1288360efbdSAlfred Perlstein  * Purpose:	Get a CLIENT* for making RPC calls to lockd on given host
1298360efbdSAlfred Perlstein  * Returns:	CLIENT* pointer, from clnt_udp_create, or NULL if error
1308360efbdSAlfred Perlstein  * Notes:	Creating a CLIENT* is quite expensive, involving a
1318360efbdSAlfred Perlstein  *		conversation with the remote portmapper to get the
1328360efbdSAlfred Perlstein  *		port number.  Since a given client is quite likely
1338360efbdSAlfred Perlstein  *		to make several locking requests in succession, it is
1348360efbdSAlfred Perlstein  *		desirable to cache the created CLIENT*.
1358360efbdSAlfred Perlstein  *
1368360efbdSAlfred Perlstein  *		Since we are using UDP rather than TCP, there is no cost
1378360efbdSAlfred Perlstein  *		to the remote system in keeping these cached indefinitely.
1388360efbdSAlfred Perlstein  *		Unfortunately there is a snag: if the remote system
1398360efbdSAlfred Perlstein  *		reboots, the cached portmapper results will be invalid,
1408360efbdSAlfred Perlstein  *		and we will never detect this since all of the xxx_msg()
1418360efbdSAlfred Perlstein  *		calls return no result - we just fire off a udp packet
1428360efbdSAlfred Perlstein  *		and hope for the best.
1438360efbdSAlfred Perlstein  *
1448360efbdSAlfred Perlstein  *		We solve this by discarding cached values after two
1458360efbdSAlfred Perlstein  *		minutes, regardless of whether they have been used
1468360efbdSAlfred Perlstein  *		in the meanwhile (since a bad one might have been used
1478360efbdSAlfred Perlstein  *		plenty of times, as the host keeps retrying the request
1488360efbdSAlfred Perlstein  *		and we keep sending the reply back to the wrong port).
1498360efbdSAlfred Perlstein  *
1508360efbdSAlfred Perlstein  *		Given that the entries will always expire in the order
1518360efbdSAlfred Perlstein  *		that they were created, there is no point in a LRU
1528360efbdSAlfred Perlstein  *		algorithm for when the cache gets full - entries are
1538360efbdSAlfred Perlstein  *		always re-used in sequence.
1548360efbdSAlfred Perlstein  */
1558360efbdSAlfred Perlstein static CLIENT *clnt_cache_ptr[CLIENT_CACHE_SIZE];
1568360efbdSAlfred Perlstein static long clnt_cache_time[CLIENT_CACHE_SIZE];	/* time entry created */
1578360efbdSAlfred Perlstein static struct sockaddr_storage clnt_cache_addr[CLIENT_CACHE_SIZE];
158c20e578fSAlfred Perlstein static rpcvers_t clnt_cache_vers[CLIENT_CACHE_SIZE];
1598360efbdSAlfred Perlstein static int clnt_cache_next_to_use = 0;
1608360efbdSAlfred Perlstein 
1618360efbdSAlfred Perlstein static int
addrcmp(struct sockaddr * sa1,struct sockaddr * sa2)16229df5733SXin LI addrcmp(struct sockaddr *sa1, struct sockaddr *sa2)
1638360efbdSAlfred Perlstein {
1648360efbdSAlfred Perlstein 	int len;
1658360efbdSAlfred Perlstein 	void *p1, *p2;
1668360efbdSAlfred Perlstein 
1678360efbdSAlfred Perlstein 	if (sa1->sa_family != sa2->sa_family)
1688360efbdSAlfred Perlstein 		return -1;
1698360efbdSAlfred Perlstein 
1708360efbdSAlfred Perlstein 	switch (sa1->sa_family) {
1718360efbdSAlfred Perlstein 	case AF_INET:
1728360efbdSAlfred Perlstein 		p1 = &((struct sockaddr_in *)sa1)->sin_addr;
1738360efbdSAlfred Perlstein 		p2 = &((struct sockaddr_in *)sa2)->sin_addr;
1748360efbdSAlfred Perlstein 		len = 4;
1758360efbdSAlfred Perlstein 		break;
1768360efbdSAlfred Perlstein 	case AF_INET6:
1778360efbdSAlfred Perlstein 		p1 = &((struct sockaddr_in6 *)sa1)->sin6_addr;
1788360efbdSAlfred Perlstein 		p2 = &((struct sockaddr_in6 *)sa2)->sin6_addr;
1798360efbdSAlfred Perlstein 		len = 16;
1808360efbdSAlfred Perlstein 		break;
1818360efbdSAlfred Perlstein 	default:
1828360efbdSAlfred Perlstein 		return -1;
1838360efbdSAlfred Perlstein 	}
1848360efbdSAlfred Perlstein 
1858360efbdSAlfred Perlstein 	return memcmp(p1, p2, len);
1868360efbdSAlfred Perlstein }
1878360efbdSAlfred Perlstein 
1888360efbdSAlfred Perlstein CLIENT *
get_client(struct sockaddr * host_addr,rpcvers_t vers)18929df5733SXin LI get_client(struct sockaddr *host_addr, rpcvers_t vers)
1908360efbdSAlfred Perlstein {
1918360efbdSAlfred Perlstein 	CLIENT *client;
1928360efbdSAlfred Perlstein 	struct timeval retry_time, time_now;
1932d914e96SJun Kuriyama 	int error, i;
1947bb4bf85SAlfred Perlstein 	const char *netid;
1958360efbdSAlfred Perlstein 	struct netconfig *nconf;
1968360efbdSAlfred Perlstein 	char host[NI_MAXHOST];
197c0f7cd1aSPeter Pentchev 	uid_t old_euid;
198c0f7cd1aSPeter Pentchev 	int clnt_fd;
1998360efbdSAlfred Perlstein 
2008360efbdSAlfred Perlstein 	gettimeofday(&time_now, NULL);
2018360efbdSAlfred Perlstein 
2028360efbdSAlfred Perlstein 	/*
2038360efbdSAlfred Perlstein 	 * Search for the given client in the cache, zapping any expired
2048360efbdSAlfred Perlstein 	 * entries that we happen to notice in passing.
2058360efbdSAlfred Perlstein 	 */
2068360efbdSAlfred Perlstein 	for (i = 0; i < CLIENT_CACHE_SIZE; i++) {
2078360efbdSAlfred Perlstein 		client = clnt_cache_ptr[i];
2088360efbdSAlfred Perlstein 		if (client && ((clnt_cache_time[i] + CLIENT_CACHE_LIFETIME)
2098360efbdSAlfred Perlstein 		    < time_now.tv_sec)) {
2108360efbdSAlfred Perlstein 			/* Cache entry has expired. */
2118360efbdSAlfred Perlstein 			if (debug_level > 3)
2128360efbdSAlfred Perlstein 				syslog(LOG_DEBUG, "Expired CLIENT* in cache");
2138360efbdSAlfred Perlstein 			clnt_cache_time[i] = 0L;
2148360efbdSAlfred Perlstein 			clnt_destroy(client);
2158360efbdSAlfred Perlstein 			clnt_cache_ptr[i] = NULL;
2168360efbdSAlfred Perlstein 			client = NULL;
2178360efbdSAlfred Perlstein 		}
2188360efbdSAlfred Perlstein 		if (client && !addrcmp((struct sockaddr *)&clnt_cache_addr[i],
219c20e578fSAlfred Perlstein 		    host_addr) && clnt_cache_vers[i] == vers) {
2208360efbdSAlfred Perlstein 			/* Found it! */
2218360efbdSAlfred Perlstein 			if (debug_level > 3)
2228360efbdSAlfred Perlstein 				syslog(LOG_DEBUG, "Found CLIENT* in cache");
2238360efbdSAlfred Perlstein 			return (client);
2248360efbdSAlfred Perlstein 		}
2258360efbdSAlfred Perlstein 	}
2268360efbdSAlfred Perlstein 
227c20e578fSAlfred Perlstein 	if (debug_level > 3)
228c20e578fSAlfred Perlstein 		syslog(LOG_DEBUG, "CLIENT* not found in cache, creating");
229c20e578fSAlfred Perlstein 
2308360efbdSAlfred Perlstein 	/* Not found in cache.  Free the next entry if it is in use. */
2318360efbdSAlfred Perlstein 	if (clnt_cache_ptr[clnt_cache_next_to_use]) {
2328360efbdSAlfred Perlstein 		clnt_destroy(clnt_cache_ptr[clnt_cache_next_to_use]);
2338360efbdSAlfred Perlstein 		clnt_cache_ptr[clnt_cache_next_to_use] = NULL;
2348360efbdSAlfred Perlstein 	}
2358360efbdSAlfred Perlstein 
2368360efbdSAlfred Perlstein 	/*
2378360efbdSAlfred Perlstein 	 * Need a host string for clnt_tp_create. Use NI_NUMERICHOST
2388360efbdSAlfred Perlstein 	 * to avoid DNS lookups.
2398360efbdSAlfred Perlstein 	 */
2402d914e96SJun Kuriyama 	error = getnameinfo(host_addr, host_addr->sa_len, host, sizeof host,
2412d914e96SJun Kuriyama 			    NULL, 0, NI_NUMERICHOST);
2422d914e96SJun Kuriyama 	if (error != 0) {
2432d914e96SJun Kuriyama 		syslog(LOG_ERR, "unable to get name string for caller: %s",
2442d914e96SJun Kuriyama 		       gai_strerror(error));
2458360efbdSAlfred Perlstein 		return NULL;
2468360efbdSAlfred Perlstein 	}
2478360efbdSAlfred Perlstein 
2488360efbdSAlfred Perlstein #if 1
2498360efbdSAlfred Perlstein 	if (host_addr->sa_family == AF_INET6)
2508360efbdSAlfred Perlstein 		netid = "udp6";
2518360efbdSAlfred Perlstein 	else
2528360efbdSAlfred Perlstein 		netid = "udp";
2538360efbdSAlfred Perlstein #else
2548360efbdSAlfred Perlstein 	if (host_addr->sa_family == AF_INET6)
2558360efbdSAlfred Perlstein 		netid = "tcp6";
2568360efbdSAlfred Perlstein 	else
2578360efbdSAlfred Perlstein 		netid = "tcp";
2588360efbdSAlfred Perlstein #endif
2598360efbdSAlfred Perlstein 	nconf = getnetconfigent(netid);
2608360efbdSAlfred Perlstein 	if (nconf == NULL) {
2618360efbdSAlfred Perlstein 		syslog(LOG_ERR, "could not get netconfig info for '%s': "
2628360efbdSAlfred Perlstein 				"no /etc/netconfig file?", netid);
2638360efbdSAlfred Perlstein 		return NULL;
2648360efbdSAlfred Perlstein 	}
2658360efbdSAlfred Perlstein 
2668360efbdSAlfred Perlstein 	client = clnt_tp_create(host, NLM_PROG, vers, nconf);
2678360efbdSAlfred Perlstein 	freenetconfigent(nconf);
2688360efbdSAlfred Perlstein 
2698360efbdSAlfred Perlstein 	if (!client) {
2708360efbdSAlfred Perlstein 		syslog(LOG_ERR, "%s", clnt_spcreateerror("clntudp_create"));
2718360efbdSAlfred Perlstein 		syslog(LOG_ERR, "Unable to return result to %s", host);
2728360efbdSAlfred Perlstein 		return NULL;
2738360efbdSAlfred Perlstein 	}
2748360efbdSAlfred Perlstein 
275c0f7cd1aSPeter Pentchev 	/* Get the FD of the client, for bindresvport. */
276c0f7cd1aSPeter Pentchev 	clnt_control(client, CLGET_FD, &clnt_fd);
277c0f7cd1aSPeter Pentchev 
278c0f7cd1aSPeter Pentchev 	/* Regain root privileges, for bindresvport. */
279c0f7cd1aSPeter Pentchev 	old_euid = geteuid();
280df9abd97SXin LI 	if (seteuid(0) != 0) {
281df9abd97SXin LI 		syslog(LOG_ERR, "seteuid(0) failed");
282df9abd97SXin LI 		return NULL;
283df9abd97SXin LI 	}
284c0f7cd1aSPeter Pentchev 
285c0f7cd1aSPeter Pentchev 	/*
286c0f7cd1aSPeter Pentchev 	 * Bind the client FD to a reserved port.
287c0f7cd1aSPeter Pentchev 	 * Some NFS servers reject any NLM request from a non-reserved port.
288c0f7cd1aSPeter Pentchev 	 */
289c0f7cd1aSPeter Pentchev 	bindresvport(clnt_fd, NULL);
290c0f7cd1aSPeter Pentchev 
291c0f7cd1aSPeter Pentchev 	/* Drop root privileges again. */
292df9abd97SXin LI 	if (seteuid(old_euid) != 0) {
293df9abd97SXin LI 		syslog(LOG_ERR, "seteuid(%d) failed", old_euid);
294df9abd97SXin LI 		return NULL;
295df9abd97SXin LI 	}
296c0f7cd1aSPeter Pentchev 
2978360efbdSAlfred Perlstein 	/* Success - update the cache entry */
2988360efbdSAlfred Perlstein 	clnt_cache_ptr[clnt_cache_next_to_use] = client;
2998360efbdSAlfred Perlstein 	memcpy(&clnt_cache_addr[clnt_cache_next_to_use], host_addr,
3008360efbdSAlfred Perlstein 	    host_addr->sa_len);
301c20e578fSAlfred Perlstein 	clnt_cache_vers[clnt_cache_next_to_use] = vers;
3028360efbdSAlfred Perlstein 	clnt_cache_time[clnt_cache_next_to_use] = time_now.tv_sec;
3033d81d1adSMichael Reifenberger 	if (++clnt_cache_next_to_use >= CLIENT_CACHE_SIZE)
3048360efbdSAlfred Perlstein 		clnt_cache_next_to_use = 0;
3058360efbdSAlfred Perlstein 
3068360efbdSAlfred Perlstein 	/*
3078360efbdSAlfred Perlstein 	 * Disable the default timeout, so we can specify our own in calls
3088360efbdSAlfred Perlstein 	 * to clnt_call().  (Note that the timeout is a different concept
3098360efbdSAlfred Perlstein 	 * from the retry period set in clnt_udp_create() above.)
3108360efbdSAlfred Perlstein 	 */
3118360efbdSAlfred Perlstein 	retry_time.tv_sec = -1;
3128360efbdSAlfred Perlstein 	retry_time.tv_usec = -1;
3138360efbdSAlfred Perlstein 	clnt_control(client, CLSET_TIMEOUT, (char *)&retry_time);
3148360efbdSAlfred Perlstein 
3158360efbdSAlfred Perlstein 	if (debug_level > 3)
3168360efbdSAlfred Perlstein 		syslog(LOG_DEBUG, "Created CLIENT* for %s", host);
3178360efbdSAlfred Perlstein 	return client;
3188360efbdSAlfred Perlstein }
3198360efbdSAlfred Perlstein 
3208360efbdSAlfred Perlstein 
3218360efbdSAlfred Perlstein /* transmit_result --------------------------------------------------------- */
3228360efbdSAlfred Perlstein /*
3238360efbdSAlfred Perlstein  * Purpose:	Transmit result for nlm_xxx_msg pseudo-RPCs
3248360efbdSAlfred Perlstein  * Returns:	Nothing - we have no idea if the datagram got there
3258360efbdSAlfred Perlstein  * Notes:	clnt_call() will always fail (with timeout) as we are
3268360efbdSAlfred Perlstein  *		calling it with timeout 0 as a hack to just issue a datagram
3278360efbdSAlfred Perlstein  *		without expecting a result
3288360efbdSAlfred Perlstein  */
3298360efbdSAlfred Perlstein void
transmit_result(int opcode,nlm_res * result,struct sockaddr * addr)33029df5733SXin LI transmit_result(int opcode, nlm_res *result, struct sockaddr *addr)
3318360efbdSAlfred Perlstein {
3328360efbdSAlfred Perlstein 	static char dummy;
3338360efbdSAlfred Perlstein 	CLIENT *cli;
3348360efbdSAlfred Perlstein 	struct timeval timeo;
3358360efbdSAlfred Perlstein 	int success;
3368360efbdSAlfred Perlstein 
3378360efbdSAlfred Perlstein 	if ((cli = get_client(addr, NLM_VERS)) != NULL) {
3388360efbdSAlfred Perlstein 		timeo.tv_sec = 0; /* No timeout - not expecting response */
3398360efbdSAlfred Perlstein 		timeo.tv_usec = 0;
3408360efbdSAlfred Perlstein 
34175e40e46SPeter Wemm 		success = clnt_call(cli, opcode, (xdrproc_t)xdr_nlm_res, result,
34275e40e46SPeter Wemm 		    (xdrproc_t)xdr_void, &dummy, timeo);
3438360efbdSAlfred Perlstein 
3448360efbdSAlfred Perlstein 		if (debug_level > 2)
3458360efbdSAlfred Perlstein 			syslog(LOG_DEBUG, "clnt_call returns %d(%s)",
3468360efbdSAlfred Perlstein 			    success, clnt_sperrno(success));
3478360efbdSAlfred Perlstein 	}
3488360efbdSAlfred Perlstein }
3498360efbdSAlfred Perlstein /* transmit4_result --------------------------------------------------------- */
3508360efbdSAlfred Perlstein /*
3518360efbdSAlfred Perlstein  * Purpose:	Transmit result for nlm4_xxx_msg pseudo-RPCs
3528360efbdSAlfred Perlstein  * Returns:	Nothing - we have no idea if the datagram got there
3538360efbdSAlfred Perlstein  * Notes:	clnt_call() will always fail (with timeout) as we are
3548360efbdSAlfred Perlstein  *		calling it with timeout 0 as a hack to just issue a datagram
3558360efbdSAlfred Perlstein  *		without expecting a result
3568360efbdSAlfred Perlstein  */
3578360efbdSAlfred Perlstein void
transmit4_result(int opcode,nlm4_res * result,struct sockaddr * addr)35829df5733SXin LI transmit4_result(int opcode, nlm4_res *result, struct sockaddr *addr)
3598360efbdSAlfred Perlstein {
3608360efbdSAlfred Perlstein 	static char dummy;
3618360efbdSAlfred Perlstein 	CLIENT *cli;
3628360efbdSAlfred Perlstein 	struct timeval timeo;
3638360efbdSAlfred Perlstein 	int success;
3648360efbdSAlfred Perlstein 
3658360efbdSAlfred Perlstein 	if ((cli = get_client(addr, NLM_VERS4)) != NULL) {
3668360efbdSAlfred Perlstein 		timeo.tv_sec = 0; /* No timeout - not expecting response */
3678360efbdSAlfred Perlstein 		timeo.tv_usec = 0;
3688360efbdSAlfred Perlstein 
36975e40e46SPeter Wemm 		success = clnt_call(cli, opcode,
37075e40e46SPeter Wemm 		    (xdrproc_t)xdr_nlm4_res, result,
37175e40e46SPeter Wemm 		    (xdrproc_t)xdr_void, &dummy, timeo);
3728360efbdSAlfred Perlstein 
3738360efbdSAlfred Perlstein 		if (debug_level > 2)
3748360efbdSAlfred Perlstein 			syslog(LOG_DEBUG, "clnt_call returns %d(%s)",
3758360efbdSAlfred Perlstein 			    success, clnt_sperrno(success));
3768360efbdSAlfred Perlstein 	}
3778360efbdSAlfred Perlstein }
3788360efbdSAlfred Perlstein 
3798360efbdSAlfred Perlstein /*
3808360efbdSAlfred Perlstein  * converts a struct nlm_lock to struct nlm4_lock
3818360efbdSAlfred Perlstein  */
3828360efbdSAlfred Perlstein static void
nlmtonlm4(struct nlm_lock * arg,struct nlm4_lock * arg4)38329df5733SXin LI nlmtonlm4(struct nlm_lock *arg, struct nlm4_lock *arg4)
3848360efbdSAlfred Perlstein {
3853d81d1adSMichael Reifenberger 	arg4->caller_name = arg->caller_name;
3863d81d1adSMichael Reifenberger 	arg4->fh = arg->fh;
3873d81d1adSMichael Reifenberger 	arg4->oh = arg->oh;
3883d81d1adSMichael Reifenberger 	arg4->svid = arg->svid;
3898360efbdSAlfred Perlstein 	arg4->l_offset = arg->l_offset;
3908360efbdSAlfred Perlstein 	arg4->l_len = arg->l_len;
3918360efbdSAlfred Perlstein }
3928360efbdSAlfred Perlstein /* ------------------------------------------------------------------------- */
3938360efbdSAlfred Perlstein /*
3948360efbdSAlfred Perlstein  * Functions for Unix<->Unix locking (ie. monitored locking, with rpc.statd
3958360efbdSAlfred Perlstein  * involved to ensure reclaim of locks after a crash of the "stateless"
3968360efbdSAlfred Perlstein  * server.
3978360efbdSAlfred Perlstein  *
3988360efbdSAlfred Perlstein  * These all come in two flavours - nlm_xxx() and nlm_xxx_msg().
3998360efbdSAlfred Perlstein  * The first are standard RPCs with argument and result.
4008360efbdSAlfred Perlstein  * The nlm_xxx_msg() calls implement exactly the same functions, but
4018360efbdSAlfred Perlstein  * use two pseudo-RPCs (one in each direction).  These calls are NOT
4028360efbdSAlfred Perlstein  * standard use of the RPC protocol in that they do not return a result
4038360efbdSAlfred Perlstein  * at all (NB. this is quite different from returning a void result).
4048360efbdSAlfred Perlstein  * The effect of this is to make the nlm_xxx_msg() calls simple unacknowledged
4058360efbdSAlfred Perlstein  * datagrams, requiring higher-level code to perform retries.
4068360efbdSAlfred Perlstein  *
4078360efbdSAlfred Perlstein  * Despite the disadvantages of the nlm_xxx_msg() approach (some of which
4088360efbdSAlfred Perlstein  * are documented in the comments to get_client() above), this is the
4098360efbdSAlfred Perlstein  * interface used by all current commercial NFS implementations
4108360efbdSAlfred Perlstein  * [Solaris, SCO, AIX etc.].  This is presumed to be because these allow
4118360efbdSAlfred Perlstein  * implementations to continue using the standard RPC libraries, while
4128360efbdSAlfred Perlstein  * avoiding the block-until-result nature of the library interface.
4138360efbdSAlfred Perlstein  *
4148360efbdSAlfred Perlstein  * No client implementations have been identified so far that make use
4158360efbdSAlfred Perlstein  * of the true RPC version (early SunOS releases would be a likely candidate
4168360efbdSAlfred Perlstein  * for testing).
4178360efbdSAlfred Perlstein  */
4188360efbdSAlfred Perlstein 
4198360efbdSAlfred Perlstein /* nlm_test ---------------------------------------------------------------- */
4208360efbdSAlfred Perlstein /*
4218360efbdSAlfred Perlstein  * Purpose:	Test whether a specified lock would be granted if requested
4228360efbdSAlfred Perlstein  * Returns:	nlm_granted (or error code)
4238360efbdSAlfred Perlstein  * Notes:
4248360efbdSAlfred Perlstein  */
4258360efbdSAlfred Perlstein nlm_testres *
nlm_test_1_svc(nlm_testargs * arg,struct svc_req * rqstp)42629df5733SXin LI nlm_test_1_svc(nlm_testargs *arg, struct svc_req *rqstp)
4278360efbdSAlfred Perlstein {
4288360efbdSAlfred Perlstein 	static nlm_testres res;
4298360efbdSAlfred Perlstein 	struct nlm4_lock arg4;
4308360efbdSAlfred Perlstein 	struct nlm4_holder *holder;
4318360efbdSAlfred Perlstein 	nlmtonlm4(&arg->alock, &arg4);
4328360efbdSAlfred Perlstein 
4338360efbdSAlfred Perlstein 	if (debug_level)
4348360efbdSAlfred Perlstein 		log_from_addr("nlm_test", rqstp);
4358360efbdSAlfred Perlstein 
436bad584e3SAlfred Perlstein 	holder = testlock(&arg4, arg->exclusive, 0);
4378360efbdSAlfred Perlstein 	/*
4388360efbdSAlfred Perlstein 	 * Copy the cookie from the argument into the result.  Note that this
4398360efbdSAlfred Perlstein 	 * is slightly hazardous, as the structure contains a pointer to a
4408360efbdSAlfred Perlstein 	 * malloc()ed buffer that will get freed by the caller.  However, the
4418360efbdSAlfred Perlstein 	 * main function transmits the result before freeing the argument
4428360efbdSAlfred Perlstein 	 * so it is in fact safe.
4438360efbdSAlfred Perlstein 	 */
4448360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
4458360efbdSAlfred Perlstein 	if (holder == NULL) {
4468360efbdSAlfred Perlstein 		res.stat.stat = nlm_granted;
4478360efbdSAlfred Perlstein 	} else {
4488360efbdSAlfred Perlstein 		res.stat.stat = nlm_denied;
4498360efbdSAlfred Perlstein 		memcpy(&res.stat.nlm_testrply_u.holder, holder,
4508360efbdSAlfred Perlstein 		    sizeof(struct nlm_holder));
4518360efbdSAlfred Perlstein 		res.stat.nlm_testrply_u.holder.l_offset = holder->l_offset;
4528360efbdSAlfred Perlstein 		res.stat.nlm_testrply_u.holder.l_len = holder->l_len;
4538360efbdSAlfred Perlstein 	}
4548360efbdSAlfred Perlstein 	return (&res);
4558360efbdSAlfred Perlstein }
4568360efbdSAlfred Perlstein 
4578360efbdSAlfred Perlstein void *
nlm_test_msg_1_svc(nlm_testargs * arg,struct svc_req * rqstp)45829df5733SXin LI nlm_test_msg_1_svc(nlm_testargs *arg, struct svc_req *rqstp)
4598360efbdSAlfred Perlstein {
4608360efbdSAlfred Perlstein 	nlm_testres res;
4618360efbdSAlfred Perlstein 	static char dummy;
4628360efbdSAlfred Perlstein 	struct sockaddr *addr;
4638360efbdSAlfred Perlstein 	CLIENT *cli;
4648360efbdSAlfred Perlstein 	int success;
4658360efbdSAlfred Perlstein 	struct timeval timeo;
4668360efbdSAlfred Perlstein 	struct nlm4_lock arg4;
4678360efbdSAlfred Perlstein 	struct nlm4_holder *holder;
4688360efbdSAlfred Perlstein 
4698360efbdSAlfred Perlstein 	nlmtonlm4(&arg->alock, &arg4);
4708360efbdSAlfred Perlstein 
4718360efbdSAlfred Perlstein 	if (debug_level)
4728360efbdSAlfred Perlstein 		log_from_addr("nlm_test_msg", rqstp);
4738360efbdSAlfred Perlstein 
474bad584e3SAlfred Perlstein 	holder = testlock(&arg4, arg->exclusive, 0);
4758360efbdSAlfred Perlstein 
4768360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
4778360efbdSAlfred Perlstein 	if (holder == NULL) {
4788360efbdSAlfred Perlstein 		res.stat.stat = nlm_granted;
4798360efbdSAlfred Perlstein 	} else {
4808360efbdSAlfred Perlstein 		res.stat.stat = nlm_denied;
4818360efbdSAlfred Perlstein 		memcpy(&res.stat.nlm_testrply_u.holder, holder,
4828360efbdSAlfred Perlstein 		    sizeof(struct nlm_holder));
4838360efbdSAlfred Perlstein 		res.stat.nlm_testrply_u.holder.l_offset = holder->l_offset;
4848360efbdSAlfred Perlstein 		res.stat.nlm_testrply_u.holder.l_len = holder->l_len;
4858360efbdSAlfred Perlstein 	}
4868360efbdSAlfred Perlstein 
4878360efbdSAlfred Perlstein 	/*
4888360efbdSAlfred Perlstein 	 * nlm_test has different result type to the other operations, so
4898360efbdSAlfred Perlstein 	 * can't use transmit_result() in this case
4908360efbdSAlfred Perlstein 	 */
4918360efbdSAlfred Perlstein 	addr = svc_getrpccaller(rqstp->rq_xprt)->buf;
4928360efbdSAlfred Perlstein 	if ((cli = get_client(addr, NLM_VERS)) != NULL) {
4938360efbdSAlfred Perlstein 		timeo.tv_sec = 0; /* No timeout - not expecting response */
4948360efbdSAlfred Perlstein 		timeo.tv_usec = 0;
4958360efbdSAlfred Perlstein 
49675e40e46SPeter Wemm 		success = clnt_call(cli, NLM_TEST_RES,
49775e40e46SPeter Wemm 		    (xdrproc_t)xdr_nlm_testres, &res,
49875e40e46SPeter Wemm 		    (xdrproc_t)xdr_void, &dummy, timeo);
4998360efbdSAlfred Perlstein 
5008360efbdSAlfred Perlstein 		if (debug_level > 2)
5018360efbdSAlfred Perlstein 			syslog(LOG_DEBUG, "clnt_call returns %d", success);
5028360efbdSAlfred Perlstein 	}
5038360efbdSAlfred Perlstein 	return (NULL);
5048360efbdSAlfred Perlstein }
5058360efbdSAlfred Perlstein 
5068360efbdSAlfred Perlstein /* nlm_lock ---------------------------------------------------------------- */
5078360efbdSAlfred Perlstein /*
5088360efbdSAlfred Perlstein  * Purposes:	Establish a lock
5098360efbdSAlfred Perlstein  * Returns:	granted, denied or blocked
5108360efbdSAlfred Perlstein  * Notes:	*** grace period support missing
5118360efbdSAlfred Perlstein  */
5128360efbdSAlfred Perlstein nlm_res *
nlm_lock_1_svc(nlm_lockargs * arg,struct svc_req * rqstp)51329df5733SXin LI nlm_lock_1_svc(nlm_lockargs *arg, struct svc_req *rqstp)
5148360efbdSAlfred Perlstein {
5158360efbdSAlfred Perlstein 	static nlm_res res;
5168360efbdSAlfred Perlstein 	struct nlm4_lockargs arg4;
5178360efbdSAlfred Perlstein 	nlmtonlm4(&arg->alock, &arg4.alock);
5188360efbdSAlfred Perlstein 	arg4.cookie = arg->cookie;
5198360efbdSAlfred Perlstein 	arg4.block = arg->block;
5208360efbdSAlfred Perlstein 	arg4.exclusive = arg->exclusive;
5218360efbdSAlfred Perlstein 	arg4.reclaim = arg->reclaim;
5228360efbdSAlfred Perlstein 	arg4.state = arg->state;
5238360efbdSAlfred Perlstein 
5248360efbdSAlfred Perlstein 	if (debug_level)
5258360efbdSAlfred Perlstein 		log_from_addr("nlm_lock", rqstp);
5268360efbdSAlfred Perlstein 
5278360efbdSAlfred Perlstein 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
5288360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
5298360efbdSAlfred Perlstein 
5308360efbdSAlfred Perlstein 	res.stat.stat = getlock(&arg4, rqstp, LOCK_MON);
5318360efbdSAlfred Perlstein 	return (&res);
5328360efbdSAlfred Perlstein }
5338360efbdSAlfred Perlstein 
5348360efbdSAlfred Perlstein void *
nlm_lock_msg_1_svc(nlm_lockargs * arg,struct svc_req * rqstp)53529df5733SXin LI nlm_lock_msg_1_svc(nlm_lockargs *arg, struct svc_req *rqstp)
5368360efbdSAlfred Perlstein {
5378360efbdSAlfred Perlstein 	static nlm_res res;
5388360efbdSAlfred Perlstein 	struct nlm4_lockargs arg4;
5398360efbdSAlfred Perlstein 
5408360efbdSAlfred Perlstein 	nlmtonlm4(&arg->alock, &arg4.alock);
5418360efbdSAlfred Perlstein 	arg4.cookie = arg->cookie;
5428360efbdSAlfred Perlstein 	arg4.block = arg->block;
5438360efbdSAlfred Perlstein 	arg4.exclusive = arg->exclusive;
5448360efbdSAlfred Perlstein 	arg4.reclaim = arg->reclaim;
5458360efbdSAlfred Perlstein 	arg4.state = arg->state;
5468360efbdSAlfred Perlstein 
5478360efbdSAlfred Perlstein 	if (debug_level)
5488360efbdSAlfred Perlstein 		log_from_addr("nlm_lock_msg", rqstp);
5498360efbdSAlfred Perlstein 
5508360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
5518360efbdSAlfred Perlstein 	res.stat.stat = getlock(&arg4, rqstp, LOCK_ASYNC | LOCK_MON);
5522d914e96SJun Kuriyama 	transmit_result(NLM_LOCK_RES, &res, getrpcaddr(rqstp));
5538360efbdSAlfred Perlstein 
5548360efbdSAlfred Perlstein 	return (NULL);
5558360efbdSAlfred Perlstein }
5568360efbdSAlfred Perlstein 
5578360efbdSAlfred Perlstein /* nlm_cancel -------------------------------------------------------------- */
5588360efbdSAlfred Perlstein /*
5598360efbdSAlfred Perlstein  * Purpose:	Cancel a blocked lock request
5608360efbdSAlfred Perlstein  * Returns:	granted or denied
5618360efbdSAlfred Perlstein  * Notes:
5628360efbdSAlfred Perlstein  */
5638360efbdSAlfred Perlstein nlm_res *
nlm_cancel_1_svc(nlm_cancargs * arg,struct svc_req * rqstp)56429df5733SXin LI nlm_cancel_1_svc(nlm_cancargs *arg, struct svc_req *rqstp)
5658360efbdSAlfred Perlstein {
5668360efbdSAlfred Perlstein 	static nlm_res res;
5678360efbdSAlfred Perlstein 	struct nlm4_lock arg4;
5688360efbdSAlfred Perlstein 
5698360efbdSAlfred Perlstein 	nlmtonlm4(&arg->alock, &arg4);
5708360efbdSAlfred Perlstein 
5718360efbdSAlfred Perlstein 	if (debug_level)
5728360efbdSAlfred Perlstein 		log_from_addr("nlm_cancel", rqstp);
5738360efbdSAlfred Perlstein 
5748360efbdSAlfred Perlstein 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
5758360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
5768360efbdSAlfred Perlstein 
5778360efbdSAlfred Perlstein 	/*
5788360efbdSAlfred Perlstein 	 * Since at present we never return 'nlm_blocked', there can never be
5798360efbdSAlfred Perlstein 	 * a lock to cancel, so this call always fails.
5808360efbdSAlfred Perlstein 	 */
5818360efbdSAlfred Perlstein 	res.stat.stat = unlock(&arg4, LOCK_CANCEL);
5828360efbdSAlfred Perlstein 	return (&res);
5838360efbdSAlfred Perlstein }
5848360efbdSAlfred Perlstein 
5858360efbdSAlfred Perlstein void *
nlm_cancel_msg_1_svc(nlm_cancargs * arg,struct svc_req * rqstp)58629df5733SXin LI nlm_cancel_msg_1_svc(nlm_cancargs *arg, struct svc_req *rqstp)
5878360efbdSAlfred Perlstein {
5888360efbdSAlfred Perlstein 	static nlm_res res;
5898360efbdSAlfred Perlstein 	struct nlm4_lock arg4;
5908360efbdSAlfred Perlstein 
5918360efbdSAlfred Perlstein 	nlmtonlm4(&arg->alock, &arg4);
5928360efbdSAlfred Perlstein 
5938360efbdSAlfred Perlstein 	if (debug_level)
5948360efbdSAlfred Perlstein 		log_from_addr("nlm_cancel_msg", rqstp);
5958360efbdSAlfred Perlstein 
5968360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
5978360efbdSAlfred Perlstein 	/*
5988360efbdSAlfred Perlstein 	 * Since at present we never return 'nlm_blocked', there can never be
5998360efbdSAlfred Perlstein 	 * a lock to cancel, so this call always fails.
6008360efbdSAlfred Perlstein 	 */
6018360efbdSAlfred Perlstein 	res.stat.stat = unlock(&arg4, LOCK_CANCEL);
6022d914e96SJun Kuriyama 	transmit_result(NLM_CANCEL_RES, &res, getrpcaddr(rqstp));
6038360efbdSAlfred Perlstein 	return (NULL);
6048360efbdSAlfred Perlstein }
6058360efbdSAlfred Perlstein 
6068360efbdSAlfred Perlstein /* nlm_unlock -------------------------------------------------------------- */
6078360efbdSAlfred Perlstein /*
6088360efbdSAlfred Perlstein  * Purpose:	Release an existing lock
6098360efbdSAlfred Perlstein  * Returns:	Always granted, unless during grace period
6108360efbdSAlfred Perlstein  * Notes:	"no such lock" error condition is ignored, as the
6118360efbdSAlfred Perlstein  *		protocol uses unreliable UDP datagrams, and may well
6128360efbdSAlfred Perlstein  *		re-try an unlock that has already succeeded.
6138360efbdSAlfred Perlstein  */
6148360efbdSAlfred Perlstein nlm_res *
nlm_unlock_1_svc(nlm_unlockargs * arg,struct svc_req * rqstp)61529df5733SXin LI nlm_unlock_1_svc(nlm_unlockargs *arg, struct svc_req *rqstp)
6168360efbdSAlfred Perlstein {
6178360efbdSAlfred Perlstein 	static nlm_res res;
6188360efbdSAlfred Perlstein 	struct nlm4_lock arg4;
6198360efbdSAlfred Perlstein 
6208360efbdSAlfred Perlstein 	nlmtonlm4(&arg->alock, &arg4);
6218360efbdSAlfred Perlstein 
6228360efbdSAlfred Perlstein 	if (debug_level)
6238360efbdSAlfred Perlstein 		log_from_addr("nlm_unlock", rqstp);
6248360efbdSAlfred Perlstein 
6258360efbdSAlfred Perlstein 	res.stat.stat = unlock(&arg4, 0);
6268360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
6278360efbdSAlfred Perlstein 
6288360efbdSAlfred Perlstein 	return (&res);
6298360efbdSAlfred Perlstein }
6308360efbdSAlfred Perlstein 
6318360efbdSAlfred Perlstein void *
nlm_unlock_msg_1_svc(nlm_unlockargs * arg,struct svc_req * rqstp)63229df5733SXin LI nlm_unlock_msg_1_svc(nlm_unlockargs *arg, struct svc_req *rqstp)
6338360efbdSAlfred Perlstein {
6348360efbdSAlfred Perlstein 	static nlm_res res;
6358360efbdSAlfred Perlstein 	struct nlm4_lock arg4;
6368360efbdSAlfred Perlstein 
6378360efbdSAlfred Perlstein 	nlmtonlm4(&arg->alock, &arg4);
6388360efbdSAlfred Perlstein 
6398360efbdSAlfred Perlstein 	if (debug_level)
6408360efbdSAlfred Perlstein 		log_from_addr("nlm_unlock_msg", rqstp);
6418360efbdSAlfred Perlstein 
6428360efbdSAlfred Perlstein 	res.stat.stat = unlock(&arg4, 0);
6438360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
6448360efbdSAlfred Perlstein 
6452d914e96SJun Kuriyama 	transmit_result(NLM_UNLOCK_RES, &res, getrpcaddr(rqstp));
6468360efbdSAlfred Perlstein 	return (NULL);
6478360efbdSAlfred Perlstein }
6488360efbdSAlfred Perlstein 
6498360efbdSAlfred Perlstein /* ------------------------------------------------------------------------- */
6508360efbdSAlfred Perlstein /*
6518360efbdSAlfred Perlstein  * Client-side pseudo-RPCs for results.  Note that for the client there
6528360efbdSAlfred Perlstein  * are only nlm_xxx_msg() versions of each call, since the 'real RPC'
6538360efbdSAlfred Perlstein  * version returns the results in the RPC result, and so the client
6548360efbdSAlfred Perlstein  * does not normally receive incoming RPCs.
6558360efbdSAlfred Perlstein  *
6568360efbdSAlfred Perlstein  * The exception to this is nlm_granted(), which is genuinely an RPC
6578360efbdSAlfred Perlstein  * call from the server to the client - a 'call-back' in normal procedure
6588360efbdSAlfred Perlstein  * call terms.
6598360efbdSAlfred Perlstein  */
6608360efbdSAlfred Perlstein 
6618360efbdSAlfred Perlstein /* nlm_granted ------------------------------------------------------------- */
6628360efbdSAlfred Perlstein /*
6638360efbdSAlfred Perlstein  * Purpose:	Receive notification that formerly blocked lock now granted
6648360efbdSAlfred Perlstein  * Returns:	always success ('granted')
6658360efbdSAlfred Perlstein  * Notes:
6668360efbdSAlfred Perlstein  */
6678360efbdSAlfred Perlstein nlm_res *
nlm_granted_1_svc(nlm_testargs * arg,struct svc_req * rqstp)66829df5733SXin LI nlm_granted_1_svc(nlm_testargs *arg, struct svc_req *rqstp)
6698360efbdSAlfred Perlstein {
6708360efbdSAlfred Perlstein 	static nlm_res res;
6718360efbdSAlfred Perlstein 
6728360efbdSAlfred Perlstein 	if (debug_level)
6738360efbdSAlfred Perlstein 		log_from_addr("nlm_granted", rqstp);
6748360efbdSAlfred Perlstein 
675603c8667SAlfred Perlstein 	res.stat.stat = lock_answer(arg->alock.svid, &arg->cookie,
676603c8667SAlfred Perlstein 		nlm_granted, NULL, NLM_VERS) == 0 ?
677603c8667SAlfred Perlstein 		nlm_granted : nlm_denied;
678603c8667SAlfred Perlstein 
6798360efbdSAlfred Perlstein 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
6808360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
6818360efbdSAlfred Perlstein 
6828360efbdSAlfred Perlstein 	return (&res);
6838360efbdSAlfred Perlstein }
6848360efbdSAlfred Perlstein 
6858360efbdSAlfred Perlstein void *
nlm_granted_msg_1_svc(nlm_testargs * arg,struct svc_req * rqstp)68629df5733SXin LI nlm_granted_msg_1_svc(nlm_testargs *arg, struct svc_req *rqstp)
6878360efbdSAlfred Perlstein {
6888360efbdSAlfred Perlstein 	static nlm_res res;
6898360efbdSAlfred Perlstein 
6908360efbdSAlfred Perlstein 	if (debug_level)
6918360efbdSAlfred Perlstein 		log_from_addr("nlm_granted_msg", rqstp);
6928360efbdSAlfred Perlstein 
6938360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
6941870b993SRobert Watson 	res.stat.stat = lock_answer(arg->alock.svid, &arg->cookie,
6951870b993SRobert Watson 		nlm_granted, NULL, NLM_VERS) == 0 ?
6961870b993SRobert Watson 		nlm_granted : nlm_denied;
6971870b993SRobert Watson 
6982d914e96SJun Kuriyama 	transmit_result(NLM_GRANTED_RES, &res, getrpcaddr(rqstp));
6998360efbdSAlfred Perlstein 	return (NULL);
7008360efbdSAlfred Perlstein }
7018360efbdSAlfred Perlstein 
7028360efbdSAlfred Perlstein /* nlm_test_res ------------------------------------------------------------ */
7038360efbdSAlfred Perlstein /*
7048360efbdSAlfred Perlstein  * Purpose:	Accept result from earlier nlm_test_msg() call
7058360efbdSAlfred Perlstein  * Returns:	Nothing
7068360efbdSAlfred Perlstein  */
7078360efbdSAlfred Perlstein void *
nlm_test_res_1_svc(nlm_testres * arg,struct svc_req * rqstp)70829df5733SXin LI nlm_test_res_1_svc(nlm_testres *arg, struct svc_req *rqstp)
7098360efbdSAlfred Perlstein {
7108360efbdSAlfred Perlstein 	if (debug_level)
7118360efbdSAlfred Perlstein 		log_from_addr("nlm_test_res", rqstp);
712603c8667SAlfred Perlstein 	(void)lock_answer(-1, &arg->cookie, arg->stat.stat,
713603c8667SAlfred Perlstein 		&arg->stat.nlm_testrply_u.holder.svid, NLM_VERS);
7148360efbdSAlfred Perlstein 	return (NULL);
7158360efbdSAlfred Perlstein }
7168360efbdSAlfred Perlstein 
7178360efbdSAlfred Perlstein /* nlm_lock_res ------------------------------------------------------------ */
7188360efbdSAlfred Perlstein /*
7198360efbdSAlfred Perlstein  * Purpose:	Accept result from earlier nlm_lock_msg() call
7208360efbdSAlfred Perlstein  * Returns:	Nothing
7218360efbdSAlfred Perlstein  */
7228360efbdSAlfred Perlstein void *
nlm_lock_res_1_svc(nlm_res * arg,struct svc_req * rqstp)72329df5733SXin LI nlm_lock_res_1_svc(nlm_res *arg, struct svc_req *rqstp)
7248360efbdSAlfred Perlstein {
7258360efbdSAlfred Perlstein 	if (debug_level)
7268360efbdSAlfred Perlstein 		log_from_addr("nlm_lock_res", rqstp);
7278360efbdSAlfred Perlstein 
728603c8667SAlfred Perlstein 	(void)lock_answer(-1, &arg->cookie, arg->stat.stat, NULL, NLM_VERS);
729603c8667SAlfred Perlstein 
7308360efbdSAlfred Perlstein 	return (NULL);
7318360efbdSAlfred Perlstein }
7328360efbdSAlfred Perlstein 
7338360efbdSAlfred Perlstein /* nlm_cancel_res ---------------------------------------------------------- */
7348360efbdSAlfred Perlstein /*
7358360efbdSAlfred Perlstein  * Purpose:	Accept result from earlier nlm_cancel_msg() call
7368360efbdSAlfred Perlstein  * Returns:	Nothing
7378360efbdSAlfred Perlstein  */
7388360efbdSAlfred Perlstein void *
nlm_cancel_res_1_svc(nlm_res * arg __unused,struct svc_req * rqstp)73929df5733SXin LI nlm_cancel_res_1_svc(nlm_res *arg __unused, struct svc_req *rqstp)
7408360efbdSAlfred Perlstein {
7418360efbdSAlfred Perlstein 	if (debug_level)
7428360efbdSAlfred Perlstein 		log_from_addr("nlm_cancel_res", rqstp);
7438360efbdSAlfred Perlstein 	return (NULL);
7448360efbdSAlfred Perlstein }
7458360efbdSAlfred Perlstein 
7468360efbdSAlfred Perlstein /* nlm_unlock_res ---------------------------------------------------------- */
7478360efbdSAlfred Perlstein /*
7488360efbdSAlfred Perlstein  * Purpose:	Accept result from earlier nlm_unlock_msg() call
7498360efbdSAlfred Perlstein  * Returns:	Nothing
7508360efbdSAlfred Perlstein  */
7518360efbdSAlfred Perlstein void *
nlm_unlock_res_1_svc(nlm_res * arg,struct svc_req * rqstp)75229df5733SXin LI nlm_unlock_res_1_svc(nlm_res *arg, struct svc_req *rqstp)
7538360efbdSAlfred Perlstein {
7548360efbdSAlfred Perlstein 	if (debug_level)
7558360efbdSAlfred Perlstein 		log_from_addr("nlm_unlock_res", rqstp);
756603c8667SAlfred Perlstein 
757a95a0d36SAlfred Perlstein 	lock_answer(-1, &arg->cookie, arg->stat.stat, NULL, NLM_VERS);
758603c8667SAlfred Perlstein 
7598360efbdSAlfred Perlstein 	return (NULL);
7608360efbdSAlfred Perlstein }
7618360efbdSAlfred Perlstein 
7628360efbdSAlfred Perlstein /* nlm_granted_res --------------------------------------------------------- */
7638360efbdSAlfred Perlstein /*
7648360efbdSAlfred Perlstein  * Purpose:	Accept result from earlier nlm_granted_msg() call
7658360efbdSAlfred Perlstein  * Returns:	Nothing
7668360efbdSAlfred Perlstein  */
7678360efbdSAlfred Perlstein void *
nlm_granted_res_1_svc(nlm_res * arg __unused,struct svc_req * rqstp)76829df5733SXin LI nlm_granted_res_1_svc(nlm_res *arg __unused, struct svc_req *rqstp)
7698360efbdSAlfred Perlstein {
7708360efbdSAlfred Perlstein 	if (debug_level)
7718360efbdSAlfred Perlstein 		log_from_addr("nlm_granted_res", rqstp);
7728360efbdSAlfred Perlstein 	return (NULL);
7738360efbdSAlfred Perlstein }
7748360efbdSAlfred Perlstein 
7758360efbdSAlfred Perlstein /* ------------------------------------------------------------------------- */
7768360efbdSAlfred Perlstein /*
7778360efbdSAlfred Perlstein  * Calls for PCNFS locking (aka non-monitored locking, no involvement
7788360efbdSAlfred Perlstein  * of rpc.statd).
7798360efbdSAlfred Perlstein  *
7808360efbdSAlfred Perlstein  * These are all genuine RPCs - no nlm_xxx_msg() nonsense here.
7818360efbdSAlfred Perlstein  */
7828360efbdSAlfred Perlstein 
7838360efbdSAlfred Perlstein /* nlm_share --------------------------------------------------------------- */
7848360efbdSAlfred Perlstein /*
7858360efbdSAlfred Perlstein  * Purpose:	Establish a DOS-style lock
7868360efbdSAlfred Perlstein  * Returns:	success or failure
7878360efbdSAlfred Perlstein  * Notes:	Blocking locks are not supported - client is expected
7888360efbdSAlfred Perlstein  *		to retry if required.
7898360efbdSAlfred Perlstein  */
7908360efbdSAlfred Perlstein nlm_shareres *
nlm_share_3_svc(nlm_shareargs * arg,struct svc_req * rqstp)79129df5733SXin LI nlm_share_3_svc(nlm_shareargs *arg, struct svc_req *rqstp)
7928360efbdSAlfred Perlstein {
7938360efbdSAlfred Perlstein 	static nlm_shareres res;
7948360efbdSAlfred Perlstein 
7958360efbdSAlfred Perlstein 	if (debug_level)
7968360efbdSAlfred Perlstein 		log_from_addr("nlm_share", rqstp);
7978360efbdSAlfred Perlstein 
7988360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
7998360efbdSAlfred Perlstein 	res.stat = nlm_granted;
8008360efbdSAlfred Perlstein 	res.sequence = 1234356;	/* X/Open says this field is ignored? */
8018360efbdSAlfred Perlstein 	return (&res);
8028360efbdSAlfred Perlstein }
8038360efbdSAlfred Perlstein 
8048360efbdSAlfred Perlstein /* nlm_unshare ------------------------------------------------------------ */
8058360efbdSAlfred Perlstein /*
8068360efbdSAlfred Perlstein  * Purpose:	Release a DOS-style lock
8078360efbdSAlfred Perlstein  * Returns:	nlm_granted, unless in grace period
8088360efbdSAlfred Perlstein  * Notes:
8098360efbdSAlfred Perlstein  */
8108360efbdSAlfred Perlstein nlm_shareres *
nlm_unshare_3_svc(nlm_shareargs * arg,struct svc_req * rqstp)81129df5733SXin LI nlm_unshare_3_svc(nlm_shareargs *arg, struct svc_req *rqstp)
8128360efbdSAlfred Perlstein {
8138360efbdSAlfred Perlstein 	static nlm_shareres res;
8148360efbdSAlfred Perlstein 
8158360efbdSAlfred Perlstein 	if (debug_level)
8168360efbdSAlfred Perlstein 		log_from_addr("nlm_unshare", rqstp);
8178360efbdSAlfred Perlstein 
8188360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
8198360efbdSAlfred Perlstein 	res.stat = nlm_granted;
8208360efbdSAlfred Perlstein 	res.sequence = 1234356;	/* X/Open says this field is ignored? */
8218360efbdSAlfred Perlstein 	return (&res);
8228360efbdSAlfred Perlstein }
8238360efbdSAlfred Perlstein 
8248360efbdSAlfred Perlstein /* nlm_nm_lock ------------------------------------------------------------ */
8258360efbdSAlfred Perlstein /*
8268360efbdSAlfred Perlstein  * Purpose:	non-monitored version of nlm_lock()
8278360efbdSAlfred Perlstein  * Returns:	as for nlm_lock()
8288360efbdSAlfred Perlstein  * Notes:	These locks are in the same style as the standard nlm_lock,
8298360efbdSAlfred Perlstein  *		but the rpc.statd should not be called to establish a
8308360efbdSAlfred Perlstein  *		monitor for the client machine, since that machine is
8318360efbdSAlfred Perlstein  *		declared not to be running a rpc.statd, and so would not
8328360efbdSAlfred Perlstein  *		respond to the statd protocol.
8338360efbdSAlfred Perlstein  */
8348360efbdSAlfred Perlstein nlm_res *
nlm_nm_lock_3_svc(nlm_lockargs * arg,struct svc_req * rqstp)83529df5733SXin LI nlm_nm_lock_3_svc(nlm_lockargs *arg, struct svc_req *rqstp)
8368360efbdSAlfred Perlstein {
8378360efbdSAlfred Perlstein 	static nlm_res res;
8388360efbdSAlfred Perlstein 
8398360efbdSAlfred Perlstein 	if (debug_level)
8408360efbdSAlfred Perlstein 		log_from_addr("nlm_nm_lock", rqstp);
8418360efbdSAlfred Perlstein 
8428360efbdSAlfred Perlstein 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
8438360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
8448360efbdSAlfred Perlstein 	res.stat.stat = nlm_granted;
8458360efbdSAlfred Perlstein 	return (&res);
8468360efbdSAlfred Perlstein }
8478360efbdSAlfred Perlstein 
8488360efbdSAlfred Perlstein /* nlm_free_all ------------------------------------------------------------ */
8498360efbdSAlfred Perlstein /*
8508360efbdSAlfred Perlstein  * Purpose:	Release all locks held by a named client
8518360efbdSAlfred Perlstein  * Returns:	Nothing
8528360efbdSAlfred Perlstein  * Notes:	Potential denial of service security problem here - the
8538360efbdSAlfred Perlstein  *		locks to be released are specified by a host name, independent
8548360efbdSAlfred Perlstein  *		of the address from which the request has arrived.
8558360efbdSAlfred Perlstein  *		Should probably be rejected if the named host has been
8568360efbdSAlfred Perlstein  *		using monitored locks.
8578360efbdSAlfred Perlstein  */
8588360efbdSAlfred Perlstein void *
nlm_free_all_3_svc(nlm_notify * arg __unused,struct svc_req * rqstp)85929df5733SXin LI nlm_free_all_3_svc(nlm_notify *arg __unused, struct svc_req *rqstp)
8608360efbdSAlfred Perlstein {
8618360efbdSAlfred Perlstein 	static char dummy;
8628360efbdSAlfred Perlstein 
8638360efbdSAlfred Perlstein 	if (debug_level)
8648360efbdSAlfred Perlstein 		log_from_addr("nlm_free_all", rqstp);
8658360efbdSAlfred Perlstein 	return (&dummy);
8668360efbdSAlfred Perlstein }
8678360efbdSAlfred Perlstein 
8688360efbdSAlfred Perlstein /* calls for nlm version 4 (NFSv3) */
8698360efbdSAlfred Perlstein /* nlm_test ---------------------------------------------------------------- */
8708360efbdSAlfred Perlstein /*
8718360efbdSAlfred Perlstein  * Purpose:	Test whether a specified lock would be granted if requested
8728360efbdSAlfred Perlstein  * Returns:	nlm_granted (or error code)
8738360efbdSAlfred Perlstein  * Notes:
8748360efbdSAlfred Perlstein  */
8758360efbdSAlfred Perlstein nlm4_testres *
nlm4_test_4_svc(nlm4_testargs * arg,struct svc_req * rqstp)87629df5733SXin LI nlm4_test_4_svc(nlm4_testargs *arg, struct svc_req *rqstp)
8778360efbdSAlfred Perlstein {
8788360efbdSAlfred Perlstein 	static nlm4_testres res;
8798360efbdSAlfred Perlstein 	struct nlm4_holder *holder;
8808360efbdSAlfred Perlstein 
8818360efbdSAlfred Perlstein 	if (debug_level)
8828360efbdSAlfred Perlstein 		log_from_addr("nlm4_test", rqstp);
883bad584e3SAlfred Perlstein 	if (debug_level > 5) {
884bad584e3SAlfred Perlstein 		syslog(LOG_DEBUG, "Locking arguments:\n");
885bad584e3SAlfred Perlstein 		log_netobj(&(arg->cookie));
886bad584e3SAlfred Perlstein 		syslog(LOG_DEBUG, "Alock arguments:\n");
887bad584e3SAlfred Perlstein 		syslog(LOG_DEBUG, "Caller Name: %s\n",arg->alock.caller_name);
888bad584e3SAlfred Perlstein 		syslog(LOG_DEBUG, "File Handle:\n");
889bad584e3SAlfred Perlstein 		log_netobj(&(arg->alock.fh));
890bad584e3SAlfred Perlstein 		syslog(LOG_DEBUG, "Owner Handle:\n");
891bad584e3SAlfred Perlstein 		log_netobj(&(arg->alock.oh));
892bad584e3SAlfred Perlstein 		syslog(LOG_DEBUG, "SVID:        %d\n", arg->alock.svid);
8932663693cSAlfred Perlstein 		syslog(LOG_DEBUG, "Lock Offset: %llu\n",
8942663693cSAlfred Perlstein 		    (unsigned long long)arg->alock.l_offset);
8952663693cSAlfred Perlstein 		syslog(LOG_DEBUG, "Lock Length: %llu\n",
8962663693cSAlfred Perlstein 		    (unsigned long long)arg->alock.l_len);
897bad584e3SAlfred Perlstein 		syslog(LOG_DEBUG, "Exclusive:   %s\n",
898bad584e3SAlfred Perlstein 		    (arg->exclusive ? "true" : "false"));
899bad584e3SAlfred Perlstein 	}
9008360efbdSAlfred Perlstein 
901bad584e3SAlfred Perlstein 	holder = testlock(&arg->alock, arg->exclusive, LOCK_V4);
9028360efbdSAlfred Perlstein 
9038360efbdSAlfred Perlstein 	/*
9048360efbdSAlfred Perlstein 	 * Copy the cookie from the argument into the result.  Note that this
9058360efbdSAlfred Perlstein 	 * is slightly hazardous, as the structure contains a pointer to a
9068360efbdSAlfred Perlstein 	 * malloc()ed buffer that will get freed by the caller.  However, the
9078360efbdSAlfred Perlstein 	 * main function transmits the result before freeing the argument
9088360efbdSAlfred Perlstein 	 * so it is in fact safe.
9098360efbdSAlfred Perlstein 	 */
9108360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
9118360efbdSAlfred Perlstein 	if (holder == NULL) {
9128360efbdSAlfred Perlstein 		res.stat.stat = nlm4_granted;
9138360efbdSAlfred Perlstein 	} else {
9148360efbdSAlfred Perlstein 		res.stat.stat = nlm4_denied;
9158360efbdSAlfred Perlstein 		memcpy(&res.stat.nlm4_testrply_u.holder, holder,
9168360efbdSAlfred Perlstein 		    sizeof(struct nlm4_holder));
9178360efbdSAlfred Perlstein 	}
9188360efbdSAlfred Perlstein 	return (&res);
9198360efbdSAlfred Perlstein }
9208360efbdSAlfred Perlstein 
9218360efbdSAlfred Perlstein void *
nlm4_test_msg_4_svc(nlm4_testargs * arg,struct svc_req * rqstp)92229df5733SXin LI nlm4_test_msg_4_svc(nlm4_testargs *arg, struct svc_req *rqstp)
9238360efbdSAlfred Perlstein {
9248360efbdSAlfred Perlstein 	nlm4_testres res;
9258360efbdSAlfred Perlstein 	static char dummy;
9268360efbdSAlfred Perlstein 	struct sockaddr *addr;
9278360efbdSAlfred Perlstein 	CLIENT *cli;
9288360efbdSAlfred Perlstein 	int success;
9298360efbdSAlfred Perlstein 	struct timeval timeo;
9308360efbdSAlfred Perlstein 	struct nlm4_holder *holder;
9318360efbdSAlfred Perlstein 
9328360efbdSAlfred Perlstein 	if (debug_level)
9338360efbdSAlfred Perlstein 		log_from_addr("nlm4_test_msg", rqstp);
9348360efbdSAlfred Perlstein 
935bad584e3SAlfred Perlstein 	holder = testlock(&arg->alock, arg->exclusive, LOCK_V4);
9368360efbdSAlfred Perlstein 
9378360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
9388360efbdSAlfred Perlstein 	if (holder == NULL) {
9398360efbdSAlfred Perlstein 		res.stat.stat = nlm4_granted;
9408360efbdSAlfred Perlstein 	} else {
9418360efbdSAlfred Perlstein 		res.stat.stat = nlm4_denied;
9428360efbdSAlfred Perlstein 		memcpy(&res.stat.nlm4_testrply_u.holder, holder,
9438360efbdSAlfred Perlstein 		    sizeof(struct nlm4_holder));
9448360efbdSAlfred Perlstein 	}
9458360efbdSAlfred Perlstein 
9468360efbdSAlfred Perlstein 	/*
9478360efbdSAlfred Perlstein 	 * nlm_test has different result type to the other operations, so
9488360efbdSAlfred Perlstein 	 * can't use transmit4_result() in this case
9498360efbdSAlfred Perlstein 	 */
9508360efbdSAlfred Perlstein 	addr = svc_getrpccaller(rqstp->rq_xprt)->buf;
9518360efbdSAlfred Perlstein 	if ((cli = get_client(addr, NLM_VERS4)) != NULL) {
9528360efbdSAlfred Perlstein 		timeo.tv_sec = 0; /* No timeout - not expecting response */
9538360efbdSAlfred Perlstein 		timeo.tv_usec = 0;
9548360efbdSAlfred Perlstein 
95575e40e46SPeter Wemm 		success = clnt_call(cli, NLM4_TEST_RES,
95675e40e46SPeter Wemm 		    (xdrproc_t)xdr_nlm4_testres, &res,
95775e40e46SPeter Wemm 		    (xdrproc_t)xdr_void, &dummy, timeo);
9588360efbdSAlfred Perlstein 
9598360efbdSAlfred Perlstein 		if (debug_level > 2)
9608360efbdSAlfred Perlstein 			syslog(LOG_DEBUG, "clnt_call returns %d", success);
9618360efbdSAlfred Perlstein 	}
9628360efbdSAlfred Perlstein 	return (NULL);
9638360efbdSAlfred Perlstein }
9648360efbdSAlfred Perlstein 
9658360efbdSAlfred Perlstein /* nlm_lock ---------------------------------------------------------------- */
9668360efbdSAlfred Perlstein /*
9678360efbdSAlfred Perlstein  * Purposes:	Establish a lock
9688360efbdSAlfred Perlstein  * Returns:	granted, denied or blocked
9698360efbdSAlfred Perlstein  * Notes:	*** grace period support missing
9708360efbdSAlfred Perlstein  */
9718360efbdSAlfred Perlstein nlm4_res *
nlm4_lock_4_svc(nlm4_lockargs * arg,struct svc_req * rqstp)97229df5733SXin LI nlm4_lock_4_svc(nlm4_lockargs *arg, struct svc_req *rqstp)
9738360efbdSAlfred Perlstein {
9748360efbdSAlfred Perlstein 	static nlm4_res res;
9758360efbdSAlfred Perlstein 
9768360efbdSAlfred Perlstein 	if (debug_level)
9778360efbdSAlfred Perlstein 		log_from_addr("nlm4_lock", rqstp);
978bad584e3SAlfred Perlstein 	if (debug_level > 5) {
979bad584e3SAlfred Perlstein 		syslog(LOG_DEBUG, "Locking arguments:\n");
980bad584e3SAlfred Perlstein 		log_netobj(&(arg->cookie));
981bad584e3SAlfred Perlstein 		syslog(LOG_DEBUG, "Alock arguments:\n");
982bad584e3SAlfred Perlstein 		syslog(LOG_DEBUG, "Caller Name: %s\n",arg->alock.caller_name);
983bad584e3SAlfred Perlstein 		syslog(LOG_DEBUG, "File Handle:\n");
984bad584e3SAlfred Perlstein 		log_netobj(&(arg->alock.fh));
985bad584e3SAlfred Perlstein 		syslog(LOG_DEBUG, "Owner Handle:\n");
986bad584e3SAlfred Perlstein 		log_netobj(&(arg->alock.oh));
987bad584e3SAlfred Perlstein 		syslog(LOG_DEBUG, "SVID:        %d\n", arg->alock.svid);
9882663693cSAlfred Perlstein 		syslog(LOG_DEBUG, "Lock Offset: %llu\n",
9892663693cSAlfred Perlstein 		    (unsigned long long)arg->alock.l_offset);
9902663693cSAlfred Perlstein 		syslog(LOG_DEBUG, "Lock Length: %llu\n",
9912663693cSAlfred Perlstein 		    (unsigned long long)arg->alock.l_len);
992bad584e3SAlfred Perlstein 		syslog(LOG_DEBUG, "Block:       %s\n", (arg->block ? "true" : "false"));
993bad584e3SAlfred Perlstein 		syslog(LOG_DEBUG, "Exclusive:   %s\n", (arg->exclusive ? "true" : "false"));
994bad584e3SAlfred Perlstein 		syslog(LOG_DEBUG, "Reclaim:     %s\n", (arg->reclaim ? "true" : "false"));
995bad584e3SAlfred Perlstein 		syslog(LOG_DEBUG, "State num:   %d\n", arg->state);
996bad584e3SAlfred Perlstein 	}
9978360efbdSAlfred Perlstein 
9988360efbdSAlfred Perlstein 	/* copy cookie from arg to result.  See comment in nlm_test_4() */
9998360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
10008360efbdSAlfred Perlstein 
1001*3b887005SJohn Baldwin 	res.stat.stat = (enum nlm4_stats)getlock(arg, rqstp, LOCK_MON | LOCK_V4);
10028360efbdSAlfred Perlstein 	return (&res);
10038360efbdSAlfred Perlstein }
10048360efbdSAlfred Perlstein 
10058360efbdSAlfred Perlstein void *
nlm4_lock_msg_4_svc(nlm4_lockargs * arg,struct svc_req * rqstp)100629df5733SXin LI nlm4_lock_msg_4_svc(nlm4_lockargs *arg, struct svc_req *rqstp)
10078360efbdSAlfred Perlstein {
10088360efbdSAlfred Perlstein 	static nlm4_res res;
10098360efbdSAlfred Perlstein 
10108360efbdSAlfred Perlstein 	if (debug_level)
10118360efbdSAlfred Perlstein 		log_from_addr("nlm4_lock_msg", rqstp);
10128360efbdSAlfred Perlstein 
10138360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
1014*3b887005SJohn Baldwin 	res.stat.stat = (enum nlm4_stats)getlock(arg, rqstp, LOCK_MON | LOCK_ASYNC | LOCK_V4);
10152d914e96SJun Kuriyama 	transmit4_result(NLM4_LOCK_RES, &res, getrpcaddr(rqstp));
10168360efbdSAlfred Perlstein 
10178360efbdSAlfred Perlstein 	return (NULL);
10188360efbdSAlfred Perlstein }
10198360efbdSAlfred Perlstein 
10208360efbdSAlfred Perlstein /* nlm_cancel -------------------------------------------------------------- */
10218360efbdSAlfred Perlstein /*
10228360efbdSAlfred Perlstein  * Purpose:	Cancel a blocked lock request
10238360efbdSAlfred Perlstein  * Returns:	granted or denied
10248360efbdSAlfred Perlstein  * Notes:
10258360efbdSAlfred Perlstein  */
10268360efbdSAlfred Perlstein nlm4_res *
nlm4_cancel_4_svc(nlm4_cancargs * arg,struct svc_req * rqstp)102729df5733SXin LI nlm4_cancel_4_svc(nlm4_cancargs *arg, struct svc_req *rqstp)
10288360efbdSAlfred Perlstein {
10298360efbdSAlfred Perlstein 	static nlm4_res res;
10308360efbdSAlfred Perlstein 
10318360efbdSAlfred Perlstein 	if (debug_level)
10328360efbdSAlfred Perlstein 		log_from_addr("nlm4_cancel", rqstp);
10338360efbdSAlfred Perlstein 
10348360efbdSAlfred Perlstein 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
10358360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
10368360efbdSAlfred Perlstein 
10378360efbdSAlfred Perlstein 	/*
10388360efbdSAlfred Perlstein 	 * Since at present we never return 'nlm_blocked', there can never be
10398360efbdSAlfred Perlstein 	 * a lock to cancel, so this call always fails.
10408360efbdSAlfred Perlstein 	 */
1041*3b887005SJohn Baldwin 	res.stat.stat = (enum nlm4_stats)unlock(&arg->alock, LOCK_CANCEL);
10428360efbdSAlfred Perlstein 	return (&res);
10438360efbdSAlfred Perlstein }
10448360efbdSAlfred Perlstein 
10458360efbdSAlfred Perlstein void *
nlm4_cancel_msg_4_svc(nlm4_cancargs * arg,struct svc_req * rqstp)104629df5733SXin LI nlm4_cancel_msg_4_svc(nlm4_cancargs *arg, struct svc_req *rqstp)
10478360efbdSAlfred Perlstein {
10488360efbdSAlfred Perlstein 	static nlm4_res res;
10498360efbdSAlfred Perlstein 
10508360efbdSAlfred Perlstein 	if (debug_level)
10518360efbdSAlfred Perlstein 		log_from_addr("nlm4_cancel_msg", rqstp);
10528360efbdSAlfred Perlstein 
10538360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
10548360efbdSAlfred Perlstein 	/*
10558360efbdSAlfred Perlstein 	 * Since at present we never return 'nlm_blocked', there can never be
10568360efbdSAlfred Perlstein 	 * a lock to cancel, so this call always fails.
10578360efbdSAlfred Perlstein 	 */
1058*3b887005SJohn Baldwin 	res.stat.stat = (enum nlm4_stats)unlock(&arg->alock, LOCK_CANCEL | LOCK_V4);
10592d914e96SJun Kuriyama 	transmit4_result(NLM4_CANCEL_RES, &res, getrpcaddr(rqstp));
10608360efbdSAlfred Perlstein 	return (NULL);
10618360efbdSAlfred Perlstein }
10628360efbdSAlfred Perlstein 
10638360efbdSAlfred Perlstein /* nlm_unlock -------------------------------------------------------------- */
10648360efbdSAlfred Perlstein /*
10658360efbdSAlfred Perlstein  * Purpose:	Release an existing lock
10668360efbdSAlfred Perlstein  * Returns:	Always granted, unless during grace period
10678360efbdSAlfred Perlstein  * Notes:	"no such lock" error condition is ignored, as the
10688360efbdSAlfred Perlstein  *		protocol uses unreliable UDP datagrams, and may well
10698360efbdSAlfred Perlstein  *		re-try an unlock that has already succeeded.
10708360efbdSAlfred Perlstein  */
10718360efbdSAlfred Perlstein nlm4_res *
nlm4_unlock_4_svc(nlm4_unlockargs * arg,struct svc_req * rqstp)107229df5733SXin LI nlm4_unlock_4_svc(nlm4_unlockargs *arg, struct svc_req *rqstp)
10738360efbdSAlfred Perlstein {
10748360efbdSAlfred Perlstein 	static nlm4_res res;
10758360efbdSAlfred Perlstein 
10768360efbdSAlfred Perlstein 	if (debug_level)
10778360efbdSAlfred Perlstein 		log_from_addr("nlm4_unlock", rqstp);
10788360efbdSAlfred Perlstein 
1079*3b887005SJohn Baldwin 	res.stat.stat = (enum nlm4_stats)unlock(&arg->alock, LOCK_V4);
10808360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
10818360efbdSAlfred Perlstein 
10828360efbdSAlfred Perlstein 	return (&res);
10838360efbdSAlfred Perlstein }
10848360efbdSAlfred Perlstein 
10858360efbdSAlfred Perlstein void *
nlm4_unlock_msg_4_svc(nlm4_unlockargs * arg,struct svc_req * rqstp)108629df5733SXin LI nlm4_unlock_msg_4_svc(nlm4_unlockargs *arg, struct svc_req *rqstp)
10878360efbdSAlfred Perlstein {
10888360efbdSAlfred Perlstein 	static nlm4_res res;
10898360efbdSAlfred Perlstein 
10908360efbdSAlfred Perlstein 	if (debug_level)
10918360efbdSAlfred Perlstein 		log_from_addr("nlm4_unlock_msg", rqstp);
10928360efbdSAlfred Perlstein 
1093*3b887005SJohn Baldwin 	res.stat.stat = (enum nlm4_stats)unlock(&arg->alock, LOCK_V4);
10948360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
10958360efbdSAlfred Perlstein 
10962d914e96SJun Kuriyama 	transmit4_result(NLM4_UNLOCK_RES, &res, getrpcaddr(rqstp));
10978360efbdSAlfred Perlstein 	return (NULL);
10988360efbdSAlfred Perlstein }
10998360efbdSAlfred Perlstein 
11008360efbdSAlfred Perlstein /* ------------------------------------------------------------------------- */
11018360efbdSAlfred Perlstein /*
11028360efbdSAlfred Perlstein  * Client-side pseudo-RPCs for results.  Note that for the client there
11038360efbdSAlfred Perlstein  * are only nlm_xxx_msg() versions of each call, since the 'real RPC'
11048360efbdSAlfred Perlstein  * version returns the results in the RPC result, and so the client
11058360efbdSAlfred Perlstein  * does not normally receive incoming RPCs.
11068360efbdSAlfred Perlstein  *
11078360efbdSAlfred Perlstein  * The exception to this is nlm_granted(), which is genuinely an RPC
11088360efbdSAlfred Perlstein  * call from the server to the client - a 'call-back' in normal procedure
11098360efbdSAlfred Perlstein  * call terms.
11108360efbdSAlfred Perlstein  */
11118360efbdSAlfred Perlstein 
11128360efbdSAlfred Perlstein /* nlm_granted ------------------------------------------------------------- */
11138360efbdSAlfred Perlstein /*
11148360efbdSAlfred Perlstein  * Purpose:	Receive notification that formerly blocked lock now granted
11158360efbdSAlfred Perlstein  * Returns:	always success ('granted')
11168360efbdSAlfred Perlstein  * Notes:
11178360efbdSAlfred Perlstein  */
11188360efbdSAlfred Perlstein nlm4_res *
nlm4_granted_4_svc(nlm4_testargs * arg,struct svc_req * rqstp)111929df5733SXin LI nlm4_granted_4_svc(nlm4_testargs *arg, struct svc_req *rqstp)
11208360efbdSAlfred Perlstein {
11218360efbdSAlfred Perlstein 	static nlm4_res res;
11228360efbdSAlfred Perlstein 
11238360efbdSAlfred Perlstein 	if (debug_level)
11248360efbdSAlfred Perlstein 		log_from_addr("nlm4_granted", rqstp);
11258360efbdSAlfred Perlstein 
1126603c8667SAlfred Perlstein 	res.stat.stat = lock_answer(arg->alock.svid, &arg->cookie,
1127603c8667SAlfred Perlstein 		nlm4_granted, NULL, NLM_VERS4) == 0 ?
1128603c8667SAlfred Perlstein 		nlm4_granted : nlm4_denied;
1129603c8667SAlfred Perlstein 
11308360efbdSAlfred Perlstein 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
11318360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
11328360efbdSAlfred Perlstein 
11338360efbdSAlfred Perlstein 	return (&res);
11348360efbdSAlfred Perlstein }
11358360efbdSAlfred Perlstein 
11368360efbdSAlfred Perlstein void *
nlm4_granted_msg_4_svc(nlm4_testargs * arg,struct svc_req * rqstp)113729df5733SXin LI nlm4_granted_msg_4_svc(nlm4_testargs *arg, struct svc_req *rqstp)
11388360efbdSAlfred Perlstein {
11398360efbdSAlfred Perlstein 	static nlm4_res res;
11408360efbdSAlfred Perlstein 
11418360efbdSAlfred Perlstein 	if (debug_level)
11428360efbdSAlfred Perlstein 		log_from_addr("nlm4_granted_msg", rqstp);
11438360efbdSAlfred Perlstein 
11448360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
11451870b993SRobert Watson 	res.stat.stat = lock_answer(arg->alock.svid, &arg->cookie,
11461870b993SRobert Watson 		nlm4_granted, NULL, NLM_VERS4) == 0 ?
11471870b993SRobert Watson 		nlm4_granted : nlm4_denied;
11482d914e96SJun Kuriyama 	transmit4_result(NLM4_GRANTED_RES, &res, getrpcaddr(rqstp));
11498360efbdSAlfred Perlstein 	return (NULL);
11508360efbdSAlfred Perlstein }
11518360efbdSAlfred Perlstein 
11528360efbdSAlfred Perlstein /* nlm_test_res ------------------------------------------------------------ */
11538360efbdSAlfred Perlstein /*
11548360efbdSAlfred Perlstein  * Purpose:	Accept result from earlier nlm_test_msg() call
11558360efbdSAlfred Perlstein  * Returns:	Nothing
11568360efbdSAlfred Perlstein  */
11578360efbdSAlfred Perlstein void *
nlm4_test_res_4_svc(nlm4_testres * arg,struct svc_req * rqstp)115829df5733SXin LI nlm4_test_res_4_svc(nlm4_testres *arg, struct svc_req *rqstp)
11598360efbdSAlfred Perlstein {
11608360efbdSAlfred Perlstein 	if (debug_level)
11618360efbdSAlfred Perlstein 		log_from_addr("nlm4_test_res", rqstp);
1162603c8667SAlfred Perlstein 
1163603c8667SAlfred Perlstein 	(void)lock_answer(-1, &arg->cookie, arg->stat.stat,
1164603c8667SAlfred Perlstein 		(int *)&arg->stat.nlm4_testrply_u.holder.svid,
1165603c8667SAlfred Perlstein 		NLM_VERS4);
11668360efbdSAlfred Perlstein 	return (NULL);
11678360efbdSAlfred Perlstein }
11688360efbdSAlfred Perlstein 
11698360efbdSAlfred Perlstein /* nlm_lock_res ------------------------------------------------------------ */
11708360efbdSAlfred Perlstein /*
11718360efbdSAlfred Perlstein  * Purpose:	Accept result from earlier nlm_lock_msg() call
11728360efbdSAlfred Perlstein  * Returns:	Nothing
11738360efbdSAlfred Perlstein  */
11748360efbdSAlfred Perlstein void *
nlm4_lock_res_4_svc(nlm4_res * arg,struct svc_req * rqstp)117529df5733SXin LI nlm4_lock_res_4_svc(nlm4_res *arg, struct svc_req *rqstp)
11768360efbdSAlfred Perlstein {
11778360efbdSAlfred Perlstein 	if (debug_level)
11788360efbdSAlfred Perlstein 		log_from_addr("nlm4_lock_res", rqstp);
11798360efbdSAlfred Perlstein 
1180603c8667SAlfred Perlstein 	(void)lock_answer(-1, &arg->cookie, arg->stat.stat, NULL, NLM_VERS4);
1181603c8667SAlfred Perlstein 
11828360efbdSAlfred Perlstein 	return (NULL);
11838360efbdSAlfred Perlstein }
11848360efbdSAlfred Perlstein 
11858360efbdSAlfred Perlstein /* nlm_cancel_res ---------------------------------------------------------- */
11868360efbdSAlfred Perlstein /*
11878360efbdSAlfred Perlstein  * Purpose:	Accept result from earlier nlm_cancel_msg() call
11888360efbdSAlfred Perlstein  * Returns:	Nothing
11898360efbdSAlfred Perlstein  */
11908360efbdSAlfred Perlstein void *
nlm4_cancel_res_4_svc(nlm4_res * arg __unused,struct svc_req * rqstp)119129df5733SXin LI nlm4_cancel_res_4_svc(nlm4_res *arg __unused, struct svc_req *rqstp)
11928360efbdSAlfred Perlstein {
11938360efbdSAlfred Perlstein 	if (debug_level)
11948360efbdSAlfred Perlstein 		log_from_addr("nlm4_cancel_res", rqstp);
11958360efbdSAlfred Perlstein 	return (NULL);
11968360efbdSAlfred Perlstein }
11978360efbdSAlfred Perlstein 
11988360efbdSAlfred Perlstein /* nlm_unlock_res ---------------------------------------------------------- */
11998360efbdSAlfred Perlstein /*
12008360efbdSAlfred Perlstein  * Purpose:	Accept result from earlier nlm_unlock_msg() call
12018360efbdSAlfred Perlstein  * Returns:	Nothing
12028360efbdSAlfred Perlstein  */
12038360efbdSAlfred Perlstein void *
nlm4_unlock_res_4_svc(nlm4_res * arg __unused,struct svc_req * rqstp)120429df5733SXin LI nlm4_unlock_res_4_svc(nlm4_res *arg __unused, struct svc_req *rqstp)
12058360efbdSAlfred Perlstein {
12068360efbdSAlfred Perlstein 	if (debug_level)
12078360efbdSAlfred Perlstein 		log_from_addr("nlm4_unlock_res", rqstp);
12088360efbdSAlfred Perlstein 	return (NULL);
12098360efbdSAlfred Perlstein }
12108360efbdSAlfred Perlstein 
12118360efbdSAlfred Perlstein /* nlm_granted_res --------------------------------------------------------- */
12128360efbdSAlfred Perlstein /*
12138360efbdSAlfred Perlstein  * Purpose:	Accept result from earlier nlm_granted_msg() call
12148360efbdSAlfred Perlstein  * Returns:	Nothing
12158360efbdSAlfred Perlstein  */
12168360efbdSAlfred Perlstein void *
nlm4_granted_res_4_svc(nlm4_res * arg __unused,struct svc_req * rqstp)121729df5733SXin LI nlm4_granted_res_4_svc(nlm4_res *arg __unused, struct svc_req *rqstp)
12188360efbdSAlfred Perlstein {
12198360efbdSAlfred Perlstein 	if (debug_level)
12208360efbdSAlfred Perlstein 		log_from_addr("nlm4_granted_res", rqstp);
12218360efbdSAlfred Perlstein 	return (NULL);
12228360efbdSAlfred Perlstein }
12238360efbdSAlfred Perlstein 
12248360efbdSAlfred Perlstein /* ------------------------------------------------------------------------- */
12258360efbdSAlfred Perlstein /*
12268360efbdSAlfred Perlstein  * Calls for PCNFS locking (aka non-monitored locking, no involvement
12278360efbdSAlfred Perlstein  * of rpc.statd).
12288360efbdSAlfred Perlstein  *
12298360efbdSAlfred Perlstein  * These are all genuine RPCs - no nlm_xxx_msg() nonsense here.
12308360efbdSAlfred Perlstein  */
12318360efbdSAlfred Perlstein 
12328360efbdSAlfred Perlstein /* nlm_share --------------------------------------------------------------- */
12338360efbdSAlfred Perlstein /*
12348360efbdSAlfred Perlstein  * Purpose:	Establish a DOS-style lock
12358360efbdSAlfred Perlstein  * Returns:	success or failure
12368360efbdSAlfred Perlstein  * Notes:	Blocking locks are not supported - client is expected
12378360efbdSAlfred Perlstein  *		to retry if required.
12388360efbdSAlfred Perlstein  */
12398360efbdSAlfred Perlstein nlm4_shareres *
nlm4_share_4_svc(nlm4_shareargs * arg,struct svc_req * rqstp)124029df5733SXin LI nlm4_share_4_svc(nlm4_shareargs *arg, struct svc_req *rqstp)
12418360efbdSAlfred Perlstein {
12428360efbdSAlfred Perlstein 	static nlm4_shareres res;
12438360efbdSAlfred Perlstein 
12448360efbdSAlfred Perlstein 	if (debug_level)
12458360efbdSAlfred Perlstein 		log_from_addr("nlm4_share", rqstp);
12468360efbdSAlfred Perlstein 
12478360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
12488360efbdSAlfred Perlstein 	res.stat = nlm4_granted;
12498360efbdSAlfred Perlstein 	res.sequence = 1234356;	/* X/Open says this field is ignored? */
12508360efbdSAlfred Perlstein 	return (&res);
12518360efbdSAlfred Perlstein }
12528360efbdSAlfred Perlstein 
12538360efbdSAlfred Perlstein /* nlm4_unshare ------------------------------------------------------------ */
12548360efbdSAlfred Perlstein /*
12558360efbdSAlfred Perlstein  * Purpose:	Release a DOS-style lock
12568360efbdSAlfred Perlstein  * Returns:	nlm_granted, unless in grace period
12578360efbdSAlfred Perlstein  * Notes:
12588360efbdSAlfred Perlstein  */
12598360efbdSAlfred Perlstein nlm4_shareres *
nlm4_unshare_4_svc(nlm4_shareargs * arg,struct svc_req * rqstp)126029df5733SXin LI nlm4_unshare_4_svc(nlm4_shareargs *arg, struct svc_req *rqstp)
12618360efbdSAlfred Perlstein {
12628360efbdSAlfred Perlstein 	static nlm4_shareres res;
12638360efbdSAlfred Perlstein 
12648360efbdSAlfred Perlstein 	if (debug_level)
12658360efbdSAlfred Perlstein 		log_from_addr("nlm_unshare", rqstp);
12668360efbdSAlfred Perlstein 
12678360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
12688360efbdSAlfred Perlstein 	res.stat = nlm4_granted;
12698360efbdSAlfred Perlstein 	res.sequence = 1234356;	/* X/Open says this field is ignored? */
12708360efbdSAlfred Perlstein 	return (&res);
12718360efbdSAlfred Perlstein }
12728360efbdSAlfred Perlstein 
12738360efbdSAlfred Perlstein /* nlm4_nm_lock ------------------------------------------------------------ */
12748360efbdSAlfred Perlstein /*
12758360efbdSAlfred Perlstein  * Purpose:	non-monitored version of nlm4_lock()
12768360efbdSAlfred Perlstein  * Returns:	as for nlm4_lock()
12778360efbdSAlfred Perlstein  * Notes:	These locks are in the same style as the standard nlm4_lock,
12788360efbdSAlfred Perlstein  *		but the rpc.statd should not be called to establish a
12798360efbdSAlfred Perlstein  *		monitor for the client machine, since that machine is
12808360efbdSAlfred Perlstein  *		declared not to be running a rpc.statd, and so would not
12818360efbdSAlfred Perlstein  *		respond to the statd protocol.
12828360efbdSAlfred Perlstein  */
12838360efbdSAlfred Perlstein nlm4_res *
nlm4_nm_lock_4_svc(nlm4_lockargs * arg,struct svc_req * rqstp)128429df5733SXin LI nlm4_nm_lock_4_svc(nlm4_lockargs *arg, struct svc_req *rqstp)
12858360efbdSAlfred Perlstein {
12868360efbdSAlfred Perlstein 	static nlm4_res res;
12878360efbdSAlfred Perlstein 
12888360efbdSAlfred Perlstein 	if (debug_level)
12898360efbdSAlfred Perlstein 		log_from_addr("nlm4_nm_lock", rqstp);
12908360efbdSAlfred Perlstein 
12918360efbdSAlfred Perlstein 	/* copy cookie from arg to result.  See comment in nlm4_test_1() */
12928360efbdSAlfred Perlstein 	res.cookie = arg->cookie;
12938360efbdSAlfred Perlstein 	res.stat.stat = nlm4_granted;
12948360efbdSAlfred Perlstein 	return (&res);
12958360efbdSAlfred Perlstein }
12968360efbdSAlfred Perlstein 
12978360efbdSAlfred Perlstein /* nlm4_free_all ------------------------------------------------------------ */
12988360efbdSAlfred Perlstein /*
12998360efbdSAlfred Perlstein  * Purpose:	Release all locks held by a named client
13008360efbdSAlfred Perlstein  * Returns:	Nothing
13018360efbdSAlfred Perlstein  * Notes:	Potential denial of service security problem here - the
13028360efbdSAlfred Perlstein  *		locks to be released are specified by a host name, independent
13038360efbdSAlfred Perlstein  *		of the address from which the request has arrived.
13048360efbdSAlfred Perlstein  *		Should probably be rejected if the named host has been
13058360efbdSAlfred Perlstein  *		using monitored locks.
13068360efbdSAlfred Perlstein  */
13078360efbdSAlfred Perlstein void *
nlm4_free_all_4_svc(struct nlm4_notify * arg __unused,struct svc_req * rqstp)130829df5733SXin LI nlm4_free_all_4_svc(struct nlm4_notify *arg __unused, struct svc_req *rqstp)
13098360efbdSAlfred Perlstein {
13108360efbdSAlfred Perlstein 	static char dummy;
13118360efbdSAlfred Perlstein 
13128360efbdSAlfred Perlstein 	if (debug_level)
13138360efbdSAlfred Perlstein 		log_from_addr("nlm4_free_all", rqstp);
13148360efbdSAlfred Perlstein 	return (&dummy);
13158360efbdSAlfred Perlstein }
13168360efbdSAlfred Perlstein 
13178360efbdSAlfred Perlstein /* nlm_sm_notify --------------------------------------------------------- */
13188360efbdSAlfred Perlstein /*
13198360efbdSAlfred Perlstein  * Purpose:	called by rpc.statd when a monitored host state changes.
13208360efbdSAlfred Perlstein  * Returns:	Nothing
13218360efbdSAlfred Perlstein  */
13228360efbdSAlfred Perlstein void *
nlm_sm_notify_0_svc(struct nlm_sm_status * arg,struct svc_req * rqstp __unused)132329df5733SXin LI nlm_sm_notify_0_svc(struct nlm_sm_status *arg, struct svc_req *rqstp __unused)
13248360efbdSAlfred Perlstein {
13258360efbdSAlfred Perlstein 	static char dummy;
13268360efbdSAlfred Perlstein 	notify(arg->mon_name, arg->state);
13278360efbdSAlfred Perlstein 	return (&dummy);
13288360efbdSAlfred Perlstein }
1329