summaryrefslogtreecommitdiffstats
path: root/src/db/sysdb_ops.c
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2011-01-12 16:41:26 -0500
committerStephen Gallagher <sgallagh@redhat.com>2011-01-21 16:34:54 -0500
commitc6257286e9a31dfd42d28c99a22a69e2c4717a61 (patch)
treeb51f2c14c4d916ca385c38d002d6fd8e136bebb3 /src/db/sysdb_ops.c
parentc3a2e4aae7198a5ec2ac8ff028d2379668dc8aa1 (diff)
downloadsssd-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/sysdb_ops.c')
-rw-r--r--src/db/sysdb_ops.c118
1 files changed, 118 insertions, 0 deletions
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;
+}