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