summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2010-09-20 14:02:39 +0200
committerStephen Gallagher <sgallagh@redhat.com>2010-10-15 09:03:07 -0400
commit3dd54ad87fd6a2bc8f646cd93be0329647e96f0e (patch)
treed068ed55f56cf9bb1ebde7f413dfc3ef1fe85b49
parent7e15d2ed3c01ab3c1f5f882fe8fa974058097bc6 (diff)
downloadsssd-3dd54ad87fd6a2bc8f646cd93be0329647e96f0e.tar.gz
sssd-3dd54ad87fd6a2bc8f646cd93be0329647e96f0e.tar.bz2
sssd-3dd54ad87fd6a2bc8f646cd93be0329647e96f0e.zip
Save dummy groups to cache during initgroups
If during initgroups operation we find out that any of the groups the user is a member of is not cached yet we add a incomplete, expired group entry. That way, we save ourselves from looking up and saving all the potential user entries the group may also consist of. Because the group is expired, it will be refreshed during the next getgrgid/getgrnam call and correct member list will be returned.
-rw-r--r--src/providers/ldap/sdap_async_accounts.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/src/providers/ldap/sdap_async_accounts.c b/src/providers/ldap/sdap_async_accounts.c
index af1f5c53..4ced1ae0 100644
--- a/src/providers/ldap/sdap_async_accounts.c
+++ b/src/providers/ldap/sdap_async_accounts.c
@@ -1392,6 +1392,119 @@ int sdap_get_groups_recv(struct tevent_req *req,
return EOK;
}
+/* ==Save-fake-group-list=====================================*/
+static errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb,
+ struct sss_domain_info *dom,
+ char **groupnames,
+ struct sysdb_attrs **ldap_groups,
+ int ldap_groups_count)
+{
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_message *msg;
+ int i, mi, ai;
+ const char *name;
+ char **missing;
+ gid_t gid;
+ int ret;
+ bool in_transaction = false;
+
+ /* There are no groups in LDAP but we should add user to groups ?? */
+ if (ldap_groups_count == 0) return EOK;
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) return ENOMEM;
+
+ missing = talloc_array(tmp_ctx, char *, ldap_groups_count+1);
+ if (!missing) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ mi = 0;
+
+ ret = sysdb_transaction_start(sysdb);
+ if (ret != EOK) {
+ DEBUG(1, ("Cannot start sysdb transaction [%d]: %s\n",
+ ret, strerror(ret)));
+ goto fail;
+ }
+ in_transaction = true;
+
+ for (i=0; groupnames[i]; i++) {
+ ret = sysdb_search_group_by_name(tmp_ctx, sysdb, dom,
+ groupnames[i], NULL, &msg);
+ if (ret == EOK) {
+ continue;
+ } else if (ret == ENOENT) {
+ DEBUG(7, ("Group #%d [%s] is not cached, need to add a fake entry\n",
+ i, groupnames[i]));
+ missing[mi] = groupnames[i];
+ mi++;
+ continue;
+ } else if (ret != ENOENT) {
+ DEBUG(1, ("search for group failed [%d]: %s\n",
+ ret, strerror(ret)));
+ goto fail;
+ }
+ }
+ missing[mi] = NULL;
+
+ /* All groups are cached, nothing to do */
+ if (mi == 0) {
+ talloc_zfree(tmp_ctx);
+ goto done;
+ }
+
+ for (i=0; missing[i]; i++) {
+ /* The group is not in sysdb, need to add a fake entry */
+ for (ai=0; ai < ldap_groups_count; ai++) {
+ ret = sysdb_attrs_get_string(ldap_groups[ai],
+ SYSDB_NAME,
+ &name);
+ if (ret) {
+ DEBUG(1, ("The group has no name attribute\n"));
+ goto fail;
+ }
+
+ if (strcmp(name, missing[i]) == 0) {
+ ret = sysdb_attrs_get_ulong(ldap_groups[ai],
+ SYSDB_GIDNUM,
+ (unsigned long *) &gid);
+ if (ret) {
+ DEBUG(1, ("The GID attribute is missing or malformed\n"));
+ goto fail;
+ }
+
+
+ DEBUG(8, ("Adding fake group %s to sysdb\n", name));
+ ret = sysdb_add_incomplete_group(sysdb, dom, name, gid);
+ if (ret != EOK) {
+ goto fail;
+ }
+ break;
+ }
+ }
+
+ if (ai == ldap_groups_count) {
+ DEBUG(2, ("Group %s not present in LDAP\n", missing[i]));
+ ret = EINVAL;
+ goto fail;
+ }
+ }
+
+done:
+ ret = sysdb_transaction_commit(sysdb);
+ if (ret != EOK) {
+ DEBUG(1, ("sysdb_transaction_commit failed.\n"));
+ goto fail;
+ }
+ in_transaction = false;
+ ret = EOK;
+fail:
+ if (in_transaction) {
+ sysdb_transaction_cancel(sysdb);
+ }
+ return ret;
+}
/* ==Initgr-call-(groups-a-user-is-member-of)-RFC2307-Classic/BIS========= */
@@ -1553,6 +1666,18 @@ static void sdap_initgr_rfc2307_process(struct tevent_req *subreq)
return;
}
+ /* Add fake entries for any groups the user should be added as
+ * member of but that are not cached in sysdb
+ */
+ if (add_groups && add_groups[0]) {
+ ret = sdap_add_incomplete_groups(state->sysdb, state->dom,
+ add_groups, ldap_groups, count);
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+ }
+
ret = sysdb_update_members(state->sysdb, state->dom, state->name,
(const char **)add_groups,
(const char **)del_groups);