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