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 ([email protected]). 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
log_from_addr(const char * fun_name,struct svc_req * req)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
log_netobj(netobj * obj)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
addrcmp(struct sockaddr * sa1,struct sockaddr * sa2)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 *
get_client(struct sockaddr * host_addr,rpcvers_t vers)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
transmit_result(int opcode,nlm_res * result,struct sockaddr * addr)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
transmit4_result(int opcode,nlm4_res * result,struct sockaddr * addr)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
nlmtonlm4(struct nlm_lock * arg,struct nlm4_lock * arg4)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 *
nlm_test_1_svc(nlm_testargs * arg,struct svc_req * rqstp)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 *
nlm_test_msg_1_svc(nlm_testargs * arg,struct svc_req * rqstp)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 *
nlm_lock_1_svc(nlm_lockargs * arg,struct svc_req * rqstp)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 *
nlm_lock_msg_1_svc(nlm_lockargs * arg,struct svc_req * rqstp)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 *
nlm_cancel_1_svc(nlm_cancargs * arg,struct svc_req * rqstp)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 *
nlm_cancel_msg_1_svc(nlm_cancargs * arg,struct svc_req * rqstp)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 *
nlm_unlock_1_svc(nlm_unlockargs * arg,struct svc_req * rqstp)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 *
nlm_unlock_msg_1_svc(nlm_unlockargs * arg,struct svc_req * rqstp)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 *
nlm_granted_1_svc(nlm_testargs * arg,struct svc_req * rqstp)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 *
nlm_granted_msg_1_svc(nlm_testargs * arg,struct svc_req * rqstp)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 *
nlm_test_res_1_svc(nlm_testres * arg,struct svc_req * rqstp)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 *
nlm_lock_res_1_svc(nlm_res * arg,struct svc_req * rqstp)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 *
nlm_cancel_res_1_svc(nlm_res * arg __unused,struct svc_req * rqstp)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 *
nlm_unlock_res_1_svc(nlm_res * arg,struct svc_req * rqstp)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 *
nlm_granted_res_1_svc(nlm_res * arg __unused,struct svc_req * rqstp)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 *
nlm_share_3_svc(nlm_shareargs * arg,struct svc_req * rqstp)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 *
nlm_unshare_3_svc(nlm_shareargs * arg,struct svc_req * rqstp)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 *
nlm_nm_lock_3_svc(nlm_lockargs * arg,struct svc_req * rqstp)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 *
nlm_free_all_3_svc(nlm_notify * arg __unused,struct svc_req * rqstp)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 *
nlm4_test_4_svc(nlm4_testargs * arg,struct svc_req * rqstp)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 *
nlm4_test_msg_4_svc(nlm4_testargs * arg,struct svc_req * rqstp)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 *
nlm4_lock_4_svc(nlm4_lockargs * arg,struct svc_req * rqstp)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 *
nlm4_lock_msg_4_svc(nlm4_lockargs * arg,struct svc_req * rqstp)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 *
nlm4_cancel_4_svc(nlm4_cancargs * arg,struct svc_req * rqstp)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 *
nlm4_cancel_msg_4_svc(nlm4_cancargs * arg,struct svc_req * rqstp)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 *
nlm4_unlock_4_svc(nlm4_unlockargs * arg,struct svc_req * rqstp)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 *
nlm4_unlock_msg_4_svc(nlm4_unlockargs * arg,struct svc_req * rqstp)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 *
nlm4_granted_4_svc(nlm4_testargs * arg,struct svc_req * rqstp)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 *
nlm4_granted_msg_4_svc(nlm4_testargs * arg,struct svc_req * rqstp)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 *
nlm4_test_res_4_svc(nlm4_testres * arg,struct svc_req * rqstp)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 *
nlm4_lock_res_4_svc(nlm4_res * arg,struct svc_req * rqstp)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 *
nlm4_cancel_res_4_svc(nlm4_res * arg __unused,struct svc_req * rqstp)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 *
nlm4_unlock_res_4_svc(nlm4_res * arg __unused,struct svc_req * rqstp)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 *
nlm4_granted_res_4_svc(nlm4_res * arg __unused,struct svc_req * rqstp)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 *
nlm4_share_4_svc(nlm4_shareargs * arg,struct svc_req * rqstp)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 *
nlm4_unshare_4_svc(nlm4_shareargs * arg,struct svc_req * rqstp)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 *
nlm4_nm_lock_4_svc(nlm4_lockargs * arg,struct svc_req * rqstp)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 *
nlm4_free_all_4_svc(struct nlm4_notify * arg __unused,struct svc_req * rqstp)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 *
nlm_sm_notify_0_svc(struct nlm_sm_status * arg,struct svc_req * rqstp __unused)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