summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Cholasta <jcholast@redhat.com>2012-02-27 08:04:26 -0500
committerStephen Gallagher <sgallagh@redhat.com>2012-02-27 11:52:34 -0500
commita836d70ad64013ec1d407388a9416ecb3d1cc992 (patch)
tree9ae01187f39f95376d21cfe4709c19a3b3cb7db9
parent26202f8e447b694843d3fb9532673dc280a4c245 (diff)
downloadsssd-a836d70ad64013ec1d407388a9416ecb3d1cc992.tar.gz
sssd-a836d70ad64013ec1d407388a9416ecb3d1cc992.tar.bz2
sssd-a836d70ad64013ec1d407388a9416ecb3d1cc992.zip
SSH: Replace blocking getaddrinfo call in the responder with asynchronous resolver code
-rw-r--r--Makefile.am4
-rw-r--r--src/responder/ssh/sshsrv.c7
-rw-r--r--src/responder/ssh/sshsrv_cmd.c74
-rw-r--r--src/responder/ssh/sshsrv_private.h1
4 files changed, 59 insertions, 27 deletions
diff --git a/Makefile.am b/Makefile.am
index a1fafcd3..81581658 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -533,9 +533,11 @@ if BUILD_SSH
sssd_ssh_SOURCES = \
src/responder/ssh/sshsrv.c \
src/responder/ssh/sshsrv_cmd.c \
- $(SSSD_RESPONDER_OBJ)
+ $(SSSD_RESPONDER_OBJ) \
+ $(SSSD_RESOLV_OBJ)
sssd_ssh_LDADD = \
$(SSSD_LIBS) \
+ $(CARES_LIBS) \
libsss_util.la
endif
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 {