From patchwork Wed Feb 13 18:09:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Paulo Alcantara (SUSE)" X-Patchwork-Id: 10810623 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4380C13A4 for ; Wed, 13 Feb 2019 18:09:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 309E029546 for ; Wed, 13 Feb 2019 18:09:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 24B592A8DE; Wed, 13 Feb 2019 18:09:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A561029546 for ; Wed, 13 Feb 2019 18:09:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729522AbfBMSJ4 (ORCPT ); Wed, 13 Feb 2019 13:09:56 -0500 Received: from mail.paulo.ac ([18.228.144.36]:36484 "EHLO mail.paulo.ac" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727937AbfBMSJz (ORCPT ); Wed, 13 Feb 2019 13:09:55 -0500 Received: from localhost (localhost [127.0.0.1]) by mail.paulo.ac (Postfix) with ESMTP id 908B04823B16; Wed, 13 Feb 2019 18:09:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=paulo.ac; s=default; t=1550081392; bh=NPHMWzhC+dOx1uqYM9k6+umJOPTfdQQb4DDuwxCPykY=; h=From:To:Cc:Subject:Date; b=T/4Gj7VIMqZKmdsNgp0GA1d/4g7rZD8wHngdPprFv5GJ3kwcM0HAiFs9IY7sqln2m +zAQ9B5qbEoeJif9o/LeR7ED+kqAZyn+uGitgiE7DcMJ5wzvGIDZyl/KAGQn/35Auf BNdDIwgVMyv0Iba6DiPlLSIXP9QBxBlXHGDD90fE= Received: from mail.paulo.ac ([127.0.0.1]) by localhost (ip-172-31-5-70.sa-east-1.compute.internal [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ztemnOMlOHdf; Wed, 13 Feb 2019 18:09:51 +0000 (UTC) Received: from localhost.localdomain (unknown [186.215.53.127]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.paulo.ac (Postfix) with ESMTPSA id CAFF84822E3F; Wed, 13 Feb 2019 18:09:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=paulo.ac; s=default; t=1550081391; bh=NPHMWzhC+dOx1uqYM9k6+umJOPTfdQQb4DDuwxCPykY=; h=From:To:Cc:Subject:Date; b=iyVAaOItT0Qa5SuPc9LRAoN1qb8VHw5hZNzhOF6NOB178UgZYt2Tt9pzR9/0UbhUF GeJP0gK64HWvGmbDz8zRhrVgnZpGgAXfaPa20AuGm3WlrtZpb3Z2s/krSAI2I1tQfx 82wY8IeZOD9F+709ZZlwlkGHMWiDLaiRH7xTJWIU= From: Paulo Alcantara To: linux-cifs@vger.kernel.org Cc: smfrench@gmail.com, aaptel@suse.com, piastryyy@gmail.com, Paulo Alcantara , Paulo Alcantara Subject: [PATCH] cifs: Allow DNS resolver key to expire Date: Wed, 13 Feb 2019 16:09:41 -0200 Message-Id: <20190213180941.2587-1-paulo@paulo.ac> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch introduces a new '--expire' option that allows the user to set a timeout value for the dns resolver key -- which is typically useful for hostnames that may get their ip addresses changed under long running mounts. The default timeout value is set to 10 minutes. Signed-off-by: Paulo Alcantara --- cifs.upcall.c | 88 +++++++++++++++++++++++++++++++++------------- cifs.upcall.rst.in | 5 ++- 2 files changed, 67 insertions(+), 26 deletions(-) diff --git a/cifs.upcall.c b/cifs.upcall.c index 89563fd42adc..c92ee62f6764 100644 --- a/cifs.upcall.c +++ b/cifs.upcall.c @@ -63,6 +63,8 @@ static krb5_context context; static const char *prog = "cifs.upcall"; +#define DNS_RESOLVER_DEFAULT_TIMEOUT 600 /* 10 minutes */ + typedef enum _sectype { NONE = 0, KRB5, @@ -749,19 +751,48 @@ decode_key_description(const char *desc, struct decoded_args *arg) return retval; } -static int cifs_resolver(const key_serial_t key, const char *key_descr) +static int setup_key(const key_serial_t key, const void *data, size_t datalen) +{ + int rc; + + rc = keyctl_instantiate(key, data, datalen, 0); + if (rc) { + switch (errno) { + case ENOMEM: + case EDQUOT: + rc = keyctl_clear(key); + if (rc) { + syslog(LOG_ERR, "%s: keyctl_clear: %s", + __func__, strerror(errno)); + return rc; + } + rc = keyctl_instantiate(key, data, datalen, 0); + break; + default: + ; + } + } + if (rc) { + syslog(LOG_ERR, "%s: keyctl_instantiate: %s", + __func__, strerror(errno)); + } + return rc; +} + +static int cifs_resolver(const key_serial_t key, const char *key_descr, + const char *key_buf, unsigned expire_time) { int c; struct addrinfo *addr; char ip[INET6_ADDRSTRLEN]; void *p; - const char *keyend = key_descr; + const char *keyend = key_buf; /* skip next 4 ';' delimiters to get to description */ for (c = 1; c <= 4; c++) { keyend = index(keyend + 1, ';'); if (!keyend) { syslog(LOG_ERR, "invalid key description: %s", - key_descr); + key_buf); return 1; } } @@ -787,15 +818,21 @@ static int cifs_resolver(const key_serial_t key, const char *key_descr) return 1; } - /* setup key */ - c = keyctl_instantiate(key, ip, strlen(ip) + 1, 0); - if (c == -1) { - syslog(LOG_ERR, "%s: keyctl_instantiate: %s", __func__, - strerror(errno)); - freeaddrinfo(addr); - return 1; - } + /* needed for keyctl_set_timeout() */ + request_key("keyring", key_descr, NULL, KEY_SPEC_THREAD_KEYRING); + c = setup_key(key, ip, strlen(ip) + 1); + if (c) { + freeaddrinfo(addr); + return 1; + } + c = keyctl_set_timeout(key, expire_time); + if (c) { + syslog(LOG_ERR, "%s: keyctl_set_timeout: %s", __func__, + strerror(errno)); + freeaddrinfo(addr); + return 1; + } freeaddrinfo(addr); return 0; } @@ -864,7 +901,7 @@ lowercase_string(char *c) static void usage(void) { - fprintf(stderr, "Usage: %s [ -K /path/to/keytab] [-k /path/to/krb5.conf] [-E] [-t] [-v] [-l] key_serial\n", prog); + fprintf(stderr, "Usage: %s [ -K /path/to/keytab] [-k /path/to/krb5.conf] [-E] [-t] [-v] [-l] [-e nsecs] key_serial\n", prog); } static const struct option long_options[] = { @@ -874,6 +911,7 @@ static const struct option long_options[] = { {"trust-dns", 0, NULL, 't'}, {"keytab", 1, NULL, 'K'}, {"version", 0, NULL, 'v'}, + {"expire", 1, NULL, 'e'}, {NULL, 0, NULL, 0} }; @@ -897,13 +935,15 @@ int main(const int argc, char *const argv[]) char *env_cachename = NULL; krb5_ccache ccache = NULL; struct passwd *pw; + unsigned expire_time = DNS_RESOLVER_DEFAULT_TIMEOUT; + const char *key_descr = NULL; hostbuf[0] = '\0'; memset(&arg, 0, sizeof(arg)); openlog(prog, 0, LOG_DAEMON); - while ((c = getopt_long(argc, argv, "cEk:K:ltv", long_options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "cEk:K:ltve:", long_options, NULL)) != -1) { switch (c) { case 'c': /* legacy option -- skip it */ @@ -931,6 +971,9 @@ int main(const int argc, char *const argv[]) rc = 0; printf("version: %s\n", VERSION); goto out; + case 'e': + expire_time = strtoul(optarg, NULL, 10); + break; default: syslog(LOG_ERR, "unknown option: %c", c); goto out; @@ -965,9 +1008,12 @@ int main(const int argc, char *const argv[]) syslog(LOG_DEBUG, "key description: %s", buf); - if ((strncmp(buf, "cifs.resolver", sizeof("cifs.resolver") - 1) == 0) || - (strncmp(buf, "dns_resolver", sizeof("dns_resolver") - 1) == 0)) { - rc = cifs_resolver(key, buf); + if (strncmp(buf, "cifs.resolver", sizeof("cifs.resolver") - 1) == 0) + key_descr = ".cifs.resolver"; + else if (strncmp(buf, "dns_resolver", sizeof("dns_resolver") - 1) == 0) + key_descr = ".dns_resolver"; + if (key_descr) { + rc = cifs_resolver(key, key_descr, buf, expire_time); goto out; } @@ -1193,16 +1239,8 @@ retry_new_hostname: memcpy(&(keydata->data) + keydata->sesskey_len, secblob.data, secblob.length); - /* setup key */ - rc = keyctl_instantiate(key, keydata, datalen, 0); - if (rc == -1) { - syslog(LOG_ERR, "keyctl_instantiate: %s", strerror(errno)); - goto out; - } + rc = setup_key(key, keydata, datalen); - /* BB: maybe we need use timeout for key: for example no more then - * ticket lifietime? */ - /* keyctl_set_timeout( key, 60); */ out: /* * on error, negatively instantiate the key ourselves so that we can diff --git a/cifs.upcall.rst.in b/cifs.upcall.rst.in index 1b8df3f31d94..08ce324fc5f6 100644 --- a/cifs.upcall.rst.in +++ b/cifs.upcall.rst.in @@ -13,7 +13,7 @@ SYNOPSIS cifs.upcall [--trust-dns|-t] [--version|-v] [--legacy-uid|-l] [--krb5conf=/path/to/krb5.conf|-k /path/to/krb5.conf] - [--keytab=/path/to/keytab|-K /path/to/keytab] {keyid} + [--keytab=/path/to/keytab|-K /path/to/keytab] [--expire|-e nsecs] {keyid} *********** DESCRIPTION @@ -85,6 +85,9 @@ OPTIONS user. Set this option if you want cifs.upcall to use the older uid= parameter instead of the creduid= parameter. +--expire|-e + Override default timeout value (600 seconds) for ``dns_resolver`` key. + --version|-v Print version number and exit.