diff options
Diffstat (limited to 'src/providers/ipa/ipa_hbac_common.c')
-rw-r--r-- | src/providers/ipa/ipa_hbac_common.c | 96 |
1 files changed, 55 insertions, 41 deletions
diff --git a/src/providers/ipa/ipa_hbac_common.c b/src/providers/ipa/ipa_hbac_common.c index f4ed839f..c10b2eeb 100644 --- a/src/providers/ipa/ipa_hbac_common.c +++ b/src/providers/ipa/ipa_hbac_common.c @@ -404,7 +404,7 @@ static errno_t hbac_eval_service_element(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, - const char *hostname, + const char *servicename, struct hbac_request_element **svc_element); static errno_t @@ -586,18 +586,18 @@ static errno_t hbac_eval_service_element(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, - const char *hostname, + const char *servicename, struct hbac_request_element **svc_element) { errno_t ret; - size_t i, count; + size_t i, j, count; TALLOC_CTX *tmp_ctx; struct hbac_request_element *svc; struct ldb_message **msgs; - const char *group_name; + struct ldb_message_element *el; struct ldb_dn *svc_dn; - const char *attrs[] = { IPA_CN, NULL }; - const char *service_filter; + const char *memberof_attrs[] = { SYSDB_ORIG_MEMBEROF, NULL }; + char *name; tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) return ENOMEM; @@ -608,15 +608,7 @@ hbac_eval_service_element(TALLOC_CTX *mem_ctx, goto done; } - svc->name = hostname; - - service_filter = talloc_asprintf(tmp_ctx, - "(objectClass=%s)", - IPA_HBAC_SERVICE_GROUP); - if (service_filter == NULL) { - ret = ENOMEM; - goto done; - } + svc->name = servicename; svc_dn = sysdb_custom_dn(sysdb, tmp_ctx, domain->name, svc->name, HBAC_SERVICES_SUBDIR); @@ -625,46 +617,68 @@ hbac_eval_service_element(TALLOC_CTX *mem_ctx, goto done; } - /* Find the service groups */ - ret = sysdb_asq_search(tmp_ctx, sysdb, svc_dn, - service_filter, SYSDB_MEMBEROF, - attrs, &count, &msgs); - if (ret != EOK && ret != ENOENT) { - DEBUG(1, ("Could not look up servicegroups\n")); + /* Look up the service to get its originalMemberOf entries */ + ret = sysdb_search_entry(tmp_ctx, sysdb, svc_dn, + LDB_SCOPE_BASE, NULL, + memberof_attrs, + &count, &msgs); + if (ret == ENOENT || count == 0) { + /* We won't be able to identify any groups + * This rule will only match the name or + * a service category of ALL + */ + svc->groups = NULL; + ret = EOK; goto done; - } else if (ret == ENOENT) { - count = 0; + } else if (ret != EOK) { + goto done; + } else if (count > 1) { + DEBUG(1, ("More than one result for a BASE search!\n")); + ret = EIO; + goto done; + } + + el = ldb_msg_find_element(msgs[0], SYSDB_ORIG_MEMBEROF); + if (!el) { + /* Service is not a member of any groups + * This rule will only match the name or + * a service category of ALL + */ + svc->groups = NULL; + ret = EOK; } - svc->groups = talloc_array(svc, const char *, count + 1); + + svc->groups = talloc_array(svc, const char *, el->num_values + 1); if (svc->groups == NULL) { ret = ENOMEM; goto done; } - for (i = 0; i < count; i++) { - group_name = ldb_msg_find_attr_as_string(msgs[i], IPA_CN, NULL); - if (group_name == NULL) { - DEBUG(1, ("Group with no name?\n")); - ret = EINVAL; - goto done; - } - svc->groups[i] = talloc_strdup(svc->groups, - group_name); - if (svc->groups[i] == NULL) { - ret = ENOMEM; - goto done; - } + for (i = j = 0; i < el->num_values; i++) { + ret = get_ipa_servicegroupname(tmp_ctx, sysdb, + (const char *)el->values[i].data, + &name); + if (ret != EOK && ret != ENOENT) goto done; - DEBUG(6, ("Added service group [%s] to the eval request\n", - svc->groups[i])); + /* ENOENT means we had a memberOf entry that wasn't a + * service group. We'll just ignore those (could be + * HBAC rules) + */ + + if (ret == EOK) { + svc->groups[j] = talloc_steal(svc->groups, name); + j++; + } } - svc->groups[i] = NULL; + svc->groups[j] = NULL; - *svc_element = talloc_steal(mem_ctx, svc); ret = EOK; done: + if (ret == EOK) { + *svc_element = talloc_steal(mem_ctx, svc); + } talloc_free(tmp_ctx); return ret; } |