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