diff options
author | Sumit Bose <sbose@redhat.com> | 2014-10-01 17:04:44 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2014-10-16 17:56:18 +0200 |
commit | ed4a9bd4d0f7fb359bed66a8d63a92e7be633aae (patch) | |
tree | 4ab1fcf529bf170722810c5833d68f89c5b363a1 /src/providers/ipa/ipa_views.c | |
parent | 9c8db0a17a66c58c36966b17d004142a4aaace8d (diff) | |
download | sssd-ed4a9bd4d0f7fb359bed66a8d63a92e7be633aae.tar.gz sssd-ed4a9bd4d0f7fb359bed66a8d63a92e7be633aae.tar.xz sssd-ed4a9bd4d0f7fb359bed66a8d63a92e7be633aae.zip |
views: search overrides for user and group requests
If the name or the POSIX ID of a user or a group is overridden the
search request for those objects have to check the overide objects first
before looking up the original objects.
This patch adds a new request for the IPA sub-domain users which checks
the overrides first if
- SSSD is running in ipa-server-mode and a name or a POSIX ID is
searched, since we do not override the SIDs we can skip the search in
the override tree here
- if the responder indicates it has not found the corresponding object
in the cache and the input might be an override name or ID and not the
original one of an object.
If an override object was found the SID is extracted from the anchor
attribute and the original object is search by its SID. If no override
object was found the original object is search with the original input
and finally it is checked if an override object exits for the found
object.
Relates to https://fedorahosted.org/sssd/ticket/2375
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
Diffstat (limited to 'src/providers/ipa/ipa_views.c')
-rw-r--r-- | src/providers/ipa/ipa_views.c | 181 |
1 files changed, 161 insertions, 20 deletions
diff --git a/src/providers/ipa/ipa_views.c b/src/providers/ipa/ipa_views.c index 86b141110..33dbf7b1c 100644 --- a/src/providers/ipa/ipa_views.c +++ b/src/providers/ipa/ipa_views.c @@ -23,20 +23,163 @@ */ #include "util/util.h" +#include "util/strtonum.h" #include "providers/ldap/sdap_async.h" #include "providers/ipa/ipa_id.h" +static errno_t be_acct_req_to_override_filter(TALLOC_CTX *mem_ctx, + struct ipa_options *ipa_opts, + struct be_acct_req *ar, + char **override_filter) +{ + char *filter; + uint32_t id; + char *endptr; + + switch (ar->filter_type) { + case BE_FILTER_NAME: + switch ((ar->entry_type & BE_REQ_TYPE_MASK)) { + case BE_REQ_USER: + case BE_REQ_INITGROUPS: + filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=%s))", + ipa_opts->override_map[IPA_OC_OVERRIDE_USER].name, + ipa_opts->override_map[IPA_AT_OVERRIDE_USER_NAME].name, + ar->filter_value); + break; + + case BE_REQ_GROUP: + filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=%s))", + ipa_opts->override_map[IPA_OC_OVERRIDE_GROUP].name, + ipa_opts->override_map[IPA_AT_OVERRIDE_GROUP_NAME].name, + ar->filter_value); + break; + + case BE_REQ_USER_AND_GROUP: + filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))", + ipa_opts->override_map[IPA_OC_OVERRIDE].name, + ipa_opts->override_map[IPA_AT_OVERRIDE_USER_NAME].name, + ar->filter_value, + ipa_opts->override_map[IPA_AT_OVERRIDE_GROUP_NAME].name, + ar->filter_value); + break; + default: + DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected entry type [%d] for name filter.\n", + ar->entry_type); + return EINVAL; + } + break; + + case BE_FILTER_IDNUM: + errno = 0; + id = strtouint32(ar->filter_value, &endptr, 10); + if (errno != 0|| *endptr != '\0' || (ar->filter_value == endptr)) { + DEBUG(SSSDBG_CRIT_FAILURE, "Invalid id value [%s].\n", + ar->filter_value); + return EINVAL; + } + switch ((ar->entry_type & BE_REQ_TYPE_MASK)) { + case BE_REQ_USER: + case BE_REQ_INITGROUPS: + filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=%"PRIu32"))", + ipa_opts->override_map[IPA_OC_OVERRIDE_USER].name, + ipa_opts->override_map[IPA_AT_OVERRIDE_UID_NUMBER].name, + id); + break; + + case BE_REQ_GROUP: + filter = talloc_asprintf(mem_ctx, + "(&(objectClass=%s)(%s=%"PRIu32"))", + ipa_opts->override_map[IPA_OC_OVERRIDE_GROUP].name, + ipa_opts->override_map[IPA_AT_OVERRIDE_GROUP_GID_NUMBER].name, + id); + break; + + case BE_REQ_USER_AND_GROUP: + filter = talloc_asprintf(mem_ctx, + "(&(objectClass=%s)(|(%s=%"PRIu32")(%s=%"PRIu32")))", + ipa_opts->override_map[IPA_OC_OVERRIDE].name, + ipa_opts->override_map[IPA_AT_OVERRIDE_UID_NUMBER].name, + id, + ipa_opts->override_map[IPA_AT_OVERRIDE_GROUP_GID_NUMBER].name, + id); + break; + default: + DEBUG(SSSDBG_CRIT_FAILURE, + "Unexpected entry type [%d] for id filter.\n", + ar->entry_type); + return EINVAL; + } + break; + + case BE_FILTER_SECID: + if ((ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_BY_SECID) { + filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=:SID:%s))", + ipa_opts->override_map[IPA_OC_OVERRIDE].name, + ipa_opts->override_map[IPA_AT_OVERRIDE_ANCHOR_UUID].name, + ar->filter_value); + } else { + DEBUG(SSSDBG_CRIT_FAILURE, + "Unexpected entry type [%d] for SID filter.\n", + ar->entry_type); + return EINVAL; + } + break; + + default: + DEBUG(SSSDBG_OP_FAILURE, "Invalid sub-domain filter type.\n"); + return EINVAL; + } + + if (filter == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); + return ENOMEM; + } + + *override_filter = filter; + + return EOK; +} + +errno_t get_be_acct_req_for_sid(TALLOC_CTX *mem_ctx, const char *sid, + const char *domain_name, + struct be_acct_req **_ar) +{ + struct be_acct_req *ar; + + ar = talloc_zero(mem_ctx, struct be_acct_req); + if (ar == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); + return ENOMEM; + } + + ar->entry_type = BE_REQ_BY_SECID; + ar->filter_type = BE_FILTER_SECID; + ar->filter_value = talloc_strdup(ar, sid); + ar->domain = talloc_strdup(ar, domain_name); + if (ar->filter_value == NULL || ar->domain == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); + talloc_free(ar); + return ENOMEM; + } + + + *_ar = ar; + + return EOK; +} + struct ipa_get_ad_override_state { struct tevent_context *ev; struct sdap_id_ctx *sdap_id_ctx; struct ipa_options *ipa_options; const char *ipa_realm; const char *ipa_view_name; - const char *obj_sid; + struct be_acct_req *ar; struct sdap_id_op *sdap_op; int dp_error; struct sysdb_attrs *override_attrs; + char *filter; }; static void ipa_get_ad_override_connect_done(struct tevent_req *subreq); @@ -48,7 +191,7 @@ struct tevent_req *ipa_get_ad_override_send(TALLOC_CTX *mem_ctx, struct ipa_options *ipa_options, const char *ipa_realm, const char *view_name, - const char *obj_sid) + struct be_acct_req *ar) { int ret; struct tevent_req *req; @@ -70,9 +213,10 @@ struct tevent_req *ipa_get_ad_override_send(TALLOC_CTX *mem_ctx, } else { state->ipa_view_name = view_name; } - state->obj_sid = obj_sid; + state->ar = ar; state->dp_error = -1; state->override_attrs = NULL; + state->filter = NULL; state->sdap_op = sdap_id_op_create(state, state->sdap_id_ctx->conn->conn_cache); @@ -115,7 +259,6 @@ static void ipa_get_ad_override_connect_done(struct tevent_req *subreq) int ret; char *basedn; char *search_base; - char *filter; struct ipa_options *ipa_opts = state->ipa_options; ret = sdap_id_op_connect_recv(subreq, &state->dp_error); @@ -147,24 +290,22 @@ static void ipa_get_ad_override_connect_done(struct tevent_req *subreq) goto fail; } - filter = talloc_asprintf(state, "(&(objectClass=%s)(%s=:SID:%s))", - ipa_opts->override_map[IPA_OC_OVERRIDE].name, - ipa_opts->override_map[IPA_AT_OVERRIDE_ANCHOR_UUID].name, - state->obj_sid); - if (filter == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); - ret = ENOMEM; + ret = be_acct_req_to_override_filter(state, state->ipa_options, state->ar, + &state->filter); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "be_acct_req_to_override_filter failed.\n"); goto fail; } DEBUG(SSSDBG_TRACE_ALL, - "Searching for overrides in view [%s] for object with SID [%s].\n", - state->ipa_view_name, state->obj_sid); + "Searching for overrides in view [%s] with filter [%s].\n", + state->ipa_view_name, state->filter); subreq = sdap_get_generic_send(state, state->ev, state->sdap_id_ctx->opts, sdap_id_op_handle(state->sdap_op), search_base, LDAP_SCOPE_SUBTREE, - filter, NULL, state->ipa_options->override_map, + state->filter, NULL, + state->ipa_options->override_map, IPA_OPTS_OVERRIDE, dp_opt_get_int(state->sdap_id_ctx->opts->basic, SDAP_ENUM_SEARCH_TIMEOUT), @@ -202,21 +343,21 @@ static void ipa_get_ad_override_done(struct tevent_req *subreq) } if (reply_count == 0) { - DEBUG(SSSDBG_TRACE_ALL, "No override found for SID [%s].\n", - state->obj_sid); + DEBUG(SSSDBG_TRACE_ALL, "No override found with filter [%s].\n", + state->filter); state->dp_error = DP_ERR_OK; tevent_req_done(req); return; } else if (reply_count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, - "Found [%zu] overrides for SID [%s], expected only 1.\n", - reply_count, state->obj_sid); + "Found [%zu] overrides with filter [%s], expected only 1.\n", + reply_count, state->filter); ret = EINVAL; goto fail; } - DEBUG(SSSDBG_TRACE_ALL, "Found override for object with SID [%s].\n", - state->obj_sid); + DEBUG(SSSDBG_TRACE_ALL, "Found override for object with filter [%s].\n", + state->filter); state->override_attrs = reply[0]; state->dp_error = DP_ERR_OK; |