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