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