summaryrefslogtreecommitdiffstats
path: root/src/db/sysdb_ops.c
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2012-11-17 23:55:13 +0100
committerJakub Hrozek <jhrozek@redhat.com>2012-11-21 11:18:10 +0100
commitf9111f464376338317e30da637353e2c25869ce8 (patch)
tree603e9228acbc691955a19e104865f1e21659c0ff /src/db/sysdb_ops.c
parentfcea2fb0044b50b54bb02238782b6631dbc9bb90 (diff)
downloadsssd-f9111f464376338317e30da637353e2c25869ce8.tar.gz
sssd-f9111f464376338317e30da637353e2c25869ce8.tar.xz
sssd-f9111f464376338317e30da637353e2c25869ce8.zip
LDAP: Only convert direct parents' ghost attribute to member
https://fedorahosted.org/sssd/ticket/1612 This patch changes the handling of ghost attributes when saving the actual user entry. Instead of always linking all groups that contained the ghost attribute with the new user entry, the original member attributes are now saved in the group object and the user entry is only linked with its direct parents. As the member attribute is compared against the originalDN of the user, if either the originalDN or the originalMember attributes are missing, the user object is linked with all the groups as a fallback. The original member attributes are only saved if the LDAP schema supports nesting.
Diffstat (limited to 'src/db/sysdb_ops.c')
-rw-r--r--src/db/sysdb_ops.c45
1 files changed, 37 insertions, 8 deletions
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
index 8b624a398..0eef6d039 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -860,6 +860,7 @@ int sysdb_add_user(struct sysdb_ctx *sysdb,
const char *gecos,
const char *homedir,
const char *shell,
+ const char *orig_dn,
struct sysdb_attrs *attrs,
int cache_timeout,
time_t now)
@@ -868,14 +869,16 @@ int sysdb_add_user(struct sysdb_ctx *sysdb,
struct ldb_message *msg;
struct ldb_message **groups;
struct ldb_message_element *alias_el;
+ struct ldb_message_element *orig_members;
size_t group_count = 0;
struct sysdb_attrs *id_attrs;
- const char *group_attrs[] = {SYSDB_NAME, SYSDB_GHOST, NULL};
+ const char *group_attrs[] = {SYSDB_NAME, SYSDB_GHOST, SYSDB_ORIG_MEMBER, NULL};
struct ldb_dn *tmpdn;
const char *userdn;
char *filter;
uint32_t id;
int ret, i, j;
+ bool add_member = false;
struct sss_domain_info *domain = sysdb->domain;
@@ -1029,7 +1032,7 @@ int sysdb_add_user(struct sysdb_ctx *sysdb,
}
/* We need to find all groups that contain this object as a ghost user
- * and replace the ghost user there by actual member record
+ * and replace the ghost user by actual member record in direct parents.
* Note that this object can be referred to either by its name or any
* of its aliases
*/
@@ -1047,8 +1050,33 @@ int sysdb_add_user(struct sysdb_ctx *sysdb,
msg->dn = groups[i]->dn;
- ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_MEMBER, userdn);
- if (ret) goto done;
+ if (orig_dn == NULL) {
+ /* We have no way of telling which groups this user belongs to.
+ * Add it to all that reference it in the ghost attribute */
+ add_member = true;
+ } else {
+ add_member = false;
+ orig_members = ldb_msg_find_element(groups[i], SYSDB_ORIG_MEMBER);
+ if (orig_members) {
+ for (j = 0; j < orig_members->num_values; j++) {
+ if (strcmp((const char *) orig_members->values[j].data,
+ orig_dn) == 0) {
+ /* This is a direct member. Add the member attribute */
+ add_member = true;
+ }
+ }
+ } else {
+ /* Nothing to compare the originalDN with. Let's rely on the
+ * memberof plugin to do the right thing during initgroups..
+ */
+ add_member = true;
+ }
+ }
+
+ if (add_member) {
+ ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_MEMBER, userdn);
+ if (ret) goto done;
+ }
ret = add_string(msg, LDB_FLAG_MOD_DELETE, SYSDB_GHOST, name);
if (ret) goto done;
@@ -1485,6 +1513,7 @@ int sysdb_store_user(struct sysdb_ctx *sysdb,
const char *gecos,
const char *homedir,
const char *shell,
+ const char *orig_dn,
struct sysdb_attrs *attrs,
char **remove_attrs,
uint64_t cache_timeout,
@@ -1535,8 +1564,8 @@ int sysdb_store_user(struct sysdb_ctx *sysdb,
if (ret == ENOENT) {
/* users doesn't exist, turn into adding a user */
- ret = sysdb_add_user(sysdb, name, uid, gid,
- gecos, homedir, shell, attrs, cache_timeout, now);
+ ret = sysdb_add_user(sysdb, name, uid, gid, gecos, homedir,
+ shell, orig_dn, attrs, cache_timeout, now);
if (ret == EEXIST) {
/* This may be a user rename. If there is a user with the
* same UID, remove it and try to add the basic user again
@@ -1554,8 +1583,8 @@ int sysdb_store_user(struct sysdb_ctx *sysdb,
DEBUG(SSSDBG_MINOR_FAILURE,
("A user with the same UID [%llu] was removed from the "
"cache\n", (unsigned long long) uid));
- ret = sysdb_add_user(sysdb, name, uid, gid, gecos,
- homedir, shell, attrs, cache_timeout, now);
+ ret = sysdb_add_user(sysdb, name, uid, gid, gecos, homedir,
+ shell, orig_dn, attrs, cache_timeout, now);
}
/* Handle the result of sysdb_add_user */