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