summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Cholasta <jcholast@redhat.com>2012-02-24 12:48:08 -0500
committerStephen Gallagher <sgallagh@redhat.com>2012-02-27 11:52:50 -0500
commitb193250ca7b71e4f07f3016e0addbc4ba521c6a5 (patch)
tree917bb093b862573c8142ac3ca8fad5453660f1af
parent6f66af7530a6421ea9d47e7351cc080c611ed677 (diff)
downloadsssd-b193250ca7b71e4f07f3016e0addbc4ba521c6a5.tar.gz
sssd-b193250ca7b71e4f07f3016e0addbc4ba521c6a5.tar.xz
sssd-b193250ca7b71e4f07f3016e0addbc4ba521c6a5.zip
SSH: Save SSH host name aliases
-rw-r--r--src/db/sysdb_ssh.c85
-rw-r--r--src/db/sysdb_ssh.h9
-rw-r--r--src/providers/data_provider_be.c4
-rw-r--r--src/providers/ipa/ipa_hostid.c34
-rw-r--r--src/responder/ssh/sshsrv_cmd.c26
-rw-r--r--src/responder/ssh/sshsrv_private.h1
6 files changed, 119 insertions, 40 deletions
diff --git a/src/db/sysdb_ssh.c b/src/db/sysdb_ssh.c
index c2ea35b03..d83ad9669 100644
--- a/src/db/sysdb_ssh.c
+++ b/src/db/sysdb_ssh.c
@@ -24,12 +24,19 @@
#include "db/sysdb_private.h"
errno_t
-sysdb_save_ssh_host(struct sysdb_ctx *sysdb_ctx,
- const char *name,
- struct sysdb_attrs *attrs)
+sysdb_store_ssh_host(struct sysdb_ctx *sysdb,
+ const char *name,
+ const char *alias,
+ struct sysdb_attrs *attrs)
{
- errno_t ret;
TALLOC_CTX *tmp_ctx;
+ errno_t ret;
+ struct ldb_message **hosts;
+ size_t num_hosts;
+ struct ldb_message_element *el;
+ unsigned int i;
+ const char *search_attrs[] = { SYSDB_NAME_ALIAS, NULL };
+ bool in_transaction = false;
DEBUG(SSSDBG_TRACE_FUNC, ("Adding host %s\n", name));
@@ -46,25 +53,89 @@ sysdb_save_ssh_host(struct sysdb_ctx *sysdb_ctx,
}
}
- ret = sysdb_store_custom(sysdb_ctx, name, SSH_HOSTS_SUBDIR, attrs);
+ ret = sysdb_transaction_start(sysdb);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Failed to start update transaction\n"));
+ goto done;
+ }
+
+ in_transaction = true;
+
+ ret = sysdb_search_ssh_hosts(tmp_ctx, sysdb, name, search_attrs,
+ &hosts, &num_hosts);
+ if (ret != EOK && ret != ENOENT) {
+ goto done;
+ }
+
+ if (num_hosts > 1) {
+ ret = EINVAL;
+ goto done;
+ }
+
+ ret = sysdb_delete_ssh_host(sysdb, name);
+ if (ret != EOK && ret != ENOENT) {
+ goto done;
+ }
+
+ if (num_hosts == 1) {
+ el = ldb_msg_find_element(hosts[0], SYSDB_NAME_ALIAS);
+
+ if (el) {
+ for (i = 0; i < el->num_values; i++) {
+ if (alias && strcmp((char *)el->values[i].data, alias) == 0) {
+ alias = NULL;
+ }
+
+ ret = sysdb_attrs_add_val(attrs,
+ SYSDB_NAME_ALIAS, &el->values[i]);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Could not add name alias\n"));
+ goto done;
+ }
+ }
+ }
+ }
+
+ if (alias) {
+ ret = sysdb_attrs_add_string(attrs, SYSDB_NAME_ALIAS, alias);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Could not add name alias\n"));
+ goto done;
+ }
+ }
+
+ ret = sysdb_store_custom(sysdb, name, SSH_HOSTS_SUBDIR, attrs);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("sysdb_store_custom failed [%d]: %s\n",
ret, strerror(ret)));
goto done;
}
+ ret = sysdb_transaction_commit(sysdb);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ in_transaction = false;
ret = EOK;
+
done:
+ if (in_transaction) {
+ sysdb_transaction_cancel(sysdb);
+ }
+
talloc_free(tmp_ctx);
+
return ret;
}
errno_t
-sysdb_delete_ssh_host(struct sysdb_ctx *sysdb_ctx,
+sysdb_delete_ssh_host(struct sysdb_ctx *sysdb,
const char *name)
{
DEBUG(SSSDBG_TRACE_FUNC, ("Deleting host %s\n", name));
- return sysdb_delete_custom(sysdb_ctx, name, SSH_HOSTS_SUBDIR);
+ return sysdb_delete_custom(sysdb, name, SSH_HOSTS_SUBDIR);
}
errno_t
diff --git a/src/db/sysdb_ssh.h b/src/db/sysdb_ssh.h
index f9d8d6eca..3136dcc07 100644
--- a/src/db/sysdb_ssh.h
+++ b/src/db/sysdb_ssh.h
@@ -26,12 +26,13 @@
#define SSH_HOSTS_SUBDIR "ssh_hosts"
errno_t
-sysdb_save_ssh_host(struct sysdb_ctx *sysdb_ctx,
- const char *name,
- struct sysdb_attrs *attrs);
+sysdb_store_ssh_host(struct sysdb_ctx *sysdb,
+ const char *name,
+ const char *alias,
+ struct sysdb_attrs *attrs);
errno_t
-sysdb_delete_ssh_host(struct sysdb_ctx *sysdb_ctx,
+sysdb_delete_ssh_host(struct sysdb_ctx *sysdb,
const char *name);
errno_t
diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c
index 2cea1933c..7e27ceacd 100644
--- a/src/providers/data_provider_be.c
+++ b/src/providers/data_provider_be.c
@@ -1182,7 +1182,9 @@ static int be_host_handler(DBusMessage *message, struct sbus_connection *conn)
if (filter) {
if (strncmp(filter, "name=", 5) == 0) {
req->filter_type = BE_FILTER_NAME;
- req->filter_value = &filter[5];
+ ret = split_service_name_filter(req, &filter[5],
+ &req->filter_value,
+ &req->extra_value);
} else {
err_maj = DP_ERR_FATAL;
err_min = EINVAL;
diff --git a/src/providers/ipa/ipa_hostid.c b/src/providers/ipa/ipa_hostid.c
index 873cc5296..8ab24fe5a 100644
--- a/src/providers/ipa/ipa_hostid.c
+++ b/src/providers/ipa/ipa_hostid.c
@@ -33,6 +33,7 @@ struct hosts_get_state {
struct sysdb_ctx *sysdb;
struct sss_domain_info *domain;
const char *name;
+ const char *alias;
const char **attrs;
size_t count;
@@ -45,6 +46,7 @@ hosts_get_send(TALLOC_CTX *memctx,
struct tevent_context *ev,
struct ipa_hostid_ctx *hostid_ctx,
const char *name,
+ const char *alias,
int attrs_type);
static errno_t
hosts_get_recv(struct tevent_req *req,
@@ -83,7 +85,7 @@ ipa_host_info_handler(struct be_req *breq)
}
req = hosts_get_send(breq, breq->be_ctx->ev, hostid_ctx,
- ar->filter_value,
+ ar->filter_value, ar->extra_value,
ar->attr_type);
if (!req) {
ret = ENOMEM;
@@ -149,6 +151,7 @@ hosts_get_send(TALLOC_CTX *memctx,
struct tevent_context *ev,
struct ipa_hostid_ctx *hostid_ctx,
const char *name,
+ const char *alias,
int attrs_type)
{
struct tevent_req *req;
@@ -175,6 +178,7 @@ hosts_get_send(TALLOC_CTX *memctx,
state->sysdb = ctx->be->sysdb;
state->domain = ctx->be->domain;
state->name = name;
+ state->alias = alias;
/* TODO: handle attrs_type */
ret = build_attrs_from_map(state, ctx->opts->host_map,
@@ -253,7 +257,6 @@ hosts_get_done(struct tevent_req *subreq)
struct hosts_get_state);
int dp_error = DP_ERR_FATAL;
errno_t ret;
- bool in_transaction = false;
ret = ipa_host_info_recv(subreq, state,
&state->count, &state->hosts,
@@ -274,20 +277,6 @@ hosts_get_done(struct tevent_req *subreq)
goto done;
}
- ret = sysdb_transaction_start(state->sysdb);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- ("Failed to start update transaction\n"));
- goto done;
- }
-
- in_transaction = true;
-
- ret = sysdb_delete_ssh_host(state->sysdb, state->name);
- if (ret != EOK && ret != ENOENT) {
- goto done;
- }
-
if (state->count == 0) {
DEBUG(SSSDBG_CRIT_FAILURE,
("No host with name [%s] found.\n", state->name));
@@ -302,18 +291,12 @@ hosts_get_done(struct tevent_req *subreq)
goto done;
}
- ret = sysdb_save_ssh_host(state->sysdb,
- state->name, state->hosts[0]);
+ ret = sysdb_store_ssh_host(state->sysdb, state->name, state->alias,
+ state->hosts[0]);
if (ret != EOK) {
goto done;
}
- ret = sysdb_transaction_commit(state->sysdb);
- if (ret != EOK) {
- goto done;
- }
-
- in_transaction = false;
dp_error = DP_ERR_OK;
done:
@@ -321,9 +304,6 @@ done:
if (ret == EOK) {
tevent_req_done(req);
} else {
- if (in_transaction) {
- sysdb_transaction_cancel(state->sysdb);
- }
tevent_req_error(req, ret);
}
}
diff --git a/src/responder/ssh/sshsrv_cmd.c b/src/responder/ssh/sshsrv_cmd.c
index 0a182f310..da6a4540b 100644
--- a/src/responder/ssh/sshsrv_cmd.c
+++ b/src/responder/ssh/sshsrv_cmd.c
@@ -22,6 +22,7 @@
#include <talloc.h>
#include <string.h>
+#include <netdb.h>
#include "util/util.h"
#include "util/crypto/sss_crypto.h"
@@ -90,6 +91,8 @@ sss_ssh_cmd_get_host_pubkeys(struct cli_ctx *cctx)
{
struct ssh_cmd_ctx *cmd_ctx;
errno_t ret;
+ struct addrinfo ai_hint;
+ struct addrinfo *ai = NULL;
cmd_ctx = talloc_zero(cctx, struct ssh_cmd_ctx);
if (!cmd_ctx) {
@@ -107,6 +110,27 @@ 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);
@@ -312,7 +336,7 @@ ssh_host_pubkeys_search(struct ssh_cmd_ctx *cmd_ctx)
if (NEED_CHECK_PROVIDER(cmd_ctx->domain->provider)) {
req = sss_dp_get_account_send(cmd_ctx, cmd_ctx->cctx->rctx,
cmd_ctx->domain, false, SSS_DP_HOST,
- cmd_ctx->name, 0, NULL);
+ cmd_ctx->name, 0, cmd_ctx->alias);
if (!req) {
DEBUG(SSSDBG_CRIT_FAILURE,
("Out of memory sending data provider request\n"));
diff --git a/src/responder/ssh/sshsrv_private.h b/src/responder/ssh/sshsrv_private.h
index 26ed6b92e..ffe88eb35 100644
--- a/src/responder/ssh/sshsrv_private.h
+++ b/src/responder/ssh/sshsrv_private.h
@@ -34,6 +34,7 @@ struct ssh_cmd_ctx {
struct cli_ctx *cctx;
enum sss_dp_acct_type type;
char *name;
+ char *alias;
char *domname;
struct sss_domain_info *domain;