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