summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Reichl <preichl@redhat.com>2014-11-20 18:27:04 +0000
committerJakub Hrozek <jhrozek@redhat.com>2014-12-15 02:10:52 +0100
commitb8fea7e509fa835542a373f79ed1370debe7c27f (patch)
tree3ffad5f5b6b9e3f31f4edee60aaf820095f71f95
parent03afa4cbef2c2ba3c70fbad4f3e1e36c05fafe82 (diff)
downloadsssd-b8fea7e509fa835542a373f79ed1370debe7c27f.tar.gz
sssd-b8fea7e509fa835542a373f79ed1370debe7c27f.tar.xz
sssd-b8fea7e509fa835542a373f79ed1370debe7c27f.zip
LDAP: retain external members
When processing group membership check sysdb for group members from extern domain and include them in newly processed group membership as extern members are curently found only when initgroups() is called. Resolves: https://fedorahosted.org/sssd/ticket/2492 Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com> Reviewed-by: Sumit Bose <sbose@redhat.com>
-rw-r--r--src/db/sysdb.h6
-rw-r--r--src/db/sysdb_ops.c83
-rw-r--r--src/providers/ldap/sdap_async_groups.c104
3 files changed, 193 insertions, 0 deletions
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 4fbbb1671..01900425a 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -1105,4 +1105,10 @@ errno_t sysdb_gpo_get_gpo_result_setting(TALLOC_CTX *mem_ctx,
const char *policy_setting_key,
const char **policy_setting_value);
+errno_t sysdb_get_sids_of_members(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *dom,
+ const char *group_name,
+ const char ***_sids,
+ const char ***_dns,
+ size_t *_n);
#endif /* __SYS_DB_H__ */
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
index 998046a2c..768f94553 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -3630,3 +3630,86 @@ errno_t sysdb_search_object_by_uuid(TALLOC_CTX *mem_ctx,
return sysdb_search_object_by_str_attr(mem_ctx, domain, SYSDB_UUID_FILTER,
uuid_str, attrs, res);
}
+
+errno_t sysdb_get_sids_of_members(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *dom,
+ const char *group_name,
+ const char ***_sids,
+ const char ***_dns,
+ size_t *_n)
+{
+ errno_t ret;
+ size_t i, m_count;
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_message *msg;
+ struct ldb_message **members;
+ const char *attrs[] = { SYSDB_SID_STR, NULL };
+ const char **sids = NULL, **dns = NULL;
+ size_t n = 0;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ ret = sysdb_search_group_by_name(tmp_ctx, dom, group_name, NULL, &msg);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ /* Get sid_str attribute of all elemets pointed to by group members */
+ ret = sysdb_asq_search(tmp_ctx, dom, msg->dn, NULL, SYSDB_MEMBER, attrs,
+ &m_count, &members);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ sids = talloc_array(tmp_ctx, const char*, m_count);
+ if (sids == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ dns = talloc_array(tmp_ctx, const char*, m_count);
+ if (dns == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ for (i=0; i < m_count; i++) {
+ const char *sidstr;
+
+ sidstr = ldb_msg_find_attr_as_string(members[i], SYSDB_SID_STR, NULL);
+
+ if (sidstr != NULL) {
+ sids[n] = talloc_steal(sids, sidstr);
+
+ dns[n] = talloc_steal(dns, ldb_dn_get_linearized(members[i]->dn));
+ if (dns[n] == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+ n++;
+ }
+ }
+
+ if (n == 0) {
+ ret = ENOENT;
+ goto done;
+ }
+
+ *_n = n;
+ *_sids = talloc_steal(mem_ctx, sids);
+ *_dns = talloc_steal(mem_ctx, dns);
+
+ ret = EOK;
+
+done:
+ if (ret == ENOENT) {
+ DEBUG(SSSDBG_TRACE_FUNC, "No such entry\n");
+ } else if (ret) {
+ DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret));
+ }
+ talloc_free(tmp_ctx);
+ return ret;
+}
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
index 8cf7f7ff1..c86b5c6b5 100644
--- a/src/providers/ldap/sdap_async_groups.c
+++ b/src/providers/ldap/sdap_async_groups.c
@@ -801,6 +801,87 @@ done:
return ret;
}
+static errno_t
+are_sids_from_same_dom(const char *sid1, const char *sid2, bool *_result)
+{
+ size_t len_prefix_sid1;
+ size_t len_prefix_sid2;
+ char *rid1, *rid2;
+ bool result;
+
+ rid1 = strrchr(sid1, '-');
+ if (rid1 == NULL) {
+ return EINVAL;
+ }
+
+ rid2 = strrchr(sid2, '-');
+ if (rid2 == NULL) {
+ return EINVAL;
+ }
+
+ len_prefix_sid1 = rid1 - sid1;
+ len_prefix_sid2 = rid2 - sid2;
+
+ result = (len_prefix_sid1 == len_prefix_sid2) &&
+ (strncmp(sid1, sid2, len_prefix_sid1) == 0);
+
+ *_result = result;
+
+ return EOK;
+}
+
+static errno_t
+retain_extern_members(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *dom,
+ const char *group_name,
+ const char *group_sid,
+ char ***_userdns,
+ size_t *_nuserdns)
+{
+ TALLOC_CTX *tmp_ctx;
+ const char **sids, **dns;
+ bool same_domain;
+ errno_t ret;
+ size_t i, n;
+ size_t nuserdns = 0;
+ const char **userdns = NULL;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ ret = sysdb_get_sids_of_members(tmp_ctx, dom, group_name, &sids, &dns, &n);
+ if (ret != EOK) {
+ if (ret != ENOENT) {
+ DEBUG(SSSDBG_TRACE_ALL,
+ "get_sids_of_members failed: %d [%s]\n",
+ ret, sss_strerror(ret));
+ }
+ goto done;
+ }
+
+ for (i=0; i < n; i++) {
+ ret = are_sids_from_same_dom(group_sid, sids[i], &same_domain);
+ if (ret == EOK && !same_domain) {
+ DEBUG(SSSDBG_TRACE_ALL, "extern member: %s\n", dns[i]);
+ nuserdns++;
+ userdns = talloc_realloc(tmp_ctx, userdns, const char*, nuserdns);
+ if (userdns == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+ userdns[nuserdns-1] = talloc_steal(userdns, dns[i]);
+ }
+ }
+ *_nuserdns = nuserdns;
+ *_userdns = discard_const(talloc_steal(mem_ctx, userdns));
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
/* ==Save-Group-Memebrs=================================================== */
@@ -817,6 +898,7 @@ static int sdap_save_grpmem(TALLOC_CTX *memctx,
{
struct ldb_message_element *el;
struct sysdb_attrs *group_attrs = NULL;
+ const char *group_sid;
const char *group_name;
char **userdns = NULL;
size_t nuserdns = 0;
@@ -843,6 +925,28 @@ static int sdap_save_grpmem(TALLOC_CTX *memctx,
}
}
+ /* This is a temporal solution until the IPA provider is able to
+ * resolve external group membership.
+ * https://fedorahosted.org/sssd/ticket/2522
+ */
+ if (opts->schema_type == SDAP_SCHEMA_IPA_V1) {
+ ret = sysdb_attrs_get_string(attrs, SYSDB_SID_STR, &group_sid);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_TRACE_FUNC, "Failed to get group sid\n");
+ group_sid = NULL;
+ }
+
+ if (group_sid != NULL) {
+ ret = retain_extern_members(memctx, dom, group_name, group_sid,
+ &userdns, &nuserdns);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_TRACE_INTERNAL,
+ "retain_extern_members failed: %d:[%s].\n",
+ ret, sss_strerror(ret));
+ }
+ }
+ }
+
ret = sysdb_attrs_get_el(attrs,
opts->group_map[SDAP_AT_GROUP_MEMBER].sys_name, &el);
if (ret != EOK) {