]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - usr.sbin/rpc.lockd/lock_proc.c
MFC r320093: Check return value of seteuid() and bail out if we fail.
[FreeBSD/stable/10.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 < maxlen;
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         if (seteuid(0) != 0) {
287                 syslog(LOG_ERR, "seteuid(0) failed");
288                 return NULL;
289         }
290
291         /*
292          * Bind the client FD to a reserved port.
293          * Some NFS servers reject any NLM request from a non-reserved port. 
294          */ 
295         bindresvport(clnt_fd, NULL);
296
297         /* Drop root privileges again. */
298         if (seteuid(old_euid) != 0) {
299                 syslog(LOG_ERR, "seteuid(%d) failed", old_euid);
300                 return NULL;
301         }
302
303         /* Success - update the cache entry */
304         clnt_cache_ptr[clnt_cache_next_to_use] = client;
305         memcpy(&clnt_cache_addr[clnt_cache_next_to_use], host_addr,
306             host_addr->sa_len);
307         clnt_cache_vers[clnt_cache_next_to_use] = vers;
308         clnt_cache_time[clnt_cache_next_to_use] = time_now.tv_sec;
309         if (++clnt_cache_next_to_use >= CLIENT_CACHE_SIZE)
310                 clnt_cache_next_to_use = 0;
311
312         /*
313          * Disable the default timeout, so we can specify our own in calls
314          * to clnt_call().  (Note that the timeout is a different concept
315          * from the retry period set in clnt_udp_create() above.)
316          */
317         retry_time.tv_sec = -1;
318         retry_time.tv_usec = -1;
319         clnt_control(client, CLSET_TIMEOUT, (char *)&retry_time);
320
321         if (debug_level > 3)
322                 syslog(LOG_DEBUG, "Created CLIENT* for %s", host);
323         return client;
324 }
325
326
327 /* transmit_result --------------------------------------------------------- */
328 /*
329  * Purpose:     Transmit result for nlm_xxx_msg pseudo-RPCs
330  * Returns:     Nothing - we have no idea if the datagram got there
331  * Notes:       clnt_call() will always fail (with timeout) as we are
332  *              calling it with timeout 0 as a hack to just issue a datagram
333  *              without expecting a result
334  */
335 void
336 transmit_result(opcode, result, addr)
337         int opcode;
338         nlm_res *result;
339         struct sockaddr *addr;
340 {
341         static char dummy;
342         CLIENT *cli;
343         struct timeval timeo;
344         int success;
345
346         if ((cli = get_client(addr, NLM_VERS)) != NULL) {
347                 timeo.tv_sec = 0; /* No timeout - not expecting response */
348                 timeo.tv_usec = 0;
349
350                 success = clnt_call(cli, opcode, (xdrproc_t)xdr_nlm_res, result,
351                     (xdrproc_t)xdr_void, &dummy, timeo);
352
353                 if (debug_level > 2)
354                         syslog(LOG_DEBUG, "clnt_call returns %d(%s)",
355                             success, clnt_sperrno(success));
356         }
357 }
358 /* transmit4_result --------------------------------------------------------- */
359 /*
360  * Purpose:     Transmit result for nlm4_xxx_msg pseudo-RPCs
361  * Returns:     Nothing - we have no idea if the datagram got there
362  * Notes:       clnt_call() will always fail (with timeout) as we are
363  *              calling it with timeout 0 as a hack to just issue a datagram
364  *              without expecting a result
365  */
366 void
367 transmit4_result(opcode, result, addr)
368         int opcode;
369         nlm4_res *result;
370         struct sockaddr *addr;
371 {
372         static char dummy;
373         CLIENT *cli;
374         struct timeval timeo;
375         int success;
376
377         if ((cli = get_client(addr, NLM_VERS4)) != NULL) {
378                 timeo.tv_sec = 0; /* No timeout - not expecting response */
379                 timeo.tv_usec = 0;
380
381                 success = clnt_call(cli, opcode,
382                     (xdrproc_t)xdr_nlm4_res, result,
383                     (xdrproc_t)xdr_void, &dummy, timeo);
384
385                 if (debug_level > 2)
386                         syslog(LOG_DEBUG, "clnt_call returns %d(%s)",
387                             success, clnt_sperrno(success));
388         }
389 }
390
391 /*
392  * converts a struct nlm_lock to struct nlm4_lock
393  */
394 static void nlmtonlm4(struct nlm_lock *, struct nlm4_lock *);
395 static void
396 nlmtonlm4(arg, arg4)
397         struct nlm_lock *arg;
398         struct nlm4_lock *arg4;
399 {
400         arg4->caller_name = arg->caller_name;
401         arg4->fh = arg->fh;
402         arg4->oh = arg->oh;
403         arg4->svid = arg->svid;
404         arg4->l_offset = arg->l_offset;
405         arg4->l_len = arg->l_len;
406 }
407 /* ------------------------------------------------------------------------- */
408 /*
409  * Functions for Unix<->Unix locking (ie. monitored locking, with rpc.statd
410  * involved to ensure reclaim of locks after a crash of the "stateless"
411  * server.
412  *
413  * These all come in two flavours - nlm_xxx() and nlm_xxx_msg().
414  * The first are standard RPCs with argument and result.
415  * The nlm_xxx_msg() calls implement exactly the same functions, but
416  * use two pseudo-RPCs (one in each direction).  These calls are NOT
417  * standard use of the RPC protocol in that they do not return a result
418  * at all (NB. this is quite different from returning a void result).
419  * The effect of this is to make the nlm_xxx_msg() calls simple unacknowledged
420  * datagrams, requiring higher-level code to perform retries.
421  *
422  * Despite the disadvantages of the nlm_xxx_msg() approach (some of which
423  * are documented in the comments to get_client() above), this is the
424  * interface used by all current commercial NFS implementations
425  * [Solaris, SCO, AIX etc.].  This is presumed to be because these allow
426  * implementations to continue using the standard RPC libraries, while
427  * avoiding the block-until-result nature of the library interface.
428  *
429  * No client implementations have been identified so far that make use
430  * of the true RPC version (early SunOS releases would be a likely candidate
431  * for testing).
432  */
433
434 /* nlm_test ---------------------------------------------------------------- */
435 /*
436  * Purpose:     Test whether a specified lock would be granted if requested
437  * Returns:     nlm_granted (or error code)
438  * Notes:
439  */
440 nlm_testres *
441 nlm_test_1_svc(arg, rqstp)
442         nlm_testargs *arg;
443         struct svc_req *rqstp;
444 {
445         static nlm_testres res;
446         struct nlm4_lock arg4;
447         struct nlm4_holder *holder;
448         nlmtonlm4(&arg->alock, &arg4);
449
450         if (debug_level)
451                 log_from_addr("nlm_test", rqstp);
452
453         holder = testlock(&arg4, arg->exclusive, 0);
454         /*
455          * Copy the cookie from the argument into the result.  Note that this
456          * is slightly hazardous, as the structure contains a pointer to a
457          * malloc()ed buffer that will get freed by the caller.  However, the
458          * main function transmits the result before freeing the argument
459          * so it is in fact safe.
460          */
461         res.cookie = arg->cookie;
462         if (holder == NULL) {
463                 res.stat.stat = nlm_granted;
464         } else {
465                 res.stat.stat = nlm_denied;
466                 memcpy(&res.stat.nlm_testrply_u.holder, holder,
467                     sizeof(struct nlm_holder));
468                 res.stat.nlm_testrply_u.holder.l_offset = holder->l_offset;
469                 res.stat.nlm_testrply_u.holder.l_len = holder->l_len;
470         }
471         return (&res);
472 }
473
474 void *
475 nlm_test_msg_1_svc(arg, rqstp)
476         nlm_testargs *arg;
477         struct svc_req *rqstp;
478 {
479         nlm_testres res;
480         static char dummy;
481         struct sockaddr *addr;
482         CLIENT *cli;
483         int success;
484         struct timeval timeo;
485         struct nlm4_lock arg4;
486         struct nlm4_holder *holder;
487
488         nlmtonlm4(&arg->alock, &arg4);
489
490         if (debug_level)
491                 log_from_addr("nlm_test_msg", rqstp);
492
493         holder = testlock(&arg4, arg->exclusive, 0);
494
495         res.cookie = arg->cookie;
496         if (holder == NULL) {
497                 res.stat.stat = nlm_granted;
498         } else {
499                 res.stat.stat = nlm_denied;
500                 memcpy(&res.stat.nlm_testrply_u.holder, holder,
501                     sizeof(struct nlm_holder));
502                 res.stat.nlm_testrply_u.holder.l_offset = holder->l_offset;
503                 res.stat.nlm_testrply_u.holder.l_len = holder->l_len;
504         }
505
506         /*
507          * nlm_test has different result type to the other operations, so
508          * can't use transmit_result() in this case
509          */
510         addr = svc_getrpccaller(rqstp->rq_xprt)->buf;
511         if ((cli = get_client(addr, NLM_VERS)) != NULL) {
512                 timeo.tv_sec = 0; /* No timeout - not expecting response */
513                 timeo.tv_usec = 0;
514
515                 success = clnt_call(cli, NLM_TEST_RES,
516                     (xdrproc_t)xdr_nlm_testres, &res,
517                     (xdrproc_t)xdr_void, &dummy, timeo);
518
519                 if (debug_level > 2)
520                         syslog(LOG_DEBUG, "clnt_call returns %d", success);
521         }
522         return (NULL);
523 }
524
525 /* nlm_lock ---------------------------------------------------------------- */
526 /*
527  * Purposes:    Establish a lock
528  * Returns:     granted, denied or blocked
529  * Notes:       *** grace period support missing
530  */
531 nlm_res *
532 nlm_lock_1_svc(arg, rqstp)
533         nlm_lockargs *arg;
534         struct svc_req *rqstp;
535 {
536         static nlm_res res;
537         struct nlm4_lockargs arg4;
538         nlmtonlm4(&arg->alock, &arg4.alock);
539         arg4.cookie = arg->cookie;
540         arg4.block = arg->block;
541         arg4.exclusive = arg->exclusive;
542         arg4.reclaim = arg->reclaim;
543         arg4.state = arg->state;
544
545         if (debug_level)
546                 log_from_addr("nlm_lock", rqstp);
547
548         /* copy cookie from arg to result.  See comment in nlm_test_1() */
549         res.cookie = arg->cookie;
550
551         res.stat.stat = getlock(&arg4, rqstp, LOCK_MON);
552         return (&res);
553 }
554
555 void *
556 nlm_lock_msg_1_svc(arg, rqstp)
557         nlm_lockargs *arg;
558         struct svc_req *rqstp;
559 {
560         static nlm_res res;
561         struct nlm4_lockargs arg4;
562
563         nlmtonlm4(&arg->alock, &arg4.alock);
564         arg4.cookie = arg->cookie;
565         arg4.block = arg->block;
566         arg4.exclusive = arg->exclusive;
567         arg4.reclaim = arg->reclaim;
568         arg4.state = arg->state;
569
570         if (debug_level)
571                 log_from_addr("nlm_lock_msg", rqstp);
572
573         res.cookie = arg->cookie;
574         res.stat.stat = getlock(&arg4, rqstp, LOCK_ASYNC | LOCK_MON);
575         transmit_result(NLM_LOCK_RES, &res, getrpcaddr(rqstp));
576
577         return (NULL);
578 }
579
580 /* nlm_cancel -------------------------------------------------------------- */
581 /*
582  * Purpose:     Cancel a blocked lock request
583  * Returns:     granted or denied
584  * Notes:
585  */
586 nlm_res *
587 nlm_cancel_1_svc(arg, rqstp)
588         nlm_cancargs *arg;
589         struct svc_req *rqstp;
590 {
591         static nlm_res res;
592         struct nlm4_lock arg4;
593
594         nlmtonlm4(&arg->alock, &arg4);
595
596         if (debug_level)
597                 log_from_addr("nlm_cancel", rqstp);
598
599         /* copy cookie from arg to result.  See comment in nlm_test_1() */
600         res.cookie = arg->cookie;
601
602         /*
603          * Since at present we never return 'nlm_blocked', there can never be
604          * a lock to cancel, so this call always fails.
605          */
606         res.stat.stat = unlock(&arg4, LOCK_CANCEL);
607         return (&res);
608 }
609
610 void *
611 nlm_cancel_msg_1_svc(arg, rqstp)
612         nlm_cancargs *arg;
613         struct svc_req *rqstp;
614 {
615         static nlm_res res;
616         struct nlm4_lock arg4;
617
618         nlmtonlm4(&arg->alock, &arg4);
619
620         if (debug_level)
621                 log_from_addr("nlm_cancel_msg", rqstp);
622
623         res.cookie = arg->cookie;
624         /*
625          * Since at present we never return 'nlm_blocked', there can never be
626          * a lock to cancel, so this call always fails.
627          */
628         res.stat.stat = unlock(&arg4, LOCK_CANCEL);
629         transmit_result(NLM_CANCEL_RES, &res, getrpcaddr(rqstp));
630         return (NULL);
631 }
632
633 /* nlm_unlock -------------------------------------------------------------- */
634 /*
635  * Purpose:     Release an existing lock
636  * Returns:     Always granted, unless during grace period
637  * Notes:       "no such lock" error condition is ignored, as the
638  *              protocol uses unreliable UDP datagrams, and may well
639  *              re-try an unlock that has already succeeded.
640  */
641 nlm_res *
642 nlm_unlock_1_svc(arg, rqstp)
643         nlm_unlockargs *arg;
644         struct svc_req *rqstp;
645 {
646         static nlm_res res;
647         struct nlm4_lock arg4;
648
649         nlmtonlm4(&arg->alock, &arg4);
650
651         if (debug_level)
652                 log_from_addr("nlm_unlock", rqstp);
653
654         res.stat.stat = unlock(&arg4, 0);
655         res.cookie = arg->cookie;
656
657         return (&res);
658 }
659
660 void *
661 nlm_unlock_msg_1_svc(arg, rqstp)
662         nlm_unlockargs *arg;
663         struct svc_req *rqstp;
664 {
665         static nlm_res res;
666         struct nlm4_lock arg4;
667
668         nlmtonlm4(&arg->alock, &arg4);
669
670         if (debug_level)
671                 log_from_addr("nlm_unlock_msg", rqstp);
672
673         res.stat.stat = unlock(&arg4, 0);
674         res.cookie = arg->cookie;
675
676         transmit_result(NLM_UNLOCK_RES, &res, getrpcaddr(rqstp));
677         return (NULL);
678 }
679
680 /* ------------------------------------------------------------------------- */
681 /*
682  * Client-side pseudo-RPCs for results.  Note that for the client there
683  * are only nlm_xxx_msg() versions of each call, since the 'real RPC'
684  * version returns the results in the RPC result, and so the client
685  * does not normally receive incoming RPCs.
686  *
687  * The exception to this is nlm_granted(), which is genuinely an RPC
688  * call from the server to the client - a 'call-back' in normal procedure
689  * call terms.
690  */
691
692 /* nlm_granted ------------------------------------------------------------- */
693 /*
694  * Purpose:     Receive notification that formerly blocked lock now granted
695  * Returns:     always success ('granted')
696  * Notes:
697  */
698 nlm_res *
699 nlm_granted_1_svc(arg, rqstp)
700         nlm_testargs *arg;
701         struct svc_req *rqstp;
702 {
703         static nlm_res res;
704
705         if (debug_level)
706                 log_from_addr("nlm_granted", rqstp);
707
708         res.stat.stat = lock_answer(arg->alock.svid, &arg->cookie,
709                 nlm_granted, NULL, NLM_VERS) == 0 ?
710                 nlm_granted : nlm_denied;
711
712         /* copy cookie from arg to result.  See comment in nlm_test_1() */
713         res.cookie = arg->cookie;
714
715         return (&res);
716 }
717
718 void *
719 nlm_granted_msg_1_svc(arg, rqstp)
720         nlm_testargs *arg;
721         struct svc_req *rqstp;
722 {
723         static nlm_res res;
724
725         if (debug_level)
726                 log_from_addr("nlm_granted_msg", rqstp);
727
728         res.cookie = arg->cookie;
729         res.stat.stat = lock_answer(arg->alock.svid, &arg->cookie,
730                 nlm_granted, NULL, NLM_VERS) == 0 ?
731                 nlm_granted : nlm_denied;
732
733         transmit_result(NLM_GRANTED_RES, &res, getrpcaddr(rqstp));
734         return (NULL);
735 }
736
737 /* nlm_test_res ------------------------------------------------------------ */
738 /*
739  * Purpose:     Accept result from earlier nlm_test_msg() call
740  * Returns:     Nothing
741  */
742 void *
743 nlm_test_res_1_svc(arg, rqstp)
744         nlm_testres *arg;
745         struct svc_req *rqstp;
746 {
747         if (debug_level)
748                 log_from_addr("nlm_test_res", rqstp);
749         (void)lock_answer(-1, &arg->cookie, arg->stat.stat, 
750                 &arg->stat.nlm_testrply_u.holder.svid, NLM_VERS);
751         return (NULL);
752 }
753
754 /* nlm_lock_res ------------------------------------------------------------ */
755 /*
756  * Purpose:     Accept result from earlier nlm_lock_msg() call
757  * Returns:     Nothing
758  */
759 void *
760 nlm_lock_res_1_svc(arg, rqstp)
761         nlm_res *arg;
762         struct svc_req *rqstp;
763 {
764         if (debug_level)
765                 log_from_addr("nlm_lock_res", rqstp);
766
767         (void)lock_answer(-1, &arg->cookie, arg->stat.stat, NULL, NLM_VERS);
768
769         return (NULL);
770 }
771
772 /* nlm_cancel_res ---------------------------------------------------------- */
773 /*
774  * Purpose:     Accept result from earlier nlm_cancel_msg() call
775  * Returns:     Nothing
776  */
777 void *
778 nlm_cancel_res_1_svc(arg, rqstp)
779         nlm_res *arg __unused;
780         struct svc_req *rqstp;
781 {
782         if (debug_level)
783                 log_from_addr("nlm_cancel_res", rqstp);
784         return (NULL);
785 }
786
787 /* nlm_unlock_res ---------------------------------------------------------- */
788 /*
789  * Purpose:     Accept result from earlier nlm_unlock_msg() call
790  * Returns:     Nothing
791  */
792 void *
793 nlm_unlock_res_1_svc(arg, rqstp)
794         nlm_res *arg;
795         struct svc_req *rqstp;
796 {
797         if (debug_level)
798                 log_from_addr("nlm_unlock_res", rqstp);
799
800         lock_answer(-1, &arg->cookie, arg->stat.stat, NULL, NLM_VERS);
801
802         return (NULL);
803 }
804
805 /* nlm_granted_res --------------------------------------------------------- */
806 /*
807  * Purpose:     Accept result from earlier nlm_granted_msg() call
808  * Returns:     Nothing
809  */
810 void *
811 nlm_granted_res_1_svc(arg, rqstp)
812         nlm_res *arg __unused;
813         struct svc_req *rqstp;
814 {
815         if (debug_level)
816                 log_from_addr("nlm_granted_res", rqstp);
817         return (NULL);
818 }
819
820 /* ------------------------------------------------------------------------- */
821 /*
822  * Calls for PCNFS locking (aka non-monitored locking, no involvement
823  * of rpc.statd).
824  *
825  * These are all genuine RPCs - no nlm_xxx_msg() nonsense here.
826  */
827
828 /* nlm_share --------------------------------------------------------------- */
829 /*
830  * Purpose:     Establish a DOS-style lock
831  * Returns:     success or failure
832  * Notes:       Blocking locks are not supported - client is expected
833  *              to retry if required.
834  */
835 nlm_shareres *
836 nlm_share_3_svc(arg, rqstp)
837         nlm_shareargs *arg;
838         struct svc_req *rqstp;
839 {
840         static nlm_shareres res;
841
842         if (debug_level)
843                 log_from_addr("nlm_share", rqstp);
844
845         res.cookie = arg->cookie;
846         res.stat = nlm_granted;
847         res.sequence = 1234356; /* X/Open says this field is ignored? */
848         return (&res);
849 }
850
851 /* nlm_unshare ------------------------------------------------------------ */
852 /*
853  * Purpose:     Release a DOS-style lock
854  * Returns:     nlm_granted, unless in grace period
855  * Notes:
856  */
857 nlm_shareres *
858 nlm_unshare_3_svc(arg, rqstp)
859         nlm_shareargs *arg;
860         struct svc_req *rqstp;
861 {
862         static nlm_shareres res;
863
864         if (debug_level)
865                 log_from_addr("nlm_unshare", rqstp);
866
867         res.cookie = arg->cookie;
868         res.stat = nlm_granted;
869         res.sequence = 1234356; /* X/Open says this field is ignored? */
870         return (&res);
871 }
872
873 /* nlm_nm_lock ------------------------------------------------------------ */
874 /*
875  * Purpose:     non-monitored version of nlm_lock()
876  * Returns:     as for nlm_lock()
877  * Notes:       These locks are in the same style as the standard nlm_lock,
878  *              but the rpc.statd should not be called to establish a
879  *              monitor for the client machine, since that machine is
880  *              declared not to be running a rpc.statd, and so would not
881  *              respond to the statd protocol.
882  */
883 nlm_res *
884 nlm_nm_lock_3_svc(arg, rqstp)
885         nlm_lockargs *arg;
886         struct svc_req *rqstp;
887 {
888         static nlm_res res;
889
890         if (debug_level)
891                 log_from_addr("nlm_nm_lock", rqstp);
892
893         /* copy cookie from arg to result.  See comment in nlm_test_1() */
894         res.cookie = arg->cookie;
895         res.stat.stat = nlm_granted;
896         return (&res);
897 }
898
899 /* nlm_free_all ------------------------------------------------------------ */
900 /*
901  * Purpose:     Release all locks held by a named client
902  * Returns:     Nothing
903  * Notes:       Potential denial of service security problem here - the
904  *              locks to be released are specified by a host name, independent
905  *              of the address from which the request has arrived.
906  *              Should probably be rejected if the named host has been
907  *              using monitored locks.
908  */
909 void *
910 nlm_free_all_3_svc(arg, rqstp)
911         nlm_notify *arg __unused;
912         struct svc_req *rqstp;
913 {
914         static char dummy;
915
916         if (debug_level)
917                 log_from_addr("nlm_free_all", rqstp);
918         return (&dummy);
919 }
920
921 /* calls for nlm version 4 (NFSv3) */
922 /* nlm_test ---------------------------------------------------------------- */
923 /*
924  * Purpose:     Test whether a specified lock would be granted if requested
925  * Returns:     nlm_granted (or error code)
926  * Notes:
927  */
928 nlm4_testres *
929 nlm4_test_4_svc(arg, rqstp)
930         nlm4_testargs *arg;
931         struct svc_req *rqstp;
932 {
933         static nlm4_testres res;
934         struct nlm4_holder *holder;
935
936         if (debug_level)
937                 log_from_addr("nlm4_test", rqstp);
938         if (debug_level > 5) {
939                 syslog(LOG_DEBUG, "Locking arguments:\n");
940                 log_netobj(&(arg->cookie));
941                 syslog(LOG_DEBUG, "Alock arguments:\n");
942                 syslog(LOG_DEBUG, "Caller Name: %s\n",arg->alock.caller_name);
943                 syslog(LOG_DEBUG, "File Handle:\n");
944                 log_netobj(&(arg->alock.fh));
945                 syslog(LOG_DEBUG, "Owner Handle:\n");
946                 log_netobj(&(arg->alock.oh));
947                 syslog(LOG_DEBUG, "SVID:        %d\n", arg->alock.svid);
948                 syslog(LOG_DEBUG, "Lock Offset: %llu\n",
949                     (unsigned long long)arg->alock.l_offset);
950                 syslog(LOG_DEBUG, "Lock Length: %llu\n",
951                     (unsigned long long)arg->alock.l_len);
952                 syslog(LOG_DEBUG, "Exclusive:   %s\n",
953                     (arg->exclusive ? "true" : "false"));
954         }
955
956         holder = testlock(&arg->alock, arg->exclusive, LOCK_V4);
957
958         /*
959          * Copy the cookie from the argument into the result.  Note that this
960          * is slightly hazardous, as the structure contains a pointer to a
961          * malloc()ed buffer that will get freed by the caller.  However, the
962          * main function transmits the result before freeing the argument
963          * so it is in fact safe.
964          */
965         res.cookie = arg->cookie;
966         if (holder == NULL) {
967                 res.stat.stat = nlm4_granted;
968         } else {
969                 res.stat.stat = nlm4_denied;
970                 memcpy(&res.stat.nlm4_testrply_u.holder, holder,
971                     sizeof(struct nlm4_holder));
972         }
973         return (&res);
974 }
975
976 void *
977 nlm4_test_msg_4_svc(arg, rqstp)
978         nlm4_testargs *arg;
979         struct svc_req *rqstp;
980 {
981         nlm4_testres res;
982         static char dummy;
983         struct sockaddr *addr;
984         CLIENT *cli;
985         int success;
986         struct timeval timeo;
987         struct nlm4_holder *holder;
988
989         if (debug_level)
990                 log_from_addr("nlm4_test_msg", rqstp);
991
992         holder = testlock(&arg->alock, arg->exclusive, LOCK_V4);
993
994         res.cookie = arg->cookie;
995         if (holder == NULL) {
996                 res.stat.stat = nlm4_granted;
997         } else {
998                 res.stat.stat = nlm4_denied;
999                 memcpy(&res.stat.nlm4_testrply_u.holder, holder,
1000                     sizeof(struct nlm4_holder));
1001         }
1002
1003         /*
1004          * nlm_test has different result type to the other operations, so
1005          * can't use transmit4_result() in this case
1006          */
1007         addr = svc_getrpccaller(rqstp->rq_xprt)->buf;
1008         if ((cli = get_client(addr, NLM_VERS4)) != NULL) {
1009                 timeo.tv_sec = 0; /* No timeout - not expecting response */
1010                 timeo.tv_usec = 0;
1011
1012                 success = clnt_call(cli, NLM4_TEST_RES,
1013                     (xdrproc_t)xdr_nlm4_testres, &res,
1014                     (xdrproc_t)xdr_void, &dummy, timeo);
1015
1016                 if (debug_level > 2)
1017                         syslog(LOG_DEBUG, "clnt_call returns %d", success);
1018         }
1019         return (NULL);
1020 }
1021
1022 /* nlm_lock ---------------------------------------------------------------- */
1023 /*
1024  * Purposes:    Establish a lock
1025  * Returns:     granted, denied or blocked
1026  * Notes:       *** grace period support missing
1027  */
1028 nlm4_res *
1029 nlm4_lock_4_svc(arg, rqstp)
1030         nlm4_lockargs *arg;
1031         struct svc_req *rqstp;
1032 {
1033         static nlm4_res res;
1034
1035         if (debug_level)
1036                 log_from_addr("nlm4_lock", rqstp);
1037         if (debug_level > 5) {
1038                 syslog(LOG_DEBUG, "Locking arguments:\n");
1039                 log_netobj(&(arg->cookie));
1040                 syslog(LOG_DEBUG, "Alock arguments:\n");
1041                 syslog(LOG_DEBUG, "Caller Name: %s\n",arg->alock.caller_name);
1042                 syslog(LOG_DEBUG, "File Handle:\n");
1043                 log_netobj(&(arg->alock.fh));
1044                 syslog(LOG_DEBUG, "Owner Handle:\n");
1045                 log_netobj(&(arg->alock.oh));
1046                 syslog(LOG_DEBUG, "SVID:        %d\n", arg->alock.svid);
1047                 syslog(LOG_DEBUG, "Lock Offset: %llu\n",
1048                     (unsigned long long)arg->alock.l_offset);
1049                 syslog(LOG_DEBUG, "Lock Length: %llu\n", 
1050                     (unsigned long long)arg->alock.l_len);
1051                 syslog(LOG_DEBUG, "Block:       %s\n", (arg->block ? "true" : "false"));
1052                 syslog(LOG_DEBUG, "Exclusive:   %s\n", (arg->exclusive ? "true" : "false"));
1053                 syslog(LOG_DEBUG, "Reclaim:     %s\n", (arg->reclaim ? "true" : "false"));
1054                 syslog(LOG_DEBUG, "State num:   %d\n", arg->state);
1055         }
1056
1057         /* copy cookie from arg to result.  See comment in nlm_test_4() */
1058         res.cookie = arg->cookie;
1059
1060         res.stat.stat = getlock(arg, rqstp, LOCK_MON | LOCK_V4);
1061         return (&res);
1062 }
1063
1064 void *
1065 nlm4_lock_msg_4_svc(arg, rqstp)
1066         nlm4_lockargs *arg;
1067         struct svc_req *rqstp;
1068 {
1069         static nlm4_res res;
1070
1071         if (debug_level)
1072                 log_from_addr("nlm4_lock_msg", rqstp);
1073
1074         res.cookie = arg->cookie;
1075         res.stat.stat = getlock(arg, rqstp, LOCK_MON | LOCK_ASYNC | LOCK_V4);
1076         transmit4_result(NLM4_LOCK_RES, &res, getrpcaddr(rqstp));
1077
1078         return (NULL);
1079 }
1080
1081 /* nlm_cancel -------------------------------------------------------------- */
1082 /*
1083  * Purpose:     Cancel a blocked lock request
1084  * Returns:     granted or denied
1085  * Notes:
1086  */
1087 nlm4_res *
1088 nlm4_cancel_4_svc(arg, rqstp)
1089         nlm4_cancargs *arg;
1090         struct svc_req *rqstp;
1091 {
1092         static nlm4_res res;
1093
1094         if (debug_level)
1095                 log_from_addr("nlm4_cancel", rqstp);
1096
1097         /* copy cookie from arg to result.  See comment in nlm_test_1() */
1098         res.cookie = arg->cookie;
1099
1100         /*
1101          * Since at present we never return 'nlm_blocked', there can never be
1102          * a lock to cancel, so this call always fails.
1103          */
1104         res.stat.stat = unlock(&arg->alock, LOCK_CANCEL);
1105         return (&res);
1106 }
1107
1108 void *
1109 nlm4_cancel_msg_4_svc(arg, rqstp)
1110         nlm4_cancargs *arg;
1111         struct svc_req *rqstp;
1112 {
1113         static nlm4_res res;
1114
1115         if (debug_level)
1116                 log_from_addr("nlm4_cancel_msg", rqstp);
1117
1118         res.cookie = arg->cookie;
1119         /*
1120          * Since at present we never return 'nlm_blocked', there can never be
1121          * a lock to cancel, so this call always fails.
1122          */
1123         res.stat.stat = unlock(&arg->alock, LOCK_CANCEL | LOCK_V4);
1124         transmit4_result(NLM4_CANCEL_RES, &res, getrpcaddr(rqstp));
1125         return (NULL);
1126 }
1127
1128 /* nlm_unlock -------------------------------------------------------------- */
1129 /*
1130  * Purpose:     Release an existing lock
1131  * Returns:     Always granted, unless during grace period
1132  * Notes:       "no such lock" error condition is ignored, as the
1133  *              protocol uses unreliable UDP datagrams, and may well
1134  *              re-try an unlock that has already succeeded.
1135  */
1136 nlm4_res *
1137 nlm4_unlock_4_svc(arg, rqstp)
1138         nlm4_unlockargs *arg;
1139         struct svc_req *rqstp;
1140 {
1141         static nlm4_res res;
1142
1143         if (debug_level)
1144                 log_from_addr("nlm4_unlock", rqstp);
1145
1146         res.stat.stat = unlock(&arg->alock, LOCK_V4);
1147         res.cookie = arg->cookie;
1148
1149         return (&res);
1150 }
1151
1152 void *
1153 nlm4_unlock_msg_4_svc(arg, rqstp)
1154         nlm4_unlockargs *arg;
1155         struct svc_req *rqstp;
1156 {
1157         static nlm4_res res;
1158
1159         if (debug_level)
1160                 log_from_addr("nlm4_unlock_msg", rqstp);
1161
1162         res.stat.stat = unlock(&arg->alock, LOCK_V4);
1163         res.cookie = arg->cookie;
1164
1165         transmit4_result(NLM4_UNLOCK_RES, &res, getrpcaddr(rqstp));
1166         return (NULL);
1167 }
1168
1169 /* ------------------------------------------------------------------------- */
1170 /*
1171  * Client-side pseudo-RPCs for results.  Note that for the client there
1172  * are only nlm_xxx_msg() versions of each call, since the 'real RPC'
1173  * version returns the results in the RPC result, and so the client
1174  * does not normally receive incoming RPCs.
1175  *
1176  * The exception to this is nlm_granted(), which is genuinely an RPC
1177  * call from the server to the client - a 'call-back' in normal procedure
1178  * call terms.
1179  */
1180
1181 /* nlm_granted ------------------------------------------------------------- */
1182 /*
1183  * Purpose:     Receive notification that formerly blocked lock now granted
1184  * Returns:     always success ('granted')
1185  * Notes:
1186  */
1187 nlm4_res *
1188 nlm4_granted_4_svc(arg, rqstp)
1189         nlm4_testargs *arg;
1190         struct svc_req *rqstp;
1191 {
1192         static nlm4_res res;
1193
1194         if (debug_level)
1195                 log_from_addr("nlm4_granted", rqstp);
1196
1197         res.stat.stat = lock_answer(arg->alock.svid, &arg->cookie,
1198                 nlm4_granted, NULL, NLM_VERS4) == 0 ?
1199                 nlm4_granted : nlm4_denied;
1200
1201         /* copy cookie from arg to result.  See comment in nlm_test_1() */
1202         res.cookie = arg->cookie;
1203
1204         return (&res);
1205 }
1206
1207 void *
1208 nlm4_granted_msg_4_svc(arg, rqstp)
1209         nlm4_testargs *arg;
1210         struct svc_req *rqstp;
1211 {
1212         static nlm4_res res;
1213
1214         if (debug_level)
1215                 log_from_addr("nlm4_granted_msg", rqstp);
1216
1217         res.cookie = arg->cookie;
1218         res.stat.stat = lock_answer(arg->alock.svid, &arg->cookie,
1219                 nlm4_granted, NULL, NLM_VERS4) == 0 ?
1220                 nlm4_granted : nlm4_denied;
1221         transmit4_result(NLM4_GRANTED_RES, &res, getrpcaddr(rqstp));
1222         return (NULL);
1223 }
1224
1225 /* nlm_test_res ------------------------------------------------------------ */
1226 /*
1227  * Purpose:     Accept result from earlier nlm_test_msg() call
1228  * Returns:     Nothing
1229  */
1230 void *
1231 nlm4_test_res_4_svc(arg, rqstp)
1232         nlm4_testres *arg;
1233         struct svc_req *rqstp;
1234 {
1235         if (debug_level)
1236                 log_from_addr("nlm4_test_res", rqstp);
1237
1238         (void)lock_answer(-1, &arg->cookie, arg->stat.stat,
1239                 (int *)&arg->stat.nlm4_testrply_u.holder.svid,
1240                 NLM_VERS4);
1241         return (NULL);
1242 }
1243
1244 /* nlm_lock_res ------------------------------------------------------------ */
1245 /*
1246  * Purpose:     Accept result from earlier nlm_lock_msg() call
1247  * Returns:     Nothing
1248  */
1249 void *
1250 nlm4_lock_res_4_svc(arg, rqstp)
1251         nlm4_res *arg;
1252         struct svc_req *rqstp;
1253 {
1254         if (debug_level)
1255                 log_from_addr("nlm4_lock_res", rqstp);
1256
1257         (void)lock_answer(-1, &arg->cookie, arg->stat.stat, NULL, NLM_VERS4);
1258
1259         return (NULL);
1260 }
1261
1262 /* nlm_cancel_res ---------------------------------------------------------- */
1263 /*
1264  * Purpose:     Accept result from earlier nlm_cancel_msg() call
1265  * Returns:     Nothing
1266  */
1267 void *
1268 nlm4_cancel_res_4_svc(arg, rqstp)
1269         nlm4_res *arg __unused;
1270         struct svc_req *rqstp;
1271 {
1272         if (debug_level)
1273                 log_from_addr("nlm4_cancel_res", rqstp);
1274         return (NULL);
1275 }
1276
1277 /* nlm_unlock_res ---------------------------------------------------------- */
1278 /*
1279  * Purpose:     Accept result from earlier nlm_unlock_msg() call
1280  * Returns:     Nothing
1281  */
1282 void *
1283 nlm4_unlock_res_4_svc(arg, rqstp)
1284         nlm4_res *arg __unused;
1285         struct svc_req *rqstp;
1286 {
1287         if (debug_level)
1288                 log_from_addr("nlm4_unlock_res", rqstp);
1289         return (NULL);
1290 }
1291
1292 /* nlm_granted_res --------------------------------------------------------- */
1293 /*
1294  * Purpose:     Accept result from earlier nlm_granted_msg() call
1295  * Returns:     Nothing
1296  */
1297 void *
1298 nlm4_granted_res_4_svc(arg, rqstp)
1299         nlm4_res *arg __unused;
1300         struct svc_req *rqstp;
1301 {
1302         if (debug_level)
1303                 log_from_addr("nlm4_granted_res", rqstp);
1304         return (NULL);
1305 }
1306
1307 /* ------------------------------------------------------------------------- */
1308 /*
1309  * Calls for PCNFS locking (aka non-monitored locking, no involvement
1310  * of rpc.statd).
1311  *
1312  * These are all genuine RPCs - no nlm_xxx_msg() nonsense here.
1313  */
1314
1315 /* nlm_share --------------------------------------------------------------- */
1316 /*
1317  * Purpose:     Establish a DOS-style lock
1318  * Returns:     success or failure
1319  * Notes:       Blocking locks are not supported - client is expected
1320  *              to retry if required.
1321  */
1322 nlm4_shareres *
1323 nlm4_share_4_svc(arg, rqstp)
1324         nlm4_shareargs *arg;
1325         struct svc_req *rqstp;
1326 {
1327         static nlm4_shareres res;
1328
1329         if (debug_level)
1330                 log_from_addr("nlm4_share", rqstp);
1331
1332         res.cookie = arg->cookie;
1333         res.stat = nlm4_granted;
1334         res.sequence = 1234356; /* X/Open says this field is ignored? */
1335         return (&res);
1336 }
1337
1338 /* nlm4_unshare ------------------------------------------------------------ */
1339 /*
1340  * Purpose:     Release a DOS-style lock
1341  * Returns:     nlm_granted, unless in grace period
1342  * Notes:
1343  */
1344 nlm4_shareres *
1345 nlm4_unshare_4_svc(arg, rqstp)
1346         nlm4_shareargs *arg;
1347         struct svc_req *rqstp;
1348 {
1349         static nlm4_shareres res;
1350
1351         if (debug_level)
1352                 log_from_addr("nlm_unshare", rqstp);
1353
1354         res.cookie = arg->cookie;
1355         res.stat = nlm4_granted;
1356         res.sequence = 1234356; /* X/Open says this field is ignored? */
1357         return (&res);
1358 }
1359
1360 /* nlm4_nm_lock ------------------------------------------------------------ */
1361 /*
1362  * Purpose:     non-monitored version of nlm4_lock()
1363  * Returns:     as for nlm4_lock()
1364  * Notes:       These locks are in the same style as the standard nlm4_lock,
1365  *              but the rpc.statd should not be called to establish a
1366  *              monitor for the client machine, since that machine is
1367  *              declared not to be running a rpc.statd, and so would not
1368  *              respond to the statd protocol.
1369  */
1370 nlm4_res *
1371 nlm4_nm_lock_4_svc(arg, rqstp)
1372         nlm4_lockargs *arg;
1373         struct svc_req *rqstp;
1374 {
1375         static nlm4_res res;
1376
1377         if (debug_level)
1378                 log_from_addr("nlm4_nm_lock", rqstp);
1379
1380         /* copy cookie from arg to result.  See comment in nlm4_test_1() */
1381         res.cookie = arg->cookie;
1382         res.stat.stat = nlm4_granted;
1383         return (&res);
1384 }
1385
1386 /* nlm4_free_all ------------------------------------------------------------ */
1387 /*
1388  * Purpose:     Release all locks held by a named client
1389  * Returns:     Nothing
1390  * Notes:       Potential denial of service security problem here - the
1391  *              locks to be released are specified by a host name, independent
1392  *              of the address from which the request has arrived.
1393  *              Should probably be rejected if the named host has been
1394  *              using monitored locks.
1395  */
1396 void *
1397 nlm4_free_all_4_svc(arg, rqstp)
1398         struct nlm4_notify *arg __unused;
1399         struct svc_req *rqstp;
1400 {
1401         static char dummy;
1402
1403         if (debug_level)
1404                 log_from_addr("nlm4_free_all", rqstp);
1405         return (&dummy);
1406 }
1407
1408 /* nlm_sm_notify --------------------------------------------------------- */
1409 /*
1410  * Purpose:     called by rpc.statd when a monitored host state changes.
1411  * Returns:     Nothing
1412  */
1413 void *
1414 nlm_sm_notify_0_svc(arg, rqstp)
1415         struct nlm_sm_status *arg;
1416         struct svc_req *rqstp __unused;
1417 {
1418         static char dummy;
1419         notify(arg->mon_name, arg->state);
1420         return (&dummy);
1421 }