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