xref: /freebsd/usr.sbin/rpc.lockd/lock_proc.c (revision 6b3455a7665208c366849f0b2b3bc916fb97516e)
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 	arg4->caller_name = arg->caller_name;
390 	arg4->fh = arg->fh;
391 	arg4->oh = arg->oh;
392 	arg4->svid = arg->svid;
393 	arg4->l_offset = arg->l_offset;
394 	arg4->l_len = arg->l_len;
395 }
396 /* ------------------------------------------------------------------------- */
397 /*
398  * Functions for Unix<->Unix locking (ie. monitored locking, with rpc.statd
399  * involved to ensure reclaim of locks after a crash of the "stateless"
400  * server.
401  *
402  * These all come in two flavours - nlm_xxx() and nlm_xxx_msg().
403  * The first are standard RPCs with argument and result.
404  * The nlm_xxx_msg() calls implement exactly the same functions, but
405  * use two pseudo-RPCs (one in each direction).  These calls are NOT
406  * standard use of the RPC protocol in that they do not return a result
407  * at all (NB. this is quite different from returning a void result).
408  * The effect of this is to make the nlm_xxx_msg() calls simple unacknowledged
409  * datagrams, requiring higher-level code to perform retries.
410  *
411  * Despite the disadvantages of the nlm_xxx_msg() approach (some of which
412  * are documented in the comments to get_client() above), this is the
413  * interface used by all current commercial NFS implementations
414  * [Solaris, SCO, AIX etc.].  This is presumed to be because these allow
415  * implementations to continue using the standard RPC libraries, while
416  * avoiding the block-until-result nature of the library interface.
417  *
418  * No client implementations have been identified so far that make use
419  * of the true RPC version (early SunOS releases would be a likely candidate
420  * for testing).
421  */
422 
423 /* nlm_test ---------------------------------------------------------------- */
424 /*
425  * Purpose:	Test whether a specified lock would be granted if requested
426  * Returns:	nlm_granted (or error code)
427  * Notes:
428  */
429 nlm_testres *
430 nlm_test_1_svc(arg, rqstp)
431 	nlm_testargs *arg;
432 	struct svc_req *rqstp;
433 {
434 	static nlm_testres res;
435 	struct nlm4_lock arg4;
436 	struct nlm4_holder *holder;
437 	nlmtonlm4(&arg->alock, &arg4);
438 
439 	if (debug_level)
440 		log_from_addr("nlm_test", rqstp);
441 
442 	holder = testlock(&arg4, arg->exclusive, 0);
443 	/*
444 	 * Copy the cookie from the argument into the result.  Note that this
445 	 * is slightly hazardous, as the structure contains a pointer to a
446 	 * malloc()ed buffer that will get freed by the caller.  However, the
447 	 * main function transmits the result before freeing the argument
448 	 * so it is in fact safe.
449 	 */
450 	res.cookie = arg->cookie;
451 	if (holder == NULL) {
452 		res.stat.stat = nlm_granted;
453 	} else {
454 		res.stat.stat = nlm_denied;
455 		memcpy(&res.stat.nlm_testrply_u.holder, holder,
456 		    sizeof(struct nlm_holder));
457 		res.stat.nlm_testrply_u.holder.l_offset = holder->l_offset;
458 		res.stat.nlm_testrply_u.holder.l_len = holder->l_len;
459 	}
460 	return (&res);
461 }
462 
463 void *
464 nlm_test_msg_1_svc(arg, rqstp)
465 	nlm_testargs *arg;
466 	struct svc_req *rqstp;
467 {
468 	nlm_testres res;
469 	static char dummy;
470 	struct sockaddr *addr;
471 	CLIENT *cli;
472 	int success;
473 	struct timeval timeo;
474 	struct nlm4_lock arg4;
475 	struct nlm4_holder *holder;
476 
477 	nlmtonlm4(&arg->alock, &arg4);
478 
479 	if (debug_level)
480 		log_from_addr("nlm_test_msg", rqstp);
481 
482 	holder = testlock(&arg4, arg->exclusive, 0);
483 
484 	res.cookie = arg->cookie;
485 	if (holder == NULL) {
486 		res.stat.stat = nlm_granted;
487 	} else {
488 		res.stat.stat = nlm_denied;
489 		memcpy(&res.stat.nlm_testrply_u.holder, holder,
490 		    sizeof(struct nlm_holder));
491 		res.stat.nlm_testrply_u.holder.l_offset = holder->l_offset;
492 		res.stat.nlm_testrply_u.holder.l_len = holder->l_len;
493 	}
494 
495 	/*
496 	 * nlm_test has different result type to the other operations, so
497 	 * can't use transmit_result() in this case
498 	 */
499 	addr = svc_getrpccaller(rqstp->rq_xprt)->buf;
500 	if ((cli = get_client(addr, NLM_VERS)) != NULL) {
501 		timeo.tv_sec = 0; /* No timeout - not expecting response */
502 		timeo.tv_usec = 0;
503 
504 		success = clnt_call(cli, NLM_TEST_RES,
505 		    (xdrproc_t)xdr_nlm_testres, &res,
506 		    (xdrproc_t)xdr_void, &dummy, timeo);
507 
508 		if (debug_level > 2)
509 			syslog(LOG_DEBUG, "clnt_call returns %d", success);
510 	}
511 	return (NULL);
512 }
513 
514 /* nlm_lock ---------------------------------------------------------------- */
515 /*
516  * Purposes:	Establish a lock
517  * Returns:	granted, denied or blocked
518  * Notes:	*** grace period support missing
519  */
520 nlm_res *
521 nlm_lock_1_svc(arg, rqstp)
522 	nlm_lockargs *arg;
523 	struct svc_req *rqstp;
524 {
525 	static nlm_res res;
526 	struct nlm4_lockargs arg4;
527 	nlmtonlm4(&arg->alock, &arg4.alock);
528 	arg4.cookie = arg->cookie;
529 	arg4.block = arg->block;
530 	arg4.exclusive = arg->exclusive;
531 	arg4.reclaim = arg->reclaim;
532 	arg4.state = arg->state;
533 
534 	if (debug_level)
535 		log_from_addr("nlm_lock", rqstp);
536 
537 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
538 	res.cookie = arg->cookie;
539 
540 	res.stat.stat = getlock(&arg4, rqstp, LOCK_MON);
541 	return (&res);
542 }
543 
544 void *
545 nlm_lock_msg_1_svc(arg, rqstp)
546 	nlm_lockargs *arg;
547 	struct svc_req *rqstp;
548 {
549 	static nlm_res res;
550 	struct nlm4_lockargs arg4;
551 
552 	nlmtonlm4(&arg->alock, &arg4.alock);
553 	arg4.cookie = arg->cookie;
554 	arg4.block = arg->block;
555 	arg4.exclusive = arg->exclusive;
556 	arg4.reclaim = arg->reclaim;
557 	arg4.state = arg->state;
558 
559 	if (debug_level)
560 		log_from_addr("nlm_lock_msg", rqstp);
561 
562 	res.cookie = arg->cookie;
563 	res.stat.stat = getlock(&arg4, rqstp, LOCK_ASYNC | LOCK_MON);
564 	transmit_result(NLM_LOCK_RES, &res,
565 	    (struct sockaddr *)svc_getcaller(rqstp->rq_xprt));
566 
567 	return (NULL);
568 }
569 
570 /* nlm_cancel -------------------------------------------------------------- */
571 /*
572  * Purpose:	Cancel a blocked lock request
573  * Returns:	granted or denied
574  * Notes:
575  */
576 nlm_res *
577 nlm_cancel_1_svc(arg, rqstp)
578 	nlm_cancargs *arg;
579 	struct svc_req *rqstp;
580 {
581 	static nlm_res res;
582 	struct nlm4_lock arg4;
583 
584 	nlmtonlm4(&arg->alock, &arg4);
585 
586 	if (debug_level)
587 		log_from_addr("nlm_cancel", rqstp);
588 
589 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
590 	res.cookie = arg->cookie;
591 
592 	/*
593 	 * Since at present we never return 'nlm_blocked', there can never be
594 	 * a lock to cancel, so this call always fails.
595 	 */
596 	res.stat.stat = unlock(&arg4, LOCK_CANCEL);
597 	return (&res);
598 }
599 
600 void *
601 nlm_cancel_msg_1_svc(arg, rqstp)
602 	nlm_cancargs *arg;
603 	struct svc_req *rqstp;
604 {
605 	static nlm_res res;
606 	struct nlm4_lock arg4;
607 
608 	nlmtonlm4(&arg->alock, &arg4);
609 
610 	if (debug_level)
611 		log_from_addr("nlm_cancel_msg", rqstp);
612 
613 	res.cookie = arg->cookie;
614 	/*
615 	 * Since at present we never return 'nlm_blocked', there can never be
616 	 * a lock to cancel, so this call always fails.
617 	 */
618 	res.stat.stat = unlock(&arg4, LOCK_CANCEL);
619 	transmit_result(NLM_CANCEL_RES, &res,
620 	    (struct sockaddr *)svc_getcaller(rqstp->rq_xprt));
621 	return (NULL);
622 }
623 
624 /* nlm_unlock -------------------------------------------------------------- */
625 /*
626  * Purpose:	Release an existing lock
627  * Returns:	Always granted, unless during grace period
628  * Notes:	"no such lock" error condition is ignored, as the
629  *		protocol uses unreliable UDP datagrams, and may well
630  *		re-try an unlock that has already succeeded.
631  */
632 nlm_res *
633 nlm_unlock_1_svc(arg, rqstp)
634 	nlm_unlockargs *arg;
635 	struct svc_req *rqstp;
636 {
637 	static nlm_res res;
638 	struct nlm4_lock arg4;
639 
640 	nlmtonlm4(&arg->alock, &arg4);
641 
642 	if (debug_level)
643 		log_from_addr("nlm_unlock", rqstp);
644 
645 	res.stat.stat = unlock(&arg4, 0);
646 	res.cookie = arg->cookie;
647 
648 	return (&res);
649 }
650 
651 void *
652 nlm_unlock_msg_1_svc(arg, rqstp)
653 	nlm_unlockargs *arg;
654 	struct svc_req *rqstp;
655 {
656 	static nlm_res res;
657 	struct nlm4_lock arg4;
658 
659 	nlmtonlm4(&arg->alock, &arg4);
660 
661 	if (debug_level)
662 		log_from_addr("nlm_unlock_msg", rqstp);
663 
664 	res.stat.stat = unlock(&arg4, 0);
665 	res.cookie = arg->cookie;
666 
667 	transmit_result(NLM_UNLOCK_RES, &res,
668 	    (struct sockaddr *)svc_getcaller(rqstp->rq_xprt));
669 	return (NULL);
670 }
671 
672 /* ------------------------------------------------------------------------- */
673 /*
674  * Client-side pseudo-RPCs for results.  Note that for the client there
675  * are only nlm_xxx_msg() versions of each call, since the 'real RPC'
676  * version returns the results in the RPC result, and so the client
677  * does not normally receive incoming RPCs.
678  *
679  * The exception to this is nlm_granted(), which is genuinely an RPC
680  * call from the server to the client - a 'call-back' in normal procedure
681  * call terms.
682  */
683 
684 /* nlm_granted ------------------------------------------------------------- */
685 /*
686  * Purpose:	Receive notification that formerly blocked lock now granted
687  * Returns:	always success ('granted')
688  * Notes:
689  */
690 nlm_res *
691 nlm_granted_1_svc(arg, rqstp)
692 	nlm_testargs *arg;
693 	struct svc_req *rqstp;
694 {
695 	static nlm_res res;
696 
697 	if (debug_level)
698 		log_from_addr("nlm_granted", rqstp);
699 
700 	res.stat.stat = lock_answer(arg->alock.svid, &arg->cookie,
701 		nlm_granted, NULL, NLM_VERS) == 0 ?
702 		nlm_granted : nlm_denied;
703 
704 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
705 	res.cookie = arg->cookie;
706 
707 	return (&res);
708 }
709 
710 void *
711 nlm_granted_msg_1_svc(arg, rqstp)
712 	nlm_testargs *arg;
713 	struct svc_req *rqstp;
714 {
715 	static nlm_res res;
716 
717 	if (debug_level)
718 		log_from_addr("nlm_granted_msg", rqstp);
719 
720 	res.cookie = arg->cookie;
721 	res.stat.stat = lock_answer(arg->alock.svid, &arg->cookie,
722 		nlm_granted, NULL, NLM_VERS) == 0 ?
723 		nlm_granted : nlm_denied;
724 
725 	transmit_result(NLM_GRANTED_RES, &res,
726 	    (struct sockaddr *)svc_getcaller(rqstp->rq_xprt));
727 	return (NULL);
728 }
729 
730 /* nlm_test_res ------------------------------------------------------------ */
731 /*
732  * Purpose:	Accept result from earlier nlm_test_msg() call
733  * Returns:	Nothing
734  */
735 void *
736 nlm_test_res_1_svc(arg, rqstp)
737 	nlm_testres *arg;
738 	struct svc_req *rqstp;
739 {
740 	if (debug_level)
741 		log_from_addr("nlm_test_res", rqstp);
742 	(void)lock_answer(-1, &arg->cookie, arg->stat.stat,
743 		&arg->stat.nlm_testrply_u.holder.svid, NLM_VERS);
744 	return (NULL);
745 }
746 
747 /* nlm_lock_res ------------------------------------------------------------ */
748 /*
749  * Purpose:	Accept result from earlier nlm_lock_msg() call
750  * Returns:	Nothing
751  */
752 void *
753 nlm_lock_res_1_svc(arg, rqstp)
754 	nlm_res *arg;
755 	struct svc_req *rqstp;
756 {
757 	if (debug_level)
758 		log_from_addr("nlm_lock_res", rqstp);
759 
760 	(void)lock_answer(-1, &arg->cookie, arg->stat.stat, NULL, NLM_VERS);
761 
762 	return (NULL);
763 }
764 
765 /* nlm_cancel_res ---------------------------------------------------------- */
766 /*
767  * Purpose:	Accept result from earlier nlm_cancel_msg() call
768  * Returns:	Nothing
769  */
770 void *
771 nlm_cancel_res_1_svc(arg, rqstp)
772 	nlm_res *arg __unused;
773 	struct svc_req *rqstp;
774 {
775 	if (debug_level)
776 		log_from_addr("nlm_cancel_res", rqstp);
777 	return (NULL);
778 }
779 
780 /* nlm_unlock_res ---------------------------------------------------------- */
781 /*
782  * Purpose:	Accept result from earlier nlm_unlock_msg() call
783  * Returns:	Nothing
784  */
785 void *
786 nlm_unlock_res_1_svc(arg, rqstp)
787 	nlm_res *arg;
788 	struct svc_req *rqstp;
789 {
790 	if (debug_level)
791 		log_from_addr("nlm_unlock_res", rqstp);
792 
793 	lock_answer(-1, &arg->cookie, arg->stat.stat, NULL, NLM_VERS);
794 
795 	return (NULL);
796 }
797 
798 /* nlm_granted_res --------------------------------------------------------- */
799 /*
800  * Purpose:	Accept result from earlier nlm_granted_msg() call
801  * Returns:	Nothing
802  */
803 void *
804 nlm_granted_res_1_svc(arg, rqstp)
805 	nlm_res *arg __unused;
806 	struct svc_req *rqstp;
807 {
808 	if (debug_level)
809 		log_from_addr("nlm_granted_res", rqstp);
810 	return (NULL);
811 }
812 
813 /* ------------------------------------------------------------------------- */
814 /*
815  * Calls for PCNFS locking (aka non-monitored locking, no involvement
816  * of rpc.statd).
817  *
818  * These are all genuine RPCs - no nlm_xxx_msg() nonsense here.
819  */
820 
821 /* nlm_share --------------------------------------------------------------- */
822 /*
823  * Purpose:	Establish a DOS-style lock
824  * Returns:	success or failure
825  * Notes:	Blocking locks are not supported - client is expected
826  *		to retry if required.
827  */
828 nlm_shareres *
829 nlm_share_3_svc(arg, rqstp)
830 	nlm_shareargs *arg;
831 	struct svc_req *rqstp;
832 {
833 	static nlm_shareres res;
834 
835 	if (debug_level)
836 		log_from_addr("nlm_share", rqstp);
837 
838 	res.cookie = arg->cookie;
839 	res.stat = nlm_granted;
840 	res.sequence = 1234356;	/* X/Open says this field is ignored? */
841 	return (&res);
842 }
843 
844 /* nlm_unshare ------------------------------------------------------------ */
845 /*
846  * Purpose:	Release a DOS-style lock
847  * Returns:	nlm_granted, unless in grace period
848  * Notes:
849  */
850 nlm_shareres *
851 nlm_unshare_3_svc(arg, rqstp)
852 	nlm_shareargs *arg;
853 	struct svc_req *rqstp;
854 {
855 	static nlm_shareres res;
856 
857 	if (debug_level)
858 		log_from_addr("nlm_unshare", rqstp);
859 
860 	res.cookie = arg->cookie;
861 	res.stat = nlm_granted;
862 	res.sequence = 1234356;	/* X/Open says this field is ignored? */
863 	return (&res);
864 }
865 
866 /* nlm_nm_lock ------------------------------------------------------------ */
867 /*
868  * Purpose:	non-monitored version of nlm_lock()
869  * Returns:	as for nlm_lock()
870  * Notes:	These locks are in the same style as the standard nlm_lock,
871  *		but the rpc.statd should not be called to establish a
872  *		monitor for the client machine, since that machine is
873  *		declared not to be running a rpc.statd, and so would not
874  *		respond to the statd protocol.
875  */
876 nlm_res *
877 nlm_nm_lock_3_svc(arg, rqstp)
878 	nlm_lockargs *arg;
879 	struct svc_req *rqstp;
880 {
881 	static nlm_res res;
882 
883 	if (debug_level)
884 		log_from_addr("nlm_nm_lock", rqstp);
885 
886 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
887 	res.cookie = arg->cookie;
888 	res.stat.stat = nlm_granted;
889 	return (&res);
890 }
891 
892 /* nlm_free_all ------------------------------------------------------------ */
893 /*
894  * Purpose:	Release all locks held by a named client
895  * Returns:	Nothing
896  * Notes:	Potential denial of service security problem here - the
897  *		locks to be released are specified by a host name, independent
898  *		of the address from which the request has arrived.
899  *		Should probably be rejected if the named host has been
900  *		using monitored locks.
901  */
902 void *
903 nlm_free_all_3_svc(arg, rqstp)
904 	nlm_notify *arg __unused;
905 	struct svc_req *rqstp;
906 {
907 	static char dummy;
908 
909 	if (debug_level)
910 		log_from_addr("nlm_free_all", rqstp);
911 	return (&dummy);
912 }
913 
914 /* calls for nlm version 4 (NFSv3) */
915 /* nlm_test ---------------------------------------------------------------- */
916 /*
917  * Purpose:	Test whether a specified lock would be granted if requested
918  * Returns:	nlm_granted (or error code)
919  * Notes:
920  */
921 nlm4_testres *
922 nlm4_test_4_svc(arg, rqstp)
923 	nlm4_testargs *arg;
924 	struct svc_req *rqstp;
925 {
926 	static nlm4_testres res;
927 	struct nlm4_holder *holder;
928 
929 	if (debug_level)
930 		log_from_addr("nlm4_test", rqstp);
931 	if (debug_level > 5) {
932 		syslog(LOG_DEBUG, "Locking arguments:\n");
933 		log_netobj(&(arg->cookie));
934 		syslog(LOG_DEBUG, "Alock arguments:\n");
935 		syslog(LOG_DEBUG, "Caller Name: %s\n",arg->alock.caller_name);
936 		syslog(LOG_DEBUG, "File Handle:\n");
937 		log_netobj(&(arg->alock.fh));
938 		syslog(LOG_DEBUG, "Owner Handle:\n");
939 		log_netobj(&(arg->alock.oh));
940 		syslog(LOG_DEBUG, "SVID:        %d\n", arg->alock.svid);
941 		syslog(LOG_DEBUG, "Lock Offset: %llu\n",
942 		    (unsigned long long)arg->alock.l_offset);
943 		syslog(LOG_DEBUG, "Lock Length: %llu\n",
944 		    (unsigned long long)arg->alock.l_len);
945 		syslog(LOG_DEBUG, "Exclusive:   %s\n",
946 		    (arg->exclusive ? "true" : "false"));
947 	}
948 
949 	holder = testlock(&arg->alock, arg->exclusive, LOCK_V4);
950 
951 	/*
952 	 * Copy the cookie from the argument into the result.  Note that this
953 	 * is slightly hazardous, as the structure contains a pointer to a
954 	 * malloc()ed buffer that will get freed by the caller.  However, the
955 	 * main function transmits the result before freeing the argument
956 	 * so it is in fact safe.
957 	 */
958 	res.cookie = arg->cookie;
959 	if (holder == NULL) {
960 		res.stat.stat = nlm4_granted;
961 	} else {
962 		res.stat.stat = nlm4_denied;
963 		memcpy(&res.stat.nlm4_testrply_u.holder, holder,
964 		    sizeof(struct nlm4_holder));
965 	}
966 	return (&res);
967 }
968 
969 void *
970 nlm4_test_msg_4_svc(arg, rqstp)
971 	nlm4_testargs *arg;
972 	struct svc_req *rqstp;
973 {
974 	nlm4_testres res;
975 	static char dummy;
976 	struct sockaddr *addr;
977 	CLIENT *cli;
978 	int success;
979 	struct timeval timeo;
980 	struct nlm4_holder *holder;
981 
982 	if (debug_level)
983 		log_from_addr("nlm4_test_msg", rqstp);
984 
985 	holder = testlock(&arg->alock, arg->exclusive, LOCK_V4);
986 
987 	res.cookie = arg->cookie;
988 	if (holder == NULL) {
989 		res.stat.stat = nlm4_granted;
990 	} else {
991 		res.stat.stat = nlm4_denied;
992 		memcpy(&res.stat.nlm4_testrply_u.holder, holder,
993 		    sizeof(struct nlm4_holder));
994 	}
995 
996 	/*
997 	 * nlm_test has different result type to the other operations, so
998 	 * can't use transmit4_result() in this case
999 	 */
1000 	addr = svc_getrpccaller(rqstp->rq_xprt)->buf;
1001 	if ((cli = get_client(addr, NLM_VERS4)) != NULL) {
1002 		timeo.tv_sec = 0; /* No timeout - not expecting response */
1003 		timeo.tv_usec = 0;
1004 
1005 		success = clnt_call(cli, NLM4_TEST_RES,
1006 		    (xdrproc_t)xdr_nlm4_testres, &res,
1007 		    (xdrproc_t)xdr_void, &dummy, timeo);
1008 
1009 		if (debug_level > 2)
1010 			syslog(LOG_DEBUG, "clnt_call returns %d", success);
1011 	}
1012 	return (NULL);
1013 }
1014 
1015 /* nlm_lock ---------------------------------------------------------------- */
1016 /*
1017  * Purposes:	Establish a lock
1018  * Returns:	granted, denied or blocked
1019  * Notes:	*** grace period support missing
1020  */
1021 nlm4_res *
1022 nlm4_lock_4_svc(arg, rqstp)
1023 	nlm4_lockargs *arg;
1024 	struct svc_req *rqstp;
1025 {
1026 	static nlm4_res res;
1027 
1028 	if (debug_level)
1029 		log_from_addr("nlm4_lock", rqstp);
1030 	if (debug_level > 5) {
1031 		syslog(LOG_DEBUG, "Locking arguments:\n");
1032 		log_netobj(&(arg->cookie));
1033 		syslog(LOG_DEBUG, "Alock arguments:\n");
1034 		syslog(LOG_DEBUG, "Caller Name: %s\n",arg->alock.caller_name);
1035 		syslog(LOG_DEBUG, "File Handle:\n");
1036 		log_netobj(&(arg->alock.fh));
1037 		syslog(LOG_DEBUG, "Owner Handle:\n");
1038 		log_netobj(&(arg->alock.oh));
1039 		syslog(LOG_DEBUG, "SVID:        %d\n", arg->alock.svid);
1040 		syslog(LOG_DEBUG, "Lock Offset: %llu\n",
1041 		    (unsigned long long)arg->alock.l_offset);
1042 		syslog(LOG_DEBUG, "Lock Length: %llu\n",
1043 		    (unsigned long long)arg->alock.l_len);
1044 		syslog(LOG_DEBUG, "Block:       %s\n", (arg->block ? "true" : "false"));
1045 		syslog(LOG_DEBUG, "Exclusive:   %s\n", (arg->exclusive ? "true" : "false"));
1046 		syslog(LOG_DEBUG, "Reclaim:     %s\n", (arg->reclaim ? "true" : "false"));
1047 		syslog(LOG_DEBUG, "State num:   %d\n", arg->state);
1048 	}
1049 
1050 	/* copy cookie from arg to result.  See comment in nlm_test_4() */
1051 	res.cookie = arg->cookie;
1052 
1053 	res.stat.stat = getlock(arg, rqstp, LOCK_MON | LOCK_V4);
1054 	return (&res);
1055 }
1056 
1057 void *
1058 nlm4_lock_msg_4_svc(arg, rqstp)
1059 	nlm4_lockargs *arg;
1060 	struct svc_req *rqstp;
1061 {
1062 	static nlm4_res res;
1063 
1064 	if (debug_level)
1065 		log_from_addr("nlm4_lock_msg", rqstp);
1066 
1067 	res.cookie = arg->cookie;
1068 	res.stat.stat = getlock(arg, rqstp, LOCK_MON | LOCK_ASYNC | LOCK_V4);
1069 	transmit4_result(NLM4_LOCK_RES, &res,
1070 	    (struct sockaddr *)svc_getcaller(rqstp->rq_xprt));
1071 
1072 	return (NULL);
1073 }
1074 
1075 /* nlm_cancel -------------------------------------------------------------- */
1076 /*
1077  * Purpose:	Cancel a blocked lock request
1078  * Returns:	granted or denied
1079  * Notes:
1080  */
1081 nlm4_res *
1082 nlm4_cancel_4_svc(arg, rqstp)
1083 	nlm4_cancargs *arg;
1084 	struct svc_req *rqstp;
1085 {
1086 	static nlm4_res res;
1087 
1088 	if (debug_level)
1089 		log_from_addr("nlm4_cancel", rqstp);
1090 
1091 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
1092 	res.cookie = arg->cookie;
1093 
1094 	/*
1095 	 * Since at present we never return 'nlm_blocked', there can never be
1096 	 * a lock to cancel, so this call always fails.
1097 	 */
1098 	res.stat.stat = unlock(&arg->alock, LOCK_CANCEL);
1099 	return (&res);
1100 }
1101 
1102 void *
1103 nlm4_cancel_msg_4_svc(arg, rqstp)
1104 	nlm4_cancargs *arg;
1105 	struct svc_req *rqstp;
1106 {
1107 	static nlm4_res res;
1108 
1109 	if (debug_level)
1110 		log_from_addr("nlm4_cancel_msg", rqstp);
1111 
1112 	res.cookie = arg->cookie;
1113 	/*
1114 	 * Since at present we never return 'nlm_blocked', there can never be
1115 	 * a lock to cancel, so this call always fails.
1116 	 */
1117 	res.stat.stat = unlock(&arg->alock, LOCK_CANCEL | LOCK_V4);
1118 	transmit4_result(NLM4_CANCEL_RES, &res,
1119 	    (struct sockaddr *)svc_getcaller(rqstp->rq_xprt));
1120 	return (NULL);
1121 }
1122 
1123 /* nlm_unlock -------------------------------------------------------------- */
1124 /*
1125  * Purpose:	Release an existing lock
1126  * Returns:	Always granted, unless during grace period
1127  * Notes:	"no such lock" error condition is ignored, as the
1128  *		protocol uses unreliable UDP datagrams, and may well
1129  *		re-try an unlock that has already succeeded.
1130  */
1131 nlm4_res *
1132 nlm4_unlock_4_svc(arg, rqstp)
1133 	nlm4_unlockargs *arg;
1134 	struct svc_req *rqstp;
1135 {
1136 	static nlm4_res res;
1137 
1138 	if (debug_level)
1139 		log_from_addr("nlm4_unlock", rqstp);
1140 
1141 	res.stat.stat = unlock(&arg->alock, LOCK_V4);
1142 	res.cookie = arg->cookie;
1143 
1144 	return (&res);
1145 }
1146 
1147 void *
1148 nlm4_unlock_msg_4_svc(arg, rqstp)
1149 	nlm4_unlockargs *arg;
1150 	struct svc_req *rqstp;
1151 {
1152 	static nlm4_res res;
1153 
1154 	if (debug_level)
1155 		log_from_addr("nlm4_unlock_msg", rqstp);
1156 
1157 	res.stat.stat = unlock(&arg->alock, LOCK_V4);
1158 	res.cookie = arg->cookie;
1159 
1160 	transmit4_result(NLM4_UNLOCK_RES, &res,
1161 	    (struct sockaddr *)svc_getcaller(rqstp->rq_xprt));
1162 	return (NULL);
1163 }
1164 
1165 /* ------------------------------------------------------------------------- */
1166 /*
1167  * Client-side pseudo-RPCs for results.  Note that for the client there
1168  * are only nlm_xxx_msg() versions of each call, since the 'real RPC'
1169  * version returns the results in the RPC result, and so the client
1170  * does not normally receive incoming RPCs.
1171  *
1172  * The exception to this is nlm_granted(), which is genuinely an RPC
1173  * call from the server to the client - a 'call-back' in normal procedure
1174  * call terms.
1175  */
1176 
1177 /* nlm_granted ------------------------------------------------------------- */
1178 /*
1179  * Purpose:	Receive notification that formerly blocked lock now granted
1180  * Returns:	always success ('granted')
1181  * Notes:
1182  */
1183 nlm4_res *
1184 nlm4_granted_4_svc(arg, rqstp)
1185 	nlm4_testargs *arg;
1186 	struct svc_req *rqstp;
1187 {
1188 	static nlm4_res res;
1189 
1190 	if (debug_level)
1191 		log_from_addr("nlm4_granted", rqstp);
1192 
1193 	res.stat.stat = lock_answer(arg->alock.svid, &arg->cookie,
1194 		nlm4_granted, NULL, NLM_VERS4) == 0 ?
1195 		nlm4_granted : nlm4_denied;
1196 
1197 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
1198 	res.cookie = arg->cookie;
1199 
1200 	return (&res);
1201 }
1202 
1203 void *
1204 nlm4_granted_msg_4_svc(arg, rqstp)
1205 	nlm4_testargs *arg;
1206 	struct svc_req *rqstp;
1207 {
1208 	static nlm4_res res;
1209 
1210 	if (debug_level)
1211 		log_from_addr("nlm4_granted_msg", rqstp);
1212 
1213 	res.cookie = arg->cookie;
1214 	res.stat.stat = lock_answer(arg->alock.svid, &arg->cookie,
1215 		nlm4_granted, NULL, NLM_VERS4) == 0 ?
1216 		nlm4_granted : nlm4_denied;
1217 	transmit4_result(NLM4_GRANTED_RES, &res,
1218 	    (struct sockaddr *)svc_getrpccaller(rqstp->rq_xprt)->buf);
1219 	return (NULL);
1220 }
1221 
1222 /* nlm_test_res ------------------------------------------------------------ */
1223 /*
1224  * Purpose:	Accept result from earlier nlm_test_msg() call
1225  * Returns:	Nothing
1226  */
1227 void *
1228 nlm4_test_res_4_svc(arg, rqstp)
1229 	nlm4_testres *arg;
1230 	struct svc_req *rqstp;
1231 {
1232 	if (debug_level)
1233 		log_from_addr("nlm4_test_res", rqstp);
1234 
1235 	(void)lock_answer(-1, &arg->cookie, arg->stat.stat,
1236 		(int *)&arg->stat.nlm4_testrply_u.holder.svid,
1237 		NLM_VERS4);
1238 	return (NULL);
1239 }
1240 
1241 /* nlm_lock_res ------------------------------------------------------------ */
1242 /*
1243  * Purpose:	Accept result from earlier nlm_lock_msg() call
1244  * Returns:	Nothing
1245  */
1246 void *
1247 nlm4_lock_res_4_svc(arg, rqstp)
1248 	nlm4_res *arg;
1249 	struct svc_req *rqstp;
1250 {
1251 	if (debug_level)
1252 		log_from_addr("nlm4_lock_res", rqstp);
1253 
1254 	(void)lock_answer(-1, &arg->cookie, arg->stat.stat, NULL, NLM_VERS4);
1255 
1256 	return (NULL);
1257 }
1258 
1259 /* nlm_cancel_res ---------------------------------------------------------- */
1260 /*
1261  * Purpose:	Accept result from earlier nlm_cancel_msg() call
1262  * Returns:	Nothing
1263  */
1264 void *
1265 nlm4_cancel_res_4_svc(arg, rqstp)
1266 	nlm4_res *arg __unused;
1267 	struct svc_req *rqstp;
1268 {
1269 	if (debug_level)
1270 		log_from_addr("nlm4_cancel_res", rqstp);
1271 	return (NULL);
1272 }
1273 
1274 /* nlm_unlock_res ---------------------------------------------------------- */
1275 /*
1276  * Purpose:	Accept result from earlier nlm_unlock_msg() call
1277  * Returns:	Nothing
1278  */
1279 void *
1280 nlm4_unlock_res_4_svc(arg, rqstp)
1281 	nlm4_res *arg __unused;
1282 	struct svc_req *rqstp;
1283 {
1284 	if (debug_level)
1285 		log_from_addr("nlm4_unlock_res", rqstp);
1286 	return (NULL);
1287 }
1288 
1289 /* nlm_granted_res --------------------------------------------------------- */
1290 /*
1291  * Purpose:	Accept result from earlier nlm_granted_msg() call
1292  * Returns:	Nothing
1293  */
1294 void *
1295 nlm4_granted_res_4_svc(arg, rqstp)
1296 	nlm4_res *arg __unused;
1297 	struct svc_req *rqstp;
1298 {
1299 	if (debug_level)
1300 		log_from_addr("nlm4_granted_res", rqstp);
1301 	return (NULL);
1302 }
1303 
1304 /* ------------------------------------------------------------------------- */
1305 /*
1306  * Calls for PCNFS locking (aka non-monitored locking, no involvement
1307  * of rpc.statd).
1308  *
1309  * These are all genuine RPCs - no nlm_xxx_msg() nonsense here.
1310  */
1311 
1312 /* nlm_share --------------------------------------------------------------- */
1313 /*
1314  * Purpose:	Establish a DOS-style lock
1315  * Returns:	success or failure
1316  * Notes:	Blocking locks are not supported - client is expected
1317  *		to retry if required.
1318  */
1319 nlm4_shareres *
1320 nlm4_share_4_svc(arg, rqstp)
1321 	nlm4_shareargs *arg;
1322 	struct svc_req *rqstp;
1323 {
1324 	static nlm4_shareres res;
1325 
1326 	if (debug_level)
1327 		log_from_addr("nlm4_share", rqstp);
1328 
1329 	res.cookie = arg->cookie;
1330 	res.stat = nlm4_granted;
1331 	res.sequence = 1234356;	/* X/Open says this field is ignored? */
1332 	return (&res);
1333 }
1334 
1335 /* nlm4_unshare ------------------------------------------------------------ */
1336 /*
1337  * Purpose:	Release a DOS-style lock
1338  * Returns:	nlm_granted, unless in grace period
1339  * Notes:
1340  */
1341 nlm4_shareres *
1342 nlm4_unshare_4_svc(arg, rqstp)
1343 	nlm4_shareargs *arg;
1344 	struct svc_req *rqstp;
1345 {
1346 	static nlm4_shareres res;
1347 
1348 	if (debug_level)
1349 		log_from_addr("nlm_unshare", rqstp);
1350 
1351 	res.cookie = arg->cookie;
1352 	res.stat = nlm4_granted;
1353 	res.sequence = 1234356;	/* X/Open says this field is ignored? */
1354 	return (&res);
1355 }
1356 
1357 /* nlm4_nm_lock ------------------------------------------------------------ */
1358 /*
1359  * Purpose:	non-monitored version of nlm4_lock()
1360  * Returns:	as for nlm4_lock()
1361  * Notes:	These locks are in the same style as the standard nlm4_lock,
1362  *		but the rpc.statd should not be called to establish a
1363  *		monitor for the client machine, since that machine is
1364  *		declared not to be running a rpc.statd, and so would not
1365  *		respond to the statd protocol.
1366  */
1367 nlm4_res *
1368 nlm4_nm_lock_4_svc(arg, rqstp)
1369 	nlm4_lockargs *arg;
1370 	struct svc_req *rqstp;
1371 {
1372 	static nlm4_res res;
1373 
1374 	if (debug_level)
1375 		log_from_addr("nlm4_nm_lock", rqstp);
1376 
1377 	/* copy cookie from arg to result.  See comment in nlm4_test_1() */
1378 	res.cookie = arg->cookie;
1379 	res.stat.stat = nlm4_granted;
1380 	return (&res);
1381 }
1382 
1383 /* nlm4_free_all ------------------------------------------------------------ */
1384 /*
1385  * Purpose:	Release all locks held by a named client
1386  * Returns:	Nothing
1387  * Notes:	Potential denial of service security problem here - the
1388  *		locks to be released are specified by a host name, independent
1389  *		of the address from which the request has arrived.
1390  *		Should probably be rejected if the named host has been
1391  *		using monitored locks.
1392  */
1393 void *
1394 nlm4_free_all_4_svc(arg, rqstp)
1395 	struct nlm4_notify *arg __unused;
1396 	struct svc_req *rqstp;
1397 {
1398 	static char dummy;
1399 
1400 	if (debug_level)
1401 		log_from_addr("nlm4_free_all", rqstp);
1402 	return (&dummy);
1403 }
1404 
1405 /* nlm_sm_notify --------------------------------------------------------- */
1406 /*
1407  * Purpose:	called by rpc.statd when a monitored host state changes.
1408  * Returns:	Nothing
1409  */
1410 void *
1411 nlm_sm_notify_0_svc(arg, rqstp)
1412 	struct nlm_sm_status *arg;
1413 	struct svc_req *rqstp __unused;
1414 {
1415 	static char dummy;
1416 	notify(arg->mon_name, arg->state);
1417 	return (&dummy);
1418 }
1419