14fef6c6d9
- Explicitly Require libini_config >= 1.0.0.1 to work around a SONAME bug in ding-libs - Fix SSH integration with fully-qualified domains - Add the ability to dynamically discover the NetBIOS name
316 lines
12 KiB
Diff
316 lines
12 KiB
Diff
From 28e55560008f21a532b103b3f612c6fca2a54d76 Mon Sep 17 00:00:00 2001
|
|
From: Jan Cholasta <jcholast@redhat.com>
|
|
Date: Fri, 26 Apr 2013 10:45:42 +0200
|
|
Subject: [PATCH 5/6] SSH: Use separate field for domain name in client
|
|
requests
|
|
|
|
Instead of appending @domain to names when the --domain option of sss_ssh_* is
|
|
used, put domain name in a separate field in client requests.
|
|
---
|
|
src/responder/ssh/sshsrv_cmd.c | 91 +++++++++++++++++++---------
|
|
src/sss_client/ssh/sss_ssh_authorizedkeys.c | 15 +----
|
|
src/sss_client/ssh/sss_ssh_client.c | 38 ++++++++----
|
|
src/sss_client/ssh/sss_ssh_client.h | 1 +
|
|
src/sss_client/ssh/sss_ssh_knownhostsproxy.c | 12 +---
|
|
src/util/sss_ssh.h | 4 ++
|
|
6 files changed, 97 insertions(+), 64 deletions(-)
|
|
|
|
diff --git a/src/responder/ssh/sshsrv_cmd.c b/src/responder/ssh/sshsrv_cmd.c
|
|
index 374abe6c6ef4ffe1abeeafa2fe94602f5bff3414..d2f889fa6ac1e414dfa9bbd943b8ef6af125ae74 100644
|
|
--- a/src/responder/ssh/sshsrv_cmd.c
|
|
+++ b/src/responder/ssh/sshsrv_cmd.c
|
|
@@ -685,12 +685,14 @@ ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx)
|
|
uint32_t name_len;
|
|
char *name;
|
|
uint32_t alias_len;
|
|
- char *alias;
|
|
+ char *alias = NULL;
|
|
+ uint32_t domain_len;
|
|
+ char *domain = cctx->rctx->default_domain;
|
|
|
|
sss_packet_get_body(cctx->creq->in, &body, &body_len);
|
|
|
|
SAFEALIGN_COPY_UINT32_CHECK(&flags, body+c, body_len, &c);
|
|
- if (flags > 1) {
|
|
+ if (flags & ~(uint32_t)SSS_SSH_REQ_MASK) {
|
|
DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid flags received [0x%x]\n", flags));
|
|
return EINVAL;
|
|
}
|
|
@@ -709,28 +711,7 @@ ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx)
|
|
}
|
|
c += name_len;
|
|
|
|
- ret = sss_parse_name(cmd_ctx, ssh_ctx->snctx, name,
|
|
- &cmd_ctx->domname, &cmd_ctx->name);
|
|
- if (ret != EOK) {
|
|
- DEBUG(SSSDBG_OP_FAILURE, ("Invalid name received [%s]\n", name));
|
|
- return ENOENT;
|
|
- }
|
|
-
|
|
- if (cmd_ctx->is_user && cmd_ctx->domname == NULL) {
|
|
- name = cmd_ctx->name;
|
|
-
|
|
- ret = sss_parse_name_for_domains(cmd_ctx, cctx->rctx->domains,
|
|
- cctx->rctx->default_domain, name,
|
|
- &cmd_ctx->domname,
|
|
- &cmd_ctx->name);
|
|
- if (ret != EOK) {
|
|
- DEBUG(SSSDBG_OP_FAILURE,
|
|
- ("Invalid name received [%s]\n", name));
|
|
- return ENOENT;
|
|
- }
|
|
- }
|
|
-
|
|
- if (flags & 1) {
|
|
+ if (flags & SSS_SSH_REQ_ALIAS) {
|
|
SAFEALIGN_COPY_UINT32_CHECK(&alias_len, body+c, body_len, &c);
|
|
if (alias_len == 0 || alias_len > body_len - c) {
|
|
DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid alias length\n"));
|
|
@@ -744,11 +725,67 @@ ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx)
|
|
return EINVAL;
|
|
}
|
|
c += alias_len;
|
|
+ }
|
|
|
|
- if (strcmp(cmd_ctx->name, alias) != 0) {
|
|
- cmd_ctx->alias = talloc_strdup(cmd_ctx, alias);
|
|
- if (!cmd_ctx->alias) return ENOMEM;
|
|
+ if (flags & SSS_SSH_REQ_DOMAIN) {
|
|
+ SAFEALIGN_COPY_UINT32_CHECK(&domain_len, body+c, body_len, &c);
|
|
+ if (domain_len > 0) {
|
|
+ if (domain_len > body_len - c) {
|
|
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid domain length\n"));
|
|
+ return EINVAL;
|
|
+ }
|
|
+
|
|
+ domain = (char *)(body+c);
|
|
+ if (!sss_utf8_check((const uint8_t *)domain, domain_len-1) ||
|
|
+ domain[domain_len-1] != 0) {
|
|
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
|
+ ("Domain is not valid UTF-8 string\n"));
|
|
+ return EINVAL;
|
|
+ }
|
|
+ c += domain_len;
|
|
+ }
|
|
+
|
|
+ DEBUG(SSSDBG_TRACE_FUNC,
|
|
+ ("Requested domain [%s]\n", domain ? domain : "<ALL>"));
|
|
+ } else {
|
|
+ DEBUG(SSSDBG_TRACE_FUNC, ("Splitting domain from name [%s]\n", name));
|
|
+
|
|
+ ret = sss_parse_name(cmd_ctx, ssh_ctx->snctx, name,
|
|
+ &cmd_ctx->domname, &cmd_ctx->name);
|
|
+ if (ret != EOK) {
|
|
+ DEBUG(SSSDBG_OP_FAILURE, ("Invalid name received [%s]\n", name));
|
|
+ return ENOENT;
|
|
}
|
|
+
|
|
+ name = cmd_ctx->name;
|
|
+ }
|
|
+
|
|
+ if (cmd_ctx->is_user && cmd_ctx->domname == NULL) {
|
|
+ DEBUG(SSSDBG_TRACE_FUNC,
|
|
+ ("Parsing name [%s][%s]\n", name, domain ? domain : "<ALL>"));
|
|
+
|
|
+ ret = sss_parse_name_for_domains(cmd_ctx, cctx->rctx->domains,
|
|
+ domain, name,
|
|
+ &cmd_ctx->domname,
|
|
+ &cmd_ctx->name);
|
|
+ if (ret != EOK) {
|
|
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
+ ("Invalid name received [%s]\n", name));
|
|
+ return ENOENT;
|
|
+ }
|
|
+ } else if (cmd_ctx->name == NULL && cmd_ctx->domname == NULL) {
|
|
+ cmd_ctx->name = talloc_strdup(cmd_ctx, name);
|
|
+ if (!cmd_ctx->name) return ENOMEM;
|
|
+
|
|
+ if (domain != NULL) {
|
|
+ cmd_ctx->domname = talloc_strdup(cmd_ctx, domain);
|
|
+ if (!cmd_ctx->domname) return ENOMEM;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (alias != NULL && strcmp(cmd_ctx->name, alias) != 0) {
|
|
+ cmd_ctx->alias = talloc_strdup(cmd_ctx, alias);
|
|
+ if (!cmd_ctx->alias) return ENOMEM;
|
|
}
|
|
|
|
return EOK;
|
|
diff --git a/src/sss_client/ssh/sss_ssh_authorizedkeys.c b/src/sss_client/ssh/sss_ssh_authorizedkeys.c
|
|
index 11deff9a6bb2592ce102ff314bcb2b92f90fa1da..bc991a837635186449b1fd5f1c6bdc944176c43d 100644
|
|
--- a/src/sss_client/ssh/sss_ssh_authorizedkeys.c
|
|
+++ b/src/sss_client/ssh/sss_ssh_authorizedkeys.c
|
|
@@ -43,7 +43,6 @@ int main(int argc, const char **argv)
|
|
POPT_TABLEEND
|
|
};
|
|
poptContext pc = NULL;
|
|
- const char *user;
|
|
struct sss_ssh_ent *ent;
|
|
size_t i;
|
|
char *repr;
|
|
@@ -84,21 +83,9 @@ int main(int argc, const char **argv)
|
|
BAD_POPT_PARAMS(pc, _("User not specified\n"), ret, fini);
|
|
}
|
|
|
|
- /* append domain to username if domain is specified */
|
|
- if (pc_domain) {
|
|
- user = talloc_asprintf(mem_ctx, "%s@%s", pc_user, pc_domain);
|
|
- if (!user) {
|
|
- ERROR("Not enough memory\n");
|
|
- ret = EXIT_FAILURE;
|
|
- goto fini;
|
|
- }
|
|
- } else {
|
|
- user = pc_user;
|
|
- }
|
|
-
|
|
/* look up public keys */
|
|
ret = sss_ssh_get_ent(mem_ctx, SSS_SSH_GET_USER_PUBKEYS,
|
|
- user, NULL, &ent);
|
|
+ pc_user, pc_domain, NULL, &ent);
|
|
if (ret != EOK) {
|
|
DEBUG(SSSDBG_CRIT_FAILURE,
|
|
("sss_ssh_get_ent() failed (%d): %s\n", ret, strerror(ret)));
|
|
diff --git a/src/sss_client/ssh/sss_ssh_client.c b/src/sss_client/ssh/sss_ssh_client.c
|
|
index 645f2928985637f26213ab7a0d48a626b088ad58..5312dba2be32aa0cc8813dedfc4189edeff7085c 100644
|
|
--- a/src/sss_client/ssh/sss_ssh_client.c
|
|
+++ b/src/sss_client/ssh/sss_ssh_client.c
|
|
@@ -70,29 +70,34 @@ int set_locale(void)
|
|
|
|
/* SSH public key request:
|
|
*
|
|
- * 0..3: flags (unsigned int, must be 0 or 1)
|
|
- * 4..7: name length (unsigned int)
|
|
- * 8..(X-1): name (null-terminated UTF-8 string)
|
|
- * if (flags & 1) {
|
|
- * X..(X+3): alias length (unsigned int)
|
|
- * (X+4)..Y: alias (null-terminated UTF-8 string)
|
|
- * }
|
|
+ * header:
|
|
+ * 0..3: flags (unsigned int, must be combination of SSS_SSH_REQ_* flags)
|
|
+ * 4..7: name length (unsigned int)
|
|
+ * 8..X: name (null-terminated UTF-8 string)
|
|
+ * alias (only included if flags & SSS_SSH_REQ_ALIAS):
|
|
+ * 0..3: alias length (unsigned int)
|
|
+ * 4..X: alias (null-terminated UTF-8 string)
|
|
+ * domain (ony included if flags & SSS_SSH_REQ_DOMAIN):
|
|
+ * 0..3: domain length (unsigned int, 0 means default domain)
|
|
+ * 4..X: domain (null-terminated UTF-8 string)
|
|
*
|
|
* SSH public key reply:
|
|
*
|
|
- * 0..3: number of results (unsigned int)
|
|
- * 4..7: reserved (unsigned int, must be 0)
|
|
- * 8..$: array of results:
|
|
+ * header:
|
|
+ * 0..3: number of results (unsigned int)
|
|
+ * 4..7: reserved (unsigned int, must be 0)
|
|
+ * results (repeated for each result):
|
|
* 0..3: flags (unsigned int, must be 0)
|
|
* 4..7: name length (unsigned int)
|
|
* 8..(X-1): name (null-terminated UTF-8 string)
|
|
* X..(X+3): key length (unsigned int)
|
|
- * (X+4)..Y: key (public key blob as defined in RFC4253, section 6.6)
|
|
+ * (X+4)..Y: key (public key data)
|
|
*/
|
|
errno_t
|
|
sss_ssh_get_ent(TALLOC_CTX *mem_ctx,
|
|
enum sss_cli_command command,
|
|
const char *name,
|
|
+ const char *domain,
|
|
const char *alias,
|
|
struct sss_ssh_ent **result)
|
|
{
|
|
@@ -102,6 +107,7 @@ sss_ssh_get_ent(TALLOC_CTX *mem_ctx,
|
|
uint32_t flags;
|
|
uint32_t name_len;
|
|
uint32_t alias_len;
|
|
+ uint32_t domain_len;
|
|
size_t req_len;
|
|
uint8_t *req = NULL;
|
|
size_t c = 0;
|
|
@@ -122,11 +128,15 @@ sss_ssh_get_ent(TALLOC_CTX *mem_ctx,
|
|
req_len = 2*sizeof(uint32_t) + name_len;
|
|
|
|
if (alias) {
|
|
- flags |= 1;
|
|
+ flags |= SSS_SSH_REQ_ALIAS;
|
|
alias_len = strlen(alias)+1;
|
|
req_len += sizeof(uint32_t) + alias_len;
|
|
}
|
|
|
|
+ flags |= SSS_SSH_REQ_DOMAIN;
|
|
+ domain_len = domain ? (strlen(domain)+1) : 0;
|
|
+ req_len += sizeof(uint32_t) + domain_len;
|
|
+
|
|
req = talloc_array(tmp_ctx, uint8_t, req_len);
|
|
if (!req) {
|
|
ret = ENOMEM;
|
|
@@ -140,6 +150,10 @@ sss_ssh_get_ent(TALLOC_CTX *mem_ctx,
|
|
SAFEALIGN_SET_UINT32(req+c, alias_len, &c);
|
|
safealign_memcpy(req+c, alias, alias_len, &c);
|
|
}
|
|
+ SAFEALIGN_SET_UINT32(req+c, domain_len, &c);
|
|
+ if (domain_len > 0) {
|
|
+ safealign_memcpy(req+c, domain, domain_len, &c);
|
|
+ }
|
|
|
|
/* send request */
|
|
rd.data = req;
|
|
diff --git a/src/sss_client/ssh/sss_ssh_client.h b/src/sss_client/ssh/sss_ssh_client.h
|
|
index 7ffc3983e11c4cfb5fcef9ff417592f63fef3b74..5ad0643f9b821d1ceec85c477ee2037c73e73d7f 100644
|
|
--- a/src/sss_client/ssh/sss_ssh_client.h
|
|
+++ b/src/sss_client/ssh/sss_ssh_client.h
|
|
@@ -34,6 +34,7 @@ errno_t
|
|
sss_ssh_get_ent(TALLOC_CTX *mem_ctx,
|
|
enum sss_cli_command command,
|
|
const char *name,
|
|
+ const char *domain,
|
|
const char *alias,
|
|
struct sss_ssh_ent **result);
|
|
|
|
diff --git a/src/sss_client/ssh/sss_ssh_knownhostsproxy.c b/src/sss_client/ssh/sss_ssh_knownhostsproxy.c
|
|
index 600895d1fec81be59f0a6e0092b8a6c9f17890ec..e2202b1839214a165d5a94e3c70ce6af47cb9187 100644
|
|
--- a/src/sss_client/ssh/sss_ssh_knownhostsproxy.c
|
|
+++ b/src/sss_client/ssh/sss_ssh_knownhostsproxy.c
|
|
@@ -282,19 +282,9 @@ int main(int argc, const char **argv)
|
|
}
|
|
|
|
if (host) {
|
|
- /* append domain to hostname if domain is specified */
|
|
- if (pc_domain) {
|
|
- host = talloc_asprintf(mem_ctx, "%s@%s", host, pc_domain);
|
|
- if (!host) {
|
|
- DEBUG(SSSDBG_CRIT_FAILURE, ("Not enough memory\n"));
|
|
- ret = EXIT_FAILURE;
|
|
- goto fini;
|
|
- }
|
|
- }
|
|
-
|
|
/* look up public keys */
|
|
ret = sss_ssh_get_ent(mem_ctx, SSS_SSH_GET_HOST_PUBKEYS,
|
|
- host, pc_host, &ent);
|
|
+ host, pc_domain, pc_host, &ent);
|
|
if (ret != EOK) {
|
|
DEBUG(SSSDBG_OP_FAILURE,
|
|
("sss_ssh_get_ent() failed (%d): %s\n", ret, strerror(ret)));
|
|
diff --git a/src/util/sss_ssh.h b/src/util/sss_ssh.h
|
|
index fec7c732bdb319a906e01ec185d7ff0e7f2de0fe..1ba50a6552904096f8950b1f53563d7903eaf786 100644
|
|
--- a/src/util/sss_ssh.h
|
|
+++ b/src/util/sss_ssh.h
|
|
@@ -21,6 +21,10 @@
|
|
#ifndef _SSS_SSH_H_
|
|
#define _SSS_SSH_H_
|
|
|
|
+#define SSS_SSH_REQ_ALIAS 0x01
|
|
+#define SSS_SSH_REQ_DOMAIN 0x02
|
|
+#define SSS_SSH_REQ_MASK 0x03
|
|
+
|
|
struct sss_ssh_pubkey {
|
|
uint8_t *data;
|
|
size_t data_len;
|
|
--
|
|
1.8.2.1
|
|
|