summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Zeleny <jzeleny@redhat.com>2011-12-15 05:16:10 -0500
committerStephen Gallagher <sgallagh@redhat.com>2012-04-24 09:19:42 -0400
commitf2d943ee47bb313e0bb7276122587989a3c54fb4 (patch)
treecc5d542c18d42cc96e735b0b1c5a137ec453805d
parent6fdde3913a11cd6148627696fa8717c34e8460fc (diff)
downloadsssd-f2d943ee47bb313e0bb7276122587989a3c54fb4.tar.gz
sssd-f2d943ee47bb313e0bb7276122587989a3c54fb4.tar.xz
sssd-f2d943ee47bb313e0bb7276122587989a3c54fb4.zip
Retrieve subdomains if there is a request for fully qualified user
-rw-r--r--src/responder/nss/nsssrv_cmd.c135
-rw-r--r--src/responder/nss/nsssrv_netgroup.c85
-rw-r--r--src/responder/nss/nsssrv_private.h3
3 files changed, 192 insertions, 31 deletions
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index 2c9a08330..d4ce66569 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -833,8 +833,10 @@ done:
}
}
+static void nss_cmd_getpwnam_cb(struct tevent_req *req);
static int nss_cmd_getpwnam(struct cli_ctx *cctx)
{
+ struct tevent_req *req;
struct nss_cmd_ctx *cmdctx;
struct nss_dom_ctx *dctx;
const char *rawname;
@@ -888,7 +890,14 @@ static int nss_cmd_getpwnam(struct cli_ctx *cctx)
if (domname) {
dctx->domain = responder_get_domain(dctx, cctx->rctx, domname);
if (!dctx->domain) {
- ret = ENOENT;
+ 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;
+ }
goto done;
}
} else {
@@ -910,6 +919,40 @@ done:
return nss_cmd_done(cmdctx, ret);
}
+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;
+ errno_t ret;
+
+ ret = sss_dp_get_domains_recv(req);
+ talloc_free(req);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ if (dctx->domname) {
+ dctx->domain = responder_get_domain(dctx, cctx->rctx, dctx->domname);
+ if (dctx->domain == NULL) {
+ ret = ENOENT;
+ goto done;
+ }
+ }
+
+ dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider);
+
+ /* ok, find it ! */
+ ret = nss_cmd_getpwnam_search(dctx);
+ if (ret == EOK) {
+ /* we have results to return */
+ ret = nss_cmd_getpw_send_reply(dctx, false);
+ }
+
+done:
+ nss_cmd_done(cmdctx, ret);
+}
+
static void nss_cmd_getpwuid_dp_callback(uint16_t err_maj, uint32_t err_min,
const char *err_msg, void *ptr);
@@ -2150,8 +2193,10 @@ done:
}
}
+static void nss_cmd_getgrnam_cb(struct tevent_req *req);
static int nss_cmd_getgrnam(struct cli_ctx *cctx)
{
+ struct tevent_req *req;
struct nss_cmd_ctx *cmdctx;
struct nss_dom_ctx *dctx;
const char *rawname;
@@ -2205,7 +2250,14 @@ static int nss_cmd_getgrnam(struct cli_ctx *cctx)
if (domname) {
dctx->domain = responder_get_domain(dctx, cctx->rctx, domname);
if (!dctx->domain) {
- ret = ENOENT;
+ 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;
+ }
goto done;
}
} else {
@@ -2227,6 +2279,40 @@ done:
return nss_cmd_done(cmdctx, ret);
}
+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;
+ errno_t ret;
+
+ ret = sss_dp_get_domains_recv(req);
+ talloc_free(req);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ if (dctx->domname) {
+ dctx->domain = responder_get_domain(dctx, cctx->rctx, dctx->domname);
+ if (dctx->domain == NULL) {
+ ret = ENOENT;
+ goto done;
+ }
+ }
+
+ dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider);
+
+ /* ok, find it ! */
+ ret = nss_cmd_getgrnam_search(dctx);
+ if (ret == EOK) {
+ /* we have results to return */
+ ret = nss_cmd_getpw_send_reply(dctx, false);
+ }
+
+done:
+ nss_cmd_done(cmdctx, ret);
+}
+
static void nss_cmd_getgrgid_dp_callback(uint16_t err_maj, uint32_t err_min,
const char *err_msg, void *ptr);
@@ -3204,8 +3290,10 @@ done:
}
/* for now, if we are online, try to always query the backend */
+static void nss_cmd_initgroups_cb(struct tevent_req *req);
static int nss_cmd_initgroups(struct cli_ctx *cctx)
{
+ struct tevent_req *req;
struct nss_cmd_ctx *cmdctx;
struct nss_dom_ctx *dctx;
const char *rawname;
@@ -3259,7 +3347,14 @@ static int nss_cmd_initgroups(struct cli_ctx *cctx)
if (domname) {
dctx->domain = responder_get_domain(dctx, cctx->rctx, domname);
if (!dctx->domain) {
- ret = ENOENT;
+ 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;
+ }
goto done;
}
} else {
@@ -3277,6 +3372,40 @@ done:
return nss_cmd_done(cmdctx, ret);
}
+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;
+ errno_t ret;
+
+ ret = sss_dp_get_domains_recv(req);
+ talloc_free(req);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ if (dctx->domname) {
+ dctx->domain = responder_get_domain(dctx, cctx->rctx, dctx->domname);
+ if (dctx->domain == NULL) {
+ ret = ENOENT;
+ goto done;
+ }
+ }
+
+ dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider);
+
+ /* ok, find it ! */
+ ret = nss_cmd_initgroups_search(dctx);
+ if (ret == EOK) {
+ /* we have results to return */
+ ret = nss_cmd_getpw_send_reply(dctx, false);
+ }
+
+done:
+ nss_cmd_done(cmdctx, ret);
+}
+
struct cli_protocol_version *register_cli_protocol_version(void)
{
static struct cli_protocol_version nss_cli_protocol_version[] = {
diff --git a/src/responder/nss/nsssrv_netgroup.c b/src/responder/nss/nsssrv_netgroup.c
index 87b105719..83e79a2fa 100644
--- a/src/responder/nss/nsssrv_netgroup.c
+++ b/src/responder/nss/nsssrv_netgroup.c
@@ -161,7 +161,9 @@ struct setnetgrent_ctx {
struct nss_dom_ctx *dctx;
char *netgr_shortname;
struct getent_ctx *netgr;
+ const char *rawname;
};
+static errno_t setnetgrent_retry(struct tevent_req *req);
static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx);
static struct tevent_req *setnetgrent_send(TALLOC_CTX *mem_ctx,
const char *rawname,
@@ -172,7 +174,6 @@ static struct tevent_req *setnetgrent_send(TALLOC_CTX *mem_ctx,
struct tevent_req *req;
struct setnetgrent_ctx *state;
struct nss_dom_ctx *dctx;
- struct setent_step_ctx *step_ctx;
struct cli_ctx *client = cmdctx->cctx;
struct nss_ctx *nctx =
@@ -186,6 +187,7 @@ static struct tevent_req *setnetgrent_send(TALLOC_CTX *mem_ctx,
state->nctx = nctx;
state->cmdctx = cmdctx;
+ state->rawname = rawname;
state->dctx = talloc_zero(state, struct nss_dom_ctx);
if (!state->dctx) {
@@ -231,6 +233,42 @@ static struct tevent_req *setnetgrent_send(TALLOC_CTX *mem_ctx,
}
}
+ ret = setnetgrent_retry(req);
+ if (ret != EOK) {
+ if (ret == EAGAIN) {
+ /* We need to reenter the mainloop
+ * We may be refreshing the cache
+ */
+ return req;
+ }
+
+ goto error;
+ }
+
+ return req;
+
+error:
+ tevent_req_error(req, ret);
+ tevent_req_post(req, cmdctx->cctx->ev);
+ return req;
+}
+
+static errno_t setnetgrent_retry(struct tevent_req *req)
+{
+ errno_t ret;
+ struct setent_step_ctx *step_ctx;
+ struct setnetgrent_ctx *state;
+ struct cli_ctx *client;
+ struct nss_ctx *nctx;
+ struct nss_cmd_ctx *cmdctx;
+ struct nss_dom_ctx *dctx;
+
+ state = tevent_req_data(req, struct setnetgrent_ctx);
+ dctx = state->dctx;
+ cmdctx = state->cmdctx;
+ client = cmdctx->cctx;
+ nctx = talloc_get_type(client->rctx->pvt_ctx, struct nss_ctx);
+
dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider);
/* Is the result context already available?
@@ -245,13 +283,15 @@ static struct tevent_req *setnetgrent_send(TALLOC_CTX *mem_ctx,
if (state->netgr->found) {
/* Ready to process results */
tevent_req_done(req);
- tevent_req_post(req, nctx->rctx->ev);
- return req;
} else {
tevent_req_error(req, ENOENT);
- tevent_req_post(req, nctx->rctx->ev);
- return req;
}
+
+ tevent_req_post(req, nctx->rctx->ev);
+ /* Return EOK, otherwise this will be treated as
+ * an error
+ */
+ return EOK;
}
/* Result object is still being constructed
@@ -259,7 +299,7 @@ static struct tevent_req *setnetgrent_send(TALLOC_CTX *mem_ctx,
*/
ret = nss_setent_add_ref(state, state->netgr, req);
if (ret != EOK) {
- goto error;
+ goto done;
}
/* Will return control below */
} else if (ret == ENOENT) {
@@ -268,7 +308,7 @@ static struct tevent_req *setnetgrent_send(TALLOC_CTX *mem_ctx,
state->netgr = talloc_zero(nctx, struct getent_ctx);
if (!state->netgr) {
ret = ENOMEM;
- goto error;
+ goto done;
}
dctx->netgr = state->netgr;
@@ -280,7 +320,7 @@ static struct tevent_req *setnetgrent_send(TALLOC_CTX *mem_ctx,
if (!state->netgr->name) {
talloc_free(state->netgr);
ret = ENOMEM;
- goto error;
+ goto done;
}
state->netgr->lookup_table = nctx->netgroups;
@@ -289,21 +329,21 @@ static struct tevent_req *setnetgrent_send(TALLOC_CTX *mem_ctx,
ret = nss_setent_add_ref(state, state->netgr, req);
if (ret != EOK) {
talloc_free(state->netgr);
- goto error;
+ goto done;
}
ret = set_netgroup_entry(nctx, state->netgr);
if (ret != EOK) {
DEBUG(1, ("set_netgroup_entry failed.\n"));
talloc_free(state->netgr);
- goto error;
+ goto done;
}
/* Perform lookup */
step_ctx = talloc_zero(state->netgr, struct setent_step_ctx);
if (!step_ctx) {
ret = ENOMEM;
- goto error;
+ goto done;
}
/* Steal the dom_ctx onto the step_ctx so it doesn't go out of scope if
@@ -318,36 +358,25 @@ static struct tevent_req *setnetgrent_send(TALLOC_CTX *mem_ctx,
talloc_strdup(step_ctx, state->netgr->name);
if (!step_ctx->name) {
ret = ENOMEM;
- goto error;
+ goto done;
}
ret = lookup_netgr_step(step_ctx);
if (ret != EOK) {
- if (ret == EAGAIN) {
- /* We need to reenter the mainloop
- * We may be refreshing the cache
- */
- return req;
- }
-
- /* An unexpected error occurred or no domains
- * were eligible for the search */
- goto error;
+ goto done;
}
tevent_req_done(req);
tevent_req_post(req, cmdctx->cctx->ev);
/* Will return control below */
} else {
/* Unexpected error from hash_lookup */
- goto error;
+ goto done;
}
- return req;
+ ret = EOK;
-error:
- tevent_req_error(req, ret);
- tevent_req_post(req, cmdctx->cctx->ev);
- return req;
+done:
+ return ret;
}
static void lookup_netgr_dp_callback(uint16_t err_maj, uint32_t err_min,
diff --git a/src/responder/nss/nsssrv_private.h b/src/responder/nss/nsssrv_private.h
index c9fb0d0a0..57975943b 100644
--- a/src/responder/nss/nsssrv_private.h
+++ b/src/responder/nss/nsssrv_private.h
@@ -63,6 +63,9 @@ struct nss_dom_ctx {
struct nss_cmd_ctx *cmdctx;
struct sss_domain_info *domain;
+ /* For a case when we are discovering subdomains */
+ const char *domname;
+
bool check_provider;
/* cache results */