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