summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/responder/nss/nsssrv_cmd.c134
-rw-r--r--src/responder/nss/nsssrv_private.h2
-rw-r--r--src/responder/pam/pamsrv_cmd.c88
-rw-r--r--src/util/usertools.c34
4 files changed, 173 insertions, 85 deletions
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index fc504700..5c5f8060 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -798,8 +798,18 @@ static int nss_cmd_getpwnam(struct cli_ctx *cctx)
domname = NULL;
ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, rawname,
&domname, &cmdctx->name);
- if (ret != EOK) {
- DEBUG(2, ("Invalid name received [%s]\n", rawname));
+ if (ret == EAGAIN) {
+ req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, true, domname);
+ if (req == NULL) {
+ ret = ENOMEM;
+ } else {
+ dctx->rawname = rawname;
+ tevent_req_set_callback(req, nss_cmd_getpwnam_cb, dctx);
+ ret = EAGAIN;
+ }
+ goto done;
+ } if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Invalid name received [%s]\n", rawname));
ret = ENOENT;
goto done;
}
@@ -810,18 +820,12 @@ static int nss_cmd_getpwnam(struct cli_ctx *cctx)
if (domname) {
dctx->domain = responder_get_domain(dctx, cctx->rctx, domname);
if (!dctx->domain) {
- req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, true, domname);
- if (req == NULL) {
- ret = ENOMEM;
- } else {
- dctx->domname = domname;
- tevent_req_set_callback(req, nss_cmd_getpwnam_cb, dctx);
- ret = EAGAIN;
- }
+ ret = ENOENT;
goto done;
}
} else {
/* this is a multidomain search */
+ dctx->rawname = rawname;
dctx->domain = cctx->rctx->domains;
cmdctx->check_next = true;
if (cctx->rctx->get_domains_last_call.tv_sec == 0) {
@@ -854,6 +858,8 @@ static void nss_cmd_getpwnam_cb(struct tevent_req *req)
struct nss_dom_ctx *dctx = tevent_req_callback_data(req, struct nss_dom_ctx);
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
struct cli_ctx *cctx = cmdctx->cctx;
+ char *domname = NULL;
+ const char *rawname = dctx->rawname;
errno_t ret;
ret = sss_dp_get_domains_recv(req);
@@ -862,12 +868,27 @@ static void nss_cmd_getpwnam_cb(struct tevent_req *req)
goto done;
}
- if (dctx->domname) {
- dctx->domain = responder_get_domain(dctx, cctx->rctx, dctx->domname);
+ ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, rawname,
+ &domname, &cmdctx->name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Invalid name received [%s]\n", rawname));
+ ret = ENOENT;
+ goto done;
+ }
+
+ DEBUG(SSSDBG_TRACE_FUNC, ("Requesting info for [%s] from [%s]\n",
+ cmdctx->name, domname?domname:"<ALL>"));
+
+ if (domname) {
+ dctx->domain = responder_get_domain(dctx, cctx->rctx, domname);
if (dctx->domain == NULL) {
ret = ENOENT;
goto done;
}
+ } else {
+ /* this is a multidomain search */
+ dctx->domain = cctx->rctx->domains;
+ cmdctx->check_next = true;
}
dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider);
@@ -2264,7 +2285,17 @@ static int nss_cmd_getgrnam(struct cli_ctx *cctx)
domname = NULL;
ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, rawname,
&domname, &cmdctx->name);
- if (ret != EOK) {
+ if (ret == EAGAIN) {
+ req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, true, domname);
+ if (req == NULL) {
+ ret = ENOMEM;
+ } else {
+ dctx->rawname = rawname;
+ tevent_req_set_callback(req, nss_cmd_getgrnam_cb, dctx);
+ ret = EAGAIN;
+ }
+ goto done;
+ } else if (ret != EOK) {
DEBUG(2, ("Invalid name received [%s]\n", rawname));
ret = ENOENT;
goto done;
@@ -2276,18 +2307,12 @@ static int nss_cmd_getgrnam(struct cli_ctx *cctx)
if (domname) {
dctx->domain = responder_get_domain(dctx, cctx->rctx, domname);
if (!dctx->domain) {
- req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, true, domname);
- if (req == NULL) {
- ret = ENOMEM;
- } else {
- dctx->domname = domname;
- tevent_req_set_callback(req, nss_cmd_getgrnam_cb, dctx);
- ret = EAGAIN;
- }
+ ret = ENOENT;
goto done;
}
} else {
/* this is a multidomain search */
+ dctx->rawname = rawname;
dctx->domain = cctx->rctx->domains;
cmdctx->check_next = true;
if (cctx->rctx->get_domains_last_call.tv_sec == 0) {
@@ -2320,6 +2345,8 @@ static void nss_cmd_getgrnam_cb(struct tevent_req *req)
struct nss_dom_ctx *dctx = tevent_req_callback_data(req, struct nss_dom_ctx);
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
struct cli_ctx *cctx = cmdctx->cctx;
+ char *domname = NULL;
+ const char *rawname = dctx->rawname;
errno_t ret;
ret = sss_dp_get_domains_recv(req);
@@ -2328,12 +2355,26 @@ static void nss_cmd_getgrnam_cb(struct tevent_req *req)
goto done;
}
- if (dctx->domname) {
- dctx->domain = responder_get_domain(dctx, cctx->rctx, dctx->domname);
- if (dctx->domain == NULL) {
+ ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, rawname,
+ &domname, &cmdctx->name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Invalid name received [%s]\n", rawname));
+ ret = ENOENT;
+ goto done;
+ }
+
+ DEBUG(SSSDBG_TRACE_FUNC, ("Requesting info for [%s] from [%s]\n",
+ cmdctx->name, domname?domname:"<ALL>"));
+ if (domname) {
+ dctx->domain = responder_get_domain(dctx, cctx->rctx, domname);
+ if (!dctx->domain) {
ret = ENOENT;
goto done;
}
+ } else {
+ /* this is a multidomain search */
+ dctx->domain = cctx->rctx->domains;
+ cmdctx->check_next = true;
}
dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider);
@@ -3374,7 +3415,17 @@ static int nss_cmd_initgroups(struct cli_ctx *cctx)
domname = NULL;
ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, rawname,
&domname, &cmdctx->name);
- if (ret != EOK) {
+ if (ret == EAGAIN) {
+ req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, true, domname);
+ if (req == NULL) {
+ ret = ENOMEM;
+ } else {
+ dctx->rawname = rawname;
+ tevent_req_set_callback(req, nss_cmd_initgroups_cb, dctx);
+ ret = EAGAIN;
+ }
+ goto done;
+ } else if (ret != EOK) {
DEBUG(2, ("Invalid name received [%s]\n", rawname));
ret = ENOENT;
goto done;
@@ -3386,18 +3437,12 @@ static int nss_cmd_initgroups(struct cli_ctx *cctx)
if (domname) {
dctx->domain = responder_get_domain(dctx, cctx->rctx, domname);
if (!dctx->domain) {
- req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, true, domname);
- if (req == NULL) {
- ret = ENOMEM;
- } else {
- dctx->domname = domname;
- tevent_req_set_callback(req, nss_cmd_initgroups_cb, dctx);
- ret = EAGAIN;
- }
+ ret = ENOENT;
goto done;
}
} else {
/* this is a multidomain search */
+ dctx->rawname = rawname;
dctx->domain = cctx->rctx->domains;
cmdctx->check_next = true;
if (cctx->rctx->get_domains_last_call.tv_sec == 0) {
@@ -3430,6 +3475,8 @@ static void nss_cmd_initgroups_cb(struct tevent_req *req)
struct nss_dom_ctx *dctx = tevent_req_callback_data(req, struct nss_dom_ctx);
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
struct cli_ctx *cctx = cmdctx->cctx;
+ char *domname = NULL;
+ const char *rawname = dctx->rawname;
errno_t ret;
ret = sss_dp_get_domains_recv(req);
@@ -3438,12 +3485,27 @@ static void nss_cmd_initgroups_cb(struct tevent_req *req)
goto done;
}
- if (dctx->domname) {
- dctx->domain = responder_get_domain(dctx, cctx->rctx, dctx->domname);
- if (dctx->domain == NULL) {
+ ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, rawname,
+ &domname, &cmdctx->name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Invalid name received [%s]\n", rawname));
+ ret = ENOENT;
+ goto done;
+ }
+
+ DEBUG(SSSDBG_TRACE_FUNC, ("Requesting info for [%s] from [%s]\n",
+ cmdctx->name, domname?domname:"<ALL>"));
+
+ if (domname) {
+ dctx->domain = responder_get_domain(dctx, cctx->rctx, domname);
+ if (!dctx->domain) {
ret = ENOENT;
goto done;
}
+ } else {
+ /* this is a multidomain search */
+ dctx->domain = cctx->rctx->domains;
+ cmdctx->check_next = true;
}
dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider);
diff --git a/src/responder/nss/nsssrv_private.h b/src/responder/nss/nsssrv_private.h
index 57975943..f1d47c3b 100644
--- a/src/responder/nss/nsssrv_private.h
+++ b/src/responder/nss/nsssrv_private.h
@@ -64,7 +64,7 @@ struct nss_dom_ctx {
struct sss_domain_info *domain;
/* For a case when we are discovering subdomains */
- const char *domname;
+ const char *rawname;
bool check_provider;
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index f6c1e835..2d0324e5 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -851,32 +851,12 @@ static void pam_dom_forwarder(struct pam_auth_req *preq);
* PAM_ENVIRONMENT, so that we can save performing some calls and cache
* data. */
-static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
+errno_t pam_forwarder_parse_data(struct cli_ctx *cctx, struct pam_data *pd)
{
- struct sss_domain_info *dom;
- struct pam_auth_req *preq;
- struct pam_data *pd;
uint8_t *body;
size_t blen;
- int ret;
- errno_t ncret;
- struct pam_ctx *pctx =
- talloc_get_type(cctx->rctx->pvt_ctx, struct pam_ctx);
+ errno_t ret;
uint32_t terminator = SSS_END_OF_PAM_REQUEST;
- struct tevent_req *req;
-
- preq = talloc_zero(cctx, struct pam_auth_req);
- if (!preq) {
- return ENOMEM;
- }
- preq->cctx = cctx;
-
- preq->pd = talloc_zero(preq, struct pam_data);
- if (!preq->pd) {
- talloc_free(preq);
- return ENOMEM;
- }
- pd = preq->pd;
sss_packet_get_body(cctx->creq->in, &body, &blen);
if (blen >= sizeof(uint32_t) &&
@@ -886,9 +866,6 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
goto done;
}
- pd->cmd = pam_cmd;
- pd->priv = cctx->priv;
-
switch (cctx->cli_protocol_version->version) {
case 1:
ret = pam_parse_in_data(cctx->rctx->domains, pd, body, blen);
@@ -904,7 +881,49 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
cctx->cli_protocol_version->version));
ret = EINVAL;
}
- if (ret != EOK) {
+
+done:
+ return ret;
+}
+
+static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
+{
+ struct sss_domain_info *dom;
+ struct pam_auth_req *preq;
+ struct pam_data *pd;
+ int ret;
+ errno_t ncret;
+ struct pam_ctx *pctx =
+ talloc_get_type(cctx->rctx->pvt_ctx, struct pam_ctx);
+ struct tevent_req *req;
+
+ preq = talloc_zero(cctx, struct pam_auth_req);
+ if (!preq) {
+ return ENOMEM;
+ }
+ preq->cctx = cctx;
+
+ preq->pd = talloc_zero(preq, struct pam_data);
+ if (!preq->pd) {
+ talloc_free(preq);
+ return ENOMEM;
+ }
+ pd = preq->pd;
+
+ pd->cmd = pam_cmd;
+ pd->priv = cctx->priv;
+
+ ret = pam_forwarder_parse_data(cctx, pd);
+ if (ret == EAGAIN) {
+ req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, true, pd->domain);
+ if (req == NULL) {
+ ret = ENOMEM;
+ } else {
+ tevent_req_set_callback(req, pam_forwarder_cb, preq);
+ ret = EAGAIN;
+ }
+ goto done;
+ } else if (ret != EOK) {
ret = EINVAL;
goto done;
}
@@ -913,13 +932,7 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
if (pd->domain) {
preq->domain = responder_get_domain(preq, cctx->rctx, pd->domain);
if (!preq->domain) {
- req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, true, pd->domain);
- if (req == NULL) {
- ret = ENOMEM;
- } else {
- tevent_req_set_callback(req, pam_forwarder_cb, preq);
- ret = EAGAIN;
- }
+ ret = ENOENT;
goto done;
}
} else {
@@ -969,6 +982,7 @@ static void pam_forwarder_cb(struct tevent_req *req)
struct pam_auth_req *preq = tevent_req_callback_data(req,
struct pam_auth_req);
struct cli_ctx *cctx = preq->cctx;
+ struct pam_data *pd;
errno_t ret = EOK;
ret = sss_dp_get_domains_recv(req);
@@ -977,6 +991,14 @@ static void pam_forwarder_cb(struct tevent_req *req)
goto done;
}
+ pd = preq->pd;
+
+ ret = pam_forwarder_parse_data(cctx, pd);
+ if (ret != EOK) {
+ ret = EINVAL;
+ goto done;
+ }
+
if (preq->pd->domain) {
preq->domain = responder_get_domain(preq, cctx->rctx, preq->pd->domain);
if (preq->domain == NULL) {
diff --git a/src/util/usertools.c b/src/util/usertools.c
index 3b23b6a7..36641d49 100644
--- a/src/util/usertools.c
+++ b/src/util/usertools.c
@@ -230,9 +230,9 @@ int sss_parse_name_for_domains(TALLOC_CTX *memctx,
struct sss_domain_info *dom, *match;
char *rdomain, *rname;
char *dmatch, *nmatch;
- char *only_name = NULL;
- bool only_name_seen = false;
- bool only_name_mismatch = false;
+ char *candidate_name = NULL;
+ char *candidate_domain = NULL;
+ bool name_mismatch = false;
TALLOC_CTX *tmp_ctx;
int code;
@@ -252,13 +252,11 @@ int sss_parse_name_for_domains(TALLOC_CTX *memctx,
* name.
*/
if (dmatch == NULL) {
- if (!only_name_seen) {
- only_name = nmatch;
- } else if (nmatch == NULL || only_name == NULL ||
- strcasecmp(only_name, nmatch) != 0) {
- only_name_mismatch = true;
+ if (candidate_name == NULL) {
+ candidate_name = nmatch;
+ } else if (strcasecmp(candidate_name, nmatch) != 0) {
+ name_mismatch = true;
}
- only_name_seen = true;
/*
* If a domain was returned, then it must match the name of the
@@ -274,6 +272,8 @@ int sss_parse_name_for_domains(TALLOC_CTX *memctx,
rdomain = dmatch;
rname = nmatch;
break;
+ } else if (candidate_name == NULL) {
+ candidate_domain = dmatch;
}
}
@@ -284,12 +284,16 @@ int sss_parse_name_for_domains(TALLOC_CTX *memctx,
}
}
- if (rdomain == NULL && rname == NULL &&
- only_name_seen && !only_name_mismatch && only_name != NULL) {
- DEBUG(SSSDBG_FUNC_DATA,
- ("name '%s' matched without domain, user is %s\n", orig, nmatch));
- rdomain = NULL;
- rname = only_name;
+ if (rdomain == NULL && rname == NULL) {
+ if (candidate_name && !name_mismatch) {
+ DEBUG(SSSDBG_FUNC_DATA,
+ ("name '%s' matched without domain, user is %s\n", orig, nmatch));
+ rdomain = NULL;
+ rname = candidate_name;
+ } else if (candidate_domain) {
+ *domain = talloc_steal(memctx, candidate_domain);
+ return EAGAIN;
+ }
}
if (rdomain == NULL && rname == NULL) {