diff options
author | Pavel Březina <pbrezina@redhat.com> | 2016-02-23 11:02:42 +0100 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2016-03-01 16:38:52 +0100 |
commit | 659232f194f83ec7c450ce89c3fd41e4e74409f2 (patch) | |
tree | 1308a50c0411f0c49e90f67a3018eb9531086197 | |
parent | 012d334cec221d8abf86dffbbaf9649ec0a4b585 (diff) | |
download | sssd-659232f194f83ec7c450ce89c3fd41e4e74409f2.tar.gz sssd-659232f194f83ec7c450ce89c3fd41e4e74409f2.tar.xz sssd-659232f194f83ec7c450ce89c3fd41e4e74409f2.zip |
remove user certificate if not found on the server
If the user is not found by cert lookup when the user is already
cached, two things may happen:
1) cert was removed from the user object
2) user was removed
Instead of issuing another cert lookup we will just remove cert
attribute from the cache not touching the expiration timestamp so
the user may be updated later when needed.
Resolves:
https://fedorahosted.org/sssd/ticket/2934
Reviewed-by: Sumit Bose <sbose@redhat.com>
-rw-r--r-- | src/db/sysdb.h | 3 | ||||
-rw-r--r-- | src/db/sysdb_ops.c | 45 | ||||
-rw-r--r-- | src/providers/ldap/ldap_id.c | 10 |
3 files changed, 57 insertions, 1 deletions
diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 95a90867..bb8ca08b 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -1155,7 +1155,8 @@ errno_t sysdb_search_user_by_cert(TALLOC_CTX *mem_ctx, const char *cert, struct ldb_result **res); - +errno_t sysdb_remove_cert(struct sss_domain_info *domain, + const char *cert); /* === Functions related to GPOs === */ diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c index ab0d59ca..843251b3 100644 --- a/src/db/sysdb_ops.c +++ b/src/db/sysdb_ops.c @@ -3764,6 +3764,51 @@ errno_t sysdb_search_user_by_cert(TALLOC_CTX *mem_ctx, return sysdb_search_object_by_cert(mem_ctx, domain, cert, user_attrs, res); } +errno_t sysdb_remove_cert(struct sss_domain_info *domain, + const char *cert) +{ + struct ldb_message_element el = { 0, SYSDB_USER_CERT, 0, NULL }; + struct sysdb_attrs del_attrs = { 1, &el }; + const char *attrs[] = {SYSDB_NAME, NULL}; + struct ldb_result *res = NULL; + unsigned int i; + errno_t ret; + + ret = sysdb_search_object_by_cert(NULL, domain, cert, attrs, &res); + if (ret == ENOENT || res == NULL) { + ret = EOK; + goto done; + } else if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, "Unable to lookup object by cert " + "[%d]: %s\n", ret, sss_strerror(ret)); + goto done; + } + + /* Certificate may be found on more objects, remove it from all. + * If object contains more then one certificate, we still remove the + * whole attribute since it will be downloaded again. */ + for (i = 0; i < res->count; i++) { + ret = sysdb_set_entry_attr(domain->sysdb, res->msgs[0]->dn, + &del_attrs, SYSDB_MOD_DEL); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to remove certificate " + "[%d]: %s\n", ret, sss_strerror(ret)); + goto done; + } + + ret = sysdb_mark_entry_as_expired_ldb_dn(domain, res->msgs[0]->dn); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, "Unable to expire object " + "[%d]: %s\n", ret, sss_strerror(ret)); + continue; + } + } + +done: + talloc_free(res); + return ret; +} + errno_t sysdb_get_sids_of_members(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, const char *group_name, diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c index b7cef4e1..8923e7e0 100644 --- a/src/providers/ldap/ldap_id.c +++ b/src/providers/ldap/ldap_id.c @@ -529,6 +529,16 @@ static void users_get_done(struct tevent_req *subreq) */ break; + case BE_FILTER_CERT: + ret = sysdb_remove_cert(state->domain, state->name); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to remove user certificate" + "[%d]: %s\n", ret, sss_strerror(ret)); + tevent_req_error(req, ret); + return; + } + break; + default: tevent_req_error(req, EINVAL); return; |