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