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