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