xref: /openbsd/usr.sbin/rpc.lockd/procs.c (revision cca36db2)
1 /*	$OpenBSD: procs.c,v 1.14 2011/03/22 10:16:23 okan Exp $	*/
2 
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/param.h>
37 #include <sys/socket.h>
38 #include <netinet/in.h>
39 #include <rpc/rpc.h>
40 #include <rpc/pmap_clnt.h>
41 #include <rpcsvc/sm_inter.h>
42 #include "nlm_prot.h"
43 #include <arpa/inet.h>
44 #include <stdio.h>
45 #include <syslog.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <netdb.h>
49 
50 #include "lockd.h"
51 #include "lockd_lock.h"
52 
53 #define	CLIENT_CACHE_SIZE	64	/* No. of client sockets cached	 */
54 #define	CLIENT_CACHE_LIFETIME	120	/* In seconds			 */
55 
56 /* log_from_addr ----------------------------------------------------------- */
57 /*
58  * Purpose:	Log name of function called and source address
59  * Returns:	Nothing
60  * Notes:	Extracts the source address from the transport handle
61  *		passed in as part of the called procedure specification
62  */
63 static void
64 log_from_addr(char *fun_name, struct svc_req *req)
65 {
66 	struct	sockaddr_in *addr;
67 	struct	hostent *host;
68 	char	hostname_buf[MAXHOSTNAMELEN];
69 
70 	addr = svc_getcaller(req->rq_xprt);
71 	host = gethostbyaddr((char *) &(addr->sin_addr), addr->sin_len, AF_INET);
72 	if (host)
73 		strlcpy(hostname_buf, host->h_name, sizeof(hostname_buf));
74 	else
75 		strlcpy(hostname_buf, inet_ntoa(addr->sin_addr),
76 		    sizeof hostname_buf);
77 	syslog(LOG_DEBUG, "%s from %s", fun_name, hostname_buf);
78 }
79 
80 
81 /* get_client -------------------------------------------------------------- */
82 /*
83  * Purpose:	Get a CLIENT* for making RPC calls to lockd on given host
84  * Returns:	CLIENT* pointer, from clnt_udp_create, or NULL if error
85  * Notes:	Creating a CLIENT* is quite expensive, involving a
86  *		conversation with the remote portmapper to get the
87  *		port number.  Since a given client is quite likely
88  *		to make several locking requests in succession, it is
89  *		desirable to cache the created CLIENT*.
90  *
91  *		Since we are using UDP rather than TCP, there is no cost
92  *		to the remote system in keeping these cached indefinitely.
93  *		Unfortunately there is a snag: if the remote system
94  *		reboots, the cached portmapper results will be invalid,
95  *		and we will never detect this since all of the xxx_msg()
96  *		calls return no result - we just fire off a udp packet
97  *		and hope for the best.
98  *
99  *		We solve this by discarding cached values after two
100  *		minutes, regardless of whether they have been used
101  *		in the meanwhile (since a bad one might have been used
102  *		plenty of times, as the host keeps retrying the request
103  *		and we keep sending the reply back to the wrong port).
104  *
105  *		Given that the entries will always expire in the order
106  *		that they were created, there is no point in a LRU
107  *		algorithm for when the cache gets full - entries are
108  *		always re-used in sequence.
109  */
110 static CLIENT *clnt_cache_ptr[CLIENT_CACHE_SIZE];
111 static long clnt_cache_time[CLIENT_CACHE_SIZE];	/* time entry created */
112 static struct in_addr clnt_cache_addr[CLIENT_CACHE_SIZE];
113 static int clnt_cache_next_to_use = 0;
114 
115 CLIENT *
116 get_client(struct sockaddr_in *host_addr, u_long vers)
117 {
118 	CLIENT *client;
119 	int     sock_no, i;
120 	struct timeval retry_time, time_now;
121 
122 	gettimeofday(&time_now, NULL);
123 
124 	/*
125 	 * Search for the given client in the cache, zapping any expired
126 	 * entries that we happen to notice in passing.
127 	 */
128 	for (i = 0; i < CLIENT_CACHE_SIZE; i++) {
129 		client = clnt_cache_ptr[i];
130 		if (client && ((clnt_cache_time[i] + CLIENT_CACHE_LIFETIME)
131 		    < time_now.tv_sec)) {
132 			/* Cache entry has expired. */
133 			if (debug_level > 3)
134 				syslog(LOG_DEBUG, "Expired CLIENT* in cache");
135 			clnt_cache_time[i] = 0L;
136 			clnt_destroy(client);
137 			clnt_cache_ptr[i] = NULL;
138 			client = NULL;
139 		}
140 		if (client && !memcmp(&clnt_cache_addr[i], &host_addr->sin_addr,
141 			sizeof(struct in_addr))) {
142 			/* Found it! */
143 			if (debug_level > 3)
144 				syslog(LOG_DEBUG, "Found CLIENT* in cache");
145 			return client;
146 		}
147 	}
148 
149 	/* Not found in cache.  Free the next entry if it is in use. */
150 	if (clnt_cache_ptr[clnt_cache_next_to_use]) {
151 		clnt_destroy(clnt_cache_ptr[clnt_cache_next_to_use]);
152 		clnt_cache_ptr[clnt_cache_next_to_use] = NULL;
153 	}
154 
155 	sock_no = RPC_ANYSOCK;
156 	retry_time.tv_sec = 5;
157 	retry_time.tv_usec = 0;
158 	host_addr->sin_port = 0;
159 	client = clntudp_create(host_addr, NLM_PROG, vers, retry_time, &sock_no);
160 	if (!client) {
161 		syslog(LOG_ERR, "%s", clnt_spcreateerror("clntudp_create"));
162 		syslog(LOG_ERR, "Unable to return result to %s",
163 		    inet_ntoa(host_addr->sin_addr));
164 		return NULL;
165 	}
166 
167 	/* Success - update the cache entry */
168 	clnt_cache_ptr[clnt_cache_next_to_use] = client;
169 	clnt_cache_addr[clnt_cache_next_to_use] = host_addr->sin_addr;
170 	clnt_cache_time[clnt_cache_next_to_use] = time_now.tv_sec;
171 	if (++clnt_cache_next_to_use >= CLIENT_CACHE_SIZE)
172 		clnt_cache_next_to_use = 0;
173 
174 	/*
175 	 * Disable the default timeout, so we can specify our own in calls
176 	 * to clnt_call().  (Note that the timeout is a different concept
177 	 * from the retry period set in clnt_udp_create() above.)
178 	 */
179 	retry_time.tv_sec = -1;
180 	retry_time.tv_usec = -1;
181 	clnt_control(client, CLSET_TIMEOUT, (char *)(void *)&retry_time);
182 
183 	if (debug_level > 3)
184 		syslog(LOG_DEBUG, "Created CLIENT* for %s",
185 		    inet_ntoa(host_addr->sin_addr));
186 	return client;
187 }
188 
189 
190 /* transmit_result --------------------------------------------------------- */
191 /*
192  * Purpose:	Transmit result for nlm_xxx_msg pseudo-RPCs
193  * Returns:	Nothing - we have no idea if the datagram got there
194  * Notes:	clnt_call() will always fail (with timeout) as we are
195  *		calling it with timeout 0 as a hack to just issue a datagram
196  *		without expecting a result
197  */
198 void
199 transmit_result(int opcode, nlm_res *result, struct sockaddr_in *addr)
200 {
201 	static char dummy;
202 	CLIENT *cli;
203 	struct timeval timeo;
204 	int success;
205 
206 	if ((cli = get_client(addr, NLM_VERS)) != NULL) {
207 		/* No timeout - not expecting response */
208 		timerclear(&timeo);
209 
210 		success = clnt_call(cli, opcode, xdr_nlm_res,
211 		    result, xdr_void, &dummy, timeo);
212 
213 		if (debug_level > 2)
214 			syslog(LOG_DEBUG, "clnt_call returns %d(%s)",
215 			    success, clnt_sperrno(success));
216 	}
217 }
218 /* transmit4_result --------------------------------------------------------- */
219 /*
220  * Purpose:	Transmit result for nlm4_xxx_msg pseudo-RPCs
221  * Returns:	Nothing - we have no idea if the datagram got there
222  * Notes:	clnt_call() will always fail (with timeout) as we are
223  *		calling it with timeout 0 as a hack to just issue a datagram
224  *		without expecting a result
225  */
226 void
227 transmit4_result(int opcode, nlm4_res *result, struct sockaddr_in *addr)
228 {
229 	static char dummy;
230 	CLIENT *cli;
231 	struct timeval timeo;
232 	int success;
233 
234 	if ((cli = get_client(addr, NLM_VERS4)) != NULL) {
235 		/* No timeout - not expecting response */
236 		timerclear(&timeo);
237 
238 		success = clnt_call(cli, opcode, xdr_nlm4_res,
239 		    result, xdr_void, &dummy, timeo);
240 
241 		if (debug_level > 2)
242 			syslog(LOG_DEBUG, "clnt_call returns %d(%s)",
243 			    success, clnt_sperrno(success));
244 	}
245 }
246 
247 /*
248  * converts a struct nlm_lock to struct nlm4_lock
249  */
250 static void
251 nlmtonlm4(struct nlm_lock *arg, struct nlm4_lock *arg4)
252 {
253 	memcpy(arg4, arg, sizeof(nlm_lock));
254 	arg4->l_offset = arg->l_offset;
255 	arg4->l_len = arg->l_len;
256 }
257 
258 /* ------------------------------------------------------------------------- */
259 /*
260  * Functions for Unix<->Unix locking (ie. monitored locking, with rpc.statd
261  * involved to ensure reclaim of locks after a crash of the "stateless"
262  * server.
263  *
264  * These all come in two flavours - nlm_xxx() and nlm_xxx_msg().
265  * The first are standard RPCs with argument and result.
266  * The nlm_xxx_msg() calls implement exactly the same functions, but
267  * use two pseudo-RPCs (one in each direction).  These calls are NOT
268  * standard use of the RPC protocol in that they do not return a result
269  * at all (NB. this is quite different from returning a void result).
270  * The effect of this is to make the nlm_xxx_msg() calls simple unacknowledged
271  * datagrams, requiring higher-level code to perform retries.
272  *
273  * Despite the disadvantages of the nlm_xxx_msg() approach (some of which
274  * are documented in the comments to get_client() above), this is the
275  * interface used by all current commercial NFS implementations
276  * [Solaris, SCO, AIX etc.].  This is presumed to be because these allow
277  * implementations to continue using the standard RPC libraries, while
278  * avoiding the block-until-result nature of the library interface.
279  *
280  * No client implementations have been identified so far that make use
281  * of the true RPC version (early SunOS releases would be a likely candidate
282  * for testing).
283  */
284 
285 /* nlm_test ---------------------------------------------------------------- */
286 /*
287  * Purpose:	Test whether a specified lock would be granted if requested
288  * Returns:	nlm_granted (or error code)
289  * Notes:
290  */
291 nlm_testres *
292 nlm_test_1_svc(nlm_testargs *arg, struct svc_req *rqstp)
293 {
294 	static nlm_testres result;
295 	struct nlm4_lock arg4;
296 	struct nlm4_holder *holder;
297 	nlmtonlm4(&arg->alock, &arg4);
298 
299 	if (debug_level)
300 		log_from_addr("nlm_test", rqstp);
301 
302 	holder = testlock(&arg4, 0);
303 	/*
304 	 * Copy the cookie from the argument into the result.  Note that this
305 	 * is slightly hazardous, as the structure contains a pointer to a
306 	 * malloc()ed buffer that will get freed by the caller.  However, the
307 	 * main function transmits the result before freeing the argument
308 	 * so it is in fact safe.
309 	 */
310 	result.cookie = arg->cookie;
311 	if (holder == NULL) {
312 		result.stat.stat = nlm_granted;
313 	} else {
314 		result.stat.stat = nlm_denied;
315 		memcpy(&result.stat.nlm_testrply_u.holder, holder,
316 		    sizeof(struct nlm_holder));
317 		result.stat.nlm_testrply_u.holder.l_offset =
318 		    (unsigned int)holder->l_offset;
319 		result.stat.nlm_testrply_u.holder.l_len =
320 		    (unsigned int)holder->l_len;
321 	}
322 	return &result;
323 }
324 
325 void *
326 nlm_test_msg_1_svc(nlm_testargs *arg, struct svc_req *rqstp)
327 {
328 	nlm_testres result;
329 	static char dummy;
330 	struct sockaddr_in *addr;
331 	CLIENT *cli;
332 	int success;
333 	struct timeval timeo;
334 	struct nlm4_lock arg4;
335 	struct nlm4_holder *holder;
336 
337 	nlmtonlm4(&arg->alock, &arg4);
338 
339 	if (debug_level)
340 		log_from_addr("nlm_test_msg", rqstp);
341 
342 	holder = testlock(&arg4, 0);
343 
344 	result.cookie = arg->cookie;
345 	if (holder == NULL) {
346 		result.stat.stat = nlm_granted;
347 	} else {
348 		result.stat.stat = nlm_denied;
349 		memcpy(&result.stat.nlm_testrply_u.holder, holder,
350 		    sizeof(struct nlm_holder));
351 		result.stat.nlm_testrply_u.holder.l_offset =
352 		    (unsigned int)holder->l_offset;
353 		result.stat.nlm_testrply_u.holder.l_len =
354 		    (unsigned int)holder->l_len;
355 	}
356 
357 	/*
358 	 * nlm_test has different result type to the other operations, so
359 	 * can't use transmit_result() in this case
360 	 */
361 	addr = svc_getcaller(rqstp->rq_xprt);
362 	if ((cli = get_client(addr, NLM_VERS)) != NULL) {
363 		/* No timeout - not expecting response */
364 		timerclear(&timeo);
365 
366 		success = clnt_call(cli, NLM_TEST_RES, xdr_nlm_testres,
367 		    &result, xdr_void, &dummy, timeo);
368 
369 		if (debug_level > 2)
370 			syslog(LOG_DEBUG, "clnt_call returns %d", success);
371 	}
372 	return NULL;
373 }
374 
375 /* nlm_lock ---------------------------------------------------------------- */
376 /*
377  * Purposes:	Establish a lock
378  * Returns:	granted, denied or blocked
379  * Notes:	*** grace period support missing
380  */
381 nlm_res *
382 nlm_lock_1_svc(nlm_lockargs *arg, struct svc_req *rqstp)
383 {
384 	static nlm_res result;
385 	struct nlm4_lockargs arg4;
386 	nlmtonlm4(&arg->alock, &arg4.alock);
387 	arg4.cookie = arg->cookie;
388 	arg4.block = arg->block;
389 	arg4.exclusive = arg->exclusive;
390 	arg4.reclaim = arg->reclaim;
391 	arg4.state = arg->state;
392 
393 	if (debug_level)
394 		log_from_addr("nlm_lock", rqstp);
395 
396 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
397 	result.cookie = arg->cookie;
398 
399 	result.stat.stat = getlock(&arg4, rqstp, LOCK_MON);
400 	return &result;
401 }
402 
403 void *
404 nlm_lock_msg_1_svc(nlm_lockargs *arg, struct svc_req *rqstp)
405 {
406 	static nlm_res result;
407 	struct nlm4_lockargs arg4;
408 
409 	nlmtonlm4(&arg->alock, &arg4.alock);
410 	arg4.cookie = arg->cookie;
411 	arg4.block = arg->block;
412 	arg4.exclusive = arg->exclusive;
413 	arg4.reclaim = arg->reclaim;
414 	arg4.state = arg->state;
415 
416 	if (debug_level)
417 		log_from_addr("nlm_lock_msg", rqstp);
418 
419 	result.cookie = arg->cookie;
420 	result.stat.stat = getlock(&arg4, rqstp, LOCK_ASYNC | LOCK_MON);
421 	transmit_result(NLM_LOCK_RES, &result, svc_getcaller(rqstp->rq_xprt));
422 
423 	return NULL;
424 }
425 
426 /* nlm_cancel -------------------------------------------------------------- */
427 /*
428  * Purpose:	Cancel a blocked lock request
429  * Returns:	granted or denied
430  * Notes:
431  */
432 nlm_res *
433 nlm_cancel_1_svc(nlm_cancargs *arg, struct svc_req *rqstp)
434 {
435 	static nlm_res result;
436 	struct nlm4_lock arg4;
437 
438 	nlmtonlm4(&arg->alock, &arg4);
439 
440 	if (debug_level)
441 		log_from_addr("nlm_cancel", rqstp);
442 
443 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
444 	result.cookie = arg->cookie;
445 
446 	/*
447 	 * Since at present we never return 'nlm_blocked', there can never be
448 	 * a lock to cancel, so this call always fails.
449 	 */
450 	result.stat.stat = unlock(&arg4, LOCK_CANCEL);
451 	return &result;
452 }
453 
454 void *
455 nlm_cancel_msg_1_svc(nlm_cancargs *arg, struct svc_req *rqstp)
456 {
457 	static nlm_res result;
458 	struct nlm4_lock arg4;
459 
460 	nlmtonlm4(&arg->alock, &arg4);
461 
462 	if (debug_level)
463 		log_from_addr("nlm_cancel_msg", rqstp);
464 
465 	result.cookie = arg->cookie;
466 	/*
467 	 * Since at present we never return 'nlm_blocked', there can never be
468 	 * a lock to cancel, so this call always fails.
469 	 */
470 	result.stat.stat = unlock(&arg4, LOCK_CANCEL);
471 	transmit_result(NLM_CANCEL_RES, &result, svc_getcaller(rqstp->rq_xprt));
472 	return NULL;
473 }
474 
475 /* nlm_unlock -------------------------------------------------------------- */
476 /*
477  * Purpose:	Release an existing lock
478  * Returns:	Always granted, unless during grace period
479  * Notes:	"no such lock" error condition is ignored, as the
480  *		protocol uses unreliable UDP datagrams, and may well
481  *		re-try an unlock that has already succeeded.
482  */
483 nlm_res *
484 nlm_unlock_1_svc(nlm_unlockargs *arg, struct svc_req *rqstp)
485 {
486 	static nlm_res result;
487 	struct nlm4_lock arg4;
488 
489 	nlmtonlm4(&arg->alock, &arg4);
490 
491 	if (debug_level)
492 		log_from_addr("nlm_unlock", rqstp);
493 
494 	result.stat.stat = unlock(&arg4, 0);
495 	result.cookie = arg->cookie;
496 
497 	return &result;
498 }
499 
500 void *
501 nlm_unlock_msg_1_svc(nlm_unlockargs *arg, struct svc_req *rqstp)
502 {
503 	static nlm_res result;
504 	struct nlm4_lock arg4;
505 
506 	nlmtonlm4(&arg->alock, &arg4);
507 
508 	if (debug_level)
509 		log_from_addr("nlm_unlock_msg", rqstp);
510 
511 	result.stat.stat = unlock(&arg4, 0);
512 	result.cookie = arg->cookie;
513 
514 	transmit_result(NLM_UNLOCK_RES, &result, svc_getcaller(rqstp->rq_xprt));
515 	return NULL;
516 }
517 
518 /* ------------------------------------------------------------------------- */
519 /*
520  * Client-side pseudo-RPCs for results.  Note that for the client there
521  * are only nlm_xxx_msg() versions of each call, since the 'real RPC'
522  * version returns the results in the RPC result, and so the client
523  * does not normally receive incoming RPCs.
524  *
525  * The exception to this is nlm_granted(), which is genuinely an RPC
526  * call from the server to the client - a 'call-back' in normal procedure
527  * call terms.
528  */
529 
530 /* nlm_granted ------------------------------------------------------------- */
531 /*
532  * Purpose:	Receive notification that formerly blocked lock now granted
533  * Returns:	always success ('granted')
534  * Notes:
535  */
536 nlm_res *
537 nlm_granted_1_svc(nlm_testargs *arg, struct svc_req *rqstp)
538 {
539 	static nlm_res result;
540 
541 	if (debug_level)
542 		log_from_addr("nlm_granted", rqstp);
543 
544 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
545 	result.cookie = arg->cookie;
546 
547 	result.stat.stat = nlm_granted;
548 	return &result;
549 }
550 
551 void *
552 nlm_granted_msg_1_svc(nlm_testargs *arg, struct svc_req *rqstp)
553 {
554 	static nlm_res result;
555 
556 	if (debug_level)
557 		log_from_addr("nlm_granted_msg", rqstp);
558 
559 	result.cookie = arg->cookie;
560 	result.stat.stat = nlm_granted;
561 	transmit_result(NLM_GRANTED_RES, &result, svc_getcaller(rqstp->rq_xprt));
562 	return NULL;
563 }
564 
565 /* nlm_test_res ------------------------------------------------------------ */
566 /*
567  * Purpose:	Accept result from earlier nlm_test_msg() call
568  * Returns:	Nothing
569  */
570 void *
571 /*ARGSUSED*/
572 nlm_test_res_1_svc(nlm_testres *arg, struct svc_req *rqstp)
573 {
574 	if (debug_level)
575 		log_from_addr("nlm_test_res", rqstp);
576 	return NULL;
577 }
578 
579 /* nlm_lock_res ------------------------------------------------------------ */
580 /*
581  * Purpose:	Accept result from earlier nlm_lock_msg() call
582  * Returns:	Nothing
583  */
584 void *
585 /*ARGSUSED*/
586 nlm_lock_res_1_svc(nlm_res *arg, struct svc_req *rqstp)
587 {
588 	if (debug_level)
589 		log_from_addr("nlm_lock_res", rqstp);
590 
591 	return NULL;
592 }
593 
594 /* nlm_cancel_res ---------------------------------------------------------- */
595 /*
596  * Purpose:	Accept result from earlier nlm_cancel_msg() call
597  * Returns:	Nothing
598  */
599 void *
600 /*ARGSUSED*/
601 nlm_cancel_res_1_svc(nlm_res *arg, struct svc_req *rqstp)
602 {
603 	if (debug_level)
604 		log_from_addr("nlm_cancel_res", rqstp);
605 	return NULL;
606 }
607 
608 /* nlm_unlock_res ---------------------------------------------------------- */
609 /*
610  * Purpose:	Accept result from earlier nlm_unlock_msg() call
611  * Returns:	Nothing
612  */
613 void *
614 /*ARGSUSED*/
615 nlm_unlock_res_1_svc(nlm_res *arg, struct svc_req *rqstp)
616 {
617 	if (debug_level)
618 		log_from_addr("nlm_unlock_res", rqstp);
619 	return NULL;
620 }
621 
622 /* nlm_granted_res --------------------------------------------------------- */
623 /*
624  * Purpose:	Accept result from earlier nlm_granted_msg() call
625  * Returns:	Nothing
626  */
627 void *
628 /*ARGSUSED*/
629 nlm_granted_res_1_svc(nlm_res *arg, struct svc_req *rqstp)
630 {
631 	if (debug_level)
632 		log_from_addr("nlm_granted_res", rqstp);
633 	return NULL;
634 }
635 
636 /* ------------------------------------------------------------------------- */
637 /*
638  * Calls for PCNFS locking (aka non-monitored locking, no involvement
639  * of rpc.statd).
640  *
641  * These are all genuine RPCs - no nlm_xxx_msg() nonsense here.
642  */
643 
644 /* nlm_share --------------------------------------------------------------- */
645 /*
646  * Purpose:	Establish a DOS-style lock
647  * Returns:	success or failure
648  * Notes:	Blocking locks are not supported - client is expected
649  *		to retry if required.
650  */
651 nlm_shareres *
652 nlm_share_3_svc(nlm_shareargs *arg, struct svc_req *rqstp)
653 {
654 	static nlm_shareres result;
655 
656 	if (debug_level)
657 		log_from_addr("nlm_share", rqstp);
658 
659 	result.cookie = arg->cookie;
660 	result.stat = nlm_granted;
661 	result.sequence = 1234356;	/* X/Open says this field is ignored? */
662 	return &result;
663 }
664 
665 /* nlm_unshare ------------------------------------------------------------ */
666 /*
667  * Purpose:	Release a DOS-style lock
668  * Returns:	nlm_granted, unless in grace period
669  * Notes:
670  */
671 nlm_shareres *
672 nlm_unshare_3_svc(nlm_shareargs *arg, struct svc_req *rqstp)
673 {
674 	static nlm_shareres result;
675 
676 	if (debug_level)
677 		log_from_addr("nlm_unshare", rqstp);
678 
679 	result.cookie = arg->cookie;
680 	result.stat = nlm_granted;
681 	result.sequence = 1234356;	/* X/Open says this field is ignored? */
682 	return &result;
683 }
684 
685 /* nlm_nm_lock ------------------------------------------------------------ */
686 /*
687  * Purpose:	non-monitored version of nlm_lock()
688  * Returns:	as for nlm_lock()
689  * Notes:	These locks are in the same style as the standard nlm_lock,
690  *		but the rpc.statd should not be called to establish a
691  *		monitor for the client machine, since that machine is
692  *		declared not to be running a rpc.statd, and so would not
693  *		respond to the statd protocol.
694  */
695 nlm_res *
696 nlm_nm_lock_3_svc(nlm_lockargs *arg, struct svc_req *rqstp)
697 {
698 	static nlm_res result;
699 
700 	if (debug_level)
701 		log_from_addr("nlm_nm_lock", rqstp);
702 
703 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
704 	result.cookie = arg->cookie;
705 	result.stat.stat = nlm_granted;
706 	return &result;
707 }
708 
709 /* nlm_free_all ------------------------------------------------------------ */
710 /*
711  * Purpose:	Release all locks held by a named client
712  * Returns:	Nothing
713  * Notes:	Potential denial of service security problem here - the
714  *		locks to be released are specified by a host name, independent
715  *		of the address from which the request has arrived.
716  *		Should probably be rejected if the named host has been
717  *		using monitored locks.
718  */
719 void *
720 /*ARGSUSED*/
721 nlm_free_all_3_svc(nlm_notify *arg, struct svc_req *rqstp)
722 {
723 	static char dummy;
724 
725 	if (debug_level)
726 		log_from_addr("nlm_free_all", rqstp);
727 	return &dummy;
728 }
729 
730 /* calls for nlm version 4 (NFSv3) */
731 /* nlm_test ---------------------------------------------------------------- */
732 /*
733  * Purpose:	Test whether a specified lock would be granted if requested
734  * Returns:	nlm_granted (or error code)
735  * Notes:
736  */
737 nlm4_testres *
738 nlm4_test_4_svc(nlm4_testargs *arg, struct svc_req *rqstp)
739 {
740 	static nlm4_testres result;
741 	struct nlm4_holder *holder;
742 
743 	if (debug_level)
744 		log_from_addr("nlm4_test", rqstp);
745 
746 	holder = testlock(&arg->alock, LOCK_V4);
747 
748 	/*
749 	 * Copy the cookie from the argument into the result.  Note that this
750 	 * is slightly hazardous, as the structure contains a pointer to a
751 	 * malloc()ed buffer that will get freed by the caller.  However, the
752 	 * main function transmits the result before freeing the argument
753 	 * so it is in fact safe.
754 	 */
755 	result.cookie = arg->cookie;
756 	if (holder == NULL) {
757 		result.stat.stat = nlm4_granted;
758 	} else {
759 		result.stat.stat = nlm4_denied;
760 		memcpy(&result.stat.nlm4_testrply_u.holder, holder,
761 		    sizeof(struct nlm4_holder));
762 	}
763 	return &result;
764 }
765 
766 void *
767 nlm4_test_msg_4_svc(nlm4_testargs *arg, struct svc_req *rqstp)
768 {
769 	nlm4_testres result;
770 	static char dummy;
771 	struct sockaddr_in *addr;
772 	CLIENT *cli;
773 	int success;
774 	struct timeval timeo;
775 	struct nlm4_holder *holder;
776 
777 	if (debug_level)
778 		log_from_addr("nlm4_test_msg", rqstp);
779 
780 	holder = testlock(&arg->alock, LOCK_V4);
781 
782 	result.cookie = arg->cookie;
783 	if (holder == NULL) {
784 		result.stat.stat = nlm4_granted;
785 	} else {
786 		result.stat.stat = nlm4_denied;
787 		memcpy(&result.stat.nlm4_testrply_u.holder, holder,
788 		    sizeof(struct nlm4_holder));
789 	}
790 
791 	/*
792 	 * nlm_test has different result type to the other operations, so
793 	 * can't use transmit4_result() in this case
794 	 */
795 	addr = svc_getcaller(rqstp->rq_xprt);
796 	if ((cli = get_client(addr, NLM_VERS4)) != NULL) {
797 		/* No timeout - not expecting response */
798 		timerclear(&timeo);
799 
800 		success = clnt_call(cli, NLM4_TEST_RES, xdr_nlm4_testres,
801 		    &result, xdr_void, &dummy, timeo);
802 
803 		if (debug_level > 2)
804 			syslog(LOG_DEBUG, "clnt_call returns %d", success);
805 	}
806 	return NULL;
807 }
808 
809 /* nlm_lock ---------------------------------------------------------------- */
810 /*
811  * Purposes:	Establish a lock
812  * Returns:	granted, denied or blocked
813  * Notes:	*** grace period support missing
814  */
815 nlm4_res *
816 nlm4_lock_4_svc(nlm4_lockargs *arg, struct svc_req *rqstp)
817 {
818 	static nlm4_res result;
819 
820 	if (debug_level)
821 		log_from_addr("nlm4_lock", rqstp);
822 
823 	/* copy cookie from arg to result.  See comment in nlm_test_4() */
824 	result.cookie = arg->cookie;
825 
826 	result.stat.stat = getlock(arg, rqstp, LOCK_MON | LOCK_V4);
827 	return &result;
828 }
829 
830 void *
831 nlm4_lock_msg_4_svc(nlm4_lockargs *arg, struct svc_req *rqstp)
832 {
833 	static nlm4_res result;
834 
835 	if (debug_level)
836 		log_from_addr("nlm4_lock_msg", rqstp);
837 
838 	result.cookie = arg->cookie;
839 	result.stat.stat = getlock(arg, rqstp, LOCK_MON | LOCK_ASYNC | LOCK_V4);
840 	transmit4_result(NLM4_LOCK_RES, &result, svc_getcaller(rqstp->rq_xprt));
841 
842 	return NULL;
843 }
844 
845 /* nlm_cancel -------------------------------------------------------------- */
846 /*
847  * Purpose:	Cancel a blocked lock request
848  * Returns:	granted or denied
849  * Notes:
850  */
851 nlm4_res *
852 nlm4_cancel_4_svc(nlm4_cancargs *arg, struct svc_req *rqstp)
853 {
854 	static nlm4_res result;
855 
856 	if (debug_level)
857 		log_from_addr("nlm4_cancel", rqstp);
858 
859 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
860 	result.cookie = arg->cookie;
861 
862 	/*
863 	 * Since at present we never return 'nlm_blocked', there can never be
864 	 * a lock to cancel, so this call always fails.
865 	 */
866 	result.stat.stat = unlock(&arg->alock, LOCK_CANCEL);
867 	return &result;
868 }
869 
870 void *
871 nlm4_cancel_msg_4_svc(nlm4_cancargs *arg, struct svc_req *rqstp)
872 {
873 	static nlm4_res result;
874 
875 	if (debug_level)
876 		log_from_addr("nlm4_cancel_msg", rqstp);
877 
878 	result.cookie = arg->cookie;
879 	/*
880 	 * Since at present we never return 'nlm_blocked', there can never be
881 	 * a lock to cancel, so this call always fails.
882 	 */
883 	result.stat.stat = unlock(&arg->alock, LOCK_CANCEL | LOCK_V4);
884 	transmit4_result(NLM4_CANCEL_RES, &result, svc_getcaller(rqstp->rq_xprt));
885 
886 	return NULL;
887 }
888 
889 /* nlm_unlock -------------------------------------------------------------- */
890 /*
891  * Purpose:	Release an existing lock
892  * Returns:	Always granted, unless during grace period
893  * Notes:	"no such lock" error condition is ignored, as the
894  *		protocol uses unreliable UDP datagrams, and may well
895  *		re-try an unlock that has already succeeded.
896  */
897 nlm4_res *
898 nlm4_unlock_4_svc(nlm4_unlockargs *arg, struct svc_req *rqstp)
899 {
900 	static nlm4_res result;
901 
902 	if (debug_level)
903 		log_from_addr("nlm4_unlock", rqstp);
904 
905 	result.stat.stat = unlock(&arg->alock, LOCK_V4);
906 	result.cookie = arg->cookie;
907 
908 	return &result;
909 }
910 
911 void *
912 nlm4_unlock_msg_4_svc(nlm4_unlockargs *arg, struct svc_req *rqstp)
913 {
914 	static nlm4_res result;
915 
916 	if (debug_level)
917 		log_from_addr("nlm4_unlock_msg", rqstp);
918 
919 	result.stat.stat = unlock(&arg->alock, LOCK_V4);
920 	result.cookie = arg->cookie;
921 
922 	transmit4_result(NLM4_UNLOCK_RES, &result, svc_getcaller(rqstp->rq_xprt));
923 	return NULL;
924 }
925 
926 /* ------------------------------------------------------------------------- */
927 /*
928  * Client-side pseudo-RPCs for results.  Note that for the client there
929  * are only nlm_xxx_msg() versions of each call, since the 'real RPC'
930  * version returns the results in the RPC result, and so the client
931  * does not normally receive incoming RPCs.
932  *
933  * The exception to this is nlm_granted(), which is genuinely an RPC
934  * call from the server to the client - a 'call-back' in normal procedure
935  * call terms.
936  */
937 
938 /* nlm_granted ------------------------------------------------------------- */
939 /*
940  * Purpose:	Receive notification that formerly blocked lock now granted
941  * Returns:	always success ('granted')
942  * Notes:
943  */
944 nlm4_res *
945 nlm4_granted_4_svc(nlm4_testargs *arg, struct svc_req *rqstp)
946 {
947 	static nlm4_res result;
948 
949 	if (debug_level)
950 		log_from_addr("nlm4_granted", rqstp);
951 
952 	/* copy cookie from arg to result.  See comment in nlm_test_1() */
953 	result.cookie = arg->cookie;
954 
955 	result.stat.stat = nlm4_granted;
956 	return &result;
957 }
958 
959 void *
960 nlm4_granted_msg_4_svc(nlm4_testargs *arg, struct svc_req *rqstp)
961 {
962 	static nlm4_res result;
963 
964 	if (debug_level)
965 		log_from_addr("nlm4_granted_msg", rqstp);
966 
967 	result.cookie = arg->cookie;
968 	result.stat.stat = nlm4_granted;
969 	transmit4_result(NLM4_GRANTED_RES, &result, svc_getcaller(rqstp->rq_xprt));
970 	return NULL;
971 }
972 
973 /* nlm_test_res ------------------------------------------------------------ */
974 /*
975  * Purpose:	Accept result from earlier nlm_test_msg() call
976  * Returns:	Nothing
977  */
978 void *
979 /*ARGSUSED*/
980 nlm4_test_res_4_svc(nlm4_testres *arg, struct svc_req *rqstp)
981 {
982 	if (debug_level)
983 		log_from_addr("nlm4_test_res", rqstp);
984 	return NULL;
985 }
986 
987 /* nlm_lock_res ------------------------------------------------------------ */
988 /*
989  * Purpose:	Accept result from earlier nlm_lock_msg() call
990  * Returns:	Nothing
991  */
992 void *
993 /*ARGSUSED*/
994 nlm4_lock_res_4_svc(nlm4_res *arg, struct svc_req *rqstp)
995 {
996 	if (debug_level)
997 		log_from_addr("nlm4_lock_res", rqstp);
998 
999 	return NULL;
1000 }
1001 
1002 /* nlm_cancel_res ---------------------------------------------------------- */
1003 /*
1004  * Purpose:	Accept result from earlier nlm_cancel_msg() call
1005  * Returns:	Nothing
1006  */
1007 void *
1008 /*ARGSUSED*/
1009 nlm4_cancel_res_4_svc(nlm4_res *arg, struct svc_req *rqstp)
1010 {
1011 	if (debug_level)
1012 		log_from_addr("nlm4_cancel_res", rqstp);
1013 	return NULL;
1014 }
1015 
1016 /* nlm_unlock_res ---------------------------------------------------------- */
1017 /*
1018  * Purpose:	Accept result from earlier nlm_unlock_msg() call
1019  * Returns:	Nothing
1020  */
1021 void *
1022 /*ARGSUSED*/
1023 nlm4_unlock_res_4_svc(nlm4_res *arg, struct svc_req *rqstp)
1024 {
1025 	if (debug_level)
1026 		log_from_addr("nlm4_unlock_res", rqstp);
1027 	return NULL;
1028 }
1029 
1030 /* nlm_granted_res --------------------------------------------------------- */
1031 /*
1032  * Purpose:	Accept result from earlier nlm_granted_msg() call
1033  * Returns:	Nothing
1034  */
1035 void *
1036 /*ARGSUSED*/
1037 nlm4_granted_res_4_svc(nlm4_res *arg, struct svc_req *rqstp)
1038 {
1039 	if (debug_level)
1040 		log_from_addr("nlm4_granted_res", rqstp);
1041 	return NULL;
1042 }
1043 
1044 /* ------------------------------------------------------------------------- */
1045 /*
1046  * Calls for PCNFS locking (aka non-monitored locking, no involvement
1047  * of rpc.statd).
1048  *
1049  * These are all genuine RPCs - no nlm_xxx_msg() nonsense here.
1050  */
1051 
1052 /* nlm_share --------------------------------------------------------------- */
1053 /*
1054  * Purpose:	Establish a DOS-style lock
1055  * Returns:	success or failure
1056  * Notes:	Blocking locks are not supported - client is expected
1057  *		to retry if required.
1058  */
1059 nlm4_shareres *
1060 nlm4_share_4_svc(nlm4_shareargs *arg, struct svc_req *rqstp)
1061 {
1062 	static nlm4_shareres result;
1063 
1064 	if (debug_level)
1065 		log_from_addr("nlm4_share", rqstp);
1066 
1067 	result.cookie = arg->cookie;
1068 	result.stat = nlm4_granted;
1069 	result.sequence = 1234356;	/* X/Open says this field is ignored? */
1070 	return &result;
1071 }
1072 
1073 /* nlm4_unshare ------------------------------------------------------------ */
1074 /*
1075  * Purpose:	Release a DOS-style lock
1076  * Returns:	nlm_granted, unless in grace period
1077  * Notes:
1078  */
1079 nlm4_shareres *
1080 nlm4_unshare_4_svc(nlm4_shareargs *arg, struct svc_req *rqstp)
1081 {
1082 	static nlm4_shareres result;
1083 
1084 	if (debug_level)
1085 		log_from_addr("nlm_unshare", rqstp);
1086 
1087 	result.cookie = arg->cookie;
1088 	result.stat = nlm4_granted;
1089 	result.sequence = 1234356;	/* X/Open says this field is ignored? */
1090 	return &result;
1091 }
1092 
1093 /* nlm4_nm_lock ------------------------------------------------------------ */
1094 /*
1095  * Purpose:	non-monitored version of nlm4_lock()
1096  * Returns:	as for nlm4_lock()
1097  * Notes:	These locks are in the same style as the standard nlm4_lock,
1098  *		but the rpc.statd should not be called to establish a
1099  *		monitor for the client machine, since that machine is
1100  *		declared not to be running a rpc.statd, and so would not
1101  *		respond to the statd protocol.
1102  */
1103 nlm4_res *
1104 nlm4_nm_lock_4_svc(nlm4_lockargs *arg, struct svc_req *rqstp)
1105 {
1106 	static nlm4_res result;
1107 
1108 	if (debug_level)
1109 		log_from_addr("nlm4_nm_lock", rqstp);
1110 
1111 	/* copy cookie from arg to result.  See comment in nlm4_test_1() */
1112 	result.cookie = arg->cookie;
1113 	result.stat.stat = nlm4_granted;
1114 	return &result;
1115 }
1116 
1117 /* nlm4_free_all ------------------------------------------------------------ */
1118 /*
1119  * Purpose:	Release all locks held by a named client
1120  * Returns:	Nothing
1121  * Notes:	Potential denial of service security problem here - the
1122  *		locks to be released are specified by a host name, independent
1123  *		of the address from which the request has arrived.
1124  *		Should probably be rejected if the named host has been
1125  *		using monitored locks.
1126  */
1127 void *
1128 /*ARGSUSED*/
1129 nlm4_free_all_4_svc(nlm_notify *arg, struct svc_req *rqstp)
1130 {
1131 	static char dummy;
1132 
1133 	if (debug_level)
1134 		log_from_addr("nlm4_free_all", rqstp);
1135 	return &dummy;
1136 }
1137 
1138 /* nlm_sm_notify --------------------------------------------------------- */
1139 /*
1140  * Purpose:	called by rpc.statd when a monitored host state changes.
1141  * Returns:	Nothing
1142  */
1143 void *
1144 /*ARGSUSED*/
1145 nlm_sm_notify_0_svc(struct nlm_sm_status *arg, struct svc_req *rqstp)
1146 {
1147 	static char dummy;
1148 	notify(arg->mon_name, arg->state);
1149 	return &dummy;
1150 }
1151