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