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