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