diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/responder/nss/nsssrv_cmd.c | 134 | ||||
-rw-r--r-- | src/responder/nss/nsssrv_private.h | 2 | ||||
-rw-r--r-- | src/responder/pam/pamsrv_cmd.c | 88 | ||||
-rw-r--r-- | src/util/usertools.c | 34 |
4 files changed, 173 insertions, 85 deletions
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c index fc504700c..5c5f8060b 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 57975943b..f1d47c3bc 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 f6c1e8350..2d0324e5b 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 3b23b6a7e..36641d49f 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) { |