diff options
author | Jan Cholasta <jcholast@redhat.com> | 2012-02-27 08:04:26 -0500 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2012-02-27 11:52:34 -0500 |
commit | a836d70ad64013ec1d407388a9416ecb3d1cc992 (patch) | |
tree | 9ae01187f39f95376d21cfe4709c19a3b3cb7db9 /src/responder | |
parent | 26202f8e447b694843d3fb9532673dc280a4c245 (diff) | |
download | sssd-a836d70ad64013ec1d407388a9416ecb3d1cc992.tar.gz sssd-a836d70ad64013ec1d407388a9416ecb3d1cc992.tar.bz2 sssd-a836d70ad64013ec1d407388a9416ecb3d1cc992.zip |
SSH: Replace blocking getaddrinfo call in the responder with asynchronous resolver code
Diffstat (limited to 'src/responder')
-rw-r--r-- | src/responder/ssh/sshsrv.c | 7 | ||||
-rw-r--r-- | src/responder/ssh/sshsrv_cmd.c | 74 | ||||
-rw-r--r-- | src/responder/ssh/sshsrv_private.h | 1 |
3 files changed, 56 insertions, 26 deletions
diff --git a/src/responder/ssh/sshsrv.c b/src/responder/ssh/sshsrv.c index 20f44ca9..886070e2 100644 --- a/src/responder/ssh/sshsrv.c +++ b/src/responder/ssh/sshsrv.c @@ -26,6 +26,7 @@ #include "responder/common/responder.h" #include "responder/ssh/sshsrv_private.h" #include "providers/data_provider.h" +#include "resolv/async_resolv.h" struct sbus_method monitor_ssh_methods[] = { { MON_CLI_METHOD_PING, monitor_common_pong }, @@ -128,6 +129,12 @@ int ssh_process_init(TALLOC_CTX *mem_ctx, ssh_dp_reconnect_init, iter); } + ret = resolv_init(ssh_ctx, ev, RESOLV_DEFAULT_TIMEOUT, &ssh_ctx->resolv); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, ("Could not set up resolver context\n")); + return ret; + } + DEBUG(SSSDBG_TRACE_FUNC, ("SSH Initialization complete\n")); return EOK; diff --git a/src/responder/ssh/sshsrv_cmd.c b/src/responder/ssh/sshsrv_cmd.c index 33f042a3..be79f0c9 100644 --- a/src/responder/ssh/sshsrv_cmd.c +++ b/src/responder/ssh/sshsrv_cmd.c @@ -33,6 +33,7 @@ #include "responder/common/responder.h" #include "responder/common/responder_packet.h" #include "responder/ssh/sshsrv_private.h" +#include "resolv/async_resolv.h" static errno_t ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx); @@ -84,16 +85,16 @@ done: return ssh_cmd_done(cmd_ctx, ret); } -static errno_t -ssh_host_pubkeys_search(struct ssh_cmd_ctx *cmd_ctx); +static void +ssh_host_pubkeys_resolv_done(struct tevent_req *req); static int sss_ssh_cmd_get_host_pubkeys(struct cli_ctx *cctx) { + struct ssh_ctx *ssh_ctx = cctx->rctx->pvt_ctx; struct ssh_cmd_ctx *cmd_ctx; errno_t ret; - struct addrinfo ai_hint; - struct addrinfo *ai = NULL; + struct tevent_req *req; cmd_ctx = talloc_zero(cctx, struct ssh_cmd_ctx); if (!cmd_ctx) { @@ -111,27 +112,6 @@ sss_ssh_cmd_get_host_pubkeys(struct cli_ctx *cctx) ("Requesting SSH host public keys for [%s] from [%s]\n", cmd_ctx->name, cmd_ctx->domname ? cmd_ctx->domname : "<ALL>")); - /* canonicalize host name */ - memset(&ai_hint, 0, sizeof(struct addrinfo)); - ai_hint.ai_flags = AI_CANONNAME; - - ret = getaddrinfo(cmd_ctx->name, NULL, &ai_hint, &ai); - if (!ret) { - if (strcmp(cmd_ctx->name, ai[0].ai_canonname) != 0) { - cmd_ctx->alias = cmd_ctx->name; - cmd_ctx->name = talloc_strdup(cmd_ctx, ai[0].ai_canonname); - if (!cmd_ctx->name) { - ret = ENOMEM; - goto done; - } - } - } else { - DEBUG(SSSDBG_OP_FAILURE, - ("getaddrinfo() failed (%d): %s\n", ret, gai_strerror(ret))); - } - - freeaddrinfo(ai); - if (cmd_ctx->domname) { cmd_ctx->domain = responder_get_domain(cctx->rctx->domains, cmd_ctx->domname); @@ -144,12 +124,54 @@ sss_ssh_cmd_get_host_pubkeys(struct cli_ctx *cctx) cmd_ctx->check_next = true; } - ret = ssh_host_pubkeys_search(cmd_ctx); + /* canonicalize host name */ + req = resolv_gethostbyname_send(cmd_ctx, cctx->rctx->ev, ssh_ctx->resolv, + cmd_ctx->name, IPV4_FIRST, + default_host_dbs); + if (!req) { + ret = ENOMEM; + DEBUG(SSSDBG_OP_FAILURE, + ("Out of memory sending resolver request\n")); + goto done; + } + + tevent_req_set_callback(req, ssh_host_pubkeys_resolv_done, cmd_ctx); + ret = EAGAIN; done: return ssh_cmd_done(cmd_ctx, ret); } +static errno_t +ssh_host_pubkeys_search(struct ssh_cmd_ctx *cmd_ctx); + +static void +ssh_host_pubkeys_resolv_done(struct tevent_req *req) +{ + struct ssh_cmd_ctx *cmd_ctx = tevent_req_callback_data(req, + struct ssh_cmd_ctx); + errno_t ret; + int resolv_status; + struct resolv_hostent *hostent; + + ret = resolv_gethostbyname_recv(req, cmd_ctx, + &resolv_status, NULL, &hostent); + talloc_zfree(req); + if (ret == EOK) { + if (strcmp(cmd_ctx->name, hostent->name) != 0) { + cmd_ctx->alias = cmd_ctx->name; + cmd_ctx->name = hostent->name; + } + } else { + DEBUG(SSSDBG_OP_FAILURE, + ("Failed to resolve [%s]: %s\n", cmd_ctx->name, + resolv_strerror(resolv_status))); + } + + ret = ssh_host_pubkeys_search(cmd_ctx); + ssh_cmd_done(cmd_ctx, ret); +} + static void ssh_dp_send_req_done(struct tevent_req *req) { diff --git a/src/responder/ssh/sshsrv_private.h b/src/responder/ssh/sshsrv_private.h index ab9edf7c..315e4f29 100644 --- a/src/responder/ssh/sshsrv_private.h +++ b/src/responder/ssh/sshsrv_private.h @@ -31,6 +31,7 @@ struct ssh_ctx { struct resp_ctx *rctx; + struct resolv_ctx *resolv; }; struct ssh_cmd_ctx { |