diff options
Diffstat (limited to 'src/db')
-rw-r--r-- | src/db/sysdb.h | 6 | ||||
-rw-r--r-- | src/db/sysdb_search.c | 112 |
2 files changed, 118 insertions, 0 deletions
diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 04733f2a8..0d0971d98 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -612,6 +612,12 @@ int sysdb_get_user_attr(TALLOC_CTX *mem_ctx, const char **attributes, struct ldb_result **res); +int sysdb_get_user_attr_with_views(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *name, + const char **attributes, + struct ldb_result **res); + int sysdb_get_netgroup_attr(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *netgrname, diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c index ca52f1185..bbc5af8a0 100644 --- a/src/db/sysdb_search.c +++ b/src/db/sysdb_search.c @@ -1028,6 +1028,118 @@ done: return ret; } +int sysdb_get_user_attr_with_views(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *name, + const char **attributes, + struct ldb_result **_res) +{ + int ret; + struct ldb_result *orig_obj = NULL; + struct ldb_result *override_obj = NULL; + struct ldb_message_element *el = NULL; + const char **attrs = NULL; + bool has_override_dn; + TALLOC_CTX *tmp_ctx; + int count; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); + return ENOMEM; + } + + /* Assume that overrideDN is requested to simplify the code. If no view + * is applied it doesn't really matter. */ + has_override_dn = true; + attrs = attributes; + + /* If there are views we first have to search the overrides for matches */ + if (DOM_HAS_VIEWS(domain)) { + /* We need overrideDN for views, so append it if missing. */ + has_override_dn = false; + for (count = 0; attributes[count] != NULL; count++) { + if (strcmp(attributes[count], SYSDB_OVERRIDE_DN) == 0) { + has_override_dn = true; + break; + } + } + + if (!has_override_dn) { + /* Copy original attributes and add overrideDN. */ + attrs = talloc_zero_array(tmp_ctx, const char *, count + 2); + if (attrs == NULL) { + ret = ENOMEM; + goto done; + } + + for (count = 0; attributes[count] != NULL; count++) { + attrs[count] = attributes[count]; + } + + attrs[count] = SYSDB_OVERRIDE_DN; + } + + ret = sysdb_search_user_override_attrs_by_name(tmp_ctx, domain, name, + attrs, &override_obj, &orig_obj); + if (ret != EOK && ret != ENOENT) { + DEBUG(SSSDBG_OP_FAILURE, + "sysdb_search_user_override_attrs_by_name failed.\n"); + return ret; + } + } + + /* If there are no views or nothing was found in the overrides the + * original objects are searched. */ + if (orig_obj == NULL) { + ret = sysdb_get_user_attr(tmp_ctx, domain, name, attrs, &orig_obj); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sysdb_get_user_attr failed.\n"); + return ret; + } + } + + /* If there are views we have to check if override values must be added to + * the original object. */ + if (DOM_HAS_VIEWS(domain) && orig_obj->count == 1) { + ret = sysdb_add_overrides_to_object(domain, orig_obj->msgs[0], + override_obj == NULL ? NULL : override_obj ->msgs[0]); + if (ret != EOK && ret != ENOENT) { + DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n"); + return ret; + } + + if (ret == ENOENT) { + *_res = talloc_zero(mem_ctx, struct ldb_result); + if (*_res == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); + ret = ENOMEM; + } else { + ret = EOK; + } + goto done; + } + } + + /* Remove overrideDN if needed. */ + if (!has_override_dn && orig_obj != NULL && orig_obj->count == 1) { + el = ldb_msg_find_element(orig_obj->msgs[0], SYSDB_OVERRIDE_DN); + if (el == NULL) { + ret = EINVAL; + goto done; + } + + ldb_msg_remove_element(orig_obj->msgs[0], el); + } + + *_res = talloc_steal(mem_ctx, orig_obj); + ret = EOK; + +done: + talloc_free(tmp_ctx); + return ret; +} + /* This function splits a three-tuple into three strings * It assumes that any whitespace between the parentheses * and commas are intentional and does not attempt to |