|
|
905b4d |
From a5a3aaafd0c1399f83bd3144344eb9a0da436307 Mon Sep 17 00:00:00 2001
|
|
|
905b4d |
From: Sumit Bose <sbose@redhat.com>
|
|
|
905b4d |
Date: Thu, 16 Oct 2014 13:17:37 +0200
|
|
|
905b4d |
Subject: [PATCH 62/64] Views: apply user SSH public key override
|
|
|
905b4d |
|
|
|
905b4d |
With this patch the SSH public key override attribute is read from the
|
|
|
905b4d |
FreeIPA server and saved in the cache with the other override data.
|
|
|
905b4d |
|
|
|
905b4d |
Since it is possible to have multiple public SSH keys this override
|
|
|
905b4d |
value does not replace any other data but will be added to existing
|
|
|
905b4d |
values.
|
|
|
905b4d |
|
|
|
905b4d |
Fixes https://fedorahosted.org/sssd/ticket/2454
|
|
|
905b4d |
|
|
|
905b4d |
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
905b4d |
---
|
|
|
905b4d |
src/db/sysdb_views.c | 38 +++++++++----
|
|
|
905b4d |
src/man/sssd-ipa.5.xml | 3 +
|
|
|
905b4d |
src/providers/ipa/ipa_common.h | 1 +
|
|
|
905b4d |
src/providers/ipa/ipa_opts.h | 1 +
|
|
|
905b4d |
src/responder/ssh/sshsrv_cmd.c | 123 +++++++++++++++++++++++++++++++----------
|
|
|
905b4d |
5 files changed, 126 insertions(+), 40 deletions(-)
|
|
|
905b4d |
|
|
|
905b4d |
diff --git a/src/db/sysdb_views.c b/src/db/sysdb_views.c
|
|
|
905b4d |
index f2cf370231b57c3cd2b563eec4ea2a0f3a0935bd..27b58701fe0f9a4f545df5e4bfb884c04517d0d3 100644
|
|
|
905b4d |
--- a/src/db/sysdb_views.c
|
|
|
905b4d |
+++ b/src/db/sysdb_views.c
|
|
|
905b4d |
@@ -560,6 +560,8 @@ errno_t sysdb_apply_default_override(struct sss_domain_info *domain,
|
|
|
905b4d |
TALLOC_CTX *tmp_ctx;
|
|
|
905b4d |
struct sysdb_attrs *attrs;
|
|
|
905b4d |
size_t c;
|
|
|
905b4d |
+ size_t d;
|
|
|
905b4d |
+ size_t num_values;
|
|
|
905b4d |
struct ldb_message_element *el = NULL;
|
|
|
905b4d |
const char *allowed_attrs[] = { SYSDB_UIDNUM,
|
|
|
905b4d |
SYSDB_GIDNUM,
|
|
|
905b4d |
@@ -567,6 +569,7 @@ errno_t sysdb_apply_default_override(struct sss_domain_info *domain,
|
|
|
905b4d |
SYSDB_HOMEDIR,
|
|
|
905b4d |
SYSDB_SHELL,
|
|
|
905b4d |
SYSDB_NAME,
|
|
|
905b4d |
+ SYSDB_SSH_PUBKEY,
|
|
|
905b4d |
NULL };
|
|
|
905b4d |
bool override_attrs_found = false;
|
|
|
905b4d |
|
|
|
905b4d |
@@ -584,7 +587,6 @@ errno_t sysdb_apply_default_override(struct sss_domain_info *domain,
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
for (c = 0; allowed_attrs[c] != NULL; c++) {
|
|
|
905b4d |
- /* TODO: add nameAlias for case-insentitive searches */
|
|
|
905b4d |
ret = sysdb_attrs_get_el_ext(override_attrs, allowed_attrs[c], false,
|
|
|
905b4d |
&el);
|
|
|
905b4d |
if (ret == EOK) {
|
|
|
905b4d |
@@ -607,17 +609,30 @@ errno_t sysdb_apply_default_override(struct sss_domain_info *domain,
|
|
|
905b4d |
goto done;
|
|
|
905b4d |
}
|
|
|
905b4d |
} else {
|
|
|
905b4d |
- ret = sysdb_attrs_add_val(attrs, allowed_attrs[c],
|
|
|
905b4d |
- &el->values[0]);
|
|
|
905b4d |
- if (ret != EOK) {
|
|
|
905b4d |
- DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_val failed.\n");
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
+ num_values = el->num_values;
|
|
|
905b4d |
+ /* Only SYSDB_SSH_PUBKEY is allowed to have multiple values. */
|
|
|
905b4d |
+ if (strcmp(allowed_attrs[c], SYSDB_SSH_PUBKEY) != 0
|
|
|
905b4d |
+ && num_values != 1) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
905b4d |
+ "Override attribute for [%s] has more [%zd] " \
|
|
|
905b4d |
+ "than one value, using only the first.\n",
|
|
|
905b4d |
+ allowed_attrs[c], num_values);
|
|
|
905b4d |
+ num_values = 1;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ for (d = 0; d < num_values; d++) {
|
|
|
905b4d |
+ ret = sysdb_attrs_add_val(attrs, allowed_attrs[c],
|
|
|
905b4d |
+ &el->values[d]);
|
|
|
905b4d |
+ if (ret != EOK) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
905b4d |
+ "sysdb_attrs_add_val failed.\n");
|
|
|
905b4d |
+ goto done;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+ DEBUG(SSSDBG_TRACE_ALL,
|
|
|
905b4d |
+ "Override [%s] with [%.*s] for [%s].\n",
|
|
|
905b4d |
+ allowed_attrs[c], (int) el->values[d].length,
|
|
|
905b4d |
+ el->values[d].data, ldb_dn_get_linearized(obj_dn));
|
|
|
905b4d |
}
|
|
|
905b4d |
- DEBUG(SSSDBG_TRACE_ALL, "Override [%s] with [%.*s] for [%s].\n",
|
|
|
905b4d |
- allowed_attrs[c],
|
|
|
905b4d |
- (int) el->values[0].length,
|
|
|
905b4d |
- el->values[0].data,
|
|
|
905b4d |
- ldb_dn_get_linearized(obj_dn));
|
|
|
905b4d |
}
|
|
|
905b4d |
} else if (ret != ENOENT) {
|
|
|
905b4d |
DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_el_ext failed.\n");
|
|
|
905b4d |
@@ -983,6 +998,7 @@ errno_t sysdb_add_overrides_to_object(struct sss_domain_info *domain,
|
|
|
905b4d |
{SYSDB_HOMEDIR, OVERRIDE_PREFIX SYSDB_HOMEDIR},
|
|
|
905b4d |
{SYSDB_SHELL, OVERRIDE_PREFIX SYSDB_SHELL},
|
|
|
905b4d |
{SYSDB_NAME, OVERRIDE_PREFIX SYSDB_NAME},
|
|
|
905b4d |
+ {SYSDB_SSH_PUBKEY, OVERRIDE_PREFIX SYSDB_SSH_PUBKEY},
|
|
|
905b4d |
{NULL, NULL}
|
|
|
905b4d |
};
|
|
|
905b4d |
size_t c;
|
|
|
905b4d |
diff --git a/src/man/sssd-ipa.5.xml b/src/man/sssd-ipa.5.xml
|
|
|
905b4d |
index 51f14f8fc16bd2843ef4b426938172c63608176e..e8a716c4104b8038e354b8ae544a04d6773e708b 100644
|
|
|
905b4d |
--- a/src/man/sssd-ipa.5.xml
|
|
|
905b4d |
+++ b/src/man/sssd-ipa.5.xml
|
|
|
905b4d |
@@ -626,6 +626,9 @@
|
|
|
905b4d |
<listitem>
|
|
|
905b4d |
<para>ldap_user_shell</para>
|
|
|
905b4d |
</listitem>
|
|
|
905b4d |
+ <listitem>
|
|
|
905b4d |
+ <para>ldap_user_ssh_public_key</para>
|
|
|
905b4d |
+ </listitem>
|
|
|
905b4d |
</itemizedlist>
|
|
|
905b4d |
</para>
|
|
|
905b4d |
<para>
|
|
|
905b4d |
diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h
|
|
|
905b4d |
index 0e9324f5b362085153abebcc4894bef607173607..495276548e57e91f9744dda6d8866971b627b4da 100644
|
|
|
905b4d |
--- a/src/providers/ipa/ipa_common.h
|
|
|
905b4d |
+++ b/src/providers/ipa/ipa_common.h
|
|
|
905b4d |
@@ -128,6 +128,7 @@ enum ipa_override_attrs {
|
|
|
905b4d |
IPA_AT_OVERRIDE_SHELL,
|
|
|
905b4d |
IPA_AT_OVERRIDE_GROUP_NAME,
|
|
|
905b4d |
IPA_AT_OVERRIDE_GROUP_GID_NUMBER,
|
|
|
905b4d |
+ IPA_AT_OVERRIDE_USER_SSH_PUBLIC_KEY,
|
|
|
905b4d |
|
|
|
905b4d |
IPA_OPTS_OVERRIDE
|
|
|
905b4d |
};
|
|
|
905b4d |
diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h
|
|
|
905b4d |
index 0e0eed49cd397fe88ce7bf41579c066088947d04..473eca4f77727e008663d082e954820a9fb0c427 100644
|
|
|
905b4d |
--- a/src/providers/ipa/ipa_opts.h
|
|
|
905b4d |
+++ b/src/providers/ipa/ipa_opts.h
|
|
|
905b4d |
@@ -283,6 +283,7 @@ struct sdap_attr_map ipa_override_map[] = {
|
|
|
905b4d |
{ "ldap_user_shell", "loginShell", SYSDB_SHELL, NULL },
|
|
|
905b4d |
{ "ldap_group_name", "cn", SYSDB_NAME, NULL },
|
|
|
905b4d |
{ "ldap_group_gid_number", "gidNumber", SYSDB_GIDNUM, NULL },
|
|
|
905b4d |
+ { "ldap_user_ssh_public_key", "ipaSshPubKey", SYSDB_SSH_PUBKEY, NULL },
|
|
|
905b4d |
SDAP_ATTR_MAP_TERMINATOR
|
|
|
905b4d |
};
|
|
|
905b4d |
|
|
|
905b4d |
diff --git a/src/responder/ssh/sshsrv_cmd.c b/src/responder/ssh/sshsrv_cmd.c
|
|
|
905b4d |
index ad831639841d42417008ea6c40c1dea045e5d6cf..5bed2e0adca0e6961337bb744729dd3e5a23c629 100644
|
|
|
905b4d |
--- a/src/responder/ssh/sshsrv_cmd.c
|
|
|
905b4d |
+++ b/src/responder/ssh/sshsrv_cmd.c
|
|
|
905b4d |
@@ -232,8 +232,8 @@ ssh_user_pubkeys_search_next(struct ssh_cmd_ctx *cmd_ctx)
|
|
|
905b4d |
return EFAULT;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
- ret = sysdb_get_user_attr(cmd_ctx, cmd_ctx->domain,
|
|
|
905b4d |
- cmd_ctx->name, attrs, &res;;
|
|
|
905b4d |
+ ret = sysdb_get_user_attr_with_views(cmd_ctx, cmd_ctx->domain,
|
|
|
905b4d |
+ cmd_ctx->name, attrs, &res;;
|
|
|
905b4d |
if (ret != EOK) {
|
|
|
905b4d |
DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
"Failed to make request to our cache!\n");
|
|
|
905b4d |
@@ -782,6 +782,65 @@ ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx)
|
|
|
905b4d |
return EOK;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
+static errno_t decode_and_add_base64_data(struct ssh_cmd_ctx *cmd_ctx,
|
|
|
905b4d |
+ struct ldb_message_element *el,
|
|
|
905b4d |
+ size_t fqname_len,
|
|
|
905b4d |
+ const char *fqname,
|
|
|
905b4d |
+ size_t *c)
|
|
|
905b4d |
+{
|
|
|
905b4d |
+ struct cli_ctx *cctx = cmd_ctx->cctx;
|
|
|
905b4d |
+ uint8_t *key;
|
|
|
905b4d |
+ size_t key_len;
|
|
|
905b4d |
+ uint8_t *body;
|
|
|
905b4d |
+ size_t body_len;
|
|
|
905b4d |
+ int ret;
|
|
|
905b4d |
+ size_t d;
|
|
|
905b4d |
+ TALLOC_CTX *tmp_ctx;
|
|
|
905b4d |
+
|
|
|
905b4d |
+ if (el == NULL) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_TRACE_ALL, "Mssing element, nothing to do.\n");
|
|
|
905b4d |
+ return EOK;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ tmp_ctx = talloc_new(NULL);
|
|
|
905b4d |
+ if (tmp_ctx == NULL) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
|
|
|
905b4d |
+ return ENOMEM;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ for (d = 0; d < el->num_values; d++) {
|
|
|
905b4d |
+ key = sss_base64_decode(tmp_ctx, (const char *) el->values[d].data,
|
|
|
905b4d |
+ &key_len);
|
|
|
905b4d |
+ if (key == NULL) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_OP_FAILURE, "sss_base64_decode failed.\n");
|
|
|
905b4d |
+ ret = ENOMEM;
|
|
|
905b4d |
+ goto done;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ ret = sss_packet_grow(cctx->creq->out,
|
|
|
905b4d |
+ 3*sizeof(uint32_t) + key_len + fqname_len);
|
|
|
905b4d |
+ if (ret != EOK) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_OP_FAILURE, "sss_packet_grow failed.\n");
|
|
|
905b4d |
+ goto done;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+ sss_packet_get_body(cctx->creq->out, &body, &body_len);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ SAFEALIGN_SET_UINT32(body+(*c), 0, c);
|
|
|
905b4d |
+ SAFEALIGN_SET_UINT32(body+(*c), fqname_len, c);
|
|
|
905b4d |
+ safealign_memcpy(body+(*c), fqname, fqname_len, c);
|
|
|
905b4d |
+ SAFEALIGN_SET_UINT32(body+(*c), key_len, c);
|
|
|
905b4d |
+ safealign_memcpy(body+(*c), key, key_len, c);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ ret = EOK;
|
|
|
905b4d |
+
|
|
|
905b4d |
+done:
|
|
|
905b4d |
+ talloc_free(tmp_ctx);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ return ret;
|
|
|
905b4d |
+}
|
|
|
905b4d |
+
|
|
|
905b4d |
static errno_t
|
|
|
905b4d |
ssh_cmd_build_reply(struct ssh_cmd_ctx *cmd_ctx)
|
|
|
905b4d |
{
|
|
|
905b4d |
@@ -790,14 +849,13 @@ ssh_cmd_build_reply(struct ssh_cmd_ctx *cmd_ctx)
|
|
|
905b4d |
uint8_t *body;
|
|
|
905b4d |
size_t body_len;
|
|
|
905b4d |
size_t c = 0;
|
|
|
905b4d |
- unsigned int i;
|
|
|
905b4d |
- struct ldb_message_element *el;
|
|
|
905b4d |
+ struct ldb_message_element *el = NULL;
|
|
|
905b4d |
+ struct ldb_message_element *el_override = NULL;
|
|
|
905b4d |
+ struct ldb_message_element *el_orig = NULL;
|
|
|
905b4d |
uint32_t count = 0;
|
|
|
905b4d |
const char *name;
|
|
|
905b4d |
char *fqname;
|
|
|
905b4d |
uint32_t fqname_len;
|
|
|
905b4d |
- uint8_t *key;
|
|
|
905b4d |
- size_t key_len;
|
|
|
905b4d |
|
|
|
905b4d |
ret = sss_packet_new(cctx->creq, 0,
|
|
|
905b4d |
sss_packet_get_cmd(cctx->creq->in),
|
|
|
905b4d |
@@ -811,6 +869,20 @@ ssh_cmd_build_reply(struct ssh_cmd_ctx *cmd_ctx)
|
|
|
905b4d |
count = el->num_values;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
+ el_orig = ldb_msg_find_element(cmd_ctx->result,
|
|
|
905b4d |
+ ORIGINALAD_PREFIX SYSDB_SSH_PUBKEY);
|
|
|
905b4d |
+ if (el_orig) {
|
|
|
905b4d |
+ count = el_orig->num_values;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ if (DOM_HAS_VIEWS(cmd_ctx->domain)) {
|
|
|
905b4d |
+ el_override = ldb_msg_find_element(cmd_ctx->result,
|
|
|
905b4d |
+ OVERRIDE_PREFIX SYSDB_SSH_PUBKEY);
|
|
|
905b4d |
+ if (el_override) {
|
|
|
905b4d |
+ count += el_override->num_values;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
ret = sss_packet_grow(cctx->creq->out, 2*sizeof(uint32_t));
|
|
|
905b4d |
if (ret != EOK) {
|
|
|
905b4d |
return ret;
|
|
|
905b4d |
@@ -820,7 +892,7 @@ ssh_cmd_build_reply(struct ssh_cmd_ctx *cmd_ctx)
|
|
|
905b4d |
SAFEALIGN_SET_UINT32(body+c, count, &c);
|
|
|
905b4d |
SAFEALIGN_SET_UINT32(body+c, 0, &c);
|
|
|
905b4d |
|
|
|
905b4d |
- if (!el) {
|
|
|
905b4d |
+ if (count == 0) {
|
|
|
905b4d |
return EOK;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
@@ -840,30 +912,23 @@ ssh_cmd_build_reply(struct ssh_cmd_ctx *cmd_ctx)
|
|
|
905b4d |
|
|
|
905b4d |
fqname_len = strlen(fqname)+1;
|
|
|
905b4d |
|
|
|
905b4d |
- for (i = 0; i < el->num_values; i++) {
|
|
|
905b4d |
- key = sss_base64_decode(cmd_ctx,
|
|
|
905b4d |
- (const char *)el->values[i].data,
|
|
|
905b4d |
- &key_len);
|
|
|
905b4d |
- if (!key) {
|
|
|
905b4d |
- return ENOMEM;
|
|
|
905b4d |
- }
|
|
|
905b4d |
+ ret = decode_and_add_base64_data(cmd_ctx, el, fqname_len, fqname, &c);
|
|
|
905b4d |
+ if (ret != EOK) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_OP_FAILURE, "decode_and_add_base64_data failed.\n");
|
|
|
905b4d |
+ return ret;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
|
|
|
905b4d |
- ret = sss_packet_grow(cctx->creq->out,
|
|
|
905b4d |
- 3*sizeof(uint32_t) + key_len + fqname_len);
|
|
|
905b4d |
- if (ret != EOK) {
|
|
|
905b4d |
- talloc_free(key);
|
|
|
905b4d |
- return ret;
|
|
|
905b4d |
- }
|
|
|
905b4d |
- sss_packet_get_body(cctx->creq->out, &body, &body_len);
|
|
|
905b4d |
+ ret = decode_and_add_base64_data(cmd_ctx, el_orig, fqname_len, fqname, &c);
|
|
|
905b4d |
+ if (ret != EOK) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_OP_FAILURE, "decode_and_add_base64_data failed.\n");
|
|
|
905b4d |
+ return ret;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
|
|
|
905b4d |
- SAFEALIGN_SET_UINT32(body+c, 0, &c);
|
|
|
905b4d |
- SAFEALIGN_SET_UINT32(body+c, fqname_len, &c);
|
|
|
905b4d |
- safealign_memcpy(body+c, fqname, fqname_len, &c);
|
|
|
905b4d |
- SAFEALIGN_SET_UINT32(body+c, key_len, &c);
|
|
|
905b4d |
- safealign_memcpy(body+c, key, key_len, &c);
|
|
|
905b4d |
-
|
|
|
905b4d |
- talloc_free(key);
|
|
|
905b4d |
- count++;
|
|
|
905b4d |
+ ret = decode_and_add_base64_data(cmd_ctx, el_override, fqname_len, fqname,
|
|
|
905b4d |
+ &c);
|
|
|
905b4d |
+ if (ret != EOK) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_OP_FAILURE, "decode_and_add_base64_data failed.\n");
|
|
|
905b4d |
+ return ret;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
return EOK;
|
|
|
905b4d |
--
|
|
|
905b4d |
1.9.3
|
|
|
905b4d |
|