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