summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam B <william@adelaide.edu.au>2014-07-21 11:13:25 +0200
committerJakub Hrozek <jhrozek@redhat.com>2014-09-05 11:40:39 +0200
commit3ac7c4fe618ede980a4df8d90341ef1fd0f1f62f (patch)
tree940c252ca1538b4d8cd60e94d95073d6a845f040
parent61602026ed8c91efd166000562899670449f1b50 (diff)
downloadsssd-3ac7c4fe618ede980a4df8d90341ef1fd0f1f62f.tar.gz
sssd-3ac7c4fe618ede980a4df8d90341ef1fd0f1f62f.tar.xz
sssd-3ac7c4fe618ede980a4df8d90341ef1fd0f1f62f.zip
SSS_CACHE: Allow sss_cache tool to flush SSH hosts cache
Resolves: https://fedorahosted.org/sssd/ticket/2358 Signed-off-by: Jan Cholasta <jcholast@redhat.com> Reviewed-by: Jan Cholasta <jcholast@redhat.com> Reviewed-by: Pavel Reichl <preichl@redhat.com>
-rw-r--r--src/confdb/confdb.c11
-rw-r--r--src/confdb/confdb.h2
-rwxr-xr-xsrc/config/SSSDConfigTest.py2
-rw-r--r--src/config/etc/sssd.api.conf1
-rw-r--r--src/db/sysdb_ssh.c63
-rw-r--r--src/db/sysdb_ssh.h15
-rw-r--r--src/man/sss_cache.8.xml23
-rw-r--r--src/man/sssd.conf.5.xml14
-rw-r--r--src/providers/ipa/ipa_hostid.c4
-rw-r--r--src/tests/sysdb_ssh-tests.c1
-rw-r--r--src/tools/sss_cache.c86
11 files changed, 204 insertions, 18 deletions
diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
index 49e23e34e..0adff2b08 100644
--- a/src/confdb/confdb.c
+++ b/src/confdb/confdb.c
@@ -1036,6 +1036,17 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb,
goto done;
}
+ /* Override the ssh known hosts timeout, if specified */
+ ret = get_entry_as_uint32(res->msgs[0], &domain->ssh_host_timeout,
+ CONFDB_DOMAIN_SSH_HOST_CACHE_TIMEOUT,
+ entry_cache_timeout);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ "Invalid value for [%s]\n",
+ CONFDB_DOMAIN_SSH_HOST_CACHE_TIMEOUT);
+ goto done;
+ }
+
/* Set refresh_expired_interval, if specified */
ret = get_entry_as_uint32(res->msgs[0], &domain->refresh_expired_interval,
CONFDB_DOMAIN_REFRESH_EXPIRED_INTERVAL,
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index a28589186..1697c69f0 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -176,6 +176,7 @@
#define CONFDB_DOMAIN_SERVICE_CACHE_TIMEOUT "entry_cache_service_timeout"
#define CONFDB_DOMAIN_AUTOFS_CACHE_TIMEOUT "entry_cache_autofs_timeout"
#define CONFDB_DOMAIN_SUDO_CACHE_TIMEOUT "entry_cache_sudo_timeout"
+#define CONFDB_DOMAIN_SSH_HOST_CACHE_TIMEOUT "entry_cache_ssh_host_timeout"
#define CONFDB_DOMAIN_PWD_EXPIRATION_WARNING "pwd_expiration_warning"
#define CONFDB_DOMAIN_REFRESH_EXPIRED_INTERVAL "refresh_expired_interval"
#define CONFDB_DOMAIN_OFFLINE_TIMEOUT "offline_timeout"
@@ -234,6 +235,7 @@ struct sss_domain_info {
uint32_t service_timeout;
uint32_t autofsmap_timeout;
uint32_t sudo_timeout;
+ uint32_t ssh_host_timeout;
uint32_t refresh_expired_interval;
uint32_t subdomain_refresh_interval;
diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py
index 14500031b..2d12bc02a 100755
--- a/src/config/SSSDConfigTest.py
+++ b/src/config/SSSDConfigTest.py
@@ -505,6 +505,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
'entry_cache_service_timeout',
'entry_cache_autofs_timeout',
'entry_cache_sudo_timeout',
+ 'entry_cache_ssh_host_timeout',
'refresh_expired_interval',
'lookup_family_order',
'account_cache_expiration',
@@ -863,6 +864,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
'entry_cache_service_timeout',
'entry_cache_autofs_timeout',
'entry_cache_sudo_timeout',
+ 'entry_cache_ssh_host_timeout',
'refresh_expired_interval',
'account_cache_expiration',
'lookup_family_order',
diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf
index a3398c8d5..52629ded4 100644
--- a/src/config/etc/sssd.api.conf
+++ b/src/config/etc/sssd.api.conf
@@ -134,6 +134,7 @@ entry_cache_netgroup_timeout = int, None, false
entry_cache_service_timeout = int, None, false
entry_cache_autofs_timeout = int, None, false
entry_cache_sudo_timeout = int, None, false
+entry_cache_ssh_host_timeout = int, None, false
refresh_expired_interval = int, None, false
# Dynamic DNS updates
diff --git a/src/db/sysdb_ssh.c b/src/db/sysdb_ssh.c
index 7dd98cfdb..4983dcc34 100644
--- a/src/db/sysdb_ssh.c
+++ b/src/db/sysdb_ssh.c
@@ -23,6 +23,14 @@
#include "db/sysdb_ssh.h"
#include "db/sysdb_private.h"
+static struct ldb_dn *
+sysdb_ssh_host_dn(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ const char *name)
+{
+ return sysdb_custom_dn(mem_ctx, domain, name, SSH_HOSTS_SUBDIR);
+}
+
static errno_t
sysdb_update_ssh_host(struct sss_domain_info *domain,
const char *name,
@@ -45,6 +53,7 @@ errno_t
sysdb_store_ssh_host(struct sss_domain_info *domain,
const char *name,
const char *alias,
+ int cache_timeout,
time_t now,
struct sysdb_attrs *attrs)
{
@@ -147,6 +156,14 @@ sysdb_store_ssh_host(struct sss_domain_info *domain,
goto done;
}
+ ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE,
+ cache_timeout ? (now + cache_timeout) : 0);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Could not set sysdb cache expire [%d]: %s\n",
+ ret, strerror(ret));
+ goto done;
+ }
+
ret = sysdb_update_ssh_host(domain, name, attrs);
if (ret != EOK) {
goto done;
@@ -176,6 +193,34 @@ done:
}
errno_t
+sysdb_set_ssh_host_attr(struct sss_domain_info *domain,
+ const char *name,
+ struct sysdb_attrs *attrs,
+ int mod_op)
+{
+ errno_t ret;
+ struct ldb_dn *dn;
+ TALLOC_CTX *tmp_ctx;
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) {
+ return ENOMEM;
+ }
+
+ dn = sysdb_ssh_host_dn(tmp_ctx, domain, name);
+ if (!dn) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = sysdb_set_entry_attr(domain->sysdb, dn, attrs, mod_op);
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+errno_t
sysdb_update_ssh_known_host_expire(struct sss_domain_info *domain,
const char *name,
time_t now,
@@ -229,13 +274,13 @@ sysdb_delete_ssh_host(struct sss_domain_info *domain,
return sysdb_delete_custom(domain, name, SSH_HOSTS_SUBDIR);
}
-static errno_t
+errno_t
sysdb_search_ssh_hosts(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
const char *filter,
const char **attrs,
- struct ldb_message ***hosts,
- size_t *num_hosts)
+ size_t *num_hosts,
+ struct ldb_message ***hosts)
{
errno_t ret;
TALLOC_CTX *tmp_ctx;
@@ -297,7 +342,7 @@ sysdb_get_ssh_host(TALLOC_CTX *mem_ctx,
}
ret = sysdb_search_ssh_hosts(tmp_ctx, domain, filter, attrs,
- &hosts, &num_hosts);
+ &num_hosts, &hosts);
if (ret != EOK) {
goto done;
}
@@ -335,15 +380,19 @@ sysdb_get_ssh_known_hosts(TALLOC_CTX *mem_ctx,
return ENOMEM;
}
- filter = talloc_asprintf(tmp_ctx, "(%s>=%ld)",
- SYSDB_SSH_KNOWN_HOSTS_EXPIRE, (long)now);
+ filter = talloc_asprintf(tmp_ctx,
+ "(&(|(!(%s=*))(%s=0)(%s>=%lld))(%s>=%lld))",
+ SYSDB_CACHE_EXPIRE,
+ SYSDB_CACHE_EXPIRE,
+ SYSDB_CACHE_EXPIRE, (long long)now + 1,
+ SYSDB_SSH_KNOWN_HOSTS_EXPIRE, (long long)now + 1);
if (!filter) {
ret = ENOMEM;
goto done;
}
ret = sysdb_search_ssh_hosts(mem_ctx, domain, filter, attrs,
- hosts, num_hosts);
+ num_hosts, hosts);
done:
talloc_free(tmp_ctx);
diff --git a/src/db/sysdb_ssh.h b/src/db/sysdb_ssh.h
index e8aca776b..960a13fd5 100644
--- a/src/db/sysdb_ssh.h
+++ b/src/db/sysdb_ssh.h
@@ -33,6 +33,7 @@ errno_t
sysdb_store_ssh_host(struct sss_domain_info *domain,
const char *name,
const char *alias,
+ int cache_timeout,
time_t now,
struct sysdb_attrs *attrs);
@@ -42,11 +43,25 @@ sysdb_update_ssh_known_host_expire(struct sss_domain_info *domain,
time_t now,
int known_hosts_timeout);
+int
+sysdb_set_ssh_host_attr(struct sss_domain_info *domain,
+ const char *name,
+ struct sysdb_attrs *attrs,
+ int mod_op);
+
errno_t
sysdb_delete_ssh_host(struct sss_domain_info *domain,
const char *name);
errno_t
+sysdb_search_ssh_hosts(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ const char *filter,
+ const char **attrs,
+ size_t *num_hosts,
+ struct ldb_message ***hosts);
+
+errno_t
sysdb_get_ssh_host(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
const char *name,
diff --git a/src/man/sss_cache.8.xml b/src/man/sss_cache.8.xml
index bf5e36d78..1bc3633d9 100644
--- a/src/man/sss_cache.8.xml
+++ b/src/man/sss_cache.8.xml
@@ -157,6 +157,29 @@
</para>
</listitem>
</varlistentry>
+ <varlistentry condition="with_ssh">
+ <term>
+ <option>-h</option>,<option>--ssh-host</option>
+ <replaceable>hostname</replaceable>
+ </term>
+ <listitem>
+ <para>
+ Invalidate SSH public keys of a specific host.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry condition="with_ssh">
+ <term>
+ <option>-H</option>,<option>--ssh-hosts</option>
+ </term>
+ <listitem>
+ <para>
+ Invalidate SSH public keys of all hosts. This option
+ overrides invalidation of SSH public keys of specific
+ host if it was also set.
+ </para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term>
<option>-d</option>,<option>--domain</option>
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index ad01f37f1..38c76ef36 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -1218,6 +1218,20 @@ fallback_homedir = /home/%u
</listitem>
</varlistentry>
+ <varlistentry condition="with_ssh">
+ <term>entry_cache_ssh_host_timeout (integer)</term>
+ <listitem>
+ <para>
+ How many seconds to keep a host ssh key after
+ refresh. IE how long to cache the host key
+ for.
+ </para>
+ <para>
+ Default: entry_cache_timeout
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term>refresh_expired_interval (integer)</term>
<listitem>
diff --git a/src/providers/ipa/ipa_hostid.c b/src/providers/ipa/ipa_hostid.c
index 905454d2e..6b8233587 100644
--- a/src/providers/ipa/ipa_hostid.c
+++ b/src/providers/ipa/ipa_hostid.c
@@ -300,8 +300,8 @@ hosts_get_done(struct tevent_req *subreq)
goto done;
}
- ret = sysdb_store_ssh_host(state->domain, state->name, state->alias, now,
- attrs);
+ ret = sysdb_store_ssh_host(state->domain, state->name, state->alias,
+ state->domain->ssh_host_timeout, now, attrs);
if (ret != EOK) {
goto done;
}
diff --git a/src/tests/sysdb_ssh-tests.c b/src/tests/sysdb_ssh-tests.c
index 6a4c219b3..46f5c4791 100644
--- a/src/tests/sysdb_ssh-tests.c
+++ b/src/tests/sysdb_ssh-tests.c
@@ -175,6 +175,7 @@ static int test_sysdb_store_ssh_host(struct test_data *data)
ret = sysdb_store_ssh_host(data->ctx->domain,
data->hostname,
data->alias,
+ data->ctx->domain->ssh_host_timeout,
now,
data->attrs);
return ret;
diff --git a/src/tools/sss_cache.c b/src/tools/sss_cache.c
index 7cd5852ab..656f71fb4 100644
--- a/src/tools/sss_cache.c
+++ b/src/tools/sss_cache.c
@@ -30,6 +30,7 @@
#include "db/sysdb.h"
#include "db/sysdb_services.h"
#include "db/sysdb_autofs.h"
+#include "db/sysdb_ssh.h"
#define INVALIDATE_NONE 0
#define INVALIDATE_USERS 1
@@ -37,22 +38,36 @@
#define INVALIDATE_NETGROUPS 4
#define INVALIDATE_SERVICES 8
#define INVALIDATE_AUTOFSMAPS 16
+#define INVALIDATE_SSH_HOSTS 32
#ifdef BUILD_AUTOFS
+#ifdef BUILD_SSH
#define INVALIDATE_EVERYTHING (INVALIDATE_USERS | INVALIDATE_GROUPS | \
INVALIDATE_NETGROUPS | INVALIDATE_SERVICES | \
- INVALIDATE_AUTOFSMAPS)
-#else
+ INVALIDATE_AUTOFSMAPS | INVALIDATE_SSH_HOSTS )
+#else /* BUILD_SSH */
+#define INVALIDATE_EVERYTHING (INVALIDATE_USERS | INVALIDATE_GROUPS | \
+ INVALIDATE_NETGROUPS | INVALIDATE_SERVICES | \
+ INVALIDATE_AUTOFSMAPS )
+#endif /* BUILD_SSH */
+#else /* BUILD_AUTOFS */
+#ifdef BUILD_SSH
+#define INVALIDATE_EVERYTHING (INVALIDATE_USERS | INVALIDATE_GROUPS | \
+ INVALIDATE_NETGROUPS | INVALIDATE_SERVICES | \
+ INVALIDATE_SSH_HOSTS )
+#else /* BUILD_SSH */
#define INVALIDATE_EVERYTHING (INVALIDATE_USERS | INVALIDATE_GROUPS | \
- INVALIDATE_NETGROUPS | INVALIDATE_SERVICES)
-#endif
+ INVALIDATE_NETGROUPS | INVALIDATE_SERVICES )
+#endif /* BUILD_SSH */
+#endif /* BUILD_AUTOFS */
enum sss_cache_entry {
TYPE_USER=0,
TYPE_GROUP,
TYPE_NETGROUP,
TYPE_SERVICE,
- TYPE_AUTOFSMAP
+ TYPE_AUTOFSMAP,
+ TYPE_SSH_HOST
};
static errno_t search_autofsmaps(TALLOC_CTX *mem_ctx,
@@ -69,18 +84,21 @@ struct cache_tool_ctx {
char *netgroup_filter;
char *service_filter;
char *autofs_filter;
+ char *ssh_host_filter;
char *user_name;
char *group_name;
char *netgroup_name;
char *service_name;
char *autofs_name;
+ char *ssh_host_name;
bool update_user_filter;
bool update_group_filter;
bool update_netgroup_filter;
bool update_service_filter;
bool update_autofs_filter;
+ bool update_ssh_host_filter;
};
errno_t init_domains(struct cache_tool_ctx *ctx, const char *domain);
@@ -152,6 +170,9 @@ int main(int argc, const char *argv[])
skipped &= !invalidate_entries(tctx, dinfo, TYPE_AUTOFSMAP,
tctx->autofs_filter,
tctx->autofs_name);
+ skipped &= !invalidate_entries(tctx, dinfo, TYPE_SSH_HOST,
+ tctx->ssh_host_filter,
+ tctx->ssh_host_name);
ret = sysdb_transaction_commit(sysdb);
if (ret != EOK) {
@@ -328,6 +349,14 @@ static errno_t update_all_filters(struct cache_tool_ctx *tctx,
return ret;
}
+ /* Update ssh host filter */
+ ret = update_filter(tctx, dinfo, tctx->ssh_host_name,
+ tctx->update_ssh_host_filter, "(%s=%s)", false,
+ &tctx->ssh_host_filter);
+ if (ret != EOK) {
+ return ret;
+ }
+
return EOK;
}
@@ -371,6 +400,15 @@ static bool invalidate_entries(TALLOC_CTX *ctx,
type_string = "autofs map";
ret = search_autofsmaps(ctx, dinfo, filter, attrs, &msg_count, &msgs);
break;
+ case TYPE_SSH_HOST:
+ type_string = "ssh_host";
+#ifdef BUILD_SSH
+ ret = sysdb_search_ssh_hosts(ctx, dinfo,
+ filter, attrs, &msg_count, &msgs);
+#else /* BUILD_SSH */
+ ret = ENOSYS;
+#endif /* BUILD_SSH */
+ break;
}
if (ret != EOK) {
@@ -446,6 +484,14 @@ static errno_t invalidate_entry(TALLOC_CTX *ctx,
ret = sysdb_set_autofsmap_attr(domain, name,
sys_attrs, SYSDB_MOD_REP);
break;
+ case TYPE_SSH_HOST:
+#ifdef BUILD_SSH
+ ret = sysdb_set_ssh_host_attr(domain, name,
+ sys_attrs, SYSDB_MOD_REP);
+#else /* BUILD_SSH */
+ ret = ENOSYS;
+#endif /* BUILD_SSH */
+ break;
default:
return EINVAL;
}
@@ -530,6 +576,7 @@ errno_t init_context(int argc, const char *argv[], struct cache_tool_ctx **tctx)
char *netgroup = NULL;
char *service = NULL;
char *map = NULL;
+ char *ssh_host = NULL;
char *domain = NULL;
int debug = SSSDBG_DEFAULT;
errno_t ret = EOK;
@@ -563,6 +610,12 @@ errno_t init_context(int argc, const char *argv[], struct cache_tool_ctx **tctx)
{ "autofs-maps", 'A', POPT_ARG_NONE, NULL, 'a',
_("Invalidate all autofs maps"), NULL },
#endif /* BUILD_AUTOFS */
+#ifdef BUILD_SSH
+ { "ssh-host", 'h', POPT_ARG_STRING, &ssh_host, 0,
+ _("Invalidate particular SSH host"), NULL },
+ { "ssh-hosts", 'H', POPT_ARG_NONE, NULL, 'h',
+ _("Invalidate all SSH hosts"), NULL },
+#endif /* BUILD_SSH */
{ "domain", 'd', POPT_ARG_STRING, &domain, 0,
_("Only invalidate entries from a particular domain"), NULL },
POPT_TABLEEND
@@ -594,6 +647,9 @@ errno_t init_context(int argc, const char *argv[], struct cache_tool_ctx **tctx)
case 'a':
idb |= INVALIDATE_AUTOFSMAPS;
break;
+ case 'h':
+ idb |= INVALIDATE_SSH_HOSTS;
+ break;
case 'e':
idb = INVALIDATE_EVERYTHING;
break;
@@ -608,7 +664,7 @@ errno_t init_context(int argc, const char *argv[], struct cache_tool_ctx **tctx)
}
if (idb == INVALIDATE_NONE && !user && !group &&
- !netgroup && !service && !map) {
+ !netgroup && !service && !map && !ssh_host) {
BAD_POPT_PARAMS(pc,
_("Please select at least one object to invalidate\n"),
ret, fini);
@@ -665,14 +721,26 @@ errno_t init_context(int argc, const char *argv[], struct cache_tool_ctx **tctx)
ctx->update_autofs_filter = true;
}
+ if (idb & INVALIDATE_SSH_HOSTS) {
+ ctx->ssh_host_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME);
+ ctx->update_ssh_host_filter = false;
+ } else if (ssh_host) {
+ ctx->ssh_host_name = talloc_strdup(ctx, ssh_host);
+ ctx->update_ssh_host_filter = true;
+ }
+
if (((idb & INVALIDATE_USERS) && !ctx->user_filter) ||
((idb & INVALIDATE_GROUPS) && !ctx->group_filter) ||
((idb & INVALIDATE_NETGROUPS) && !ctx->netgroup_filter) ||
((idb & INVALIDATE_SERVICES) && !ctx->service_filter) ||
((idb & INVALIDATE_AUTOFSMAPS) && !ctx->autofs_filter) ||
- (user && !ctx->user_name) || (group && !ctx->group_name) ||
- (netgroup && !ctx->netgroup_name) || (map && !ctx->autofs_name) ||
- (service && !ctx->service_name)) {
+ ((idb & INVALIDATE_SSH_HOSTS) && !ctx->ssh_host_filter) ||
+ (user && !ctx->user_name) ||
+ (group && !ctx->group_name) ||
+ (netgroup && !ctx->netgroup_name) ||
+ (service && !ctx->service_name) ||
+ (map && !ctx->autofs_name) ||
+ (ssh_host && !ctx->ssh_host_name)) {
DEBUG(SSSDBG_CRIT_FAILURE, "Construction of filters failed\n");
ret = ENOMEM;
goto fini;