summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2014-09-29 12:12:01 +0200
committerJakub Hrozek <jhrozek@redhat.com>2014-10-20 16:15:19 +0200
commitd2f4551519698809e73a029c49599e1f67e6bdd4 (patch)
treec1b0282a7f76a0f90cf7d95cfcf5378d28b2d0a9 /src
parentf1d5f72459ec7d776e66c4516da2c1b9c6c1a84d (diff)
downloadsssd-d2f4551519698809e73a029c49599e1f67e6bdd4.tar.gz
sssd-d2f4551519698809e73a029c49599e1f67e6bdd4.tar.xz
sssd-d2f4551519698809e73a029c49599e1f67e6bdd4.zip
sysdb: add sysdb_getgrnam_with_views and sysdb_getgrgid_with_views
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
Diffstat (limited to 'src')
-rw-r--r--src/db/sysdb.h13
-rw-r--r--src/db/sysdb_search.c168
-rw-r--r--src/db/sysdb_views.c130
3 files changed, 311 insertions, 0 deletions
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index b65fa1d31..f7e507c91 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -475,6 +475,9 @@ errno_t sysdb_add_overrides_to_object(struct sss_domain_info *domain,
struct ldb_message *obj,
struct ldb_message *override_obj);
+errno_t sysdb_add_group_member_overrides(struct sss_domain_info *domain,
+ struct ldb_message *obj);
+
errno_t sysdb_getpwnam_with_views(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
const char *name,
@@ -485,6 +488,16 @@ errno_t sysdb_getpwuid_with_views(TALLOC_CTX *mem_ctx,
uid_t uid,
struct ldb_result **res);
+int sysdb_getgrnam_with_views(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ const char *name,
+ struct ldb_result **res);
+
+int sysdb_getgrgid_with_views(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ gid_t gid,
+ struct ldb_result **res);
+
struct ldb_message_element *
sss_view_ldb_msg_find_element(struct sss_domain_info *dom,
const struct ldb_message *msg,
diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c
index 803a96ae7..f4cecfc47 100644
--- a/src/db/sysdb_search.c
+++ b/src/db/sysdb_search.c
@@ -335,6 +335,90 @@ static int mpg_res_convert(struct ldb_result *res)
return EOK;
}
+int sysdb_getgrnam_with_views(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ const char *name,
+ struct ldb_result **res)
+{
+ TALLOC_CTX *tmp_ctx;
+ int ret;
+ struct ldb_result *orig_obj = NULL;
+ struct ldb_result *override_obj = NULL;
+ struct ldb_message_element *el;
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) {
+ return ENOMEM;
+ }
+
+ /* If there are views we first have to search the overrides for matches */
+ if (DOM_HAS_VIEWS(domain)) {
+ ret = sysdb_search_group_override_by_name(tmp_ctx, domain, name,
+ &override_obj, &orig_obj);
+ if (ret != EOK && ret != ENOENT) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sysdb_search_group_override_by_name failed.\n");
+ goto done;
+ }
+ }
+
+ /* If there are no views or nothing was found in the overrides the
+ * original objects are searched. */
+ if (orig_obj == NULL) {
+ ret = sysdb_getgrnam(tmp_ctx, domain, name, &orig_obj);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_getgrnam failed.\n");
+ goto done;
+ }
+ }
+
+ /* 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) {
+ el = ldb_msg_find_element(orig_obj->msgs[0], SYSDB_GHOST);
+ if (el != NULL && el->num_values != 0) {
+ DEBUG(SSSDBG_TRACE_ALL,
+ "Group object [%s], contains ghost entries which must be " \
+ "resolved before overrides can be applied.\n",
+ ldb_dn_get_linearized(orig_obj->msgs[0]->dn));
+ ret = ENOENT;
+ goto done;
+ }
+
+ ret = sysdb_add_overrides_to_object(domain, orig_obj->msgs[0],
+ override_obj == NULL ? NULL : override_obj ->msgs[0]);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n");
+ goto done;
+ }
+
+ ret = sysdb_add_group_member_overrides(domain, orig_obj->msgs[0]);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sysdb_add_group_member_overrides failed.\n");
+ goto done;
+ }
+ }
+
+ *res = talloc_steal(mem_ctx, orig_obj);
+ ret = EOK;
+
+done:
+ if (ret == ENOENT) {
+ DEBUG(SSSDBG_TRACE_ALL, "Returning empty result.\n");
+ *res = talloc_zero(mem_ctx, struct ldb_result);
+ if (*res == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n");
+ ret = ENOMEM;
+ } else {
+ ret = EOK;
+ }
+ }
+
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
int sysdb_getgrnam(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
const char *name,
@@ -403,6 +487,90 @@ done:
return ret;
}
+int sysdb_getgrgid_with_views(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ gid_t gid,
+ struct ldb_result **res)
+{
+ TALLOC_CTX *tmp_ctx;
+ int ret;
+ struct ldb_result *orig_obj = NULL;
+ struct ldb_result *override_obj = NULL;
+ struct ldb_message_element *el;
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) {
+ return ENOMEM;
+ }
+
+ /* If there are views we first have to search the overrides for matches */
+ if (DOM_HAS_VIEWS(domain)) {
+ ret = sysdb_search_group_override_by_gid(tmp_ctx, domain, gid,
+ &override_obj, &orig_obj);
+ if (ret != EOK && ret != ENOENT) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sysdb_search_group_override_by_gid failed.\n");
+ goto done;
+ }
+ }
+
+ /* If there are no views or nothing was found in the overrides the
+ * original objects are searched. */
+ if (orig_obj == NULL) {
+ ret = sysdb_getgrgid(tmp_ctx, domain, gid, &orig_obj);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_getgrgid failed.\n");
+ goto done;
+ }
+ }
+
+ /* 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) {
+ el = ldb_msg_find_element(orig_obj->msgs[0], SYSDB_GHOST);
+ if (el != NULL && el->num_values != 0) {
+ DEBUG(SSSDBG_TRACE_ALL,
+ "Group object [%s], contains ghost entries which must be " \
+ "resolved before overrides can be applied.\n",
+ ldb_dn_get_linearized(orig_obj->msgs[0]->dn));
+ ret = ENOENT;
+ goto done;
+ }
+
+ ret = sysdb_add_overrides_to_object(domain, orig_obj->msgs[0],
+ override_obj == NULL ? NULL : override_obj ->msgs[0]);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n");
+ goto done;
+ }
+
+ ret = sysdb_add_group_member_overrides(domain, orig_obj->msgs[0]);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sysdb_add_group_member_overrides failed.\n");
+ goto done;
+ }
+ }
+
+ *res = talloc_steal(mem_ctx, orig_obj);
+ ret = EOK;
+
+done:
+ if (ret == ENOENT) {
+ DEBUG(SSSDBG_TRACE_ALL, "Returning empty result.\n");
+ *res = talloc_zero(mem_ctx, struct ldb_result);
+ if (*res == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n");
+ ret = ENOMEM;
+ } else {
+ ret = EOK;
+ }
+ }
+
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
int sysdb_getgrgid(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
gid_t gid,
diff --git a/src/db/sysdb_views.c b/src/db/sysdb_views.c
index 7252bad19..acb5d8138 100644
--- a/src/db/sysdb_views.c
+++ b/src/db/sysdb_views.c
@@ -1057,6 +1057,136 @@ done:
return ret;
}
+errno_t sysdb_add_group_member_overrides(struct sss_domain_info *domain,
+ struct ldb_message *obj)
+{
+ int ret;
+ size_t c;
+ struct ldb_message_element *members;
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_dn *member_dn;
+ struct ldb_result *member_obj;
+ struct ldb_result *override_obj;
+ static const char *member_attrs[] = SYSDB_PW_ATTRS;
+ const char *override_dn_str;
+ struct ldb_dn *override_dn;
+ const char *memberuid;
+
+ members = ldb_msg_find_element(obj, SYSDB_MEMBER);
+ if (members == NULL || members->num_values == 0) {
+ DEBUG(SSSDBG_TRACE_ALL, "Group has no members.\n");
+ return EOK;
+ }
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ for (c = 0; c < members->num_values; c++) {
+ member_dn = ldb_dn_from_ldb_val(tmp_ctx, domain->sysdb->ldb,
+ &members->values[c]);
+ if (member_dn == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_from_ldb_val failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = ldb_search(domain->sysdb->ldb, member_dn, &member_obj, member_dn,
+ LDB_SCOPE_BASE, member_attrs, NULL);
+ if (ret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+
+ if (member_obj->count != 1) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Base search for member object returned [%d] results.\n",
+ member_obj->count);
+ ret = EINVAL;
+ goto done;
+ }
+
+ override_dn_str = ldb_msg_find_attr_as_string(member_obj->msgs[0],
+ SYSDB_OVERRIDE_DN, NULL);
+ if (override_dn_str == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Missing override DN for objext [%s].\n",
+ ldb_dn_get_linearized(member_obj->msgs[0]->dn));
+ ret = ENOENT;
+ goto done;
+ }
+
+ override_dn = ldb_dn_new(member_obj, domain->sysdb->ldb,
+ override_dn_str);
+ if (override_dn == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ memberuid = NULL;
+ if (ldb_dn_compare(member_obj->msgs[0]->dn, override_dn) != 0) {
+ DEBUG(SSSDBG_TRACE_ALL, "Checking override for object [%s].\n",
+ ldb_dn_get_linearized(member_obj->msgs[0]->dn));
+
+ ret = ldb_search(domain->sysdb->ldb, member_obj, &override_obj,
+ override_dn, LDB_SCOPE_BASE, member_attrs, NULL);
+ if (ret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+
+ if (override_obj->count != 1) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Base search for override object returned [%d] results.\n",
+ member_obj->count);
+ ret = EINVAL;
+ goto done;
+ }
+
+ memberuid = ldb_msg_find_attr_as_string(override_obj->msgs[0],
+ SYSDB_NAME,
+ NULL);
+ }
+
+ if (memberuid == NULL) {
+ DEBUG(SSSDBG_TRACE_ALL, "No override name available.\n");
+
+ memberuid = ldb_msg_find_attr_as_string(member_obj->msgs[0],
+ SYSDB_NAME,
+ NULL);
+ if (memberuid == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Object [%s] has no name.\n",
+ ldb_dn_get_linearized(member_obj->msgs[0]->dn));
+ ret = EINVAL;
+ goto done;
+ }
+ }
+
+ ret = ldb_msg_add_string(obj, OVERRIDE_PREFIX SYSDB_MEMBERUID,
+ memberuid);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_string failed.\n");
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+
+ /* Free all temporary data of the current member to avoid memory usage
+ * spikes. All temporary data should be allocated below member_dn. */
+ talloc_free(member_dn);
+ }
+
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+
+ return ret;
+}
+
struct ldb_message_element *
sss_view_ldb_msg_find_element(struct sss_domain_info *dom,
const struct ldb_message *msg,