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