1/*	$NetBSD: lock_proc.c,v 1.7 2000/10/11 20:23:56 is Exp $	*/
2/*-
3 * SPDX-License-Identifier: BSD-4-Clause
4 *
5 * Copyright (c) 1995
6 *	A.R. Gordon (andrew.gordon@net-tel.co.uk).  All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *	This product includes software developed for the FreeBSD project
19 * 4. Neither the name of the author nor the names of any co-contributors
20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY ANDREW GORDON AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 */
36
37#include <sys/cdefs.h>
38#ifndef lint
39__RCSID("$NetBSD: lock_proc.c,v 1.7 2000/10/11 20:23:56 is Exp $");
40#endif
41
42#include <sys/param.h>
43#include <sys/socket.h>
44
45#include <netinet/in.h>
46#include <arpa/inet.h>
47
48#include <netdb.h>
49#include <stdio.h>
50#include <string.h>
51#include <syslog.h>
52#include <unistd.h>
53#include <netconfig.h>
54
55#include <rpc/rpc.h>
56#include <rpcsvc/sm_inter.h>
57
58#include "lockd.h"
59#include <rpcsvc/nlm_prot.h>
60#include "lockd_lock.h"
61
62
63#define	CLIENT_CACHE_SIZE	64	/* No. of client sockets cached */
64#define	CLIENT_CACHE_LIFETIME	120	/* In seconds */
65
66#define	getrpcaddr(rqstp)	(struct sockaddr *)(svc_getrpccaller((rqstp)->rq_xprt)->buf)
67
68static void	log_from_addr(const char *, struct svc_req *);
69static void	log_netobj(netobj *obj);
70static int	addrcmp(struct sockaddr *, struct sockaddr *);
71
72/* log_from_addr ----------------------------------------------------------- */
73/*
74 * Purpose:	Log name of function called and source address
75 * Returns:	Nothing
76 * Notes:	Extracts the source address from the transport handle
77 *		passed in as part of the called procedure specification
78 */
79static void
80log_from_addr(const char *fun_name, struct svc_req *req)
81{
82	struct sockaddr *addr;
83	char hostname_buf[NI_MAXHOST];
84
85	addr = svc_getrpccaller(req->rq_xprt)->buf;
86	if (getnameinfo(addr , addr->sa_len, hostname_buf, sizeof hostname_buf,
87	    NULL, 0, 0) != 0)
88		return;
89
90	syslog(LOG_DEBUG, "%s from %s", fun_name, hostname_buf);
91}
92
93/* log_netobj ----------------------------------------------------------- */
94/*
95 * Purpose:	Log a netobj
96 * Returns:	Nothing
97 * Notes:	This function should only really be called as part of
98 *  		a debug subsystem.
99*/
100static void
101log_netobj(netobj *obj)
102{
103	char objvalbuffer[(sizeof(char)*2)*MAX_NETOBJ_SZ+2];
104	char objascbuffer[sizeof(char)*MAX_NETOBJ_SZ+1];
105	unsigned int i, maxlen;
106	char *tmp1, *tmp2;
107
108	/* Notify of potential security attacks */
109	if (obj->n_len > MAX_NETOBJ_SZ)	{
110		syslog(LOG_DEBUG, "SOMEONE IS TRYING TO DO SOMETHING NASTY!\n");
111		syslog(LOG_DEBUG, "netobj too large! Should be %d was %d\n",
112		    MAX_NETOBJ_SZ, obj->n_len);
113	}
114	/* Prevent the security hazard from the buffer overflow */
115	maxlen = (obj->n_len < MAX_NETOBJ_SZ ? obj->n_len : MAX_NETOBJ_SZ);
116	for (i=0, tmp1 = objvalbuffer, tmp2 = objascbuffer; i < maxlen;
117	    i++, tmp1 +=2, tmp2 +=1) {
118		sprintf(tmp1,"%02X",*(obj->n_bytes+i));
119		sprintf(tmp2,"%c",*(obj->n_bytes+i));
120	}
121	*tmp1 = '\0';
122	*tmp2 = '\0';
123	syslog(LOG_DEBUG,"netobjvals: %s\n",objvalbuffer);
124	syslog(LOG_DEBUG,"netobjascs: %s\n",objascbuffer);
125}
126/* get_client -------------------------------------------------------------- */
127/*
128 * Purpose:	Get a CLIENT* for making RPC calls to lockd on given host
129 * Returns:	CLIENT* pointer, from clnt_udp_create, or NULL if error
130 * Notes:	Creating a CLIENT* is quite expensive, involving a
131 *		conversation with the remote portmapper to get the
132 *		port number.  Since a given client is quite likely
133 *		to make several locking requests in succession, it is
134 *		desirable to cache the created CLIENT*.
135 *
136 *		Since we are using UDP rather than TCP, there is no cost
137 *		to the remote system in keeping these cached indefinitely.
138 *		Unfortunately there is a snag: if the remote system
139 *		reboots, the cached portmapper results will be invalid,
140 *		and we will never detect this since all of the xxx_msg()
141 *		calls return no result - we just fire off a udp packet
142 *		and hope for the best.
143 *
144 *		We solve this by discarding cached values after two
145 *		minutes, regardless of whether they have been used
146 *		in the meanwhile (since a bad one might have been used
147 *		plenty of times, as the host keeps retrying the request
148 *		and we keep sending the reply back to the wrong port).
149 *
150 *		Given that the entries will always expire in the order
151 *		that they were created, there is no point in a LRU
152 *		algorithm for when the cache gets full - entries are
153 *		always re-used in sequence.
154 */
155static CLIENT *clnt_cache_ptr[CLIENT_CACHE_SIZE];
156static long clnt_cache_time[CLIENT_CACHE_SIZE];	/* time entry created */
157static struct sockaddr_storage clnt_cache_addr[CLIENT_CACHE_SIZE];
158static rpcvers_t clnt_cache_vers[CLIENT_CACHE_SIZE];
159static int clnt_cache_next_to_use = 0;
160
161static int
162addrcmp(struct sockaddr *sa1, struct sockaddr *sa2)
163{
164	int len;
165	void *p1, *p2;
166
167	if (sa1->sa_family != sa2->sa_family)
168		return -1;
169
170	switch (sa1->sa_family) {
171	case AF_INET:
172		p1 = &((struct sockaddr_in *)sa1)->sin_addr;
173		p2 = &((struct sockaddr_in *)sa2)->sin_addr;
174		len = 4;
175		break;
176	case AF_INET6:
177		p1 = &((struct sockaddr_in6 *)sa1)->sin6_addr;
178		p2 = &((struct sockaddr_in6 *)sa2)->sin6_addr;
179		len = 16;
180		break;
181	default:
182		return -1;
183	}
184
185	return memcmp(p1, p2, len);
186}
187
188CLIENT *
189get_client(struct sockaddr *host_addr, rpcvers_t vers)
190{
191	CLIENT *client;
192	struct timeval retry_time, time_now;
193	int error, i;
194	const char *netid;
195	struct netconfig *nconf;
196	char host[NI_MAXHOST];
197	uid_t old_euid;
198	int clnt_fd;
199
200	gettimeofday(&time_now, NULL);
201
202	/*
203	 * Search for the given client in the cache, zapping any expired
204	 * entries that we happen to notice in passing.
205	 */
206	for (i = 0; i < CLIENT_CACHE_SIZE; i++) {
207		client = clnt_cache_ptr[i];
208		if (client && ((clnt_cache_time[i] + CLIENT_CACHE_LIFETIME)
209		    < time_now.tv_sec)) {
210			/* Cache entry has expired. */
211			if (debug_level > 3)
212				syslog(LOG_DEBUG, "Expired CLIENT* in cache");
213			clnt_cache_time[i] = 0L;
214			clnt_destroy(client);
215			clnt_cache_ptr[i] = NULL;
216			client = NULL;
217		}
218		if (client && !addrcmp((struct sockaddr *)&clnt_cache_addr[i],
219		    host_addr) && clnt_cache_vers[i] == vers) {
220			/* Found it! */
221			if (debug_level > 3)
222				syslog(LOG_DEBUG, "Found CLIENT* in cache");
223			return (client);
224		}
225	}
226
227	if (debug_level > 3)
228		syslog(LOG_DEBUG, "CLIENT* not found in cache, creating");
229
230	/* Not found in cache.  Free the next entry if it is in use. */
231	if (clnt_cache_ptr[clnt_cache_next_to_use]) {
232		clnt_destroy(clnt_cache_ptr[clnt_cache_next_to_use]);
233		clnt_cache_ptr[clnt_cache_next_to_use] = NULL;
234	}
235
236	/*
237	 * Need a host string for clnt_tp_create. Use NI_NUMERICHOST
238	 * to avoid DNS lookups.
239	 */
240	error = getnameinfo(host_addr, host_addr->sa_len, host, sizeof host,
241			    NULL, 0, NI_NUMERICHOST);
242	if (error != 0) {
243		syslog(LOG_ERR, "unable to get name string for caller: %s",
244		       gai_strerror(error));
245		return NULL;
246	}
247
248#if 1
249	if (host_addr->sa_family == AF_INET6)
250		netid = "udp6";
251	else
252		netid = "udp";
253#else
254	if (host_addr->sa_family == AF_INET6)
255		netid = "tcp6";
256	else
257		netid = "tcp";
258#endif
259	nconf = getnetconfigent(netid);
260	if (nconf == NULL) {
261		syslog(LOG_ERR, "could not get netconfig info for '%s': "
262				"no /etc/netconfig file?", netid);
263		return NULL;
264	}
265
266	client = clnt_tp_create(host, NLM_PROG, vers, nconf);
267	freenetconfigent(nconf);
268
269	if (!client) {
270		syslog(LOG_ERR, "%s", clnt_spcreateerror("clntudp_create"));
271		syslog(LOG_ERR, "Unable to return result to %s", host);
272		return NULL;
273	}
274
275	/* Get the FD of the client, for bindresvport. */
276	clnt_control(client, CLGET_FD, &clnt_fd);
277
278	/* Regain root privileges, for bindresvport. */
279	old_euid = geteuid();
280	if (seteuid(0) != 0) {
281		syslog(LOG_ERR, "seteuid(0) failed");
282		return NULL;
283	}
284
285	/*
286	 * Bind the client FD to a reserved port.
287	 * Some NFS servers reject any NLM request from a non-reserved port.
288	 */
289	bindresvport(clnt_fd, NULL);
290
291	/* Drop root privileges again. */
292	if (seteuid(old_euid) != 0) {
293		syslog(LOG_ERR, "seteuid(%d) failed", old_euid);
294		return NULL;
295	}
296
297	/* Success - update the cache entry */
298	clnt_cache_ptr[clnt_cache_next_to_use] = client;
299	memcpy(&clnt_cache_addr[clnt_cache_next_to_use], host_addr,
300	    host_addr->sa_len);
301	clnt_cache_vers[clnt_cache_next_to_use] = vers;
302	clnt_cache_time[clnt_cache_next_to_use] = time_now.tv_sec;
303	if (++clnt_cache_next_to_use >= CLIENT_CACHE_SIZE)
304		clnt_cache_next_to_use = 0;
305
306	/*
307	 * Disable the default timeout, so we can specify our own in calls
308	 * to clnt_call().  (Note that the timeout is a different concept
309	 * from the retry period set in clnt_udp_create() above.)
310	 */
311	retry_time.tv_sec = -1;
312	retry_time.tv_usec = -1;
313	clnt_control(client, CLSET_TIMEOUT, (char *)&retry_time);
314
315	if (debug_level > 3)
316		syslog(LOG_DEBUG, "Created CLIENT* for %s", host);
317	return client;
318}
319
320
321/* transmit_result --------------------------------------------------------- */
322/*
323 * Purpose:	Transmit result for nlm_xxx_msg pseudo-RPCs
324 * Returns:	Nothing - we have no idea if the datagram got there
325 * Notes:	clnt_call() will always fail (with timeout) as we are
326 *		calling it with timeout 0 as a hack to just issue a datagram
327 *		without expecting a result
328 */
329void
330transmit_result(int opcode, nlm_res *result, struct sockaddr *addr)
331{
332	static char dummy;
333	CLIENT *cli;
334	struct timeval timeo;
335	int success;
336
337	if ((cli = get_client(addr, NLM_VERS)) != NULL) {
338		timeo.tv_sec = 0; /* No timeout - not expecting response */
339		timeo.tv_usec = 0;
340
341		success = clnt_call(cli, opcode, (xdrproc_t)xdr_nlm_res, result,
342		    (xdrproc_t)xdr_void, &dummy, timeo);
343
344		if (debug_level > 2)
345			syslog(LOG_DEBUG, "clnt_call returns %d(%s)",
346			    success, clnt_sperrno(success));
347	}
348}
349/* transmit4_result --------------------------------------------------------- */
350/*
351 * Purpose:	Transmit result for nlm4_xxx_msg pseudo-RPCs
352 * Returns:	Nothing - we have no idea if the datagram got there
353 * Notes:	clnt_call() will always fail (with timeout) as we are
354 *		calling it with timeout 0 as a hack to just issue a datagram
355 *		without expecting a result
356 */
357void
358transmit4_result(int opcode, nlm4_res *result, struct sockaddr *addr)
359{
360	static char dummy;
361	CLIENT *cli;
362	struct timeval timeo;
363	int success;
364
365	if ((cli = get_client(addr, NLM_VERS4)) != NULL) {
366		timeo.tv_sec = 0; /* No timeout - not expecting response */
367		timeo.tv_usec = 0;
368
369		success = clnt_call(cli, opcode,
370		    (xdrproc_t)xdr_nlm4_res, result,
371		    (xdrproc_t)xdr_void, &dummy, timeo);
372
373		if (debug_level > 2)
374			syslog(LOG_DEBUG, "clnt_call returns %d(%s)",
375			    success, clnt_sperrno(success));
376	}
377}
378
379/*
380 * converts a struct nlm_lock to struct nlm4_lock
381 */
382static void
383nlmtonlm4(struct nlm_lock *arg, struct nlm4_lock *arg4)
384{
385	arg4->caller_name = arg->caller_name;
386	arg4->fh = arg->fh;
387	arg4->oh = arg->oh;
388	arg4->svid = arg->svid;
389	arg4->l_offset = arg->l_offset;
390	arg4->l_len = arg->l_len;
391}
392/* ------------------------------------------------------------------------- */
393/*
394 * Functions for Unix<->Unix locking (ie. monitored locking, with rpc.statd
395 * involved to ensure reclaim of locks after a crash of the "stateless"
396 * server.
397 *
398 * These all come in two flavours - nlm_xxx() and nlm_xxx_msg().
399 * The first are standard RPCs with argument and result.
400 * The nlm_xxx_msg() calls implement exactly the same functions, but
401 * use two pseudo-RPCs (one in each direction).  These calls are NOT
402 * standard use of the RPC protocol in that they do not return a result
403 * at all (NB. this is quite different from returning a void result).
404 * The effect of this is to make the nlm_xxx_msg() calls simple unacknowledged
405 * datagrams, requiring higher-level code to perform retries.
406 *
407 * Despite the disadvantages of the nlm_xxx_msg() approach (some of which
408 * are documented in the comments to get_client() above), this is the
409 * interface used by all current commercial NFS implementations
410 * [Solaris, SCO, AIX etc.].  This is presumed to be because these allow
411 * implementations to continue using the standard RPC libraries, while
412 * avoiding the block-until-result nature of the library interface.
413 *
414 * No client implementations have been identified so far that make use
415 * of the true RPC version (early SunOS releases would be a likely candidate
416 * for testing).
417 */
418
419/* nlm_test ---------------------------------------------------------------- */
420/*
421 * Purpose:	Test whether a specified lock would be granted if requested
422 * Returns:	nlm_granted (or error code)
423 * Notes:
424 */
425nlm_testres *
426nlm_test_1_svc(nlm_testargs *arg, struct svc_req *rqstp)
427{
428	static nlm_testres res;
429	struct nlm4_lock arg4;
430	struct nlm4_holder *holder;
431	nlmtonlm4(&arg->alock, &arg4);
432
433	if (debug_level)
434		log_from_addr("nlm_test", rqstp);
435
436	holder = testlock(&arg4, arg->exclusive, 0);
437	/*
438	 * Copy the cookie from the argument into the result.  Note that this
439	 * is slightly hazardous, as the structure contains a pointer to a
440	 * malloc()ed buffer that will get freed by the caller.  However, the
441	 * main function transmits the result before freeing the argument
442	 * so it is in fact safe.
443	 */
444	res.cookie = arg->cookie;
445	if (holder == NULL) {
446		res.stat.stat = nlm_granted;
447	} else {
448		res.stat.stat = nlm_denied;
449		memcpy(&res.stat.nlm_testrply_u.holder, holder,
450		    sizeof(struct nlm_holder));
451		res.stat.nlm_testrply_u.holder.l_offset = holder->l_offset;
452		res.stat.nlm_testrply_u.holder.l_len = holder->l_len;
453	}
454	return (&res);
455}
456
457void *
458nlm_test_msg_1_svc(nlm_testargs *arg, struct svc_req *rqstp)
459{
460	nlm_testres res;
461	static char dummy;
462	struct sockaddr *addr;
463	CLIENT *cli;
464	int success;
465	struct timeval timeo;
466	struct nlm4_lock arg4;
467	struct nlm4_holder *holder;
468
469	nlmtonlm4(&arg->alock, &arg4);
470
471	if (debug_level)
472		log_from_addr("nlm_test_msg", rqstp);
473
474	holder = testlock(&arg4, arg->exclusive, 0);
475
476	res.cookie = arg->cookie;
477	if (holder == NULL) {
478		res.stat.stat = nlm_granted;
479	} else {
480		res.stat.stat = nlm_denied;
481		memcpy(&res.stat.nlm_testrply_u.holder, holder,
482		    sizeof(struct nlm_holder));
483		res.stat.nlm_testrply_u.holder.l_offset = holder->l_offset;
484		res.stat.nlm_testrply_u.holder.l_len = holder->l_len;
485	}
486
487	/*
488	 * nlm_test has different result type to the other operations, so
489	 * can't use transmit_result() in this case
490	 */
491	addr = svc_getrpccaller(rqstp->rq_xprt)->buf;
492	if ((cli = get_client(addr, NLM_VERS)) != NULL) {
493		timeo.tv_sec = 0; /* No timeout - not expecting response */
494		timeo.tv_usec = 0;
495
496		success = clnt_call(cli, NLM_TEST_RES,
497		    (xdrproc_t)xdr_nlm_testres, &res,
498		    (xdrproc_t)xdr_void, &dummy, timeo);
499
500		if (debug_level > 2)
501			syslog(LOG_DEBUG, "clnt_call returns %d", success);
502	}
503	return (NULL);
504}
505
506/* nlm_lock ---------------------------------------------------------------- */
507/*
508 * Purposes:	Establish a lock
509 * Returns:	granted, denied or blocked
510 * Notes:	*** grace period support missing
511 */
512nlm_res *
513nlm_lock_1_svc(nlm_lockargs *arg, struct svc_req *rqstp)
514{
515	static nlm_res res;
516	struct nlm4_lockargs arg4;
517	nlmtonlm4(&arg->alock, &arg4.alock);
518	arg4.cookie = arg->cookie;
519	arg4.block = arg->block;
520	arg4.exclusive = arg->exclusive;
521	arg4.reclaim = arg->reclaim;
522	arg4.state = arg->state;
523
524	if (debug_level)
525		log_from_addr("nlm_lock", rqstp);
526
527	/* copy cookie from arg to result.  See comment in nlm_test_1() */
528	res.cookie = arg->cookie;
529
530	res.stat.stat = getlock(&arg4, rqstp, LOCK_MON);
531	return (&res);
532}
533
534void *
535nlm_lock_msg_1_svc(nlm_lockargs *arg, struct svc_req *rqstp)
536{
537	static nlm_res res;
538	struct nlm4_lockargs arg4;
539
540	nlmtonlm4(&arg->alock, &arg4.alock);
541	arg4.cookie = arg->cookie;
542	arg4.block = arg->block;
543	arg4.exclusive = arg->exclusive;
544	arg4.reclaim = arg->reclaim;
545	arg4.state = arg->state;
546
547	if (debug_level)
548		log_from_addr("nlm_lock_msg", rqstp);
549
550	res.cookie = arg->cookie;
551	res.stat.stat = getlock(&arg4, rqstp, LOCK_ASYNC | LOCK_MON);
552	transmit_result(NLM_LOCK_RES, &res, getrpcaddr(rqstp));
553
554	return (NULL);
555}
556
557/* nlm_cancel -------------------------------------------------------------- */
558/*
559 * Purpose:	Cancel a blocked lock request
560 * Returns:	granted or denied
561 * Notes:
562 */
563nlm_res *
564nlm_cancel_1_svc(nlm_cancargs *arg, struct svc_req *rqstp)
565{
566	static nlm_res res;
567	struct nlm4_lock arg4;
568
569	nlmtonlm4(&arg->alock, &arg4);
570
571	if (debug_level)
572		log_from_addr("nlm_cancel", rqstp);
573
574	/* copy cookie from arg to result.  See comment in nlm_test_1() */
575	res.cookie = arg->cookie;
576
577	/*
578	 * Since at present we never return 'nlm_blocked', there can never be
579	 * a lock to cancel, so this call always fails.
580	 */
581	res.stat.stat = unlock(&arg4, LOCK_CANCEL);
582	return (&res);
583}
584
585void *
586nlm_cancel_msg_1_svc(nlm_cancargs *arg, struct svc_req *rqstp)
587{
588	static nlm_res res;
589	struct nlm4_lock arg4;
590
591	nlmtonlm4(&arg->alock, &arg4);
592
593	if (debug_level)
594		log_from_addr("nlm_cancel_msg", rqstp);
595
596	res.cookie = arg->cookie;
597	/*
598	 * Since at present we never return 'nlm_blocked', there can never be
599	 * a lock to cancel, so this call always fails.
600	 */
601	res.stat.stat = unlock(&arg4, LOCK_CANCEL);
602	transmit_result(NLM_CANCEL_RES, &res, getrpcaddr(rqstp));
603	return (NULL);
604}
605
606/* nlm_unlock -------------------------------------------------------------- */
607/*
608 * Purpose:	Release an existing lock
609 * Returns:	Always granted, unless during grace period
610 * Notes:	"no such lock" error condition is ignored, as the
611 *		protocol uses unreliable UDP datagrams, and may well
612 *		re-try an unlock that has already succeeded.
613 */
614nlm_res *
615nlm_unlock_1_svc(nlm_unlockargs *arg, struct svc_req *rqstp)
616{
617	static nlm_res res;
618	struct nlm4_lock arg4;
619
620	nlmtonlm4(&arg->alock, &arg4);
621
622	if (debug_level)
623		log_from_addr("nlm_unlock", rqstp);
624
625	res.stat.stat = unlock(&arg4, 0);
626	res.cookie = arg->cookie;
627
628	return (&res);
629}
630
631void *
632nlm_unlock_msg_1_svc(nlm_unlockargs *arg, struct svc_req *rqstp)
633{
634	static nlm_res res;
635	struct nlm4_lock arg4;
636
637	nlmtonlm4(&arg->alock, &arg4);
638
639	if (debug_level)
640		log_from_addr("nlm_unlock_msg", rqstp);
641
642	res.stat.stat = unlock(&arg4, 0);
643	res.cookie = arg->cookie;
644
645	transmit_result(NLM_UNLOCK_RES, &res, getrpcaddr(rqstp));
646	return (NULL);
647}
648
649/* ------------------------------------------------------------------------- */
650/*
651 * Client-side pseudo-RPCs for results.  Note that for the client there
652 * are only nlm_xxx_msg() versions of each call, since the 'real RPC'
653 * version returns the results in the RPC result, and so the client
654 * does not normally receive incoming RPCs.
655 *
656 * The exception to this is nlm_granted(), which is genuinely an RPC
657 * call from the server to the client - a 'call-back' in normal procedure
658 * call terms.
659 */
660
661/* nlm_granted ------------------------------------------------------------- */
662/*
663 * Purpose:	Receive notification that formerly blocked lock now granted
664 * Returns:	always success ('granted')
665 * Notes:
666 */
667nlm_res *
668nlm_granted_1_svc(nlm_testargs *arg, struct svc_req *rqstp)
669{
670	static nlm_res res;
671
672	if (debug_level)
673		log_from_addr("nlm_granted", rqstp);
674
675	res.stat.stat = lock_answer(arg->alock.svid, &arg->cookie,
676		nlm_granted, NULL, NLM_VERS) == 0 ?
677		nlm_granted : nlm_denied;
678
679	/* copy cookie from arg to result.  See comment in nlm_test_1() */
680	res.cookie = arg->cookie;
681
682	return (&res);
683}
684
685void *
686nlm_granted_msg_1_svc(nlm_testargs *arg, struct svc_req *rqstp)
687{
688	static nlm_res res;
689
690	if (debug_level)
691		log_from_addr("nlm_granted_msg", rqstp);
692
693	res.cookie = arg->cookie;
694	res.stat.stat = lock_answer(arg->alock.svid, &arg->cookie,
695		nlm_granted, NULL, NLM_VERS) == 0 ?
696		nlm_granted : nlm_denied;
697
698	transmit_result(NLM_GRANTED_RES, &res, getrpcaddr(rqstp));
699	return (NULL);
700}
701
702/* nlm_test_res ------------------------------------------------------------ */
703/*
704 * Purpose:	Accept result from earlier nlm_test_msg() call
705 * Returns:	Nothing
706 */
707void *
708nlm_test_res_1_svc(nlm_testres *arg, struct svc_req *rqstp)
709{
710	if (debug_level)
711		log_from_addr("nlm_test_res", rqstp);
712	(void)lock_answer(-1, &arg->cookie, arg->stat.stat,
713		&arg->stat.nlm_testrply_u.holder.svid, NLM_VERS);
714	return (NULL);
715}
716
717/* nlm_lock_res ------------------------------------------------------------ */
718/*
719 * Purpose:	Accept result from earlier nlm_lock_msg() call
720 * Returns:	Nothing
721 */
722void *
723nlm_lock_res_1_svc(nlm_res *arg, struct svc_req *rqstp)
724{
725	if (debug_level)
726		log_from_addr("nlm_lock_res", rqstp);
727
728	(void)lock_answer(-1, &arg->cookie, arg->stat.stat, NULL, NLM_VERS);
729
730	return (NULL);
731}
732
733/* nlm_cancel_res ---------------------------------------------------------- */
734/*
735 * Purpose:	Accept result from earlier nlm_cancel_msg() call
736 * Returns:	Nothing
737 */
738void *
739nlm_cancel_res_1_svc(nlm_res *arg __unused, struct svc_req *rqstp)
740{
741	if (debug_level)
742		log_from_addr("nlm_cancel_res", rqstp);
743	return (NULL);
744}
745
746/* nlm_unlock_res ---------------------------------------------------------- */
747/*
748 * Purpose:	Accept result from earlier nlm_unlock_msg() call
749 * Returns:	Nothing
750 */
751void *
752nlm_unlock_res_1_svc(nlm_res *arg, struct svc_req *rqstp)
753{
754	if (debug_level)
755		log_from_addr("nlm_unlock_res", rqstp);
756
757	lock_answer(-1, &arg->cookie, arg->stat.stat, NULL, NLM_VERS);
758
759	return (NULL);
760}
761
762/* nlm_granted_res --------------------------------------------------------- */
763/*
764 * Purpose:	Accept result from earlier nlm_granted_msg() call
765 * Returns:	Nothing
766 */
767void *
768nlm_granted_res_1_svc(nlm_res *arg __unused, struct svc_req *rqstp)
769{
770	if (debug_level)
771		log_from_addr("nlm_granted_res", rqstp);
772	return (NULL);
773}
774
775/* ------------------------------------------------------------------------- */
776/*
777 * Calls for PCNFS locking (aka non-monitored locking, no involvement
778 * of rpc.statd).
779 *
780 * These are all genuine RPCs - no nlm_xxx_msg() nonsense here.
781 */
782
783/* nlm_share --------------------------------------------------------------- */
784/*
785 * Purpose:	Establish a DOS-style lock
786 * Returns:	success or failure
787 * Notes:	Blocking locks are not supported - client is expected
788 *		to retry if required.
789 */
790nlm_shareres *
791nlm_share_3_svc(nlm_shareargs *arg, struct svc_req *rqstp)
792{
793	static nlm_shareres res;
794
795	if (debug_level)
796		log_from_addr("nlm_share", rqstp);
797
798	res.cookie = arg->cookie;
799	res.stat = nlm_granted;
800	res.sequence = 1234356;	/* X/Open says this field is ignored? */
801	return (&res);
802}
803
804/* nlm_unshare ------------------------------------------------------------ */
805/*
806 * Purpose:	Release a DOS-style lock
807 * Returns:	nlm_granted, unless in grace period
808 * Notes:
809 */
810nlm_shareres *
811nlm_unshare_3_svc(nlm_shareargs *arg, struct svc_req *rqstp)
812{
813	static nlm_shareres res;
814
815	if (debug_level)
816		log_from_addr("nlm_unshare", rqstp);
817
818	res.cookie = arg->cookie;
819	res.stat = nlm_granted;
820	res.sequence = 1234356;	/* X/Open says this field is ignored? */
821	return (&res);
822}
823
824/* nlm_nm_lock ------------------------------------------------------------ */
825/*
826 * Purpose:	non-monitored version of nlm_lock()
827 * Returns:	as for nlm_lock()
828 * Notes:	These locks are in the same style as the standard nlm_lock,
829 *		but the rpc.statd should not be called to establish a
830 *		monitor for the client machine, since that machine is
831 *		declared not to be running a rpc.statd, and so would not
832 *		respond to the statd protocol.
833 */
834nlm_res *
835nlm_nm_lock_3_svc(nlm_lockargs *arg, struct svc_req *rqstp)
836{
837	static nlm_res res;
838
839	if (debug_level)
840		log_from_addr("nlm_nm_lock", rqstp);
841
842	/* copy cookie from arg to result.  See comment in nlm_test_1() */
843	res.cookie = arg->cookie;
844	res.stat.stat = nlm_granted;
845	return (&res);
846}
847
848/* nlm_free_all ------------------------------------------------------------ */
849/*
850 * Purpose:	Release all locks held by a named client
851 * Returns:	Nothing
852 * Notes:	Potential denial of service security problem here - the
853 *		locks to be released are specified by a host name, independent
854 *		of the address from which the request has arrived.
855 *		Should probably be rejected if the named host has been
856 *		using monitored locks.
857 */
858void *
859nlm_free_all_3_svc(nlm_notify *arg __unused, struct svc_req *rqstp)
860{
861	static char dummy;
862
863	if (debug_level)
864		log_from_addr("nlm_free_all", rqstp);
865	return (&dummy);
866}
867
868/* calls for nlm version 4 (NFSv3) */
869/* nlm_test ---------------------------------------------------------------- */
870/*
871 * Purpose:	Test whether a specified lock would be granted if requested
872 * Returns:	nlm_granted (or error code)
873 * Notes:
874 */
875nlm4_testres *
876nlm4_test_4_svc(nlm4_testargs *arg, struct svc_req *rqstp)
877{
878	static nlm4_testres res;
879	struct nlm4_holder *holder;
880
881	if (debug_level)
882		log_from_addr("nlm4_test", rqstp);
883	if (debug_level > 5) {
884		syslog(LOG_DEBUG, "Locking arguments:\n");
885		log_netobj(&(arg->cookie));
886		syslog(LOG_DEBUG, "Alock arguments:\n");
887		syslog(LOG_DEBUG, "Caller Name: %s\n",arg->alock.caller_name);
888		syslog(LOG_DEBUG, "File Handle:\n");
889		log_netobj(&(arg->alock.fh));
890		syslog(LOG_DEBUG, "Owner Handle:\n");
891		log_netobj(&(arg->alock.oh));
892		syslog(LOG_DEBUG, "SVID:        %d\n", arg->alock.svid);
893		syslog(LOG_DEBUG, "Lock Offset: %llu\n",
894		    (unsigned long long)arg->alock.l_offset);
895		syslog(LOG_DEBUG, "Lock Length: %llu\n",
896		    (unsigned long long)arg->alock.l_len);
897		syslog(LOG_DEBUG, "Exclusive:   %s\n",
898		    (arg->exclusive ? "true" : "false"));
899	}
900
901	holder = testlock(&arg->alock, arg->exclusive, LOCK_V4);
902
903	/*
904	 * Copy the cookie from the argument into the result.  Note that this
905	 * is slightly hazardous, as the structure contains a pointer to a
906	 * malloc()ed buffer that will get freed by the caller.  However, the
907	 * main function transmits the result before freeing the argument
908	 * so it is in fact safe.
909	 */
910	res.cookie = arg->cookie;
911	if (holder == NULL) {
912		res.stat.stat = nlm4_granted;
913	} else {
914		res.stat.stat = nlm4_denied;
915		memcpy(&res.stat.nlm4_testrply_u.holder, holder,
916		    sizeof(struct nlm4_holder));
917	}
918	return (&res);
919}
920
921void *
922nlm4_test_msg_4_svc(nlm4_testargs *arg, struct svc_req *rqstp)
923{
924	nlm4_testres res;
925	static char dummy;
926	struct sockaddr *addr;
927	CLIENT *cli;
928	int success;
929	struct timeval timeo;
930	struct nlm4_holder *holder;
931
932	if (debug_level)
933		log_from_addr("nlm4_test_msg", rqstp);
934
935	holder = testlock(&arg->alock, arg->exclusive, LOCK_V4);
936
937	res.cookie = arg->cookie;
938	if (holder == NULL) {
939		res.stat.stat = nlm4_granted;
940	} else {
941		res.stat.stat = nlm4_denied;
942		memcpy(&res.stat.nlm4_testrply_u.holder, holder,
943		    sizeof(struct nlm4_holder));
944	}
945
946	/*
947	 * nlm_test has different result type to the other operations, so
948	 * can't use transmit4_result() in this case
949	 */
950	addr = svc_getrpccaller(rqstp->rq_xprt)->buf;
951	if ((cli = get_client(addr, NLM_VERS4)) != NULL) {
952		timeo.tv_sec = 0; /* No timeout - not expecting response */
953		timeo.tv_usec = 0;
954
955		success = clnt_call(cli, NLM4_TEST_RES,
956		    (xdrproc_t)xdr_nlm4_testres, &res,
957		    (xdrproc_t)xdr_void, &dummy, timeo);
958
959		if (debug_level > 2)
960			syslog(LOG_DEBUG, "clnt_call returns %d", success);
961	}
962	return (NULL);
963}
964
965/* nlm_lock ---------------------------------------------------------------- */
966/*
967 * Purposes:	Establish a lock
968 * Returns:	granted, denied or blocked
969 * Notes:	*** grace period support missing
970 */
971nlm4_res *
972nlm4_lock_4_svc(nlm4_lockargs *arg, struct svc_req *rqstp)
973{
974	static nlm4_res res;
975
976	if (debug_level)
977		log_from_addr("nlm4_lock", rqstp);
978	if (debug_level > 5) {
979		syslog(LOG_DEBUG, "Locking arguments:\n");
980		log_netobj(&(arg->cookie));
981		syslog(LOG_DEBUG, "Alock arguments:\n");
982		syslog(LOG_DEBUG, "Caller Name: %s\n",arg->alock.caller_name);
983		syslog(LOG_DEBUG, "File Handle:\n");
984		log_netobj(&(arg->alock.fh));
985		syslog(LOG_DEBUG, "Owner Handle:\n");
986		log_netobj(&(arg->alock.oh));
987		syslog(LOG_DEBUG, "SVID:        %d\n", arg->alock.svid);
988		syslog(LOG_DEBUG, "Lock Offset: %llu\n",
989		    (unsigned long long)arg->alock.l_offset);
990		syslog(LOG_DEBUG, "Lock Length: %llu\n",
991		    (unsigned long long)arg->alock.l_len);
992		syslog(LOG_DEBUG, "Block:       %s\n", (arg->block ? "true" : "false"));
993		syslog(LOG_DEBUG, "Exclusive:   %s\n", (arg->exclusive ? "true" : "false"));
994		syslog(LOG_DEBUG, "Reclaim:     %s\n", (arg->reclaim ? "true" : "false"));
995		syslog(LOG_DEBUG, "State num:   %d\n", arg->state);
996	}
997
998	/* copy cookie from arg to result.  See comment in nlm_test_4() */
999	res.cookie = arg->cookie;
1000
1001	res.stat.stat = (enum nlm4_stats)getlock(arg, rqstp, LOCK_MON | LOCK_V4);
1002	return (&res);
1003}
1004
1005void *
1006nlm4_lock_msg_4_svc(nlm4_lockargs *arg, struct svc_req *rqstp)
1007{
1008	static nlm4_res res;
1009
1010	if (debug_level)
1011		log_from_addr("nlm4_lock_msg", rqstp);
1012
1013	res.cookie = arg->cookie;
1014	res.stat.stat = (enum nlm4_stats)getlock(arg, rqstp, LOCK_MON | LOCK_ASYNC | LOCK_V4);
1015	transmit4_result(NLM4_LOCK_RES, &res, getrpcaddr(rqstp));
1016
1017	return (NULL);
1018}
1019
1020/* nlm_cancel -------------------------------------------------------------- */
1021/*
1022 * Purpose:	Cancel a blocked lock request
1023 * Returns:	granted or denied
1024 * Notes:
1025 */
1026nlm4_res *
1027nlm4_cancel_4_svc(nlm4_cancargs *arg, struct svc_req *rqstp)
1028{
1029	static nlm4_res res;
1030
1031	if (debug_level)
1032		log_from_addr("nlm4_cancel", rqstp);
1033
1034	/* copy cookie from arg to result.  See comment in nlm_test_1() */
1035	res.cookie = arg->cookie;
1036
1037	/*
1038	 * Since at present we never return 'nlm_blocked', there can never be
1039	 * a lock to cancel, so this call always fails.
1040	 */
1041	res.stat.stat = (enum nlm4_stats)unlock(&arg->alock, LOCK_CANCEL);
1042	return (&res);
1043}
1044
1045void *
1046nlm4_cancel_msg_4_svc(nlm4_cancargs *arg, struct svc_req *rqstp)
1047{
1048	static nlm4_res res;
1049
1050	if (debug_level)
1051		log_from_addr("nlm4_cancel_msg", rqstp);
1052
1053	res.cookie = arg->cookie;
1054	/*
1055	 * Since at present we never return 'nlm_blocked', there can never be
1056	 * a lock to cancel, so this call always fails.
1057	 */
1058	res.stat.stat = (enum nlm4_stats)unlock(&arg->alock, LOCK_CANCEL | LOCK_V4);
1059	transmit4_result(NLM4_CANCEL_RES, &res, getrpcaddr(rqstp));
1060	return (NULL);
1061}
1062
1063/* nlm_unlock -------------------------------------------------------------- */
1064/*
1065 * Purpose:	Release an existing lock
1066 * Returns:	Always granted, unless during grace period
1067 * Notes:	"no such lock" error condition is ignored, as the
1068 *		protocol uses unreliable UDP datagrams, and may well
1069 *		re-try an unlock that has already succeeded.
1070 */
1071nlm4_res *
1072nlm4_unlock_4_svc(nlm4_unlockargs *arg, struct svc_req *rqstp)
1073{
1074	static nlm4_res res;
1075
1076	if (debug_level)
1077		log_from_addr("nlm4_unlock", rqstp);
1078
1079	res.stat.stat = (enum nlm4_stats)unlock(&arg->alock, LOCK_V4);
1080	res.cookie = arg->cookie;
1081
1082	return (&res);
1083}
1084
1085void *
1086nlm4_unlock_msg_4_svc(nlm4_unlockargs *arg, struct svc_req *rqstp)
1087{
1088	static nlm4_res res;
1089
1090	if (debug_level)
1091		log_from_addr("nlm4_unlock_msg", rqstp);
1092
1093	res.stat.stat = (enum nlm4_stats)unlock(&arg->alock, LOCK_V4);
1094	res.cookie = arg->cookie;
1095
1096	transmit4_result(NLM4_UNLOCK_RES, &res, getrpcaddr(rqstp));
1097	return (NULL);
1098}
1099
1100/* ------------------------------------------------------------------------- */
1101/*
1102 * Client-side pseudo-RPCs for results.  Note that for the client there
1103 * are only nlm_xxx_msg() versions of each call, since the 'real RPC'
1104 * version returns the results in the RPC result, and so the client
1105 * does not normally receive incoming RPCs.
1106 *
1107 * The exception to this is nlm_granted(), which is genuinely an RPC
1108 * call from the server to the client - a 'call-back' in normal procedure
1109 * call terms.
1110 */
1111
1112/* nlm_granted ------------------------------------------------------------- */
1113/*
1114 * Purpose:	Receive notification that formerly blocked lock now granted
1115 * Returns:	always success ('granted')
1116 * Notes:
1117 */
1118nlm4_res *
1119nlm4_granted_4_svc(nlm4_testargs *arg, struct svc_req *rqstp)
1120{
1121	static nlm4_res res;
1122
1123	if (debug_level)
1124		log_from_addr("nlm4_granted", rqstp);
1125
1126	res.stat.stat = lock_answer(arg->alock.svid, &arg->cookie,
1127		nlm4_granted, NULL, NLM_VERS4) == 0 ?
1128		nlm4_granted : nlm4_denied;
1129
1130	/* copy cookie from arg to result.  See comment in nlm_test_1() */
1131	res.cookie = arg->cookie;
1132
1133	return (&res);
1134}
1135
1136void *
1137nlm4_granted_msg_4_svc(nlm4_testargs *arg, struct svc_req *rqstp)
1138{
1139	static nlm4_res res;
1140
1141	if (debug_level)
1142		log_from_addr("nlm4_granted_msg", rqstp);
1143
1144	res.cookie = arg->cookie;
1145	res.stat.stat = lock_answer(arg->alock.svid, &arg->cookie,
1146		nlm4_granted, NULL, NLM_VERS4) == 0 ?
1147		nlm4_granted : nlm4_denied;
1148	transmit4_result(NLM4_GRANTED_RES, &res, getrpcaddr(rqstp));
1149	return (NULL);
1150}
1151
1152/* nlm_test_res ------------------------------------------------------------ */
1153/*
1154 * Purpose:	Accept result from earlier nlm_test_msg() call
1155 * Returns:	Nothing
1156 */
1157void *
1158nlm4_test_res_4_svc(nlm4_testres *arg, struct svc_req *rqstp)
1159{
1160	if (debug_level)
1161		log_from_addr("nlm4_test_res", rqstp);
1162
1163	(void)lock_answer(-1, &arg->cookie, arg->stat.stat,
1164		(int *)&arg->stat.nlm4_testrply_u.holder.svid,
1165		NLM_VERS4);
1166	return (NULL);
1167}
1168
1169/* nlm_lock_res ------------------------------------------------------------ */
1170/*
1171 * Purpose:	Accept result from earlier nlm_lock_msg() call
1172 * Returns:	Nothing
1173 */
1174void *
1175nlm4_lock_res_4_svc(nlm4_res *arg, struct svc_req *rqstp)
1176{
1177	if (debug_level)
1178		log_from_addr("nlm4_lock_res", rqstp);
1179
1180	(void)lock_answer(-1, &arg->cookie, arg->stat.stat, NULL, NLM_VERS4);
1181
1182	return (NULL);
1183}
1184
1185/* nlm_cancel_res ---------------------------------------------------------- */
1186/*
1187 * Purpose:	Accept result from earlier nlm_cancel_msg() call
1188 * Returns:	Nothing
1189 */
1190void *
1191nlm4_cancel_res_4_svc(nlm4_res *arg __unused, struct svc_req *rqstp)
1192{
1193	if (debug_level)
1194		log_from_addr("nlm4_cancel_res", rqstp);
1195	return (NULL);
1196}
1197
1198/* nlm_unlock_res ---------------------------------------------------------- */
1199/*
1200 * Purpose:	Accept result from earlier nlm_unlock_msg() call
1201 * Returns:	Nothing
1202 */
1203void *
1204nlm4_unlock_res_4_svc(nlm4_res *arg __unused, struct svc_req *rqstp)
1205{
1206	if (debug_level)
1207		log_from_addr("nlm4_unlock_res", rqstp);
1208	return (NULL);
1209}
1210
1211/* nlm_granted_res --------------------------------------------------------- */
1212/*
1213 * Purpose:	Accept result from earlier nlm_granted_msg() call
1214 * Returns:	Nothing
1215 */
1216void *
1217nlm4_granted_res_4_svc(nlm4_res *arg __unused, struct svc_req *rqstp)
1218{
1219	if (debug_level)
1220		log_from_addr("nlm4_granted_res", rqstp);
1221	return (NULL);
1222}
1223
1224/* ------------------------------------------------------------------------- */
1225/*
1226 * Calls for PCNFS locking (aka non-monitored locking, no involvement
1227 * of rpc.statd).
1228 *
1229 * These are all genuine RPCs - no nlm_xxx_msg() nonsense here.
1230 */
1231
1232/* nlm_share --------------------------------------------------------------- */
1233/*
1234 * Purpose:	Establish a DOS-style lock
1235 * Returns:	success or failure
1236 * Notes:	Blocking locks are not supported - client is expected
1237 *		to retry if required.
1238 */
1239nlm4_shareres *
1240nlm4_share_4_svc(nlm4_shareargs *arg, struct svc_req *rqstp)
1241{
1242	static nlm4_shareres res;
1243
1244	if (debug_level)
1245		log_from_addr("nlm4_share", rqstp);
1246
1247	res.cookie = arg->cookie;
1248	res.stat = nlm4_granted;
1249	res.sequence = 1234356;	/* X/Open says this field is ignored? */
1250	return (&res);
1251}
1252
1253/* nlm4_unshare ------------------------------------------------------------ */
1254/*
1255 * Purpose:	Release a DOS-style lock
1256 * Returns:	nlm_granted, unless in grace period
1257 * Notes:
1258 */
1259nlm4_shareres *
1260nlm4_unshare_4_svc(nlm4_shareargs *arg, struct svc_req *rqstp)
1261{
1262	static nlm4_shareres res;
1263
1264	if (debug_level)
1265		log_from_addr("nlm_unshare", rqstp);
1266
1267	res.cookie = arg->cookie;
1268	res.stat = nlm4_granted;
1269	res.sequence = 1234356;	/* X/Open says this field is ignored? */
1270	return (&res);
1271}
1272
1273/* nlm4_nm_lock ------------------------------------------------------------ */
1274/*
1275 * Purpose:	non-monitored version of nlm4_lock()
1276 * Returns:	as for nlm4_lock()
1277 * Notes:	These locks are in the same style as the standard nlm4_lock,
1278 *		but the rpc.statd should not be called to establish a
1279 *		monitor for the client machine, since that machine is
1280 *		declared not to be running a rpc.statd, and so would not
1281 *		respond to the statd protocol.
1282 */
1283nlm4_res *
1284nlm4_nm_lock_4_svc(nlm4_lockargs *arg, struct svc_req *rqstp)
1285{
1286	static nlm4_res res;
1287
1288	if (debug_level)
1289		log_from_addr("nlm4_nm_lock", rqstp);
1290
1291	/* copy cookie from arg to result.  See comment in nlm4_test_1() */
1292	res.cookie = arg->cookie;
1293	res.stat.stat = nlm4_granted;
1294	return (&res);
1295}
1296
1297/* nlm4_free_all ------------------------------------------------------------ */
1298/*
1299 * Purpose:	Release all locks held by a named client
1300 * Returns:	Nothing
1301 * Notes:	Potential denial of service security problem here - the
1302 *		locks to be released are specified by a host name, independent
1303 *		of the address from which the request has arrived.
1304 *		Should probably be rejected if the named host has been
1305 *		using monitored locks.
1306 */
1307void *
1308nlm4_free_all_4_svc(struct nlm4_notify *arg __unused, struct svc_req *rqstp)
1309{
1310	static char dummy;
1311
1312	if (debug_level)
1313		log_from_addr("nlm4_free_all", rqstp);
1314	return (&dummy);
1315}
1316
1317/* nlm_sm_notify --------------------------------------------------------- */
1318/*
1319 * Purpose:	called by rpc.statd when a monitored host state changes.
1320 * Returns:	Nothing
1321 */
1322void *
1323nlm_sm_notify_0_svc(struct nlm_sm_status *arg, struct svc_req *rqstp __unused)
1324{
1325	static char dummy;
1326	notify(arg->mon_name, arg->state);
1327	return (&dummy);
1328}
1329