kern.c revision 86188
175631Salfred/*- 275631Salfred * Copyright (c) 1997 Berkeley Software Design, Inc. All rights reserved. 375631Salfred * 475631Salfred * Redistribution and use in source and binary forms, with or without 575631Salfred * modification, are permitted provided that the following conditions 675631Salfred * are met: 775631Salfred * 1. Redistributions of source code must retain the above copyright 875631Salfred * notice, this list of conditions and the following disclaimer. 975631Salfred * 2. Redistributions in binary form must reproduce the above copyright 1075631Salfred * notice, this list of conditions and the following disclaimer in the 1175631Salfred * documentation and/or other materials provided with the distribution. 1275631Salfred * 3. Berkeley Software Design Inc's name may not be used to endorse or 1375631Salfred * promote products derived from this software without specific prior 1475631Salfred * written permission. 1575631Salfred * 1675631Salfred * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``AS IS'' AND 1775631Salfred * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1875631Salfred * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1975631Salfred * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN INC BE LIABLE 2075631Salfred * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2175631Salfred * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2275631Salfred * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2375631Salfred * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2475631Salfred * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2575631Salfred * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2675631Salfred * SUCH DAMAGE. 2775631Salfred * 2875631Salfred * from BSDI kern.c,v 1.2 1998/11/25 22:38:27 don Exp 2975631Salfred * $FreeBSD: head/usr.sbin/rpc.lockd/kern.c 86188 2001-11-08 10:37:32Z alfred $ 3075631Salfred */ 3175631Salfred 3275631Salfred#include <sys/param.h> 3375631Salfred#include <sys/mount.h> 3475631Salfred#include <sys/queue.h> 3575631Salfred#include <sys/socket.h> 3675631Salfred#include <sys/stat.h> 3775631Salfred 3875631Salfred#include <err.h> 3975631Salfred#include <errno.h> 4075631Salfred#include <fcntl.h> 4175631Salfred#include <stdio.h> 4275631Salfred#include <stdlib.h> 4375631Salfred#include <string.h> 4475631Salfred#include <syslog.h> 4575631Salfred#include <unistd.h> 4675631Salfred 4775631Salfred#include "nlm_prot.h" 4883653Speter#include <nfs/rpcv2.h> 4983653Speter#include <nfs/nfsproto.h> 5083653Speter#include <nfsclient/nfs_lock.h> 5175631Salfred 5275631Salfred#include "lockd.h" 5375631Salfred#include "lockd_lock.h" 5483653Speter#include <nfsclient/nfs.h> 5575631Salfred 5675631Salfred#define nfslockdans(_v, _ansp) \ 5775631Salfred ((_ansp)->la_vers = _v, \ 5883653Speter nfsclnt(NFSCLNT_LOCKDANS, _ansp)) 5975631Salfred 6075631Salfred/* Lock request owner. */ 6175631Salfredtypedef struct __owner { 6275631Salfred pid_t pid; /* Process ID. */ 6375631Salfred time_t tod; /* Time-of-day. */ 6475631Salfred} OWNER; 6575631Salfredstatic OWNER owner; 6675631Salfred 6775631Salfredstatic char hostname[MAXHOSTNAMELEN + 1]; /* Hostname. */ 6875631Salfred 6975631Salfredint lock_request(LOCKD_MSG *); 7075631Salfredint test_request(LOCKD_MSG *); 7175631Salfredvoid show(LOCKD_MSG *); 7275631Salfredint unlock_request(LOCKD_MSG *); 7375631Salfred 7475631Salfred/* 7575631Salfred * will break because fifo needs to be repopened when EOF'd 7675631Salfred */ 7775631Salfred#ifdef SETUID_DAEMON 7875631Salfred#define lockd_seteuid(uid) seteuid(uid) 7975631Salfred#else 8075631Salfred#define lockd_seteuid(uid) (1) 8175631Salfred#endif 8275631Salfred 8375979Salfred#define d_calls (debug_level > 1) 8475979Salfred#define d_args (debug_level > 2) 8575631Salfred 8675979Salfred#define from_addr(sockaddr) \ 8775979Salfred (inet_ntoa((sockaddr)->sin_addr)) 8875979Salfred 8975631Salfredvoid 9075631Salfredclient_cleanup(sig, code) 9175631Salfred int sig; 9275631Salfred int code; 9375631Salfred{ 9475631Salfred (void)lockd_seteuid(0); 9575631Salfred (void)unlink(_PATH_LCKFIFO); 9675631Salfred exit(-1); 9775631Salfred} 9875631Salfred 9975631Salfred/* 10075631Salfred * client_request -- 10175631Salfred * Loop around messages from the kernel, forwarding them off to 10275631Salfred * NLM servers. 10375631Salfred */ 10475631Salfredpid_t 10575631Salfredclient_request(void) 10675631Salfred{ 10775631Salfred LOCKD_MSG msg; 10875631Salfred fd_set rdset; 10975631Salfred int fd, nr, ret; 11075631Salfred pid_t child; 11175631Salfred 11275631Salfred /* Recreate the NLM fifo. */ 11375631Salfred (void)unlink(_PATH_LCKFIFO); 11475631Salfred (void)umask(S_IXGRP|S_IXOTH); 11575631Salfred if (mkfifo(_PATH_LCKFIFO, S_IWUSR | S_IRUSR)) { 11675631Salfred syslog(LOG_ERR, "mkfifo: %s: %m", _PATH_LCKFIFO); 11775631Salfred exit (1); 11875631Salfred } 11975631Salfred 12075631Salfred /* 12175631Salfred * Create a separate process, the client code is really a separate 12275631Salfred * daemon that shares a lot of code. 12375631Salfred */ 12475631Salfred switch (child = fork()) { 12575631Salfred case -1: 12675631Salfred err(1, "fork"); 12775631Salfred case 0: 12875631Salfred break; 12975631Salfred default: 13075631Salfred return (child); 13175631Salfred } 13275631Salfred 13375631Salfred signal(SIGHUP, client_cleanup); 13475631Salfred signal(SIGTERM, client_cleanup); 13575631Salfred 13675631Salfred /* Setup. */ 13775631Salfred (void)time(&owner.tod); 13875631Salfred owner.pid = getpid(); 13975631Salfred (void)gethostname(hostname, sizeof(hostname) - 1); 14075631Salfred 14175631Salfred /* Open the fifo for reading. */ 14286188Salfred if ((fd = open(_PATH_LCKFIFO, O_RDONLY | O_NONBLOCK)) < 0) 14375631Salfred syslog(LOG_ERR, "open: %s: %m", _PATH_LCKFIFO); 14475631Salfred 14575631Salfred /* drop our root priviledges */ 14675631Salfred (void)lockd_seteuid(daemon_uid); 14775631Salfred 14875631Salfred for (;;) { 14975631Salfred /* Wait for contact... fifo's return EAGAIN when read with 15075631Salfred * no data 15175631Salfred */ 15286188Salfred /* Set up the select. */ 15386188Salfred FD_ZERO(&rdset); 15475631Salfred FD_SET(fd, &rdset); 15575631Salfred (void)select(fd + 1, &rdset, NULL, NULL, NULL); 15675631Salfred 15775631Salfred /* Read the fixed length message. */ 15875631Salfred if ((nr = read(fd, &msg, sizeof(msg))) == sizeof(msg)) { 15975631Salfred if (d_args) 16075631Salfred show(&msg); 16175631Salfred 16275631Salfred if (msg.lm_version != LOCKD_MSG_VERSION) { 16375631Salfred syslog(LOG_ERR, 16475631Salfred "unknown msg type: %d", msg.lm_version); 16575631Salfred } 16675631Salfred /* 16775631Salfred * Send it to the NLM server and don't grant the lock 16875631Salfred * if we fail for any reason. 16975631Salfred */ 17075631Salfred switch (msg.lm_fl.l_type) { 17175631Salfred case F_RDLCK: 17275631Salfred case F_WRLCK: 17375631Salfred if (msg.lm_getlk) 17475631Salfred ret = test_request(&msg); 17575631Salfred else 17675631Salfred ret = lock_request(&msg); 17775631Salfred break; 17875631Salfred case F_UNLCK: 17975631Salfred ret = unlock_request(&msg); 18075631Salfred break; 18175631Salfred default: 18275631Salfred ret = 1; 18375631Salfred syslog(LOG_ERR, 18475631Salfred "unknown lock type: %d", msg.lm_fl.l_type); 18575631Salfred break; 18675631Salfred } 18775631Salfred if (ret) { 18875631Salfred struct lockd_ans ans; 18975631Salfred 19075631Salfred ans.la_msg_ident = msg.lm_msg_ident; 19175631Salfred ans.la_errno = EHOSTUNREACH; 19275631Salfred 19375631Salfred if (nfslockdans(LOCKD_ANS_VERSION, &ans)) { 19475631Salfred syslog((errno == EPIPE ? LOG_INFO : 19575631Salfred LOG_ERR), "process %lu: %m", 19675631Salfred (u_long)msg.lm_msg_ident.pid); 19775631Salfred } 19875631Salfred } 19975631Salfred } else if (nr == -1) { 20075631Salfred if (errno != EAGAIN) { 20175631Salfred syslog(LOG_ERR, "read: %s: %m", _PATH_LCKFIFO); 20275631Salfred goto err; 20375631Salfred } 20475631Salfred } else if (nr != 0) { 20575631Salfred syslog(LOG_ERR, 20675631Salfred "%s: discard %d bytes", _PATH_LCKFIFO, nr); 20775631Salfred } 20875631Salfred } 20975631Salfred 21075631Salfred /* Reached only on error. */ 21175631Salfrederr: 21275631Salfred (void)lockd_seteuid(0); 21375631Salfred (void)unlink(_PATH_LCKFIFO); 21475631Salfred _exit (1); 21575631Salfred} 21675631Salfred 21775631Salfredvoid 21886186Salfredset_auth(cl, ucred) 21986186Salfred CLIENT *cl; 22086186Salfred struct ucred *ucred; 22175631Salfred{ 22275631Salfred if (cl->cl_auth != NULL) 22375631Salfred cl->cl_auth->ah_ops->ah_destroy(cl->cl_auth); 22475631Salfred cl->cl_auth = authunix_create(hostname, 22575631Salfred ucred->cr_uid, 22675631Salfred ucred->cr_groups[0], 22775631Salfred ucred->cr_ngroups-1, 22875631Salfred &ucred->cr_groups[1]); 22975631Salfred} 23075631Salfred 23175631Salfred 23275631Salfred/* 23375631Salfred * test_request -- 23475631Salfred * Convert a lock LOCKD_MSG into an NLM request, and send it off. 23575631Salfred */ 23675631Salfredint 23775631Salfredtest_request(LOCKD_MSG *msg) 23875631Salfred{ 23975631Salfred CLIENT *cli; 24075631Salfred struct timeval timeout = {0, 0}; /* No timeout, no response. */ 24175631Salfred char dummy; 24275631Salfred 24375631Salfred if (d_calls) 24475631Salfred syslog(LOG_DEBUG, "test request: %s: %s to %s", 24575631Salfred msg->lm_nfsv3 ? "V4" : "V1/3", 24675631Salfred msg->lm_fl.l_type == F_WRLCK ? "write" : "read", 24775631Salfred from_addr((struct sockaddr_in *)&msg->lm_addr)); 24875631Salfred 24975631Salfred if (msg->lm_nfsv3) { 25075631Salfred struct nlm4_testargs arg4; 25175631Salfred 25275631Salfred arg4.cookie.n_bytes = (char *)&msg->lm_msg_ident; 25375631Salfred arg4.cookie.n_len = sizeof(msg->lm_msg_ident); 25475631Salfred arg4.exclusive = msg->lm_fl.l_type == F_WRLCK ? 1 : 0; 25575631Salfred arg4.alock.caller_name = hostname; 25675631Salfred arg4.alock.fh.n_bytes = (char *)&msg->lm_fh; 25775631Salfred arg4.alock.fh.n_len = msg->lm_fh_len; 25875631Salfred arg4.alock.oh.n_bytes = (char *)&owner; 25975631Salfred arg4.alock.oh.n_len = sizeof(owner); 26075631Salfred arg4.alock.svid = msg->lm_msg_ident.pid; 26175631Salfred arg4.alock.l_offset = msg->lm_fl.l_start; 26275631Salfred arg4.alock.l_len = msg->lm_fl.l_len; 26375631Salfred 26475631Salfred if ((cli = get_client( 26575631Salfred (struct sockaddr *)&msg->lm_addr, 26675631Salfred NLM_VERS4)) == NULL) 26775631Salfred return (1); 26875631Salfred 26975631Salfred set_auth(cli, &msg->lm_cred); 27075631Salfred (void)clnt_call(cli, NLM_TEST_MSG, 27175631Salfred xdr_nlm4_testargs, &arg4, xdr_void, &dummy, timeout); 27275631Salfred } else { 27375631Salfred struct nlm_testargs arg; 27475631Salfred 27575631Salfred arg.cookie.n_bytes = (char *)&msg->lm_msg_ident; 27675631Salfred arg.cookie.n_len = sizeof(msg->lm_msg_ident); 27775631Salfred arg.exclusive = msg->lm_fl.l_type == F_WRLCK ? 1 : 0; 27875631Salfred arg.alock.caller_name = hostname; 27975631Salfred arg.alock.fh.n_bytes = (char *)&msg->lm_fh; 28075631Salfred arg.alock.fh.n_len = msg->lm_fh_len; 28175631Salfred arg.alock.oh.n_bytes = (char *)&owner; 28275631Salfred arg.alock.oh.n_len = sizeof(owner); 28375631Salfred arg.alock.svid = msg->lm_msg_ident.pid; 28475631Salfred arg.alock.l_offset = msg->lm_fl.l_start; 28575631Salfred arg.alock.l_len = msg->lm_fl.l_len; 28675631Salfred 28775631Salfred if ((cli = get_client( 28875631Salfred (struct sockaddr *)&msg->lm_addr, 28975631Salfred NLM_VERS)) == NULL) 29075631Salfred return (1); 29175631Salfred 29275631Salfred set_auth(cli, &msg->lm_cred); 29375631Salfred (void)clnt_call(cli, NLM_TEST_MSG, 29475631Salfred xdr_nlm_testargs, &arg, xdr_void, &dummy, timeout); 29575631Salfred } 29675631Salfred return (0); 29775631Salfred} 29875631Salfred 29975631Salfred/* 30075631Salfred * lock_request -- 30175631Salfred * Convert a lock LOCKD_MSG into an NLM request, and send it off. 30275631Salfred */ 30375631Salfredint 30475631Salfredlock_request(LOCKD_MSG *msg) 30575631Salfred{ 30675631Salfred CLIENT *cli; 30775631Salfred struct nlm4_lockargs arg4; 30875631Salfred struct nlm_lockargs arg; 30975631Salfred struct timeval timeout = {0, 0}; /* No timeout, no response. */ 31075631Salfred char dummy; 31175631Salfred 31275631Salfred if (d_calls) 31375631Salfred syslog(LOG_DEBUG, "lock request: %s: %s to %s", 31475631Salfred msg->lm_nfsv3 ? "V4" : "V1/3", 31575631Salfred msg->lm_fl.l_type == F_WRLCK ? "write" : "read", 31675631Salfred from_addr((struct sockaddr_in *)&msg->lm_addr)); 31775631Salfred 31875631Salfred if (msg->lm_nfsv3) { 31975631Salfred arg4.cookie.n_bytes = (char *)&msg->lm_msg_ident; 32075631Salfred arg4.cookie.n_len = sizeof(msg->lm_msg_ident); 32175631Salfred arg4.block = msg->lm_wait ? 1 : 0; 32275631Salfred arg4.exclusive = msg->lm_fl.l_type == F_WRLCK ? 1 : 0; 32375631Salfred arg4.alock.caller_name = hostname; 32475631Salfred arg4.alock.fh.n_bytes = (char *)&msg->lm_fh; 32575631Salfred arg4.alock.fh.n_len = msg->lm_fh_len; 32675631Salfred arg4.alock.oh.n_bytes = (char *)&owner; 32775631Salfred arg4.alock.oh.n_len = sizeof(owner); 32875631Salfred arg4.alock.svid = msg->lm_msg_ident.pid; 32975631Salfred arg4.alock.l_offset = msg->lm_fl.l_start; 33075631Salfred arg4.alock.l_len = msg->lm_fl.l_len; 33175631Salfred arg4.reclaim = 0; 33275631Salfred arg4.state = nsm_state; 33375631Salfred 33475631Salfred if ((cli = get_client( 33575631Salfred (struct sockaddr *)&msg->lm_addr, 33675631Salfred NLM_VERS4)) == NULL) 33775631Salfred return (1); 33875631Salfred 33975631Salfred set_auth(cli, &msg->lm_cred); 34075631Salfred (void)clnt_call(cli, NLM_LOCK_MSG, 34175631Salfred xdr_nlm4_lockargs, &arg4, xdr_void, &dummy, timeout); 34275631Salfred } else { 34375631Salfred arg.cookie.n_bytes = (char *)&msg->lm_msg_ident; 34475631Salfred arg.cookie.n_len = sizeof(msg->lm_msg_ident); 34575631Salfred arg.block = msg->lm_wait ? 1 : 0; 34675631Salfred arg.exclusive = msg->lm_fl.l_type == F_WRLCK ? 1 : 0; 34775631Salfred arg.alock.caller_name = hostname; 34875631Salfred arg.alock.fh.n_bytes = (char *)&msg->lm_fh; 34975631Salfred arg.alock.fh.n_len = msg->lm_fh_len; 35075631Salfred arg.alock.oh.n_bytes = (char *)&owner; 35175631Salfred arg.alock.oh.n_len = sizeof(owner); 35275631Salfred arg.alock.svid = msg->lm_msg_ident.pid; 35375631Salfred arg.alock.l_offset = msg->lm_fl.l_start; 35475631Salfred arg.alock.l_len = msg->lm_fl.l_len; 35575631Salfred arg.reclaim = 0; 35675631Salfred arg.state = nsm_state; 35775631Salfred 35875631Salfred if ((cli = get_client( 35975631Salfred (struct sockaddr *)&msg->lm_addr, 36075631Salfred NLM_VERS)) == NULL) 36175631Salfred return (1); 36275631Salfred 36375631Salfred set_auth(cli, &msg->lm_cred); 36475631Salfred (void)clnt_call(cli, NLM_LOCK_MSG, 36575631Salfred xdr_nlm_lockargs, &arg, xdr_void, &dummy, timeout); 36675631Salfred } 36775631Salfred return (0); 36875631Salfred} 36975631Salfred 37075631Salfred/* 37175631Salfred * unlock_request -- 37275631Salfred * Convert an unlock LOCKD_MSG into an NLM request, and send it off. 37375631Salfred */ 37475631Salfredint 37575631Salfredunlock_request(LOCKD_MSG *msg) 37675631Salfred{ 37775631Salfred CLIENT *cli; 37875631Salfred struct nlm4_unlockargs arg4; 37975631Salfred struct nlm_unlockargs arg; 38075631Salfred struct timeval timeout = {0, 0}; /* No timeout, no response. */ 38175631Salfred char dummy; 38275631Salfred 38375631Salfred if (d_calls) 38475631Salfred syslog(LOG_DEBUG, "unlock request: %s: to %s", 38575631Salfred msg->lm_nfsv3 ? "V4" : "V1/3", 38675631Salfred from_addr((struct sockaddr_in *)&msg->lm_addr)); 38775631Salfred 38875631Salfred if (msg->lm_nfsv3) { 38975631Salfred arg4.cookie.n_bytes = (char *)&msg->lm_msg_ident; 39075631Salfred arg4.cookie.n_len = sizeof(msg->lm_msg_ident); 39175631Salfred arg4.alock.caller_name = hostname; 39275631Salfred arg4.alock.fh.n_bytes = (char *)&msg->lm_fh; 39375631Salfred arg4.alock.fh.n_len = msg->lm_fh_len; 39475631Salfred arg4.alock.oh.n_bytes = (char *)&owner; 39575631Salfred arg4.alock.oh.n_len = sizeof(owner); 39675631Salfred arg4.alock.svid = msg->lm_msg_ident.pid; 39775631Salfred arg4.alock.l_offset = msg->lm_fl.l_start; 39875631Salfred arg4.alock.l_len = msg->lm_fl.l_len; 39975631Salfred 40075631Salfred if ((cli = get_client( 40175631Salfred (struct sockaddr *)&msg->lm_addr, 40275631Salfred NLM_VERS4)) == NULL) 40375631Salfred return (1); 40475631Salfred 40575631Salfred set_auth(cli, &msg->lm_cred); 40675631Salfred (void)clnt_call(cli, NLM_UNLOCK_MSG, 40775631Salfred xdr_nlm4_unlockargs, &arg4, xdr_void, &dummy, timeout); 40875631Salfred } else { 40975631Salfred arg.cookie.n_bytes = (char *)&msg->lm_msg_ident; 41075631Salfred arg.cookie.n_len = sizeof(msg->lm_msg_ident); 41175631Salfred arg.alock.caller_name = hostname; 41275631Salfred arg.alock.fh.n_bytes = (char *)&msg->lm_fh; 41375631Salfred arg.alock.fh.n_len = msg->lm_fh_len; 41475631Salfred arg.alock.oh.n_bytes = (char *)&owner; 41575631Salfred arg.alock.oh.n_len = sizeof(owner); 41675631Salfred arg.alock.svid = msg->lm_msg_ident.pid; 41775631Salfred arg.alock.l_offset = msg->lm_fl.l_start; 41875631Salfred arg.alock.l_len = msg->lm_fl.l_len; 41975631Salfred 42075631Salfred if ((cli = get_client( 42175631Salfred (struct sockaddr *)&msg->lm_addr, 42275631Salfred NLM_VERS)) == NULL) 42375631Salfred return (1); 42475631Salfred 42575631Salfred set_auth(cli, &msg->lm_cred); 42675631Salfred (void)clnt_call(cli, NLM_UNLOCK_MSG, 42775631Salfred xdr_nlm_unlockargs, &arg, xdr_void, &dummy, timeout); 42875631Salfred } 42975631Salfred 43075631Salfred return (0); 43175631Salfred} 43275631Salfred 43375631Salfredint 43475631Salfredlock_answer(int pid, netobj *netcookie, int result, int *pid_p, int version) 43575631Salfred{ 43675631Salfred struct lockd_ans ans; 43775631Salfred 43875631Salfred if (netcookie->n_len != sizeof(ans.la_msg_ident)) { 43975631Salfred if (pid == -1) { /* we're screwed */ 44075631Salfred syslog(LOG_ERR, "inedible nlm cookie"); 44175631Salfred return -1; 44275631Salfred } 44375631Salfred ans.la_msg_ident.pid = pid; 44475631Salfred ans.la_msg_ident.msg_seq = -1; 44575631Salfred } else { 44686186Salfred memcpy(&ans.la_msg_ident, netcookie->n_bytes, 44786186Salfred sizeof(ans.la_msg_ident)); 44875631Salfred } 44975631Salfred 45075631Salfred if (d_calls) 45175979Salfred syslog(LOG_DEBUG, "lock answer: pid %lu: %s %d", 45275979Salfred ans.la_msg_ident.pid, 45375979Salfred version == NLM_VERS4 ? "nlmv4" : "nlmv3", 45475979Salfred result); 45575631Salfred 45675631Salfred ans.la_set_getlk_pid = 0; 45775631Salfred if (version == NLM_VERS4) 45875631Salfred switch (result) { 45975631Salfred case nlm4_granted: 46075631Salfred ans.la_errno = 0; 46175631Salfred break; 46275631Salfred default: 46375631Salfred ans.la_errno = EACCES; 46475631Salfred break; 46575631Salfred case nlm4_denied: 46675631Salfred if (pid_p == NULL) 46775631Salfred ans.la_errno = EACCES; 46875631Salfred else { 46975631Salfred /* this is an answer to a nlm_test msg */ 47075631Salfred ans.la_set_getlk_pid = 1; 47175631Salfred ans.la_getlk_pid = *pid_p; 47275631Salfred ans.la_errno = 0; 47375631Salfred } 47475631Salfred break; 47575631Salfred case nlm4_denied_nolocks: 47675631Salfred ans.la_errno = EAGAIN; 47775631Salfred break; 47875631Salfred case nlm4_blocked: 47975631Salfred return -1; 48075631Salfred /* NOTREACHED */ 48175631Salfred case nlm4_denied_grace_period: 48275631Salfred ans.la_errno = EAGAIN; 48375631Salfred break; 48475631Salfred case nlm4_deadlck: 48575631Salfred ans.la_errno = EDEADLK; 48675631Salfred break; 48775631Salfred case nlm4_rofs: 48875631Salfred ans.la_errno = EROFS; 48975631Salfred break; 49075631Salfred case nlm4_stale_fh: 49175631Salfred ans.la_errno = ESTALE; 49275631Salfred break; 49375631Salfred case nlm4_fbig: 49475631Salfred ans.la_errno = EFBIG; 49575631Salfred break; 49675631Salfred case nlm4_failed: 49775631Salfred ans.la_errno = EACCES; 49875631Salfred break; 49975631Salfred } 50075631Salfred else 50175631Salfred switch (result) { 50275631Salfred case nlm_granted: 50375631Salfred ans.la_errno = 0; 50475631Salfred break; 50575631Salfred default: 50675631Salfred ans.la_errno = EACCES; 50775631Salfred break; 50875631Salfred case nlm_denied: 50975631Salfred if (pid_p == NULL) 51075631Salfred ans.la_errno = EACCES; 51175631Salfred else { 51275631Salfred /* this is an answer to a nlm_test msg */ 51375631Salfred ans.la_set_getlk_pid = 1; 51475631Salfred ans.la_getlk_pid = *pid_p; 51575631Salfred ans.la_errno = 0; 51675631Salfred } 51775631Salfred break; 51875631Salfred case nlm_denied_nolocks: 51975631Salfred ans.la_errno = EAGAIN; 52075631Salfred break; 52175631Salfred case nlm_blocked: 52275631Salfred return -1; 52375631Salfred /* NOTREACHED */ 52475631Salfred case nlm_denied_grace_period: 52575631Salfred ans.la_errno = EAGAIN; 52675631Salfred break; 52775631Salfred case nlm_deadlck: 52875631Salfred ans.la_errno = EDEADLK; 52975631Salfred break; 53075631Salfred } 53175631Salfred 53275631Salfred if (nfslockdans(LOCKD_ANS_VERSION, &ans)) { 53375631Salfred syslog(((errno == EPIPE || errno == ESRCH) ? 53475631Salfred LOG_INFO : LOG_ERR), 53575631Salfred "process %lu: %m", (u_long)ans.la_msg_ident.pid); 53675631Salfred return -1; 53775631Salfred } 53875631Salfred return 0; 53975631Salfred} 54075631Salfred 54175631Salfred/* 54275631Salfred * show -- 54375631Salfred * Display the contents of a kernel LOCKD_MSG structure. 54475631Salfred */ 54575631Salfredvoid 54675631Salfredshow(LOCKD_MSG *mp) 54775631Salfred{ 54875631Salfred static char hex[] = "0123456789abcdef"; 54975631Salfred struct fid *fidp; 55075631Salfred fsid_t *fsidp; 55175631Salfred size_t len; 55275631Salfred u_int8_t *p, *t, buf[NFS_SMALLFH*3+1]; 55375631Salfred 55486187Salfred syslog(LOG_DEBUG, "process ID: %lu\n", (long)mp->lm_msg_ident.pid); 55575631Salfred 55675631Salfred fsidp = (fsid_t *)&mp->lm_fh; 55775631Salfred fidp = (struct fid *)((u_int8_t *)&mp->lm_fh + sizeof(fsid_t)); 55875631Salfred 55975631Salfred for (t = buf, p = (u_int8_t *)mp->lm_fh, 56075631Salfred len = mp->lm_fh_len; 56175631Salfred len > 0; ++p, --len) { 56275631Salfred *t++ = '\\'; 56375631Salfred *t++ = hex[(*p & 0xf0) >> 4]; 56475631Salfred *t++ = hex[*p & 0x0f]; 56575631Salfred } 56675631Salfred *t = '\0'; 56775631Salfred 56886187Salfred syslog(LOG_DEBUG, "fh_len %d, fh %s\n", mp->lm_fh_len, buf); 56975631Salfred 57075631Salfred /* Show flock structure. */ 57186187Salfred syslog(LOG_DEBUG, "start %qu; len %qu; pid %lu; type %d; whence %d\n", 57275631Salfred mp->lm_fl.l_start, mp->lm_fl.l_len, (u_long)mp->lm_fl.l_pid, 57375631Salfred mp->lm_fl.l_type, mp->lm_fl.l_whence); 57475631Salfred 57575631Salfred /* Show wait flag. */ 57686187Salfred syslog(LOG_DEBUG, "wait was %s\n", mp->lm_wait ? "set" : "not set"); 57775631Salfred} 578