1192811Srmacklem/*-
2192811Srmacklem * Copyright (c) 2009 Rick Macklem, University of Guelph
3192811Srmacklem * All rights reserved.
4192811Srmacklem *
5192811Srmacklem * Redistribution and use in source and binary forms, with or without
6192811Srmacklem * modification, are permitted provided that the following conditions
7192811Srmacklem * are met:
8192811Srmacklem * 1. Redistributions of source code must retain the above copyright
9192811Srmacklem *    notice, this list of conditions and the following disclaimer.
10192811Srmacklem * 2. Redistributions in binary form must reproduce the above copyright
11192811Srmacklem *    notice, this list of conditions and the following disclaimer in the
12192811Srmacklem *    documentation and/or other materials provided with the distribution.
13192811Srmacklem *
14192811Srmacklem * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15192811Srmacklem * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16192811Srmacklem * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17192811Srmacklem * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18192811Srmacklem * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19192811Srmacklem * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20192811Srmacklem * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21192811Srmacklem * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22192811Srmacklem * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23192811Srmacklem * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24192811Srmacklem * SUCH DAMAGE.
25192811Srmacklem *
26192811Srmacklem */
27192811Srmacklem
28192811Srmacklem#include <sys/cdefs.h>
29192811Srmacklem__FBSDID("$FreeBSD$");
30192811Srmacklem
31192811Srmacklem#include <sys/param.h>
32192811Srmacklem#include <sys/linker.h>
33192811Srmacklem#include <sys/module.h>
34192811Srmacklem#include <sys/mount.h>
35192811Srmacklem#include <sys/socket.h>
36192811Srmacklem#include <sys/sysctl.h>
37192811Srmacklem#include <sys/vnode.h>
38192811Srmacklem
39192811Srmacklem#include <netinet/in.h>
40192811Srmacklem
41192811Srmacklem#include <nfs/nfssvc.h>
42192811Srmacklem
43192811Srmacklem#include <fs/nfs/rpcv2.h>
44192811Srmacklem#include <fs/nfs/nfsproto.h>
45192811Srmacklem#include <fs/nfs/nfskpiport.h>
46192811Srmacklem#include <fs/nfs/nfs.h>
47192811Srmacklem
48192811Srmacklem#include <ctype.h>
49192811Srmacklem#include <err.h>
50192811Srmacklem#include <errno.h>
51192811Srmacklem#include <fcntl.h>
52192811Srmacklem#include <limits.h>
53192811Srmacklem#include <paths.h>
54192811Srmacklem#include <signal.h>
55192811Srmacklem#include <stdio.h>
56192811Srmacklem#include <stdlib.h>
57192811Srmacklem#include <string.h>
58192811Srmacklem#include <unistd.h>
59192811Srmacklem
60193070Sdelphijstatic void usage(void);
61192811Srmacklem
62192811Srmacklemint
63192811Srmacklemmain(int argc, char **argv)
64192811Srmacklem{
65192811Srmacklem	char *cp;
66192811Srmacklem	u_char val;
67192811Srmacklem	int cnt, even;
68193070Sdelphij	struct nfsd_clid revoke_handle;
69192811Srmacklem
70192811Srmacklem	if (modfind("nfsd") < 0)
71192811Srmacklem		errx(1, "nfsd not loaded - self terminating");
72192811Srmacklem	if (argc != 2)
73192811Srmacklem		usage();
74192811Srmacklem	cnt = 0;
75192811Srmacklem	cp = argv[1];
76192811Srmacklem	if (strlen(cp) % 2)
77192811Srmacklem		even = 0;
78192811Srmacklem	else
79192811Srmacklem		even = 1;
80192811Srmacklem	val = 0;
81192811Srmacklem	while (*cp) {
82193070Sdelphij		if (*cp >= '0' && *cp <= '9')
83192811Srmacklem			val += (u_char)(*cp - '0');
84192811Srmacklem		else if (*cp >= 'A' && *cp <= 'F')
85192811Srmacklem			val += ((u_char)(*cp - 'A')) + 0xa;
86192811Srmacklem		else if (*cp >= 'a' && *cp <= 'f')
87192811Srmacklem			val += ((u_char)(*cp - 'a')) + 0xa;
88192811Srmacklem		else
89192811Srmacklem			errx(1, "Non hexadecimal digit in %s", argv[1]);
90192811Srmacklem		if (even) {
91192811Srmacklem			val <<= 4;
92192811Srmacklem			even = 0;
93192811Srmacklem		} else {
94193070Sdelphij			revoke_handle.nclid_id[cnt++] = val;
95192811Srmacklem			if (cnt > NFSV4_OPAQUELIMIT)
96192811Srmacklem				errx(1, "Clientid %s, loo long", argv[1]);
97192811Srmacklem			val = 0;
98192811Srmacklem			even = 1;
99192811Srmacklem		}
100192811Srmacklem		cp++;
101192811Srmacklem	}
102192811Srmacklem
103192811Srmacklem	/*
104192811Srmacklem	 * Do the revocation system call.
105192811Srmacklem	 */
106193070Sdelphij	revoke_handle.nclid_idlen = cnt;
107192811Srmacklem#ifdef DEBUG
108193070Sdelphij	printf("Idlen=%d\n", revoke_handle.nclid_idlen);
109193070Sdelphij	for (cnt = 0; cnt < revoke_handle.nclid_idlen; cnt++)
110193070Sdelphij		printf("%02x", revoke_handle.nclid_id[cnt]);
111192811Srmacklem	printf("\n");
112192811Srmacklem#else
113193070Sdelphij	if (nfssvc(NFSSVC_ADMINREVOKE, &revoke_handle) < 0)
114192811Srmacklem		err(1, "Admin revoke failed");
115192811Srmacklem#endif
116192811Srmacklem}
117192811Srmacklem
118193070Sdelphijstatic void
119192811Srmacklemusage(void)
120192811Srmacklem{
121192811Srmacklem
122192811Srmacklem	errx(1, "Usage: nfsrevoke <ClientID>");
123192811Srmacklem}
124