diff options
-rw-r--r-- | src/db/sysdb_views.c | 38 | ||||
-rw-r--r-- | src/man/sssd-ipa.5.xml | 3 | ||||
-rw-r--r-- | src/providers/ipa/ipa_common.h | 1 | ||||
-rw-r--r-- | src/providers/ipa/ipa_opts.h | 1 | ||||
-rw-r--r-- | src/responder/ssh/sshsrv_cmd.c | 123 |
5 files changed, 126 insertions, 40 deletions
diff --git a/src/db/sysdb_views.c b/src/db/sysdb_views.c index f2cf37023..27b58701f 100644 --- a/src/db/sysdb_views.c +++ b/src/db/sysdb_views.c @@ -560,6 +560,8 @@ errno_t sysdb_apply_default_override(struct sss_domain_info *domain, TALLOC_CTX *tmp_ctx; struct sysdb_attrs *attrs; size_t c; + size_t d; + size_t num_values; struct ldb_message_element *el = NULL; const char *allowed_attrs[] = { SYSDB_UIDNUM, SYSDB_GIDNUM, @@ -567,6 +569,7 @@ errno_t sysdb_apply_default_override(struct sss_domain_info *domain, SYSDB_HOMEDIR, SYSDB_SHELL, SYSDB_NAME, + SYSDB_SSH_PUBKEY, NULL }; bool override_attrs_found = false; @@ -584,7 +587,6 @@ errno_t sysdb_apply_default_override(struct sss_domain_info *domain, } for (c = 0; allowed_attrs[c] != NULL; c++) { - /* TODO: add nameAlias for case-insentitive searches */ ret = sysdb_attrs_get_el_ext(override_attrs, allowed_attrs[c], false, &el); if (ret == EOK) { @@ -607,17 +609,30 @@ errno_t sysdb_apply_default_override(struct sss_domain_info *domain, goto done; } } else { - ret = sysdb_attrs_add_val(attrs, allowed_attrs[c], - &el->values[0]); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_val failed.\n"); - goto done; + num_values = el->num_values; + /* Only SYSDB_SSH_PUBKEY is allowed to have multiple values. */ + if (strcmp(allowed_attrs[c], SYSDB_SSH_PUBKEY) != 0 + && num_values != 1) { + DEBUG(SSSDBG_MINOR_FAILURE, + "Override attribute for [%s] has more [%zd] " \ + "than one value, using only the first.\n", + allowed_attrs[c], num_values); + num_values = 1; + } + + for (d = 0; d < num_values; d++) { + ret = sysdb_attrs_add_val(attrs, allowed_attrs[c], + &el->values[d]); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "sysdb_attrs_add_val failed.\n"); + goto done; + } + DEBUG(SSSDBG_TRACE_ALL, + "Override [%s] with [%.*s] for [%s].\n", + allowed_attrs[c], (int) el->values[d].length, + el->values[d].data, ldb_dn_get_linearized(obj_dn)); } - DEBUG(SSSDBG_TRACE_ALL, "Override [%s] with [%.*s] for [%s].\n", - allowed_attrs[c], - (int) el->values[0].length, - el->values[0].data, - ldb_dn_get_linearized(obj_dn)); } } else if (ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_el_ext failed.\n"); @@ -983,6 +998,7 @@ errno_t sysdb_add_overrides_to_object(struct sss_domain_info *domain, {SYSDB_HOMEDIR, OVERRIDE_PREFIX SYSDB_HOMEDIR}, {SYSDB_SHELL, OVERRIDE_PREFIX SYSDB_SHELL}, {SYSDB_NAME, OVERRIDE_PREFIX SYSDB_NAME}, + {SYSDB_SSH_PUBKEY, OVERRIDE_PREFIX SYSDB_SSH_PUBKEY}, {NULL, NULL} }; size_t c; diff --git a/src/man/sssd-ipa.5.xml b/src/man/sssd-ipa.5.xml index 51f14f8fc..e8a716c41 100644 --- a/src/man/sssd-ipa.5.xml +++ b/src/man/sssd-ipa.5.xml @@ -626,6 +626,9 @@ <listitem> <para>ldap_user_shell</para> </listitem> + <listitem> + <para>ldap_user_ssh_public_key</para> + </listitem> </itemizedlist> </para> <para> diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h index 0e9324f5b..495276548 100644 --- a/src/providers/ipa/ipa_common.h +++ b/src/providers/ipa/ipa_common.h @@ -128,6 +128,7 @@ enum ipa_override_attrs { IPA_AT_OVERRIDE_SHELL, IPA_AT_OVERRIDE_GROUP_NAME, IPA_AT_OVERRIDE_GROUP_GID_NUMBER, + IPA_AT_OVERRIDE_USER_SSH_PUBLIC_KEY, IPA_OPTS_OVERRIDE }; diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h index 0e0eed49c..473eca4f7 100644 --- a/src/providers/ipa/ipa_opts.h +++ b/src/providers/ipa/ipa_opts.h @@ -283,6 +283,7 @@ struct sdap_attr_map ipa_override_map[] = { { "ldap_user_shell", "loginShell", SYSDB_SHELL, NULL }, { "ldap_group_name", "cn", SYSDB_NAME, NULL }, { "ldap_group_gid_number", "gidNumber", SYSDB_GIDNUM, NULL }, + { "ldap_user_ssh_public_key", "ipaSshPubKey", SYSDB_SSH_PUBKEY, NULL }, SDAP_ATTR_MAP_TERMINATOR }; diff --git a/src/responder/ssh/sshsrv_cmd.c b/src/responder/ssh/sshsrv_cmd.c index ad8316398..5bed2e0ad 100644 --- a/src/responder/ssh/sshsrv_cmd.c +++ b/src/responder/ssh/sshsrv_cmd.c @@ -232,8 +232,8 @@ ssh_user_pubkeys_search_next(struct ssh_cmd_ctx *cmd_ctx) return EFAULT; } - ret = sysdb_get_user_attr(cmd_ctx, cmd_ctx->domain, - cmd_ctx->name, attrs, &res); + ret = sysdb_get_user_attr_with_views(cmd_ctx, cmd_ctx->domain, + cmd_ctx->name, attrs, &res); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache!\n"); @@ -782,6 +782,65 @@ ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx) return EOK; } +static errno_t decode_and_add_base64_data(struct ssh_cmd_ctx *cmd_ctx, + struct ldb_message_element *el, + size_t fqname_len, + const char *fqname, + size_t *c) +{ + struct cli_ctx *cctx = cmd_ctx->cctx; + uint8_t *key; + size_t key_len; + uint8_t *body; + size_t body_len; + int ret; + size_t d; + TALLOC_CTX *tmp_ctx; + + if (el == NULL) { + DEBUG(SSSDBG_TRACE_ALL, "Mssing element, nothing to do.\n"); + return EOK; + } + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); + return ENOMEM; + } + + for (d = 0; d < el->num_values; d++) { + key = sss_base64_decode(tmp_ctx, (const char *) el->values[d].data, + &key_len); + if (key == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "sss_base64_decode failed.\n"); + ret = ENOMEM; + goto done; + } + + ret = sss_packet_grow(cctx->creq->out, + 3*sizeof(uint32_t) + key_len + fqname_len); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sss_packet_grow failed.\n"); + goto done; + } + sss_packet_get_body(cctx->creq->out, &body, &body_len); + + SAFEALIGN_SET_UINT32(body+(*c), 0, c); + SAFEALIGN_SET_UINT32(body+(*c), fqname_len, c); + safealign_memcpy(body+(*c), fqname, fqname_len, c); + SAFEALIGN_SET_UINT32(body+(*c), key_len, c); + safealign_memcpy(body+(*c), key, key_len, c); + + } + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + static errno_t ssh_cmd_build_reply(struct ssh_cmd_ctx *cmd_ctx) { @@ -790,14 +849,13 @@ ssh_cmd_build_reply(struct ssh_cmd_ctx *cmd_ctx) uint8_t *body; size_t body_len; size_t c = 0; - unsigned int i; - struct ldb_message_element *el; + struct ldb_message_element *el = NULL; + struct ldb_message_element *el_override = NULL; + struct ldb_message_element *el_orig = NULL; uint32_t count = 0; const char *name; char *fqname; uint32_t fqname_len; - uint8_t *key; - size_t key_len; ret = sss_packet_new(cctx->creq, 0, sss_packet_get_cmd(cctx->creq->in), @@ -811,6 +869,20 @@ ssh_cmd_build_reply(struct ssh_cmd_ctx *cmd_ctx) count = el->num_values; } + el_orig = ldb_msg_find_element(cmd_ctx->result, + ORIGINALAD_PREFIX SYSDB_SSH_PUBKEY); + if (el_orig) { + count = el_orig->num_values; + } + + if (DOM_HAS_VIEWS(cmd_ctx->domain)) { + el_override = ldb_msg_find_element(cmd_ctx->result, + OVERRIDE_PREFIX SYSDB_SSH_PUBKEY); + if (el_override) { + count += el_override->num_values; + } + } + ret = sss_packet_grow(cctx->creq->out, 2*sizeof(uint32_t)); if (ret != EOK) { return ret; @@ -820,7 +892,7 @@ ssh_cmd_build_reply(struct ssh_cmd_ctx *cmd_ctx) SAFEALIGN_SET_UINT32(body+c, count, &c); SAFEALIGN_SET_UINT32(body+c, 0, &c); - if (!el) { + if (count == 0) { return EOK; } @@ -840,30 +912,23 @@ ssh_cmd_build_reply(struct ssh_cmd_ctx *cmd_ctx) fqname_len = strlen(fqname)+1; - for (i = 0; i < el->num_values; i++) { - key = sss_base64_decode(cmd_ctx, - (const char *)el->values[i].data, - &key_len); - if (!key) { - return ENOMEM; - } - - ret = sss_packet_grow(cctx->creq->out, - 3*sizeof(uint32_t) + key_len + fqname_len); - if (ret != EOK) { - talloc_free(key); - return ret; - } - sss_packet_get_body(cctx->creq->out, &body, &body_len); + ret = decode_and_add_base64_data(cmd_ctx, el, fqname_len, fqname, &c); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "decode_and_add_base64_data failed.\n"); + return ret; + } - SAFEALIGN_SET_UINT32(body+c, 0, &c); - SAFEALIGN_SET_UINT32(body+c, fqname_len, &c); - safealign_memcpy(body+c, fqname, fqname_len, &c); - SAFEALIGN_SET_UINT32(body+c, key_len, &c); - safealign_memcpy(body+c, key, key_len, &c); + ret = decode_and_add_base64_data(cmd_ctx, el_orig, fqname_len, fqname, &c); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "decode_and_add_base64_data failed.\n"); + return ret; + } - talloc_free(key); - count++; + ret = decode_and_add_base64_data(cmd_ctx, el_override, fqname_len, fqname, + &c); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "decode_and_add_base64_data failed.\n"); + return ret; } return EOK; |