diff options
author | William B <william@adelaide.edu.au> | 2014-07-21 11:13:25 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2014-09-05 11:40:39 +0200 |
commit | 3ac7c4fe618ede980a4df8d90341ef1fd0f1f62f (patch) | |
tree | 940c252ca1538b4d8cd60e94d95073d6a845f040 /src | |
parent | 61602026ed8c91efd166000562899670449f1b50 (diff) | |
download | sssd-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>
Diffstat (limited to 'src')
-rw-r--r-- | src/confdb/confdb.c | 11 | ||||
-rw-r--r-- | src/confdb/confdb.h | 2 | ||||
-rwxr-xr-x | src/config/SSSDConfigTest.py | 2 | ||||
-rw-r--r-- | src/config/etc/sssd.api.conf | 1 | ||||
-rw-r--r-- | src/db/sysdb_ssh.c | 63 | ||||
-rw-r--r-- | src/db/sysdb_ssh.h | 15 | ||||
-rw-r--r-- | src/man/sss_cache.8.xml | 23 | ||||
-rw-r--r-- | src/man/sssd.conf.5.xml | 14 | ||||
-rw-r--r-- | src/providers/ipa/ipa_hostid.c | 4 | ||||
-rw-r--r-- | src/tests/sysdb_ssh-tests.c | 1 | ||||
-rw-r--r-- | src/tools/sss_cache.c | 86 |
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; |