diff options
author | Stephen Gallagher <sgallagh@redhat.com> | 2011-01-12 16:41:26 -0500 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2011-01-21 16:34:54 -0500 |
commit | c6257286e9a31dfd42d28c99a22a69e2c4717a61 (patch) | |
tree | b51f2c14c4d916ca385c38d002d6fd8e136bebb3 /src/db | |
parent | c3a2e4aae7198a5ec2ac8ff028d2379668dc8aa1 (diff) | |
download | sssd-c6257286e9a31dfd42d28c99a22a69e2c4717a61.tar.gz sssd-c6257286e9a31dfd42d28c99a22a69e2c4717a61.tar.xz sssd-c6257286e9a31dfd42d28c99a22a69e2c4717a61.zip |
Delete attributes that are removed from LDAP
Sometimes, a value in LDAP will cease to exist (the classic
example being shadowExpire). We need to make sure we purge that
value from SSSD's sysdb as well.
https://fedorahosted.org/sssd/ticket/750
Diffstat (limited to 'src/db')
-rw-r--r-- | src/db/sysdb.h | 7 | ||||
-rw-r--r-- | src/db/sysdb_ops.c | 118 |
2 files changed, 125 insertions, 0 deletions
diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 3fefdf215..ae0b33ce1 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -521,6 +521,7 @@ int sysdb_store_user(TALLOC_CTX *mem_ctx, const char *homedir, const char *shell, struct sysdb_attrs *attrs, + char **remove_attrs, uint64_t cache_timeout); int sysdb_store_group(TALLOC_CTX *mem_ctx, @@ -712,4 +713,10 @@ errno_t sysdb_set_enumerated(struct sysdb_ctx *ctx, struct sss_domain_info *dom, bool enumerated); +errno_t sysdb_remove_attrs(struct sysdb_ctx *sysdb, + struct sss_domain_info *domain, + const char *name, + enum sysdb_member_type type, + char **remove_attrs); + #endif /* __SYS_DB_H__ */ diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c index e8ef9a249..c36b0ee83 100644 --- a/src/db/sysdb_ops.c +++ b/src/db/sysdb_ops.c @@ -1362,12 +1362,15 @@ int sysdb_store_user(TALLOC_CTX *mem_ctx, const char *homedir, const char *shell, struct sysdb_attrs *attrs, + char **remove_attrs, uint64_t cache_timeout) { TALLOC_CTX *tmpctx; struct ldb_message *msg; time_t now; int ret; + errno_t sret = EOK; + bool in_transaction = false; tmpctx = talloc_new(mem_ctx); if (!tmpctx) { @@ -1379,6 +1382,11 @@ int sysdb_store_user(TALLOC_CTX *mem_ctx, if (ret) goto done; } + ret = sysdb_transaction_start(ctx); + if (ret != EOK) goto done; + + in_transaction = true; + ret = sysdb_search_user_by_name(tmpctx, ctx, domain, name, NULL, &msg); if (ret && ret != ENOENT) { @@ -1443,8 +1451,33 @@ int sysdb_store_user(TALLOC_CTX *mem_ctx, ret = sysdb_set_user_attr(tmpctx, ctx, domain, name, attrs, SYSDB_MOD_REP); + if (ret != EOK) goto done; + + if (remove_attrs) { + ret = sysdb_remove_attrs(ctx, domain, name, + SYSDB_MEMBER_USER, + remove_attrs); + if (ret != EOK) { + DEBUG(4, ("Could not remove missing attributes\n")); + } + } done: + if (in_transaction) { + if (ret == EOK) { + sret = sysdb_transaction_commit(ctx); + if (sret != EOK) { + DEBUG(2, ("Could not commit transaction\n")); + } + } + + if (ret != EOK || sret != EOK){ + sret = sysdb_transaction_cancel(ctx); + if (sret != EOK) { + DEBUG(2, ("Could not cancel transaction\n")); + } + } + } if (ret) { DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret))); } @@ -2767,3 +2800,88 @@ done: talloc_free(msg); return ret; } + +errno_t sysdb_remove_attrs(struct sysdb_ctx *sysdb, + struct sss_domain_info *domain, + const char *name, + enum sysdb_member_type type, + char **remove_attrs) +{ + errno_t ret; + errno_t sret = EOK; + bool in_transaction = false; + struct ldb_message *msg; + int lret; + size_t i; + + msg = ldb_msg_new(NULL); + if (!msg) return ENOMEM; + + if (type == SYSDB_MEMBER_USER) { + msg->dn = sysdb_user_dn(sysdb, msg, domain->name, name); + if (!msg->dn) { + ret = ENOMEM; + goto done; + } + } else if (type == SYSDB_MEMBER_GROUP) { + msg->dn = sysdb_group_dn(sysdb, msg, domain->name, name); + if (!msg->dn) { + ret = ENOMEM; + goto done; + } + } else { + ret = EINVAL; + goto done; + } + + ret = sysdb_transaction_start(sysdb); + if (ret != EOK) goto done; + + in_transaction = true; + + for (i = 0; remove_attrs[i]; i++) { + DEBUG(8, ("Removing attribute [%s] from [%s]\n", + remove_attrs[i], name)); + lret = ldb_msg_add_empty(msg, remove_attrs[i], + LDB_FLAG_MOD_DELETE, NULL); + if (lret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(lret); + goto done; + } + + /* We need to do individual modifies so that we can + * skip unknown attributes. Otherwise, any nonexistent + * attribute in the sysdb will cause other removals to + * fail. + */ + lret = ldb_modify(sysdb->ldb, msg); + if (lret != LDB_SUCCESS && lret != LDB_ERR_NO_SUCH_ATTRIBUTE) { + ret = sysdb_error_to_errno(lret); + goto done; + } + + /* Remove this attribute and move on to the next one */ + ldb_msg_remove_attr(msg, remove_attrs[i]); + } + + ret = EOK; + +done: + if (in_transaction) { + if (ret == EOK) { + sret = sysdb_transaction_commit(sysdb); + if (sret != EOK) { + DEBUG(2, ("Could not commit transaction\n")); + } + } + + if (ret != EOK || sret != EOK){ + sret = sysdb_transaction_cancel(sysdb); + if (sret != EOK) { + DEBUG(2, ("Could not cancel transaction\n")); + } + } + } + talloc_free(msg); + return ret; +} |