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