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 static void log_from_addr(const char *, struct svc_req *); 66 static void log_netobj(netobj *obj); 67 static int addrcmp(struct sockaddr *, struct sockaddr *); 68 69 /* log_from_addr ----------------------------------------------------------- */ 70 /* 71 * Purpose: Log name of function called and source address 72 * Returns: Nothing 73 * Notes: Extracts the source address from the transport handle 74 * passed in as part of the called procedure specification 75 */ 76 static void 77 log_from_addr(fun_name, req) 78 const char *fun_name; 79 struct svc_req *req; 80 { 81 struct sockaddr *addr; 82 char hostname_buf[NI_MAXHOST]; 83 84 addr = svc_getrpccaller(req->rq_xprt)->buf; 85 if (getnameinfo(addr , addr->sa_len, hostname_buf, sizeof hostname_buf, 86 NULL, 0, 0) != 0) 87 return; 88 89 syslog(LOG_DEBUG, "%s from %s", fun_name, hostname_buf); 90 } 91 92 /* log_netobj ----------------------------------------------------------- */ 93 /* 94 * Purpose: Log a netobj 95 * Returns: Nothing 96 * Notes: This function should only really be called as part of 97 * a debug subsystem. 98 */ 99 static void 100 log_netobj(obj) 101 netobj *obj; 102 { 103 char objvalbuffer[(sizeof(char)*2)*MAX_NETOBJ_SZ+2]; 104 char objascbuffer[sizeof(char)*MAX_NETOBJ_SZ+1]; 105 unsigned int i, maxlen; 106 char *tmp1, *tmp2; 107 108 /* Notify of potential security attacks */ 109 if (obj->n_len > MAX_NETOBJ_SZ) { 110 syslog(LOG_DEBUG, "SOMEONE IS TRYING TO DO SOMETHING NASTY!\n"); 111 syslog(LOG_DEBUG, "netobj too large! Should be %d was %d\n", 112 MAX_NETOBJ_SZ, obj->n_len); 113 } 114 /* Prevent the security hazard from the buffer overflow */ 115 maxlen = (obj->n_len < MAX_NETOBJ_SZ ? obj->n_len : MAX_NETOBJ_SZ); 116 for (i=0, tmp1 = objvalbuffer, tmp2 = objascbuffer; i < obj->n_len; 117 i++, tmp1 +=2, tmp2 +=1) { 118 sprintf(tmp1,"%02X",*(obj->n_bytes+i)); 119 sprintf(tmp2,"%c",*(obj->n_bytes+i)); 120 } 121 *tmp1 = '\0'; 122 *tmp2 = '\0'; 123 syslog(LOG_DEBUG,"netobjvals: %s\n",objvalbuffer); 124 syslog(LOG_DEBUG,"netobjascs: %s\n",objascbuffer); 125 } 126 /* get_client -------------------------------------------------------------- */ 127 /* 128 * Purpose: Get a CLIENT* for making RPC calls to lockd on given host 129 * Returns: CLIENT* pointer, from clnt_udp_create, or NULL if error 130 * Notes: Creating a CLIENT* is quite expensive, involving a 131 * conversation with the remote portmapper to get the 132 * port number. Since a given client is quite likely 133 * to make several locking requests in succession, it is 134 * desirable to cache the created CLIENT*. 135 * 136 * Since we are using UDP rather than TCP, there is no cost 137 * to the remote system in keeping these cached indefinitely. 138 * Unfortunately there is a snag: if the remote system 139 * reboots, the cached portmapper results will be invalid, 140 * and we will never detect this since all of the xxx_msg() 141 * calls return no result - we just fire off a udp packet 142 * and hope for the best. 143 * 144 * We solve this by discarding cached values after two 145 * minutes, regardless of whether they have been used 146 * in the meanwhile (since a bad one might have been used 147 * plenty of times, as the host keeps retrying the request 148 * and we keep sending the reply back to the wrong port). 149 * 150 * Given that the entries will always expire in the order 151 * that they were created, there is no point in a LRU 152 * algorithm for when the cache gets full - entries are 153 * always re-used in sequence. 154 */ 155 static CLIENT *clnt_cache_ptr[CLIENT_CACHE_SIZE]; 156 static long clnt_cache_time[CLIENT_CACHE_SIZE]; /* time entry created */ 157 static struct sockaddr_storage clnt_cache_addr[CLIENT_CACHE_SIZE]; 158 static rpcvers_t clnt_cache_vers[CLIENT_CACHE_SIZE]; 159 static int clnt_cache_next_to_use = 0; 160 161 static int 162 addrcmp(sa1, sa2) 163 struct sockaddr *sa1; 164 struct sockaddr *sa2; 165 { 166 int len; 167 void *p1, *p2; 168 169 if (sa1->sa_family != sa2->sa_family) 170 return -1; 171 172 switch (sa1->sa_family) { 173 case AF_INET: 174 p1 = &((struct sockaddr_in *)sa1)->sin_addr; 175 p2 = &((struct sockaddr_in *)sa2)->sin_addr; 176 len = 4; 177 break; 178 case AF_INET6: 179 p1 = &((struct sockaddr_in6 *)sa1)->sin6_addr; 180 p2 = &((struct sockaddr_in6 *)sa2)->sin6_addr; 181 len = 16; 182 break; 183 default: 184 return -1; 185 } 186 187 return memcmp(p1, p2, len); 188 } 189 190 CLIENT * 191 get_client(host_addr, vers) 192 struct sockaddr *host_addr; 193 rpcvers_t vers; 194 { 195 CLIENT *client; 196 struct timeval retry_time, time_now; 197 int i; 198 const char *netid; 199 struct netconfig *nconf; 200 char host[NI_MAXHOST]; 201 uid_t old_euid; 202 int clnt_fd; 203 204 gettimeofday(&time_now, NULL); 205 206 /* 207 * Search for the given client in the cache, zapping any expired 208 * entries that we happen to notice in passing. 209 */ 210 for (i = 0; i < CLIENT_CACHE_SIZE; i++) { 211 client = clnt_cache_ptr[i]; 212 if (client && ((clnt_cache_time[i] + CLIENT_CACHE_LIFETIME) 213 < time_now.tv_sec)) { 214 /* Cache entry has expired. */ 215 if (debug_level > 3) 216 syslog(LOG_DEBUG, "Expired CLIENT* in cache"); 217 clnt_cache_time[i] = 0L; 218 clnt_destroy(client); 219 clnt_cache_ptr[i] = NULL; 220 client = NULL; 221 } 222 if (client && !addrcmp((struct sockaddr *)&clnt_cache_addr[i], 223 host_addr) && clnt_cache_vers[i] == vers) { 224 /* Found it! */ 225 if (debug_level > 3) 226 syslog(LOG_DEBUG, "Found CLIENT* in cache"); 227 return (client); 228 } 229 } 230 231 if (debug_level > 3) 232 syslog(LOG_DEBUG, "CLIENT* not found in cache, creating"); 233 234 /* Not found in cache. Free the next entry if it is in use. */ 235 if (clnt_cache_ptr[clnt_cache_next_to_use]) { 236 clnt_destroy(clnt_cache_ptr[clnt_cache_next_to_use]); 237 clnt_cache_ptr[clnt_cache_next_to_use] = NULL; 238 } 239 240 /* 241 * Need a host string for clnt_tp_create. Use NI_NUMERICHOST 242 * to avoid DNS lookups. 243 */ 244 if (getnameinfo(host_addr, host_addr->sa_len, host, sizeof host, 245 NULL, 0, NI_NUMERICHOST) != 0) { 246 syslog(LOG_ERR, "unable to get name string for caller"); 247 return NULL; 248 } 249 250 #if 1 251 if (host_addr->sa_family == AF_INET6) 252 netid = "udp6"; 253 else 254 netid = "udp"; 255 #else 256 if (host_addr->sa_family == AF_INET6) 257 netid = "tcp6"; 258 else 259 netid = "tcp"; 260 #endif 261 nconf = getnetconfigent(netid); 262 if (nconf == NULL) { 263 syslog(LOG_ERR, "could not get netconfig info for '%s': " 264 "no /etc/netconfig file?", netid); 265 return NULL; 266 } 267 268 client = clnt_tp_create(host, NLM_PROG, vers, nconf); 269 freenetconfigent(nconf); 270 271 if (!client) { 272 syslog(LOG_ERR, "%s", clnt_spcreateerror("clntudp_create")); 273 syslog(LOG_ERR, "Unable to return result to %s", host); 274 return NULL; 275 } 276 277 /* Get the FD of the client, for bindresvport. */ 278 clnt_control(client, CLGET_FD, &clnt_fd); 279 280 /* Regain root privileges, for bindresvport. */ 281 old_euid = geteuid(); 282 seteuid(0); 283 284 /* 285 * Bind the client FD to a reserved port. 286 * Some NFS servers reject any NLM request from a non-reserved port. 287 */ 288 bindresvport(clnt_fd, NULL); 289 290 /* Drop root privileges again. */ 291 seteuid(old_euid); 292 293 /* Success - update the cache entry */ 294 clnt_cache_ptr[clnt_cache_next_to_use] = client; 295 memcpy(&clnt_cache_addr[clnt_cache_next_to_use], host_addr, 296 host_addr->sa_len); 297 clnt_cache_vers[clnt_cache_next_to_use] = vers; 298 clnt_cache_time[clnt_cache_next_to_use] = time_now.tv_sec; 299 if (++clnt_cache_next_to_use >= CLIENT_CACHE_SIZE) 300 clnt_cache_next_to_use = 0; 301 302 /* 303 * Disable the default timeout, so we can specify our own in calls 304 * to clnt_call(). (Note that the timeout is a different concept 305 * from the retry period set in clnt_udp_create() above.) 306 */ 307 retry_time.tv_sec = -1; 308 retry_time.tv_usec = -1; 309 clnt_control(client, CLSET_TIMEOUT, (char *)&retry_time); 310 311 if (debug_level > 3) 312 syslog(LOG_DEBUG, "Created CLIENT* for %s", host); 313 return client; 314 } 315 316 317 /* transmit_result --------------------------------------------------------- */ 318 /* 319 * Purpose: Transmit result for nlm_xxx_msg pseudo-RPCs 320 * Returns: Nothing - we have no idea if the datagram got there 321 * Notes: clnt_call() will always fail (with timeout) as we are 322 * calling it with timeout 0 as a hack to just issue a datagram 323 * without expecting a result 324 */ 325 void 326 transmit_result(opcode, result, addr) 327 int opcode; 328 nlm_res *result; 329 struct sockaddr *addr; 330 { 331 static char dummy; 332 CLIENT *cli; 333 struct timeval timeo; 334 int success; 335 336 if ((cli = get_client(addr, NLM_VERS)) != NULL) { 337 timeo.tv_sec = 0; /* No timeout - not expecting response */ 338 timeo.tv_usec = 0; 339 340 success = clnt_call(cli, opcode, (xdrproc_t)xdr_nlm_res, result, 341 (xdrproc_t)xdr_void, &dummy, timeo); 342 343 if (debug_level > 2) 344 syslog(LOG_DEBUG, "clnt_call returns %d(%s)", 345 success, clnt_sperrno(success)); 346 } 347 } 348 /* transmit4_result --------------------------------------------------------- */ 349 /* 350 * Purpose: Transmit result for nlm4_xxx_msg pseudo-RPCs 351 * Returns: Nothing - we have no idea if the datagram got there 352 * Notes: clnt_call() will always fail (with timeout) as we are 353 * calling it with timeout 0 as a hack to just issue a datagram 354 * without expecting a result 355 */ 356 void 357 transmit4_result(opcode, result, addr) 358 int opcode; 359 nlm4_res *result; 360 struct sockaddr *addr; 361 { 362 static char dummy; 363 CLIENT *cli; 364 struct timeval timeo; 365 int success; 366 367 if ((cli = get_client(addr, NLM_VERS4)) != NULL) { 368 timeo.tv_sec = 0; /* No timeout - not expecting response */ 369 timeo.tv_usec = 0; 370 371 success = clnt_call(cli, opcode, 372 (xdrproc_t)xdr_nlm4_res, result, 373 (xdrproc_t)xdr_void, &dummy, timeo); 374 375 if (debug_level > 2) 376 syslog(LOG_DEBUG, "clnt_call returns %d(%s)", 377 success, clnt_sperrno(success)); 378 } 379 } 380 381 /* 382 * converts a struct nlm_lock to struct nlm4_lock 383 */ 384 static void nlmtonlm4(struct nlm_lock *, struct nlm4_lock *); 385 static void 386 nlmtonlm4(arg, arg4) 387 struct nlm_lock *arg; 388 struct nlm4_lock *arg4; 389 { 390 arg4->caller_name = arg->caller_name; 391 arg4->fh = arg->fh; 392 arg4->oh = arg->oh; 393 arg4->svid = arg->svid; 394 arg4->l_offset = arg->l_offset; 395 arg4->l_len = arg->l_len; 396 } 397 /* ------------------------------------------------------------------------- */ 398 /* 399 * Functions for Unix<->Unix locking (ie. monitored locking, with rpc.statd 400 * involved to ensure reclaim of locks after a crash of the "stateless" 401 * server. 402 * 403 * These all come in two flavours - nlm_xxx() and nlm_xxx_msg(). 404 * The first are standard RPCs with argument and result. 405 * The nlm_xxx_msg() calls implement exactly the same functions, but 406 * use two pseudo-RPCs (one in each direction). These calls are NOT 407 * standard use of the RPC protocol in that they do not return a result 408 * at all (NB. this is quite different from returning a void result). 409 * The effect of this is to make the nlm_xxx_msg() calls simple unacknowledged 410 * datagrams, requiring higher-level code to perform retries. 411 * 412 * Despite the disadvantages of the nlm_xxx_msg() approach (some of which 413 * are documented in the comments to get_client() above), this is the 414 * interface used by all current commercial NFS implementations 415 * [Solaris, SCO, AIX etc.]. This is presumed to be because these allow 416 * implementations to continue using the standard RPC libraries, while 417 * avoiding the block-until-result nature of the library interface. 418 * 419 * No client implementations have been identified so far that make use 420 * of the true RPC version (early SunOS releases would be a likely candidate 421 * for testing). 422 */ 423 424 /* nlm_test ---------------------------------------------------------------- */ 425 /* 426 * Purpose: Test whether a specified lock would be granted if requested 427 * Returns: nlm_granted (or error code) 428 * Notes: 429 */ 430 nlm_testres * 431 nlm_test_1_svc(arg, rqstp) 432 nlm_testargs *arg; 433 struct svc_req *rqstp; 434 { 435 static nlm_testres res; 436 struct nlm4_lock arg4; 437 struct nlm4_holder *holder; 438 nlmtonlm4(&arg->alock, &arg4); 439 440 if (debug_level) 441 log_from_addr("nlm_test", rqstp); 442 443 holder = testlock(&arg4, arg->exclusive, 0); 444 /* 445 * Copy the cookie from the argument into the result. Note that this 446 * is slightly hazardous, as the structure contains a pointer to a 447 * malloc()ed buffer that will get freed by the caller. However, the 448 * main function transmits the result before freeing the argument 449 * so it is in fact safe. 450 */ 451 res.cookie = arg->cookie; 452 if (holder == NULL) { 453 res.stat.stat = nlm_granted; 454 } else { 455 res.stat.stat = nlm_denied; 456 memcpy(&res.stat.nlm_testrply_u.holder, holder, 457 sizeof(struct nlm_holder)); 458 res.stat.nlm_testrply_u.holder.l_offset = holder->l_offset; 459 res.stat.nlm_testrply_u.holder.l_len = holder->l_len; 460 } 461 return (&res); 462 } 463 464 void * 465 nlm_test_msg_1_svc(arg, rqstp) 466 nlm_testargs *arg; 467 struct svc_req *rqstp; 468 { 469 nlm_testres res; 470 static char dummy; 471 struct sockaddr *addr; 472 CLIENT *cli; 473 int success; 474 struct timeval timeo; 475 struct nlm4_lock arg4; 476 struct nlm4_holder *holder; 477 478 nlmtonlm4(&arg->alock, &arg4); 479 480 if (debug_level) 481 log_from_addr("nlm_test_msg", rqstp); 482 483 holder = testlock(&arg4, arg->exclusive, 0); 484 485 res.cookie = arg->cookie; 486 if (holder == NULL) { 487 res.stat.stat = nlm_granted; 488 } else { 489 res.stat.stat = nlm_denied; 490 memcpy(&res.stat.nlm_testrply_u.holder, holder, 491 sizeof(struct nlm_holder)); 492 res.stat.nlm_testrply_u.holder.l_offset = holder->l_offset; 493 res.stat.nlm_testrply_u.holder.l_len = holder->l_len; 494 } 495 496 /* 497 * nlm_test has different result type to the other operations, so 498 * can't use transmit_result() in this case 499 */ 500 addr = svc_getrpccaller(rqstp->rq_xprt)->buf; 501 if ((cli = get_client(addr, NLM_VERS)) != NULL) { 502 timeo.tv_sec = 0; /* No timeout - not expecting response */ 503 timeo.tv_usec = 0; 504 505 success = clnt_call(cli, NLM_TEST_RES, 506 (xdrproc_t)xdr_nlm_testres, &res, 507 (xdrproc_t)xdr_void, &dummy, timeo); 508 509 if (debug_level > 2) 510 syslog(LOG_DEBUG, "clnt_call returns %d", success); 511 } 512 return (NULL); 513 } 514 515 /* nlm_lock ---------------------------------------------------------------- */ 516 /* 517 * Purposes: Establish a lock 518 * Returns: granted, denied or blocked 519 * Notes: *** grace period support missing 520 */ 521 nlm_res * 522 nlm_lock_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 nlmtonlm4(&arg->alock, &arg4.alock); 529 arg4.cookie = arg->cookie; 530 arg4.block = arg->block; 531 arg4.exclusive = arg->exclusive; 532 arg4.reclaim = arg->reclaim; 533 arg4.state = arg->state; 534 535 if (debug_level) 536 log_from_addr("nlm_lock", rqstp); 537 538 /* copy cookie from arg to result. See comment in nlm_test_1() */ 539 res.cookie = arg->cookie; 540 541 res.stat.stat = getlock(&arg4, rqstp, LOCK_MON); 542 return (&res); 543 } 544 545 void * 546 nlm_lock_msg_1_svc(arg, rqstp) 547 nlm_lockargs *arg; 548 struct svc_req *rqstp; 549 { 550 static nlm_res res; 551 struct nlm4_lockargs arg4; 552 553 nlmtonlm4(&arg->alock, &arg4.alock); 554 arg4.cookie = arg->cookie; 555 arg4.block = arg->block; 556 arg4.exclusive = arg->exclusive; 557 arg4.reclaim = arg->reclaim; 558 arg4.state = arg->state; 559 560 if (debug_level) 561 log_from_addr("nlm_lock_msg", rqstp); 562 563 res.cookie = arg->cookie; 564 res.stat.stat = getlock(&arg4, rqstp, LOCK_ASYNC | LOCK_MON); 565 transmit_result(NLM_LOCK_RES, &res, 566 (struct sockaddr *)svc_getcaller(rqstp->rq_xprt)); 567 568 return (NULL); 569 } 570 571 /* nlm_cancel -------------------------------------------------------------- */ 572 /* 573 * Purpose: Cancel a blocked lock request 574 * Returns: granted or denied 575 * Notes: 576 */ 577 nlm_res * 578 nlm_cancel_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", rqstp); 589 590 /* copy cookie from arg to result. See comment in nlm_test_1() */ 591 res.cookie = arg->cookie; 592 593 /* 594 * Since at present we never return 'nlm_blocked', there can never be 595 * a lock to cancel, so this call always fails. 596 */ 597 res.stat.stat = unlock(&arg4, LOCK_CANCEL); 598 return (&res); 599 } 600 601 void * 602 nlm_cancel_msg_1_svc(arg, rqstp) 603 nlm_cancargs *arg; 604 struct svc_req *rqstp; 605 { 606 static nlm_res res; 607 struct nlm4_lock arg4; 608 609 nlmtonlm4(&arg->alock, &arg4); 610 611 if (debug_level) 612 log_from_addr("nlm_cancel_msg", rqstp); 613 614 res.cookie = arg->cookie; 615 /* 616 * Since at present we never return 'nlm_blocked', there can never be 617 * a lock to cancel, so this call always fails. 618 */ 619 res.stat.stat = unlock(&arg4, LOCK_CANCEL); 620 transmit_result(NLM_CANCEL_RES, &res, 621 (struct sockaddr *)svc_getcaller(rqstp->rq_xprt)); 622 return (NULL); 623 } 624 625 /* nlm_unlock -------------------------------------------------------------- */ 626 /* 627 * Purpose: Release an existing lock 628 * Returns: Always granted, unless during grace period 629 * Notes: "no such lock" error condition is ignored, as the 630 * protocol uses unreliable UDP datagrams, and may well 631 * re-try an unlock that has already succeeded. 632 */ 633 nlm_res * 634 nlm_unlock_1_svc(arg, rqstp) 635 nlm_unlockargs *arg; 636 struct svc_req *rqstp; 637 { 638 static nlm_res res; 639 struct nlm4_lock arg4; 640 641 nlmtonlm4(&arg->alock, &arg4); 642 643 if (debug_level) 644 log_from_addr("nlm_unlock", rqstp); 645 646 res.stat.stat = unlock(&arg4, 0); 647 res.cookie = arg->cookie; 648 649 return (&res); 650 } 651 652 void * 653 nlm_unlock_msg_1_svc(arg, rqstp) 654 nlm_unlockargs *arg; 655 struct svc_req *rqstp; 656 { 657 static nlm_res res; 658 struct nlm4_lock arg4; 659 660 nlmtonlm4(&arg->alock, &arg4); 661 662 if (debug_level) 663 log_from_addr("nlm_unlock_msg", rqstp); 664 665 res.stat.stat = unlock(&arg4, 0); 666 res.cookie = arg->cookie; 667 668 transmit_result(NLM_UNLOCK_RES, &res, 669 (struct sockaddr *)svc_getcaller(rqstp->rq_xprt)); 670 return (NULL); 671 } 672 673 /* ------------------------------------------------------------------------- */ 674 /* 675 * Client-side pseudo-RPCs for results. Note that for the client there 676 * are only nlm_xxx_msg() versions of each call, since the 'real RPC' 677 * version returns the results in the RPC result, and so the client 678 * does not normally receive incoming RPCs. 679 * 680 * The exception to this is nlm_granted(), which is genuinely an RPC 681 * call from the server to the client - a 'call-back' in normal procedure 682 * call terms. 683 */ 684 685 /* nlm_granted ------------------------------------------------------------- */ 686 /* 687 * Purpose: Receive notification that formerly blocked lock now granted 688 * Returns: always success ('granted') 689 * Notes: 690 */ 691 nlm_res * 692 nlm_granted_1_svc(arg, rqstp) 693 nlm_testargs *arg; 694 struct svc_req *rqstp; 695 { 696 static nlm_res res; 697 698 if (debug_level) 699 log_from_addr("nlm_granted", rqstp); 700 701 res.stat.stat = lock_answer(arg->alock.svid, &arg->cookie, 702 nlm_granted, NULL, NLM_VERS) == 0 ? 703 nlm_granted : nlm_denied; 704 705 /* copy cookie from arg to result. See comment in nlm_test_1() */ 706 res.cookie = arg->cookie; 707 708 return (&res); 709 } 710 711 void * 712 nlm_granted_msg_1_svc(arg, rqstp) 713 nlm_testargs *arg; 714 struct svc_req *rqstp; 715 { 716 static nlm_res res; 717 718 if (debug_level) 719 log_from_addr("nlm_granted_msg", rqstp); 720 721 res.cookie = arg->cookie; 722 res.stat.stat = lock_answer(arg->alock.svid, &arg->cookie, 723 nlm_granted, NULL, NLM_VERS) == 0 ? 724 nlm_granted : nlm_denied; 725 726 transmit_result(NLM_GRANTED_RES, &res, 727 (struct sockaddr *)svc_getcaller(rqstp->rq_xprt)); 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, 1071 (struct sockaddr *)svc_getcaller(rqstp->rq_xprt)); 1072 1073 return (NULL); 1074 } 1075 1076 /* nlm_cancel -------------------------------------------------------------- */ 1077 /* 1078 * Purpose: Cancel a blocked lock request 1079 * Returns: granted or denied 1080 * Notes: 1081 */ 1082 nlm4_res * 1083 nlm4_cancel_4_svc(arg, rqstp) 1084 nlm4_cancargs *arg; 1085 struct svc_req *rqstp; 1086 { 1087 static nlm4_res res; 1088 1089 if (debug_level) 1090 log_from_addr("nlm4_cancel", rqstp); 1091 1092 /* copy cookie from arg to result. See comment in nlm_test_1() */ 1093 res.cookie = arg->cookie; 1094 1095 /* 1096 * Since at present we never return 'nlm_blocked', there can never be 1097 * a lock to cancel, so this call always fails. 1098 */ 1099 res.stat.stat = unlock(&arg->alock, LOCK_CANCEL); 1100 return (&res); 1101 } 1102 1103 void * 1104 nlm4_cancel_msg_4_svc(arg, rqstp) 1105 nlm4_cancargs *arg; 1106 struct svc_req *rqstp; 1107 { 1108 static nlm4_res res; 1109 1110 if (debug_level) 1111 log_from_addr("nlm4_cancel_msg", rqstp); 1112 1113 res.cookie = arg->cookie; 1114 /* 1115 * Since at present we never return 'nlm_blocked', there can never be 1116 * a lock to cancel, so this call always fails. 1117 */ 1118 res.stat.stat = unlock(&arg->alock, LOCK_CANCEL | LOCK_V4); 1119 transmit4_result(NLM4_CANCEL_RES, &res, 1120 (struct sockaddr *)svc_getcaller(rqstp->rq_xprt)); 1121 return (NULL); 1122 } 1123 1124 /* nlm_unlock -------------------------------------------------------------- */ 1125 /* 1126 * Purpose: Release an existing lock 1127 * Returns: Always granted, unless during grace period 1128 * Notes: "no such lock" error condition is ignored, as the 1129 * protocol uses unreliable UDP datagrams, and may well 1130 * re-try an unlock that has already succeeded. 1131 */ 1132 nlm4_res * 1133 nlm4_unlock_4_svc(arg, rqstp) 1134 nlm4_unlockargs *arg; 1135 struct svc_req *rqstp; 1136 { 1137 static nlm4_res res; 1138 1139 if (debug_level) 1140 log_from_addr("nlm4_unlock", rqstp); 1141 1142 res.stat.stat = unlock(&arg->alock, LOCK_V4); 1143 res.cookie = arg->cookie; 1144 1145 return (&res); 1146 } 1147 1148 void * 1149 nlm4_unlock_msg_4_svc(arg, rqstp) 1150 nlm4_unlockargs *arg; 1151 struct svc_req *rqstp; 1152 { 1153 static nlm4_res res; 1154 1155 if (debug_level) 1156 log_from_addr("nlm4_unlock_msg", rqstp); 1157 1158 res.stat.stat = unlock(&arg->alock, LOCK_V4); 1159 res.cookie = arg->cookie; 1160 1161 transmit4_result(NLM4_UNLOCK_RES, &res, 1162 (struct sockaddr *)svc_getcaller(rqstp->rq_xprt)); 1163 return (NULL); 1164 } 1165 1166 /* ------------------------------------------------------------------------- */ 1167 /* 1168 * Client-side pseudo-RPCs for results. Note that for the client there 1169 * are only nlm_xxx_msg() versions of each call, since the 'real RPC' 1170 * version returns the results in the RPC result, and so the client 1171 * does not normally receive incoming RPCs. 1172 * 1173 * The exception to this is nlm_granted(), which is genuinely an RPC 1174 * call from the server to the client - a 'call-back' in normal procedure 1175 * call terms. 1176 */ 1177 1178 /* nlm_granted ------------------------------------------------------------- */ 1179 /* 1180 * Purpose: Receive notification that formerly blocked lock now granted 1181 * Returns: always success ('granted') 1182 * Notes: 1183 */ 1184 nlm4_res * 1185 nlm4_granted_4_svc(arg, rqstp) 1186 nlm4_testargs *arg; 1187 struct svc_req *rqstp; 1188 { 1189 static nlm4_res res; 1190 1191 if (debug_level) 1192 log_from_addr("nlm4_granted", rqstp); 1193 1194 res.stat.stat = lock_answer(arg->alock.svid, &arg->cookie, 1195 nlm4_granted, NULL, NLM_VERS4) == 0 ? 1196 nlm4_granted : nlm4_denied; 1197 1198 /* copy cookie from arg to result. See comment in nlm_test_1() */ 1199 res.cookie = arg->cookie; 1200 1201 return (&res); 1202 } 1203 1204 void * 1205 nlm4_granted_msg_4_svc(arg, rqstp) 1206 nlm4_testargs *arg; 1207 struct svc_req *rqstp; 1208 { 1209 static nlm4_res res; 1210 1211 if (debug_level) 1212 log_from_addr("nlm4_granted_msg", rqstp); 1213 1214 res.cookie = arg->cookie; 1215 res.stat.stat = lock_answer(arg->alock.svid, &arg->cookie, 1216 nlm4_granted, NULL, NLM_VERS4) == 0 ? 1217 nlm4_granted : nlm4_denied; 1218 transmit4_result(NLM4_GRANTED_RES, &res, 1219 (struct sockaddr *)svc_getrpccaller(rqstp->rq_xprt)->buf); 1220 return (NULL); 1221 } 1222 1223 /* nlm_test_res ------------------------------------------------------------ */ 1224 /* 1225 * Purpose: Accept result from earlier nlm_test_msg() call 1226 * Returns: Nothing 1227 */ 1228 void * 1229 nlm4_test_res_4_svc(arg, rqstp) 1230 nlm4_testres *arg; 1231 struct svc_req *rqstp; 1232 { 1233 if (debug_level) 1234 log_from_addr("nlm4_test_res", rqstp); 1235 1236 (void)lock_answer(-1, &arg->cookie, arg->stat.stat, 1237 (int *)&arg->stat.nlm4_testrply_u.holder.svid, 1238 NLM_VERS4); 1239 return (NULL); 1240 } 1241 1242 /* nlm_lock_res ------------------------------------------------------------ */ 1243 /* 1244 * Purpose: Accept result from earlier nlm_lock_msg() call 1245 * Returns: Nothing 1246 */ 1247 void * 1248 nlm4_lock_res_4_svc(arg, rqstp) 1249 nlm4_res *arg; 1250 struct svc_req *rqstp; 1251 { 1252 if (debug_level) 1253 log_from_addr("nlm4_lock_res", rqstp); 1254 1255 (void)lock_answer(-1, &arg->cookie, arg->stat.stat, NULL, NLM_VERS4); 1256 1257 return (NULL); 1258 } 1259 1260 /* nlm_cancel_res ---------------------------------------------------------- */ 1261 /* 1262 * Purpose: Accept result from earlier nlm_cancel_msg() call 1263 * Returns: Nothing 1264 */ 1265 void * 1266 nlm4_cancel_res_4_svc(arg, rqstp) 1267 nlm4_res *arg __unused; 1268 struct svc_req *rqstp; 1269 { 1270 if (debug_level) 1271 log_from_addr("nlm4_cancel_res", rqstp); 1272 return (NULL); 1273 } 1274 1275 /* nlm_unlock_res ---------------------------------------------------------- */ 1276 /* 1277 * Purpose: Accept result from earlier nlm_unlock_msg() call 1278 * Returns: Nothing 1279 */ 1280 void * 1281 nlm4_unlock_res_4_svc(arg, rqstp) 1282 nlm4_res *arg __unused; 1283 struct svc_req *rqstp; 1284 { 1285 if (debug_level) 1286 log_from_addr("nlm4_unlock_res", rqstp); 1287 return (NULL); 1288 } 1289 1290 /* nlm_granted_res --------------------------------------------------------- */ 1291 /* 1292 * Purpose: Accept result from earlier nlm_granted_msg() call 1293 * Returns: Nothing 1294 */ 1295 void * 1296 nlm4_granted_res_4_svc(arg, rqstp) 1297 nlm4_res *arg __unused; 1298 struct svc_req *rqstp; 1299 { 1300 if (debug_level) 1301 log_from_addr("nlm4_granted_res", rqstp); 1302 return (NULL); 1303 } 1304 1305 /* ------------------------------------------------------------------------- */ 1306 /* 1307 * Calls for PCNFS locking (aka non-monitored locking, no involvement 1308 * of rpc.statd). 1309 * 1310 * These are all genuine RPCs - no nlm_xxx_msg() nonsense here. 1311 */ 1312 1313 /* nlm_share --------------------------------------------------------------- */ 1314 /* 1315 * Purpose: Establish a DOS-style lock 1316 * Returns: success or failure 1317 * Notes: Blocking locks are not supported - client is expected 1318 * to retry if required. 1319 */ 1320 nlm4_shareres * 1321 nlm4_share_4_svc(arg, rqstp) 1322 nlm4_shareargs *arg; 1323 struct svc_req *rqstp; 1324 { 1325 static nlm4_shareres res; 1326 1327 if (debug_level) 1328 log_from_addr("nlm4_share", rqstp); 1329 1330 res.cookie = arg->cookie; 1331 res.stat = nlm4_granted; 1332 res.sequence = 1234356; /* X/Open says this field is ignored? */ 1333 return (&res); 1334 } 1335 1336 /* nlm4_unshare ------------------------------------------------------------ */ 1337 /* 1338 * Purpose: Release a DOS-style lock 1339 * Returns: nlm_granted, unless in grace period 1340 * Notes: 1341 */ 1342 nlm4_shareres * 1343 nlm4_unshare_4_svc(arg, rqstp) 1344 nlm4_shareargs *arg; 1345 struct svc_req *rqstp; 1346 { 1347 static nlm4_shareres res; 1348 1349 if (debug_level) 1350 log_from_addr("nlm_unshare", rqstp); 1351 1352 res.cookie = arg->cookie; 1353 res.stat = nlm4_granted; 1354 res.sequence = 1234356; /* X/Open says this field is ignored? */ 1355 return (&res); 1356 } 1357 1358 /* nlm4_nm_lock ------------------------------------------------------------ */ 1359 /* 1360 * Purpose: non-monitored version of nlm4_lock() 1361 * Returns: as for nlm4_lock() 1362 * Notes: These locks are in the same style as the standard nlm4_lock, 1363 * but the rpc.statd should not be called to establish a 1364 * monitor for the client machine, since that machine is 1365 * declared not to be running a rpc.statd, and so would not 1366 * respond to the statd protocol. 1367 */ 1368 nlm4_res * 1369 nlm4_nm_lock_4_svc(arg, rqstp) 1370 nlm4_lockargs *arg; 1371 struct svc_req *rqstp; 1372 { 1373 static nlm4_res res; 1374 1375 if (debug_level) 1376 log_from_addr("nlm4_nm_lock", rqstp); 1377 1378 /* copy cookie from arg to result. See comment in nlm4_test_1() */ 1379 res.cookie = arg->cookie; 1380 res.stat.stat = nlm4_granted; 1381 return (&res); 1382 } 1383 1384 /* nlm4_free_all ------------------------------------------------------------ */ 1385 /* 1386 * Purpose: Release all locks held by a named client 1387 * Returns: Nothing 1388 * Notes: Potential denial of service security problem here - the 1389 * locks to be released are specified by a host name, independent 1390 * of the address from which the request has arrived. 1391 * Should probably be rejected if the named host has been 1392 * using monitored locks. 1393 */ 1394 void * 1395 nlm4_free_all_4_svc(arg, rqstp) 1396 struct nlm4_notify *arg __unused; 1397 struct svc_req *rqstp; 1398 { 1399 static char dummy; 1400 1401 if (debug_level) 1402 log_from_addr("nlm4_free_all", rqstp); 1403 return (&dummy); 1404 } 1405 1406 /* nlm_sm_notify --------------------------------------------------------- */ 1407 /* 1408 * Purpose: called by rpc.statd when a monitored host state changes. 1409 * Returns: Nothing 1410 */ 1411 void * 1412 nlm_sm_notify_0_svc(arg, rqstp) 1413 struct nlm_sm_status *arg; 1414 struct svc_req *rqstp __unused; 1415 { 1416 static char dummy; 1417 notify(arg->mon_name, arg->state); 1418 return (&dummy); 1419 } 1420