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