summaryrefslogtreecommitdiffstats
path: root/src/responder/common
diff options
context:
space:
mode:
authorPavel Březina <pbrezina@redhat.com>2015-05-06 12:16:46 +0200
committerJakub Hrozek <jhrozek@redhat.com>2015-10-08 19:56:26 +0200
commit28ebfa4373d1e7ce45b5d70a3619df1c074a661e (patch)
tree0aafa2697dfa3a29b9b1b3b4103fda964914ce03 /src/responder/common
parentd8125f0e0d38c6939887a0849a44859d6c498c57 (diff)
downloadsssd-28ebfa4373d1e7ce45b5d70a3619df1c074a661e.tar.gz
sssd-28ebfa4373d1e7ce45b5d70a3619df1c074a661e.tar.xz
sssd-28ebfa4373d1e7ce45b5d70a3619df1c074a661e.zip
cache_req: add support for UPN
Reviewed-by: Sumit Bose <sbose@redhat.com>
Diffstat (limited to 'src/responder/common')
-rw-r--r--src/responder/common/responder_cache_req.c116
-rw-r--r--src/responder/common/responder_cache_req.h4
-rw-r--r--src/responder/common/responder_get_domains.c21
3 files changed, 127 insertions, 14 deletions
diff --git a/src/responder/common/responder_cache_req.c b/src/responder/common/responder_cache_req.c
index fba500147..70a3010eb 100644
--- a/src/responder/common/responder_cache_req.c
+++ b/src/responder/common/responder_cache_req.c
@@ -70,6 +70,7 @@ struct cache_req_input {
enum cache_req_type type;
/* Provided input. */
+ const char *raw_name;
const char *orig_name;
uint32_t id;
const char *cert;
@@ -113,15 +114,22 @@ cache_req_input_create(TALLOC_CTX *mem_ctx,
/* Check that input parameters match selected type. */
switch (input->type) {
case CACHE_REQ_USER_BY_NAME:
+ case CACHE_REQ_USER_BY_UPN:
case CACHE_REQ_GROUP_BY_NAME:
case CACHE_REQ_USER_BY_FILTER:
case CACHE_REQ_GROUP_BY_FILTER:
case CACHE_REQ_INITGROUPS:
+ case CACHE_REQ_INITGROUPS_BY_UPN:
if (name == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "Bug: name cannot be NULL!\n");
goto fail;
}
+ input->raw_name = talloc_strdup(input, name);
+ if (input->raw_name == NULL) {
+ goto fail;
+ }
+
input->orig_name = talloc_strdup(input, name);
if (input->orig_name == NULL) {
goto fail;
@@ -152,6 +160,7 @@ cache_req_input_create(TALLOC_CTX *mem_ctx,
/* Resolve Data Provider request type. */
switch (type) {
case CACHE_REQ_USER_BY_NAME:
+ case CACHE_REQ_USER_BY_UPN:
case CACHE_REQ_USER_BY_ID:
input->dp_type = SSS_DP_USER;
break;
@@ -162,6 +171,7 @@ cache_req_input_create(TALLOC_CTX *mem_ctx,
break;
case CACHE_REQ_INITGROUPS:
+ case CACHE_REQ_INITGROUPS_BY_UPN:
input->dp_type = SSS_DP_INITGROUPS;
break;
@@ -222,10 +232,12 @@ cache_req_input_set_domain(struct cache_req_input *input,
switch (input->type) {
case CACHE_REQ_USER_BY_NAME:
+ case CACHE_REQ_USER_BY_UPN:
case CACHE_REQ_GROUP_BY_NAME:
case CACHE_REQ_USER_BY_FILTER:
case CACHE_REQ_GROUP_BY_FILTER:
case CACHE_REQ_INITGROUPS:
+ case CACHE_REQ_INITGROUPS_BY_UPN:
name = sss_get_cased_name(tmp_ctx, input->orig_name,
domain->case_sensitive);
if (name == NULL) {
@@ -286,6 +298,56 @@ done:
return ret;
}
+static bool
+cache_req_input_is_upn(struct cache_req_input *input)
+{
+ switch (input->type) {
+ case CACHE_REQ_USER_BY_UPN:
+ case CACHE_REQ_INITGROUPS_BY_UPN:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool
+cache_req_input_assume_upn(struct cache_req_input *input)
+{
+ errno_t ret;
+ bool bret;
+
+ if (input->raw_name == NULL || strchr(input->raw_name, '@') == NULL) {
+ return false;
+ }
+
+ switch (input->type) {
+ case CACHE_REQ_USER_BY_NAME:
+ input->type = CACHE_REQ_USER_BY_UPN;
+ bret = true;
+ break;
+ case CACHE_REQ_INITGROUPS:
+ input->type = CACHE_REQ_INITGROUPS_BY_UPN;
+ bret = true;
+ break;
+ default:
+ bret = false;
+ break;
+ }
+
+ if (bret == true) {
+ ret = cache_req_input_set_orig_name(input, input->raw_name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "cache_req_input_set_orig_name() failed\n");
+ return false;
+ }
+
+ DEBUG(SSSDBG_TRACE_FUNC, "Assuming UPN %s\n", input->raw_name);
+ }
+
+ return bret;
+}
+
static errno_t cache_req_check_ncache(struct cache_req_input *input,
struct sss_nc_ctx *ncache,
int neg_timeout)
@@ -294,7 +356,9 @@ static errno_t cache_req_check_ncache(struct cache_req_input *input,
switch (input->type) {
case CACHE_REQ_USER_BY_NAME:
+ case CACHE_REQ_USER_BY_UPN:
case CACHE_REQ_INITGROUPS:
+ case CACHE_REQ_INITGROUPS_BY_UPN:
ret = sss_ncache_check_user(ncache, neg_timeout,
input->domain, input->dom_objname);
break;
@@ -332,7 +396,9 @@ static void cache_req_add_to_ncache(struct cache_req_input *input,
switch (input->type) {
case CACHE_REQ_USER_BY_NAME:
+ case CACHE_REQ_USER_BY_UPN:
case CACHE_REQ_INITGROUPS:
+ case CACHE_REQ_INITGROUPS_BY_UPN:
ret = sss_ncache_set_user(ncache, false, input->domain,
input->dom_objname);
break;
@@ -375,8 +441,10 @@ static void cache_req_add_to_ncache_global(struct cache_req_input *input,
/* Nothing to do, adding a wildcard request to ncache doesn't
* make sense */
case CACHE_REQ_USER_BY_NAME:
+ case CACHE_REQ_USER_BY_UPN:
case CACHE_REQ_GROUP_BY_NAME:
case CACHE_REQ_INITGROUPS:
+ case CACHE_REQ_INITGROUPS_BY_UPN:
/* Nothing to do. Those types are already in ncache for selected
* domains. */
ret = EOK;
@@ -418,6 +486,11 @@ static errno_t cache_req_get_object(TALLOC_CTX *mem_ctx,
ret = sysdb_getpwnam_with_views(mem_ctx, input->domain,
input->dom_objname, &result);
break;
+ case CACHE_REQ_USER_BY_UPN:
+ one_item_only = true;
+ ret = sysdb_getpwupn(mem_ctx, input->domain,
+ input->dom_objname, &result);
+ break;
case CACHE_REQ_USER_BY_ID:
one_item_only = true;
ret = sysdb_getpwuid_with_views(mem_ctx, input->domain,
@@ -438,6 +511,11 @@ static errno_t cache_req_get_object(TALLOC_CTX *mem_ctx,
ret = sysdb_initgroups_with_views(mem_ctx, input->domain,
input->dom_objname, &result);
break;
+ case CACHE_REQ_INITGROUPS_BY_UPN:
+ one_item_only = false;
+ ret = sysdb_initgroups_by_upn(mem_ctx, input->domain,
+ input->dom_objname, &result);
+ break;
case CACHE_REQ_USER_BY_CERT:
one_item_only = true;
ret = sysdb_search_user_by_cert(mem_ctx, input->domain,
@@ -618,6 +696,8 @@ static errno_t cache_req_cache_check(struct tevent_req *req)
if (DOM_HAS_VIEWS(state->input->domain)) {
extra_flag = EXTRA_INPUT_MAYBE_WITH_VIEW;
+ } else if (cache_req_input_is_upn(state->input)) {
+ extra_flag = EXTRA_NAME_IS_UPN;
}
switch (ret) {
@@ -821,23 +901,35 @@ static void cache_req_input_parsed(struct tevent_req *subreq)
char *name;
char *domain;
errno_t ret;
+ bool maybe_upn;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct cache_req_state);
ret = sss_parse_inp_recv(subreq, state, &name, &domain);
- if (ret != EOK) {
- tevent_req_error(req, ret);
- return;
- }
-
- if (strcmp(name, state->input->orig_name) != 0) {
- /* The name has changed during input parse phase. */
- ret = cache_req_input_set_orig_name(state->input, name);
- if (ret != EOK) {
+ switch (ret) {
+ case EOK:
+ if (strcmp(name, state->input->orig_name) != 0) {
+ /* The name has changed during input parse phase. */
+ ret = cache_req_input_set_orig_name(state->input, name);
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+ }
+ break;
+ case ERR_DOMAIN_NOT_FOUND:
+ maybe_upn = cache_req_input_assume_upn(state->input);
+ if (!maybe_upn) {
tevent_req_error(req, ret);
return;
}
+
+ domain = NULL;
+ break;
+ default:
+ tevent_req_error(req, ret);
+ return;
}
ret = cache_req_select_domains(req, domain);
@@ -943,6 +1035,12 @@ static void cache_req_done(struct tevent_req *subreq)
}
if (state->check_next == false) {
+ if (ret == ENOENT && cache_req_input_assume_upn(state->input)) {
+ /* search by upn now */
+ cache_req_select_domains(req, NULL);
+ return;
+ }
+
tevent_req_error(req, ret);
return;
}
diff --git a/src/responder/common/responder_cache_req.h b/src/responder/common/responder_cache_req.h
index 9e3f88a14..474d42647 100644
--- a/src/responder/common/responder_cache_req.h
+++ b/src/responder/common/responder_cache_req.h
@@ -29,13 +29,15 @@
enum cache_req_type {
CACHE_REQ_USER_BY_NAME,
+ CACHE_REQ_USER_BY_UPN,
CACHE_REQ_USER_BY_ID,
CACHE_REQ_GROUP_BY_NAME,
CACHE_REQ_GROUP_BY_ID,
CACHE_REQ_INITGROUPS,
+ CACHE_REQ_INITGROUPS_BY_UPN,
CACHE_REQ_USER_BY_CERT,
CACHE_REQ_USER_BY_FILTER,
- CACHE_REQ_GROUP_BY_FILTER,
+ CACHE_REQ_GROUP_BY_FILTER
};
struct cache_req_input;
diff --git a/src/responder/common/responder_get_domains.c b/src/responder/common/responder_get_domains.c
index 8fbab082a..7fd0b48ee 100644
--- a/src/responder/common/responder_get_domains.c
+++ b/src/responder/common/responder_get_domains.c
@@ -446,6 +446,7 @@ struct sss_parse_inp_state {
char *name;
char *domname;
+ errno_t error;
};
static void sss_parse_inp_done(struct tevent_req *subreq);
@@ -527,14 +528,24 @@ static void sss_parse_inp_done(struct tevent_req *subreq)
return;
}
+ state->error = ERR_OK;
+
ret = sss_parse_name_for_domains(state, state->rctx->domains,
state->rctx->default_domain,
state->rawinp,
&state->domname, &state->name);
- if (ret != EOK) {
+ if (ret == EAGAIN && state->domname != NULL && state->name == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Unknown domain in [%s]\n", state->rawinp);
+ state->error = ERR_DOMAIN_NOT_FOUND;
+ } else if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"Invalid name received [%s]\n", state->rawinp);
- tevent_req_error(req, ERR_INPUT_PARSE);
+ state->error = ERR_INPUT_PARSE;
+ }
+
+ if (state->error != ERR_OK) {
+ tevent_req_error(req, state->error);
return;
}
@@ -548,7 +559,9 @@ errno_t sss_parse_inp_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
struct sss_parse_inp_state *state = tevent_req_data(req,
struct sss_parse_inp_state);
- TEVENT_REQ_RETURN_ON_ERROR(req);
+ if (state->error != ERR_DOMAIN_NOT_FOUND) {
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+ }
if (_name) {
*_name = talloc_steal(mem_ctx, state->name);
@@ -558,5 +571,5 @@ errno_t sss_parse_inp_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
*_domname = talloc_steal(mem_ctx, state->domname);
}
- return EOK;
+ return state->error;
}