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