lock_proc.c revision 320587
1/* $NetBSD: lock_proc.c,v 1.7 2000/10/11 20:23:56 is Exp $ */ 2/* $FreeBSD: stable/10/usr.sbin/rpc.lockd/lock_proc.c 320587 2017-07-03 05:30:31Z delphij $ */ 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 67static void log_from_addr(const char *, struct svc_req *); 68static void log_netobj(netobj *obj); 69static 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 */ 78static void 79log_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*/ 101static void 102log_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 */ 157static CLIENT *clnt_cache_ptr[CLIENT_CACHE_SIZE]; 158static long clnt_cache_time[CLIENT_CACHE_SIZE]; /* time entry created */ 159static struct sockaddr_storage clnt_cache_addr[CLIENT_CACHE_SIZE]; 160static rpcvers_t clnt_cache_vers[CLIENT_CACHE_SIZE]; 161static int clnt_cache_next_to_use = 0; 162 163static int 164addrcmp(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 192CLIENT * 193get_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 */ 335void 336transmit_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 */ 366void 367transmit4_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 */ 394static void nlmtonlm4(struct nlm_lock *, struct nlm4_lock *); 395static void 396nlmtonlm4(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 */ 440nlm_testres * 441nlm_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 474void * 475nlm_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 */ 531nlm_res * 532nlm_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 555void * 556nlm_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 */ 586nlm_res * 587nlm_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 610void * 611nlm_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 */ 641nlm_res * 642nlm_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 660void * 661nlm_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 */ 698nlm_res * 699nlm_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 718void * 719nlm_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 */ 742void * 743nlm_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 */ 759void * 760nlm_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 */ 777void * 778nlm_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 */ 792void * 793nlm_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 */ 810void * 811nlm_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 */ 835nlm_shareres * 836nlm_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 */ 857nlm_shareres * 858nlm_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 */ 883nlm_res * 884nlm_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 */ 909void * 910nlm_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 */ 928nlm4_testres * 929nlm4_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 976void * 977nlm4_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 */ 1028nlm4_res * 1029nlm4_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 1064void * 1065nlm4_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 */ 1087nlm4_res * 1088nlm4_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 1108void * 1109nlm4_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 */ 1136nlm4_res * 1137nlm4_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 1152void * 1153nlm4_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 */ 1187nlm4_res * 1188nlm4_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 1207void * 1208nlm4_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 */ 1230void * 1231nlm4_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 */ 1249void * 1250nlm4_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 */ 1267void * 1268nlm4_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 */ 1282void * 1283nlm4_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 */ 1297void * 1298nlm4_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 */ 1322nlm4_shareres * 1323nlm4_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 */ 1344nlm4_shareres * 1345nlm4_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 */ 1370nlm4_res * 1371nlm4_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 */ 1396void * 1397nlm4_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 */ 1413void * 1414nlm_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} 1422