From 09cc3c831c8b1f27439fe09c951139bb6ec8e6c6 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Thu, 8 Nov 2012 15:00:04 -0500 Subject: [PATCH] nfsdcltrack: add a new "one-shot" program for manipulating the client tracking db Usermode helper upcalls are all the rage these days for infrequent upcalls, since they make it rather idiot-proof. No running daemon is required, so there's really no setup beyond ensuring that the callout exists and is runnable. This program adds a callout program to nfs-utils for that purpose. The storage engine on the backend is identical to the one used by nfsdcld. This just adds a new frontend for it. For now, building with --enable-nfsdcltrack gives you both nfsdcld and nfsdcltrack programs. A later patch will remove nfsdcld altogether. Signed-off-by: Jeff Layton Signed-off-by: Steve Dickson --- .gitignore | 2 +- utils/nfsdcltrack/Makefile.am | 6 +- utils/nfsdcltrack/nfsdcld | Bin 64072 -> 64499 bytes utils/nfsdcltrack/nfsdcltrack.c | 436 ++++++++++++++++++++++++++++++++ 4 files changed, 441 insertions(+), 3 deletions(-) create mode 100644 utils/nfsdcltrack/nfsdcltrack.c diff --git a/.gitignore b/.gitignore index 96f9750..39853d9 100644 --- a/.gitignore +++ b/.gitignore @@ -49,7 +49,7 @@ utils/rquotad/rquotad utils/rquotad/rquota.h utils/rquotad/rquota_xdr.c utils/showmount/showmount -utils/nfsdcld/nfsdcld +utils/nfsdcltrack/nfsdcltrack utils/statd/statd tools/locktest/testlk tools/getiversion/getiversion diff --git a/utils/nfsdcltrack/Makefile.am b/utils/nfsdcltrack/Makefile.am index 073a71b..afae455 100644 --- a/utils/nfsdcltrack/Makefile.am +++ b/utils/nfsdcltrack/Makefile.am @@ -4,11 +4,13 @@ man8_MANS = nfsdcld.man EXTRA_DIST = $(man8_MANS) AM_CFLAGS += -D_LARGEFILE64_SOURCE -sbin_PROGRAMS = nfsdcld +sbin_PROGRAMS = nfsdcld nfsdcltrack nfsdcld_SOURCES = nfsdcld.c sqlite.c - nfsdcld_LDADD = ../../support/nfs/libnfs.a $(LIBEVENT) $(LIBSQLITE) $(LIBCAP) +nfsdcltrack_SOURCES = nfsdcltrack.c sqlite.c +nfsdcltrack_LDADD = ../../support/nfs/libnfs.a $(LIBSQLITE) $(LIBCAP) + MAINTAINERCLEANFILES = Makefile.in diff --git a/utils/nfsdcltrack/nfsdcld b/utils/nfsdcltrack/nfsdcld index 651b0c35306120de549505a083ea8d50ffab7b48..eedf29d773f26fcedc4c39c5142e6b045135d77a 100755 GIT binary patch delta 19913 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 IpKYf91N(-R%K!iX delta 19371 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�M05PEc5 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 diff --git a/utils/nfsdcltrack/nfsdcltrack.c b/utils/nfsdcltrack/nfsdcltrack.c new file mode 100644 index 0000000..1d262a2 --- /dev/null +++ b/utils/nfsdcltrack/nfsdcltrack.c @@ -0,0 +1,436 @@ +/* + * nfsdcltrack.c -- NFSv4 client name tracking program + * + * Copyright (C) 2012 Jeff Layton + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_CAPABILITY_H +#include +#include +#endif + +#include "xlog.h" +#include "sqlite.h" + +#ifndef CLD_DEFAULT_STORAGEDIR +#define CLD_DEFAULT_STORAGEDIR NFS_STATEDIR "/nfsdcltrack" +#endif + +/* defined by RFC 3530 */ +#define NFS4_OPAQUE_LIMIT 1024 + +/* private data structures */ +struct cltrack_cmd { + char *name; + bool needs_arg; + int (*func)(const char *arg); +}; + +/* forward declarations */ +static int cltrack_init(const char *unused); +static int cltrack_create(const char *id); +static int cltrack_remove(const char *id); +static int cltrack_check(const char *id); +static int cltrack_gracedone(const char *gracetime); + +/* global variables */ +static struct option longopts[] = +{ + { "help", 0, NULL, 'h' }, + { "debug", 0, NULL, 'd' }, + { "foreground", 0, NULL, 'f' }, + { "storagedir", 1, NULL, 's' }, + { NULL, 0, 0, 0 }, +}; + +static struct cltrack_cmd commands[] = +{ + { "init", false, cltrack_init }, + { "create", true, cltrack_create }, + { "remove", true, cltrack_remove }, + { "check", true, cltrack_check }, + { "gracedone", true, cltrack_gracedone }, + { NULL, false, NULL }, +}; + +static char *storagedir = CLD_DEFAULT_STORAGEDIR; + +/* common buffer for holding id4 blobs */ +static unsigned char blob[NFS4_OPAQUE_LIMIT]; + +static void +usage(char *progname) +{ + printf("%s [ -hfd ] [ -s dir ] < cmd > < arg >\n", progname); + printf("Where < cmd > is one of the following and takes the following < arg >:\n"); + printf(" init\n"); + printf(" create \n"); + printf(" remove \n"); + printf(" check \n"); + printf(" gracedone \n"); +} + + +/** + * hex_to_bin - convert a hex digit to its real value + * @ch: ascii character represents hex digit + * + * hex_to_bin() converts one hex digit to its actual value or -1 in case of bad + * input. + * + * Note: borrowed from lib/hexdump.c in the Linux kernel sources. + */ +static int +hex_to_bin(char ch) +{ + if ((ch >= '0') && (ch <= '9')) + return ch - '0'; + ch = tolower(ch); + if ((ch >= 'a') && (ch <= 'f')) + return ch - 'a' + 10; + return -1; +} + +/** + * hex_str_to_bin - convert a hexidecimal string into a binary blob + * + * @src: string of hex digit pairs + * @dst: destination buffer to hold binary data + * @dstsize: size of the destination buffer + * + * Walk a string of hex digit pairs and convert them into binary data. Returns + * the resulting length of the binary data or a negative error code. If the + * data will not fit in the buffer, it returns -ENOBUFS (but will likely have + * clobbered the dst buffer in the process of determining that). If there are + * non-hexidecimal characters in the src, or an odd number of them then it + * returns -EINVAL. + */ +static ssize_t +hex_str_to_bin(const char *src, unsigned char *dst, ssize_t dstsize) +{ + unsigned char *tmpdst = dst; + + while (*src) { + int hi, lo; + + /* make sure we don't overrun the dst buffer */ + if ((tmpdst - dst) >= dstsize) + return -ENOBUFS; + + hi = hex_to_bin(*src++); + + /* did we get an odd number of characters? */ + if (!*src) + return -EINVAL; + lo = hex_to_bin(*src++); + + /* one of the characters isn't a hex digit */ + if (hi < 0 || lo < 0) + return -EINVAL; + + /* now place it in the dst buffer */ + *tmpdst++ = (hi << 4) | lo; + } + + return (ssize_t)(tmpdst - dst); +} + +/* + * This program will almost always be run with root privileges since the + * kernel will call out to run it. Drop all capabilities prior to doing + * anything important to limit the exposure to potential compromise. + * + * FIXME: should we setuid to a different user early on instead? + */ +static int +cltrack_set_caps(void) +{ + int ret = 0; +#ifdef HAVE_SYS_CAPABILITY_H + unsigned long i; + cap_t caps; + + /* prune the bounding set to nothing */ + for (i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0 ; ++i) { + ret = prctl(PR_CAPBSET_DROP, i, 0, 0, 0); + if (ret) { + xlog(L_ERROR, "Unable to prune capability %lu from " + "bounding set: %m", i); + return -errno; + } + } + + /* get a blank capset */ + caps = cap_init(); + if (caps == NULL) { + xlog(L_ERROR, "Unable to get blank capability set: %m"); + return -errno; + } + + /* reset the process capabilities */ + if (cap_set_proc(caps) != 0) { + xlog(L_ERROR, "Unable to set process capabilities: %m"); + ret = -errno; + } + cap_free(caps); +#endif + return ret; +} + +static int +cltrack_init(const char __attribute__((unused)) *unused) +{ + int ret; + + /* + * see if the storagedir is writable by root w/o CAP_DAC_OVERRIDE. + * If it isn't then give the user a warning but proceed as if + * everything is OK. If the DB has already been created, then + * everything might still work. If it doesn't exist at all, then + * assume that the maindb init will be able to create it. Fail on + * anything else. + */ + if (access(storagedir, W_OK) == -1) { + switch (errno) { + case EACCES: + xlog(L_WARNING, "Storage directory %s is not writable. " + "Should be owned by root and writable " + "by owner!", storagedir); + break; + case ENOENT: + /* ignore and assume that we can create dir as root */ + break; + default: + xlog(L_ERROR, "Unexpected error when checking access " + "on %s: %m", storagedir); + return -errno; + } + } + + /* set up storage db */ + ret = sqlite_maindb_init(storagedir); + if (ret) { + xlog(L_ERROR, "Failed to init database: %d", ret); + /* + * Convert any error here into -EACCES. It's not truly + * accurate in all cases, but it should cause the kernel to + * stop upcalling until the problem is resolved. + */ + ret = -EACCES; + } + return ret; +} + +static int +cltrack_create(const char *id) +{ + int ret; + ssize_t len; + + xlog(D_GENERAL, "%s: create client record.", __func__); + + ret = sqlite_prepare_dbh(storagedir); + if (ret) + return ret; + + len = hex_str_to_bin(id, blob, sizeof(blob)); + if (len < 0) + return (int)len; + + ret = sqlite_insert_client(blob, len); + + return ret ? -EREMOTEIO : ret; +} + +static int +cltrack_remove(const char *id) +{ + int ret; + ssize_t len; + + xlog(D_GENERAL, "%s: remove client record.", __func__); + + ret = sqlite_prepare_dbh(storagedir); + if (ret) + return ret; + + len = hex_str_to_bin(id, blob, sizeof(blob)); + if (len < 0) + return (int)len; + + ret = sqlite_remove_client(blob, len); + + return ret ? -EREMOTEIO : ret; +} + +static int +cltrack_check(const char *id) +{ + int ret; + ssize_t len; + + xlog(D_GENERAL, "%s: check client record", __func__); + + ret = sqlite_prepare_dbh(storagedir); + if (ret) + return ret; + + len = hex_str_to_bin(id, blob, sizeof(blob)); + if (len < 0) + return (int)len; + + ret = sqlite_check_client(blob, len); + + return ret ? -EPERM : ret; +} + +static int +cltrack_gracedone(const char *timestr) +{ + int ret; + char *tail; + time_t gracetime; + + + ret = sqlite_prepare_dbh(storagedir); + if (ret) + return ret; + + errno = 0; + gracetime = strtol(timestr, &tail, 0); + + /* did the resulting value overflow? (Probably -ERANGE here) */ + if (errno) + return -errno; + + /* string wasn't fully converted */ + if (*tail) + return -EINVAL; + + xlog(D_GENERAL, "%s: grace done. gracetime=%ld", __func__, gracetime); + + ret = sqlite_remove_unreclaimed(gracetime); + + return ret ? -EREMOTEIO : ret; +} + +static struct cltrack_cmd * +find_cmd(char *cmdname) +{ + struct cltrack_cmd *current = &commands[0]; + + while (current->name) { + if (!strcmp(cmdname, current->name)) + return current; + ++current; + } + + xlog(L_ERROR, "%s: '%s' doesn't match any known command", + __func__, cmdname); + return NULL; +} + +int +main(int argc, char **argv) +{ + char arg; + int rc = 0; + char *progname, *cmdarg = NULL; + struct cltrack_cmd *cmd; + + progname = basename(argv[0]); + + xlog_syslog(1); + xlog_stderr(0); + + /* process command-line options */ + while ((arg = getopt_long(argc, argv, "hdfs:", longopts, + NULL)) != EOF) { + switch (arg) { + case 'd': + xlog_config(D_ALL, 1); + case 'f': + xlog_syslog(0); + xlog_stderr(1); + break; + case 's': + storagedir = optarg; + break; + default: + usage(progname); + return 0; + } + } + + xlog_open(progname); + + /* we expect a command, at least */ + if (optind >= argc) { + xlog(L_ERROR, "Missing command name\n"); + rc = -EINVAL; + goto out; + } + + /* drop all capabilities */ + rc = cltrack_set_caps(); + if (rc) + goto out; + + cmd = find_cmd(argv[optind]); + if (!cmd) { + /* + * In the event that we get a command that we don't understand + * then return a distinct error. The kernel can use this to + * determine a new kernel/old userspace situation and cope + * with it. + */ + rc = -ENOSYS; + goto out; + } + + /* populate arg var if command needs it */ + if (cmd->needs_arg) { + if (optind + 1 >= argc) { + xlog(L_ERROR, "Command %s requires an argument\n", + cmd->name); + rc = -EINVAL; + goto out; + } + cmdarg = argv[optind + 1]; + } + rc = cmd->func(cmdarg); +out: + return rc; +} -- 2.39.2