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