summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/providers/ipa/ipa_s2n_exop.c362
-rw-r--r--src/providers/ipa/ipa_subdomains_id.c258
-rw-r--r--src/providers/ipa/ipa_views.c4
3 files changed, 522 insertions, 102 deletions
diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c
index 6f5fac337..1ee9c238b 100644
--- a/src/providers/ipa/ipa_s2n_exop.c
+++ b/src/providers/ipa/ipa_s2n_exop.c
@@ -674,7 +674,9 @@ done:
static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
struct req_input *req_input,
struct resp_attrs *attrs,
- struct resp_attrs *simple_attrs);
+ struct resp_attrs *simple_attrs,
+ const char *view_name,
+ struct sysdb_attrs *override_attrs);
static errno_t s2n_response_to_attrs(TALLOC_CTX *mem_ctx,
char *retoid,
@@ -881,9 +883,11 @@ struct ipa_s2n_get_groups_state {
char **group_list;
size_t group_idx;
int exop_timeout;
+ struct resp_attrs *attrs;
};
static errno_t ipa_s2n_get_groups_step(struct tevent_req *req);
+static void ipa_s2n_get_groups_get_override_done(struct tevent_req *subreq);
static void ipa_s2n_get_groups_next(struct tevent_req *subreq);
static struct tevent_req *ipa_s2n_get_groups_send(TALLOC_CTX *mem_ctx,
@@ -912,6 +916,7 @@ static struct tevent_req *ipa_s2n_get_groups_send(TALLOC_CTX *mem_ctx,
state->req_input.type = REQ_INP_NAME;
state->req_input.inp.name = NULL;
state->exop_timeout = exop_timeout;
+ state->attrs = NULL;
ret = ipa_s2n_get_groups_step(req);
if (ret != EOK) {
@@ -988,7 +993,7 @@ static void ipa_s2n_get_groups_next(struct tevent_req *subreq)
struct ipa_s2n_get_groups_state);
char *retoid = NULL;
struct berval *retdata = NULL;
- struct resp_attrs *attrs;
+ const char *sid_str;
ret = ipa_s2n_exop_recv(subreq, state, &retoid, &retdata);
talloc_zfree(subreq);
@@ -997,13 +1002,59 @@ static void ipa_s2n_get_groups_next(struct tevent_req *subreq)
goto fail;
}
- ret = s2n_response_to_attrs(state, retoid, retdata, &attrs);
+ talloc_zfree(state->attrs);
+ ret = s2n_response_to_attrs(state, retoid, retdata, &state->attrs);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "s2n_response_to_attrs failed.\n");
goto fail;
}
- ret = ipa_s2n_save_objects(state->dom, &state->req_input, attrs, NULL);
+ ret = sysdb_attrs_get_string(state->attrs->sysdb_attrs, SYSDB_SID_STR,
+ &sid_str);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
+ goto fail;
+ }
+
+ subreq = ipa_get_ad_override_send(state, state->ev,
+ state->ipa_ctx->sdap_id_ctx,
+ state->ipa_ctx->ipa_options,
+ dp_opt_get_string(state->ipa_ctx->ipa_options->basic,
+ IPA_KRB5_REALM),
+ state->ipa_ctx->view_name,
+ sid_str);
+ if (subreq == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n");
+ ret = ENOMEM;
+ goto fail;
+ }
+ tevent_req_set_callback(subreq, ipa_s2n_get_groups_get_override_done, req);
+
+ return;
+
+fail:
+ tevent_req_error(req,ret);
+ return;
+}
+
+static void ipa_s2n_get_groups_get_override_done(struct tevent_req *subreq)
+{
+ int ret;
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct ipa_s2n_get_groups_state *state = tevent_req_data(req,
+ struct ipa_s2n_get_groups_state);
+ struct sysdb_attrs *override_attrs = NULL;
+
+ ret = ipa_get_ad_override_recv(subreq, NULL, state, &override_attrs);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "IPA override lookup failed: %d\n", ret);
+ goto fail;
+ }
+
+ ret = ipa_s2n_save_objects(state->dom, &state->req_input, state->attrs,
+ NULL, state->ipa_ctx->view_name, override_attrs);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_save_objects failed.\n");
goto fail;
@@ -1046,6 +1097,7 @@ struct ipa_s2n_get_user_state {
enum request_types request_type;
struct resp_attrs *attrs;
struct resp_attrs *simple_attrs;
+ struct resp_attrs *override_attrs;
int exop_timeout;
};
@@ -1273,6 +1325,7 @@ done:
}
static void ipa_s2n_get_groups_done(struct tevent_req *subreq);
+static void ipa_s2n_get_user_get_override_done(struct tevent_req *subreq);
static void ipa_s2n_get_user_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
@@ -1286,6 +1339,7 @@ static void ipa_s2n_get_user_done(struct tevent_req *subreq)
struct berval *bv_req = NULL;
char **missing_groups = NULL;
struct ldb_dn **group_dn_list = NULL;
+ const char *sid_str;
ret = ipa_s2n_exop_recv(subreq, state, &retoid, &retdata);
talloc_zfree(subreq);
@@ -1392,10 +1446,44 @@ static void ipa_s2n_get_user_done(struct tevent_req *subreq)
goto done;
}
- ret = ipa_s2n_save_objects(state->dom, state->req_input, state->attrs,
- state->simple_attrs);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_save_objects failed.\n");
+ if (state->simple_attrs != NULL
+ && state->simple_attrs->response_type == RESP_SID) {
+ sid_str = state->simple_attrs->a.sid_str;
+ ret = EOK;
+ } else if (state->attrs->sysdb_attrs != NULL) {
+ ret = sysdb_attrs_get_string(state->attrs->sysdb_attrs, SYSDB_SID_STR,
+ &sid_str);
+ } else {
+ DEBUG(SSSDBG_TRACE_FUNC, "No SID available.\n");
+ ret = ENOENT;
+ }
+
+ if (ret == ENOENT) {
+ ret = ipa_s2n_save_objects(state->dom, state->req_input, state->attrs,
+ state->simple_attrs, NULL, NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_save_objects failed.\n");
+ goto done;
+ }
+ } else if (ret == EOK) {
+ subreq = ipa_get_ad_override_send(state, state->ev,
+ state->ipa_ctx->sdap_id_ctx,
+ state->ipa_ctx->ipa_options,
+ dp_opt_get_string(state->ipa_ctx->ipa_options->basic,
+ IPA_KRB5_REALM),
+ state->ipa_ctx->view_name,
+ sid_str);
+ if (subreq == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+ tevent_req_set_callback(subreq, ipa_s2n_get_user_get_override_done,
+ req);
+
+ return;
+ } else {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
goto done;
}
@@ -1411,17 +1499,23 @@ done:
static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
struct req_input *req_input,
struct resp_attrs *attrs,
- struct resp_attrs *simple_attrs)
+ struct resp_attrs *simple_attrs,
+ const char *view_name,
+ struct sysdb_attrs *override_attrs)
{
int ret;
time_t now;
uint64_t timeout = 10*60*60; /* FIXME: find a better timeout ! */
struct sss_nss_homedir_ctx homedir_ctx;
- char *name;
+ char *name = NULL;
char *realm;
- char *upn;
+ char *upn = NULL;
gid_t gid;
TALLOC_CTX *tmp_ctx;
+ const char *sid_str;
+ const char *tmp_str;
+ struct ldb_result *res;
+ enum sysdb_member_type type;
tmp_ctx = talloc_new(NULL);
if (tmp_ctx == NULL) {
@@ -1440,9 +1534,59 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
}
}
+ if (attrs->sysdb_attrs != NULL) {
+ ret = sysdb_attrs_get_string(attrs->sysdb_attrs,
+ ORIGINALAD_PREFIX SYSDB_NAME, &tmp_str);
+ if (ret == EOK) {
+ name = talloc_strdup(tmp_ctx, tmp_str);
+ if (name == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+ DEBUG(SSSDBG_TRACE_ALL, "Found original AD name [%s].\n", name);
+ } else if (ret == ENOENT) {
+ name = NULL;
+ } else {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
+ goto done;
+ }
+
+ ret = sysdb_attrs_get_string(attrs->sysdb_attrs,
+ SYSDB_DEFAULT_OVERRIDE_NAME, &tmp_str);
+ if (ret == EOK) {
+ ret = sysdb_attrs_add_lc_name_alias(attrs->sysdb_attrs, tmp_str);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sysdb_attrs_add_lc_name_alias failed.\n");
+ goto done;
+ }
+ } else if (ret != ENOENT) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
+ goto done;
+ }
+
+ ret = sysdb_attrs_get_string(attrs->sysdb_attrs, SYSDB_UPN, &tmp_str);
+ if (ret == EOK) {
+ upn = talloc_strdup(tmp_ctx, tmp_str);
+ if (upn == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+ DEBUG(SSSDBG_TRACE_ALL, "Found original AD upn [%s].\n", upn);
+ } else if (ret == ENOENT) {
+ upn = NULL;
+ } else {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
+ goto done;
+ }
+ }
+
switch (attrs->response_type) {
case RESP_USER:
case RESP_USER_GROUPLIST:
+ type = SYSDB_MEMBER_USER;
if (dom->subdomain_homedir
&& attrs->a.user.pw_dir == NULL) {
ZERO_STRUCT(homedir_ctx);
@@ -1461,13 +1605,15 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
}
}
- /* we always use the fully qualified name for subdomain users */
- name = sss_tc_fqname(tmp_ctx, dom->names, dom,
- attrs->a.user.pw_name);
- if (!name) {
- DEBUG(SSSDBG_OP_FAILURE, "failed to format user name.\n");
- ret = ENOMEM;
- goto done;
+ if (name == NULL) {
+ /* we always use the fully qualified name for subdomain users */
+ name = sss_tc_fqname(tmp_ctx, dom->names, dom,
+ attrs->a.user.pw_name);
+ if (!name) {
+ DEBUG(SSSDBG_OP_FAILURE, "failed to format user name.\n");
+ ret = ENOMEM;
+ goto done;
+ }
}
ret = sysdb_attrs_add_lc_name_alias(attrs->sysdb_attrs, name);
@@ -1477,35 +1623,43 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
goto done;
}
- /* We also have to store a fake UPN here, because otherwise the
- * krb5 child later won't be able to properly construct one as
- * the username is fully qualified but the child doesn't have
- * access to the regex to deconstruct it */
- /* FIXME: The real UPN is available from the PAC, we should get
- * it from there. */
- realm = get_uppercase_realm(tmp_ctx, dom->name);
- if (!realm) {
- DEBUG(SSSDBG_OP_FAILURE, "failed to get realm.\n");
- ret = ENOMEM;
- goto done;
- }
- upn = talloc_asprintf(tmp_ctx, "%s@%s",
- attrs->a.user.pw_name, realm);
- if (!upn) {
- DEBUG(SSSDBG_OP_FAILURE, "failed to format UPN.\n");
- ret = ENOMEM;
- goto done;
- }
+ if (upn == NULL) {
+ /* We also have to store a fake UPN here, because otherwise the
+ * krb5 child later won't be able to properly construct one as
+ * the username is fully qualified but the child doesn't have
+ * access to the regex to deconstruct it */
+ /* FIXME: The real UPN is available from the PAC, we should get
+ * it from there. */
+ realm = get_uppercase_realm(tmp_ctx, dom->name);
+ if (!realm) {
+ DEBUG(SSSDBG_OP_FAILURE, "failed to get realm.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+ upn = talloc_asprintf(tmp_ctx, "%s@%s",
+ attrs->a.user.pw_name, realm);
+ if (!upn) {
+ DEBUG(SSSDBG_OP_FAILURE, "failed to format UPN.\n");
+ ret = ENOMEM;
+ goto done;
+ }
- ret = sysdb_attrs_add_string(attrs->sysdb_attrs, SYSDB_UPN, upn);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n");
- goto done;
+ /* We might already have the SID or the UPN from other sources
+ * hence sysdb_attrs_add_string_safe is used to avoid double
+ * entries. */
+ ret = sysdb_attrs_add_string_safe(attrs->sysdb_attrs, SYSDB_UPN,
+ upn);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sysdb_attrs_add_string failed.\n");
+ goto done;
+ }
}
if (req_input->type == REQ_INP_SECID) {
- ret = sysdb_attrs_add_string(attrs->sysdb_attrs, SYSDB_SID_STR,
- req_input->inp.secid);
+ ret = sysdb_attrs_add_string_safe(attrs->sysdb_attrs,
+ SYSDB_SID_STR,
+ req_input->inp.secid);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"sysdb_attrs_add_string failed.\n");
@@ -1515,8 +1669,9 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
if (simple_attrs != NULL
&& simple_attrs->response_type == RESP_SID) {
- ret = sysdb_attrs_add_string(attrs->sysdb_attrs, SYSDB_SID_STR,
- simple_attrs->a.sid_str);
+ ret = sysdb_attrs_add_string_safe(attrs->sysdb_attrs,
+ SYSDB_SID_STR,
+ simple_attrs->a.sid_str);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"sysdb_attrs_add_string failed.\n");
@@ -1535,16 +1690,24 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
attrs->a.user.pw_dir, attrs->a.user.pw_shell,
NULL, attrs->sysdb_attrs, NULL,
timeout, now);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_user failed.\n");
+ goto done;
+ }
break;
case RESP_GROUP:
case RESP_GROUP_MEMBERS:
- /* we always use the fully qualified name for subdomain users */
- name = sss_tc_fqname(tmp_ctx, dom->names, dom,
- attrs->a.group.gr_name);
- if (!name) {
- DEBUG(SSSDBG_OP_FAILURE, "failed to format user name,\n");
- ret = ENOMEM;
- goto done;
+ type = SYSDB_MEMBER_GROUP;
+
+ if (name == NULL) {
+ /* we always use the fully qualified name for subdomain users */
+ name = sss_tc_fqname(tmp_ctx, dom->names, dom,
+ attrs->a.group.gr_name);
+ if (!name) {
+ DEBUG(SSSDBG_OP_FAILURE, "failed to format user name,\n");
+ ret = ENOMEM;
+ goto done;
+ }
}
ret = sysdb_attrs_add_lc_name_alias(attrs->sysdb_attrs, name);
@@ -1554,9 +1717,12 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
goto done;
}
+ /* We might already have the SID from other sources hence
+ * sysdb_attrs_add_string_safe is used to avoid double entries. */
if (req_input->type == REQ_INP_SECID) {
- ret = sysdb_attrs_add_string(attrs->sysdb_attrs, SYSDB_SID_STR,
- req_input->inp.secid);
+ ret = sysdb_attrs_add_string_safe(attrs->sysdb_attrs,
+ SYSDB_SID_STR,
+ req_input->inp.secid);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"sysdb_attrs_add_string failed.\n");
@@ -1566,8 +1732,9 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
if (simple_attrs != NULL
&& simple_attrs->response_type == RESP_SID) {
- ret = sysdb_attrs_add_string(attrs->sysdb_attrs, SYSDB_SID_STR,
- simple_attrs->a.sid_str);
+ ret = sysdb_attrs_add_string_safe(attrs->sysdb_attrs,
+ SYSDB_SID_STR,
+ simple_attrs->a.sid_str);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"sysdb_attrs_add_string failed.\n");
@@ -1584,6 +1751,10 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
ret = sysdb_store_group(dom, name, attrs->a.group.gr_gid,
attrs->sysdb_attrs, timeout, now);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_group failed.\n");
+ goto done;
+ }
break;
default:
DEBUG(SSSDBG_OP_FAILURE, "Unexpected response type [%d].\n",
@@ -1592,6 +1763,27 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
goto done;
}
+ ret = sysdb_attrs_get_string(attrs->sysdb_attrs, SYSDB_SID_STR, &sid_str);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Cannot find SID of object with override.\n");
+ goto done;
+ }
+
+ ret = sysdb_search_object_by_sid(tmp_ctx, dom, sid_str, NULL, &res);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Cannot find object with override with SID [%s].\n", sid_str);
+ goto done;
+ }
+
+ ret = sysdb_store_override(dom, view_name, type, override_attrs,
+ res->msgs[0]->dn);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_override failed.\n");
+ goto done;
+ }
+
done:
talloc_free(tmp_ctx);
@@ -1605,6 +1797,7 @@ static void ipa_s2n_get_groups_done(struct tevent_req *subreq)
struct tevent_req);
struct ipa_s2n_get_user_state *state = tevent_req_data(req,
struct ipa_s2n_get_user_state);
+ const char *sid_str;
ret = ipa_s2n_get_groups_recv(subreq);
talloc_zfree(subreq);
@@ -1614,8 +1807,63 @@ static void ipa_s2n_get_groups_done(struct tevent_req *subreq)
return;
}
+ ret = sysdb_attrs_get_string(state->attrs->sysdb_attrs, SYSDB_SID_STR,
+ &sid_str);
+ if (ret == ENOENT) {
+ ret = ipa_s2n_save_objects(state->dom, state->req_input, state->attrs,
+ state->simple_attrs, NULL, NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_save_objects failed.\n");
+ goto fail;
+ }
+ tevent_req_done(req);
+ return;
+ } else if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
+ goto fail;
+ }
+
+ subreq = ipa_get_ad_override_send(state, state->ev,
+ state->ipa_ctx->sdap_id_ctx,
+ state->ipa_ctx->ipa_options,
+ dp_opt_get_string(state->ipa_ctx->ipa_options->basic,
+ IPA_KRB5_REALM),
+ state->ipa_ctx->view_name,
+ sid_str);
+ if (subreq == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n");
+ ret = ENOMEM;
+ goto fail;
+ }
+ tevent_req_set_callback(subreq, ipa_s2n_get_user_get_override_done, req);
+
+ return;
+
+fail:
+ tevent_req_error(req, ret);
+ return;
+}
+
+static void ipa_s2n_get_user_get_override_done(struct tevent_req *subreq)
+{
+ int ret;
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct ipa_s2n_get_user_state *state = tevent_req_data(req,
+ struct ipa_s2n_get_user_state);
+ struct sysdb_attrs *override_attrs = NULL;
+
+ ret = ipa_get_ad_override_recv(subreq, NULL, state, &override_attrs);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "IPA override lookup failed: %d\n", ret);
+ tevent_req_error(req, ret);
+ return;
+ }
+
ret = ipa_s2n_save_objects(state->dom, state->req_input, state->attrs,
- state->simple_attrs);
+ state->simple_attrs, state->ipa_ctx->view_name,
+ override_attrs);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_save_objects failed.\n");
tevent_req_error(req, ret);
diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c
index d1bd08d6e..f6cc92e3d 100644
--- a/src/providers/ipa/ipa_subdomains_id.c
+++ b/src/providers/ipa/ipa_subdomains_id.c
@@ -259,9 +259,12 @@ struct ipa_get_ad_acct_state {
struct be_req *be_req;
struct be_acct_req *ar;
struct sss_domain_info *user_dom;
+ char *object_sid;
+ struct ldb_message *obj_msg;
};
static void ipa_get_ad_acct_ad_part_done(struct tevent_req *subreq);
+static void ipa_get_ad_override_done(struct tevent_req *subreq);
static void ipa_get_ad_acct_done(struct tevent_req *subreq);
static struct ad_id_ctx *ipa_get_ad_id_ctx(struct ipa_id_ctx *ipa_ctx,
struct sss_domain_info *dom);
@@ -290,6 +293,7 @@ ipa_get_ad_acct_send(TALLOC_CTX *mem_ctx,
state->ipa_ctx = ipa_ctx;
state->be_req = be_req;
state->ar = ar;
+ state->obj_msg = NULL;
/* This can only be a subdomain request, verify subdomain */
state->user_dom = find_domain_by_name(ipa_ctx->sdap_id_ctx->be->domain,
@@ -491,67 +495,50 @@ done:
static errno_t
apply_subdomain_homedir(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom,
- int filter_type, const char *filter_value)
+ struct ldb_message *msg)
{
errno_t ret;
uint32_t uid;
const char *fqname;
const char *homedir = NULL;
- struct ldb_result *res = NULL;
- struct ldb_message *msg = NULL;
- const char *attrs[] = { SYSDB_NAME,
- SYSDB_UIDNUM,
- NULL };
+ struct ldb_message_element *msg_el = NULL;
+ size_t c;
- if (filter_type == BE_FILTER_NAME) {
- ret = sysdb_getpwnam(mem_ctx, dom, filter_value, &res);
- if (res && res->count == 0) {
- ret = ENOENT;
- }
- } else if (filter_type == BE_FILTER_IDNUM) {
- errno = 0;
- uid = strtouint32(filter_value, NULL, 10);
- if (errno != 0) {
- ret = errno;
- goto done;
- }
- ret = sysdb_getpwuid(mem_ctx, dom, uid, &res);
- if (res && res->count == 0) {
- ret = ENOENT;
- }
- } else if (filter_type == BE_FILTER_SECID) {
- ret = sysdb_search_user_by_sid_str(mem_ctx, dom, filter_value,
- attrs, &msg);
- } else {
- DEBUG(SSSDBG_OP_FAILURE,
- "Unsupported filter type: [%d].\n", filter_type);
- ret = EINVAL;
+ msg_el = ldb_msg_find_element(msg, SYSDB_OBJECTCLASS);
+ if (msg_el == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_find_element failed.\n");
+ ret = ENOENT;
goto done;
}
- if (ret != EOK && ret != ENOENT) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Failed to make request to our cache: [%d]: [%s]\n",
- ret, sss_strerror(ret));
- goto done;
- } else if (ret == ENOENT) {
- DEBUG(SSSDBG_TRACE_FUNC, "Cannot find [%s] with search type [%d]\n",
- filter_value, filter_type);
+ for (c = 0; c < msg_el->num_values; c++) {
+ if (strncmp(SYSDB_USER_CLASS, (const char *)msg_el->values[c].data,
+ msg_el->values[c].length) == 0) {
+ break;
+ }
+ }
+ if (c == msg_el->num_values) {
+ DEBUG(SSSDBG_TRACE_ALL,
+ "User objectclass not found, object is not a user.\n");
+ ret = ENOENT;
goto done;
}
- if (res != NULL) {
- msg = res->msgs[0];
- }
/*
* Homedir is always overriden by subdomain_homedir even if it was
* explicitly set by user.
*/
fqname = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
+ if (fqname == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Missing user name.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
uid = ldb_msg_find_attr_as_uint64(msg, SYSDB_UIDNUM, 0);
if (uid == 0) {
DEBUG(SSSDBG_OP_FAILURE, "UID for user [%s] is not known.\n",
- filter_value);
+ fqname);
ret = ENOENT;
goto done;
}
@@ -576,6 +563,115 @@ done:
return ret;
}
+static errno_t get_object_from_cache(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *dom,
+ struct be_acct_req *ar,
+ struct ldb_message **_msg)
+{
+ errno_t ret;
+ uint32_t id;
+ struct ldb_message *msg = NULL;
+ struct ldb_result *res = NULL;
+ const char *attrs[] = { SYSDB_NAME,
+ SYSDB_UIDNUM,
+ SYSDB_SID_STR,
+ SYSDB_OBJECTCLASS,
+ NULL };
+ char *name;
+
+ if (ar->filter_type == BE_FILTER_SECID) {
+ ret = sysdb_search_object_by_sid(mem_ctx, dom, ar->filter_value, attrs,
+ &res);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Failed to make request to our cache: [%d]: [%s]\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ *_msg = res->msgs[0];
+
+ ret = EOK;
+ goto done;
+ }
+
+ if (ar->filter_type == BE_FILTER_IDNUM) {
+ errno = 0;
+ id = strtouint32(ar->filter_value, NULL, 10);
+ if (errno != 0) {
+ ret = errno;
+ DEBUG(SSSDBG_OP_FAILURE, "strtouint32 failed.\n");
+ goto done;
+ }
+
+ switch (ar->entry_type & BE_REQ_TYPE_MASK) {
+ case BE_REQ_GROUP:
+ ret = sysdb_search_group_by_gid(mem_ctx, dom, id, attrs, &msg);
+ break;
+ case BE_REQ_INITGROUPS:
+ case BE_REQ_USER:
+ case BE_REQ_USER_AND_GROUP:
+ ret = sysdb_search_user_by_uid(mem_ctx, dom, id, attrs, &msg);
+ if (ret == ENOENT && (ar->entry_type & BE_REQ_TYPE_MASK)
+ == BE_REQ_USER_AND_GROUP) {
+ ret = sysdb_search_group_by_gid(mem_ctx, dom, id, attrs, &msg);
+ }
+ break;
+ default:
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected entry type [%d].\n",
+ (ar->entry_type & BE_REQ_TYPE_MASK));
+ ret = EINVAL;
+ goto done;
+ }
+ } else if (ar->filter_type == BE_FILTER_NAME) {
+ name = sss_get_domain_name(mem_ctx, ar->filter_value, dom);
+ if (name == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_get_domain_name failed\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ switch (ar->entry_type & BE_REQ_TYPE_MASK) {
+ case BE_REQ_GROUP:
+ ret = sysdb_search_group_by_name(mem_ctx, dom, name, attrs, &msg);
+ break;
+ case BE_REQ_INITGROUPS:
+ case BE_REQ_USER:
+ case BE_REQ_USER_AND_GROUP:
+ ret = sysdb_search_user_by_name(mem_ctx, dom, name, attrs, &msg);
+ if (ret == ENOENT && (ar->entry_type & BE_REQ_TYPE_MASK)
+ == BE_REQ_USER_AND_GROUP) {
+ ret = sysdb_search_group_by_name(mem_ctx, dom, name,
+ attrs, &msg);
+ }
+ break;
+ default:
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected entry type [%d].\n",
+ (ar->entry_type & BE_REQ_TYPE_MASK));
+ ret = EINVAL;
+ goto done;
+ }
+ } else {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected filter type.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Failed to make request to our cache: [%d]: [%s]\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ *_msg = msg;
+
+ ret = EOK;
+
+done:
+ return ret;
+}
+
static void
ipa_get_ad_acct_ad_part_done(struct tevent_req *subreq)
{
@@ -584,6 +680,7 @@ ipa_get_ad_acct_ad_part_done(struct tevent_req *subreq)
struct ipa_get_ad_acct_state *state = tevent_req_data(req,
struct ipa_get_ad_acct_state);
errno_t ret;
+ const char *sid;
ret = ad_handle_acct_info_recv(subreq, &state->dp_error, NULL);
talloc_zfree(subreq);
@@ -593,9 +690,15 @@ ipa_get_ad_acct_ad_part_done(struct tevent_req *subreq)
return;
}
+ ret = get_object_from_cache(state, state->user_dom, state->ar,
+ &state->obj_msg);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "get_object_from_cache failed.\n");
+ goto fail;
+ }
+
ret = apply_subdomain_homedir(state, state->user_dom,
- state->ar->filter_type,
- state->ar->filter_value);
+ state->obj_msg);
if (ret != EOK && ret != ENOENT) {
DEBUG(SSSDBG_OP_FAILURE,
"apply_subdomain_homedir failed: [%d]: [%s].\n",
@@ -603,6 +706,74 @@ ipa_get_ad_acct_ad_part_done(struct tevent_req *subreq)
goto fail;
}
+ sid = ldb_msg_find_attr_as_string(state->obj_msg, SYSDB_SID_STR, NULL);
+ if (sid == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find a SID.\n");
+ ret = EINVAL;
+ goto fail;
+ }
+
+ state->object_sid = talloc_strdup(state, sid);
+ if (state->object_sid == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
+ ret = ENOMEM;
+ goto fail;
+ }
+
+ subreq = ipa_get_ad_override_send(state, state->ev,
+ state->ipa_ctx->sdap_id_ctx,
+ state->ipa_ctx->ipa_options,
+ state->ipa_ctx->server_mode->realm,
+ state->ipa_ctx->view_name,
+ state->object_sid);
+ if (subreq == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n");
+ ret = ENOMEM;
+ goto fail;
+ }
+ tevent_req_set_callback(subreq, ipa_get_ad_override_done, req);
+
+ return;
+
+fail:
+ state->dp_error = DP_ERR_FATAL;
+ tevent_req_error(req, ret);
+ return;
+}
+
+
+static void
+ipa_get_ad_override_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct ipa_get_ad_acct_state *state = tevent_req_data(req,
+ struct ipa_get_ad_acct_state);
+ errno_t ret;
+ struct sysdb_attrs *override_attrs = NULL;
+
+ ret = ipa_get_ad_override_recv(subreq, &state->dp_error, state,
+ &override_attrs);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "IPA override lookup failed: %d\n", ret);
+ tevent_req_error(req, ret);
+ return;
+
+ }
+
+ if (override_attrs != NULL) {
+ /* We are in ipa-server-mode, so the view is the default view by
+ * definition. */
+ ret = sysdb_apply_default_override(state->user_dom,
+ override_attrs,
+ state->obj_msg->dn);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_apply_default_override failed.\n");
+ goto fail;
+ }
+ }
+
if ((state->ar->entry_type & BE_REQ_TYPE_MASK) != BE_REQ_INITGROUPS) {
tevent_req_done(req);
return;
@@ -645,6 +816,7 @@ ipa_get_ad_acct_done(struct tevent_req *subreq)
ret);
tevent_req_error(req, ret);
return;
+
}
tevent_req_done(req);
diff --git a/src/providers/ipa/ipa_views.c b/src/providers/ipa/ipa_views.c
index 0b71ffc12..86b141110 100644
--- a/src/providers/ipa/ipa_views.c
+++ b/src/providers/ipa/ipa_views.c
@@ -191,8 +191,8 @@ static void ipa_get_ad_override_done(struct tevent_req *subreq)
struct ipa_get_ad_override_state *state = tevent_req_data(req,
struct ipa_get_ad_override_state);
int ret;
- size_t reply_count;
- struct sysdb_attrs **reply;
+ size_t reply_count = 0;
+ struct sysdb_attrs **reply = NULL;
ret = sdap_get_generic_recv(subreq, state, &reply_count, &reply);
talloc_zfree(subreq);