|
|
5eee7b |
From bc41dbe55098629101fbf286755e123c9a2b6b77 Mon Sep 17 00:00:00 2001
|
|
|
5eee7b |
From: Paulo Alcantara <paulo@paulo.ac>
|
|
|
5eee7b |
Date: Wed, 13 Feb 2019 16:09:41 -0200
|
|
|
5eee7b |
Subject: [PATCH 10/36] cifs: Allow DNS resolver key to expire
|
|
|
5eee7b |
|
|
|
5eee7b |
This patch introduces a new '--expire' option that allows the user to
|
|
|
5eee7b |
set a timeout value for the dns resolver key -- which is typically
|
|
|
5eee7b |
useful for hostnames that may get their ip addresses changed under
|
|
|
5eee7b |
long running mounts.
|
|
|
5eee7b |
|
|
|
5eee7b |
The default timeout value is set to 10 minutes.
|
|
|
5eee7b |
|
|
|
5eee7b |
Signed-off-by: Paulo Alcantara <palcantara@suse.de>
|
|
|
5eee7b |
(cherry picked from commit b101af793c8415f298072d06841a278df0368bc3)
|
|
|
5eee7b |
Signed-off-by: Sachin Prabhu <sprabhu@redhat.com>
|
|
|
5eee7b |
---
|
|
|
5eee7b |
cifs.upcall.c | 82 +++++++++++++++++++++++++++++++++++++++---------------
|
|
|
5eee7b |
cifs.upcall.rst.in | 5 +++-
|
|
|
5eee7b |
2 files changed, 64 insertions(+), 23 deletions(-)
|
|
|
5eee7b |
|
|
|
5eee7b |
diff --git a/cifs.upcall.c b/cifs.upcall.c
|
|
|
5eee7b |
index 89563fd..c92ee62 100644
|
|
|
5eee7b |
--- a/cifs.upcall.c
|
|
|
5eee7b |
+++ b/cifs.upcall.c
|
|
|
5eee7b |
@@ -63,6 +63,8 @@
|
|
|
5eee7b |
static krb5_context context;
|
|
|
5eee7b |
static const char *prog = "cifs.upcall";
|
|
|
5eee7b |
|
|
|
5eee7b |
+#define DNS_RESOLVER_DEFAULT_TIMEOUT 600 /* 10 minutes */
|
|
|
5eee7b |
+
|
|
|
5eee7b |
typedef enum _sectype {
|
|
|
5eee7b |
NONE = 0,
|
|
|
5eee7b |
KRB5,
|
|
|
5eee7b |
@@ -749,19 +751,48 @@ decode_key_description(const char *desc, struct decoded_args *arg)
|
|
|
5eee7b |
return retval;
|
|
|
5eee7b |
}
|
|
|
5eee7b |
|
|
|
5eee7b |
-static int cifs_resolver(const key_serial_t key, const char *key_descr)
|
|
|
5eee7b |
+static int setup_key(const key_serial_t key, const void *data, size_t datalen)
|
|
|
5eee7b |
+{
|
|
|
5eee7b |
+ int rc;
|
|
|
5eee7b |
+
|
|
|
5eee7b |
+ rc = keyctl_instantiate(key, data, datalen, 0);
|
|
|
5eee7b |
+ if (rc) {
|
|
|
5eee7b |
+ switch (errno) {
|
|
|
5eee7b |
+ case ENOMEM:
|
|
|
5eee7b |
+ case EDQUOT:
|
|
|
5eee7b |
+ rc = keyctl_clear(key);
|
|
|
5eee7b |
+ if (rc) {
|
|
|
5eee7b |
+ syslog(LOG_ERR, "%s: keyctl_clear: %s",
|
|
|
5eee7b |
+ __func__, strerror(errno));
|
|
|
5eee7b |
+ return rc;
|
|
|
5eee7b |
+ }
|
|
|
5eee7b |
+ rc = keyctl_instantiate(key, data, datalen, 0);
|
|
|
5eee7b |
+ break;
|
|
|
5eee7b |
+ default:
|
|
|
5eee7b |
+ ;
|
|
|
5eee7b |
+ }
|
|
|
5eee7b |
+ }
|
|
|
5eee7b |
+ if (rc) {
|
|
|
5eee7b |
+ syslog(LOG_ERR, "%s: keyctl_instantiate: %s",
|
|
|
5eee7b |
+ __func__, strerror(errno));
|
|
|
5eee7b |
+ }
|
|
|
5eee7b |
+ return rc;
|
|
|
5eee7b |
+}
|
|
|
5eee7b |
+
|
|
|
5eee7b |
+static int cifs_resolver(const key_serial_t key, const char *key_descr,
|
|
|
5eee7b |
+ const char *key_buf, unsigned expire_time)
|
|
|
5eee7b |
{
|
|
|
5eee7b |
int c;
|
|
|
5eee7b |
struct addrinfo *addr;
|
|
|
5eee7b |
char ip[INET6_ADDRSTRLEN];
|
|
|
5eee7b |
void *p;
|
|
|
5eee7b |
- const char *keyend = key_descr;
|
|
|
5eee7b |
+ const char *keyend = key_buf;
|
|
|
5eee7b |
/* skip next 4 ';' delimiters to get to description */
|
|
|
5eee7b |
for (c = 1; c <= 4; c++) {
|
|
|
5eee7b |
keyend = index(keyend + 1, ';');
|
|
|
5eee7b |
if (!keyend) {
|
|
|
5eee7b |
syslog(LOG_ERR, "invalid key description: %s",
|
|
|
5eee7b |
- key_descr);
|
|
|
5eee7b |
+ key_buf);
|
|
|
5eee7b |
return 1;
|
|
|
5eee7b |
}
|
|
|
5eee7b |
}
|
|
|
5eee7b |
@@ -787,15 +818,21 @@ static int cifs_resolver(const key_serial_t key, const char *key_descr)
|
|
|
5eee7b |
return 1;
|
|
|
5eee7b |
}
|
|
|
5eee7b |
|
|
|
5eee7b |
- /* setup key */
|
|
|
5eee7b |
- c = keyctl_instantiate(key, ip, strlen(ip) + 1, 0);
|
|
|
5eee7b |
- if (c == -1) {
|
|
|
5eee7b |
- syslog(LOG_ERR, "%s: keyctl_instantiate: %s", __func__,
|
|
|
5eee7b |
+ /* needed for keyctl_set_timeout() */
|
|
|
5eee7b |
+ request_key("keyring", key_descr, NULL, KEY_SPEC_THREAD_KEYRING);
|
|
|
5eee7b |
+
|
|
|
5eee7b |
+ c = setup_key(key, ip, strlen(ip) + 1);
|
|
|
5eee7b |
+ if (c) {
|
|
|
5eee7b |
+ freeaddrinfo(addr);
|
|
|
5eee7b |
+ return 1;
|
|
|
5eee7b |
+ }
|
|
|
5eee7b |
+ c = keyctl_set_timeout(key, expire_time);
|
|
|
5eee7b |
+ if (c) {
|
|
|
5eee7b |
+ syslog(LOG_ERR, "%s: keyctl_set_timeout: %s", __func__,
|
|
|
5eee7b |
strerror(errno));
|
|
|
5eee7b |
freeaddrinfo(addr);
|
|
|
5eee7b |
return 1;
|
|
|
5eee7b |
}
|
|
|
5eee7b |
-
|
|
|
5eee7b |
freeaddrinfo(addr);
|
|
|
5eee7b |
return 0;
|
|
|
5eee7b |
}
|
|
|
5eee7b |
@@ -864,7 +901,7 @@ lowercase_string(char *c)
|
|
|
5eee7b |
|
|
|
5eee7b |
static void usage(void)
|
|
|
5eee7b |
{
|
|
|
5eee7b |
- fprintf(stderr, "Usage: %s [ -K /path/to/keytab] [-k /path/to/krb5.conf] [-E] [-t] [-v] [-l] key_serial\n", prog);
|
|
|
5eee7b |
+ fprintf(stderr, "Usage: %s [ -K /path/to/keytab] [-k /path/to/krb5.conf] [-E] [-t] [-v] [-l] [-e nsecs] key_serial\n", prog);
|
|
|
5eee7b |
}
|
|
|
5eee7b |
|
|
|
5eee7b |
static const struct option long_options[] = {
|
|
|
5eee7b |
@@ -874,6 +911,7 @@ static const struct option long_options[] = {
|
|
|
5eee7b |
{"trust-dns", 0, NULL, 't'},
|
|
|
5eee7b |
{"keytab", 1, NULL, 'K'},
|
|
|
5eee7b |
{"version", 0, NULL, 'v'},
|
|
|
5eee7b |
+ {"expire", 1, NULL, 'e'},
|
|
|
5eee7b |
{NULL, 0, NULL, 0}
|
|
|
5eee7b |
};
|
|
|
5eee7b |
|
|
|
5eee7b |
@@ -897,13 +935,15 @@ int main(const int argc, char *const argv[])
|
|
|
5eee7b |
char *env_cachename = NULL;
|
|
|
5eee7b |
krb5_ccache ccache = NULL;
|
|
|
5eee7b |
struct passwd *pw;
|
|
|
5eee7b |
+ unsigned expire_time = DNS_RESOLVER_DEFAULT_TIMEOUT;
|
|
|
5eee7b |
+ const char *key_descr = NULL;
|
|
|
5eee7b |
|
|
|
5eee7b |
hostbuf[0] = '\0';
|
|
|
5eee7b |
memset(&arg, 0, sizeof(arg));
|
|
|
5eee7b |
|
|
|
5eee7b |
openlog(prog, 0, LOG_DAEMON);
|
|
|
5eee7b |
|
|
|
5eee7b |
- while ((c = getopt_long(argc, argv, "cEk:K:ltv", long_options, NULL)) != -1) {
|
|
|
5eee7b |
+ while ((c = getopt_long(argc, argv, "cEk:K:ltve:", long_options, NULL)) != -1) {
|
|
|
5eee7b |
switch (c) {
|
|
|
5eee7b |
case 'c':
|
|
|
5eee7b |
/* legacy option -- skip it */
|
|
|
5eee7b |
@@ -931,6 +971,9 @@ int main(const int argc, char *const argv[])
|
|
|
5eee7b |
rc = 0;
|
|
|
5eee7b |
printf("version: %s\n", VERSION);
|
|
|
5eee7b |
goto out;
|
|
|
5eee7b |
+ case 'e':
|
|
|
5eee7b |
+ expire_time = strtoul(optarg, NULL, 10);
|
|
|
5eee7b |
+ break;
|
|
|
5eee7b |
default:
|
|
|
5eee7b |
syslog(LOG_ERR, "unknown option: %c", c);
|
|
|
5eee7b |
goto out;
|
|
|
5eee7b |
@@ -965,9 +1008,12 @@ int main(const int argc, char *const argv[])
|
|
|
5eee7b |
|
|
|
5eee7b |
syslog(LOG_DEBUG, "key description: %s", buf);
|
|
|
5eee7b |
|
|
|
5eee7b |
- if ((strncmp(buf, "cifs.resolver", sizeof("cifs.resolver") - 1) == 0) ||
|
|
|
5eee7b |
- (strncmp(buf, "dns_resolver", sizeof("dns_resolver") - 1) == 0)) {
|
|
|
5eee7b |
- rc = cifs_resolver(key, buf);
|
|
|
5eee7b |
+ if (strncmp(buf, "cifs.resolver", sizeof("cifs.resolver") - 1) == 0)
|
|
|
5eee7b |
+ key_descr = ".cifs.resolver";
|
|
|
5eee7b |
+ else if (strncmp(buf, "dns_resolver", sizeof("dns_resolver") - 1) == 0)
|
|
|
5eee7b |
+ key_descr = ".dns_resolver";
|
|
|
5eee7b |
+ if (key_descr) {
|
|
|
5eee7b |
+ rc = cifs_resolver(key, key_descr, buf, expire_time);
|
|
|
5eee7b |
goto out;
|
|
|
5eee7b |
}
|
|
|
5eee7b |
|
|
|
5eee7b |
@@ -1193,16 +1239,8 @@ retry_new_hostname:
|
|
|
5eee7b |
memcpy(&(keydata->data) + keydata->sesskey_len,
|
|
|
5eee7b |
secblob.data, secblob.length);
|
|
|
5eee7b |
|
|
|
5eee7b |
- /* setup key */
|
|
|
5eee7b |
- rc = keyctl_instantiate(key, keydata, datalen, 0);
|
|
|
5eee7b |
- if (rc == -1) {
|
|
|
5eee7b |
- syslog(LOG_ERR, "keyctl_instantiate: %s", strerror(errno));
|
|
|
5eee7b |
- goto out;
|
|
|
5eee7b |
- }
|
|
|
5eee7b |
+ rc = setup_key(key, keydata, datalen);
|
|
|
5eee7b |
|
|
|
5eee7b |
- /* BB: maybe we need use timeout for key: for example no more then
|
|
|
5eee7b |
- * ticket lifietime? */
|
|
|
5eee7b |
- /* keyctl_set_timeout( key, 60); */
|
|
|
5eee7b |
out:
|
|
|
5eee7b |
/*
|
|
|
5eee7b |
* on error, negatively instantiate the key ourselves so that we can
|
|
|
5eee7b |
diff --git a/cifs.upcall.rst.in b/cifs.upcall.rst.in
|
|
|
5eee7b |
index 1b8df3f..08ce324 100644
|
|
|
5eee7b |
--- a/cifs.upcall.rst.in
|
|
|
5eee7b |
+++ b/cifs.upcall.rst.in
|
|
|
5eee7b |
@@ -13,7 +13,7 @@ SYNOPSIS
|
|
|
5eee7b |
|
|
|
5eee7b |
cifs.upcall [--trust-dns|-t] [--version|-v] [--legacy-uid|-l]
|
|
|
5eee7b |
[--krb5conf=/path/to/krb5.conf|-k /path/to/krb5.conf]
|
|
|
5eee7b |
- [--keytab=/path/to/keytab|-K /path/to/keytab] {keyid}
|
|
|
5eee7b |
+ [--keytab=/path/to/keytab|-K /path/to/keytab] [--expire|-e nsecs] {keyid}
|
|
|
5eee7b |
|
|
|
5eee7b |
***********
|
|
|
5eee7b |
DESCRIPTION
|
|
|
5eee7b |
@@ -85,6 +85,9 @@ OPTIONS
|
|
|
5eee7b |
user. Set this option if you want cifs.upcall to use the older uid=
|
|
|
5eee7b |
parameter instead of the creduid= parameter.
|
|
|
5eee7b |
|
|
|
5eee7b |
+--expire|-e
|
|
|
5eee7b |
+ Override default timeout value (600 seconds) for ``dns_resolver`` key.
|
|
|
5eee7b |
+
|
|
|
5eee7b |
--version|-v
|
|
|
5eee7b |
Print version number and exit.
|
|
|
5eee7b |
|
|
|
5eee7b |
--
|
|
|
5eee7b |
1.8.3.1
|
|
|
5eee7b |
|