summaryrefslogtreecommitdiffstats
path: root/src/providers/ipa/ipa_views.c
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2014-10-01 17:04:44 +0200
committerJakub Hrozek <jhrozek@redhat.com>2014-10-16 17:56:18 +0200
commited4a9bd4d0f7fb359bed66a8d63a92e7be633aae (patch)
tree4ab1fcf529bf170722810c5833d68f89c5b363a1 /src/providers/ipa/ipa_views.c
parent9c8db0a17a66c58c36966b17d004142a4aaace8d (diff)
downloadsssd-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.c181
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;