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