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