a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina/*
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina Authors:
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina Jan Cholasta <jcholast@redhat.com>
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina Copyright (C) 2012 Red Hat
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina This program is free software; you can redistribute it and/or modify
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina it under the terms of the GNU General Public License as published by
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina the Free Software Foundation; either version 3 of the License, or
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina (at your option) any later version.
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina This program is distributed in the hope that it will be useful,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina but WITHOUT ANY WARRANTY; without even the implied warranty of
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina GNU General Public License for more details.
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina You should have received a copy of the GNU General Public License
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina along with this program. If not, see <http://www.gnu.org/licenses/>.
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina*/
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina#include "config.h"
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina#include <talloc.h>
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina#include <ldb.h>
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina#include "util/util.h"
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina#include "util/crypto/sss_crypto.h"
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina#include "util/sss_ssh.h"
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina#include "util/cert.h"
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina#include "responder/common/responder.h"
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina#include "responder/common/responder_packet.h"
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina#include "responder/common/cache_req/cache_req.h"
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina#include "responder/ssh/ssh_private.h"
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
bd1fa0ec90be717c3b7796d74b6f243f40178d16Sumit Bose/* Locally used flag for libldb's ldb_message_element structure to indicate
bd1fa0ec90be717c3b7796d74b6f243f40178d16Sumit Bose * binary data. Since the related data is only used in memory it is safe. If
bd1fa0ec90be717c3b7796d74b6f243f40178d16Sumit Bose * should be used with care if libldb's I/O operations are involved. */
bd1fa0ec90be717c3b7796d74b6f243f40178d16Sumit Bose#define SSS_EL_FLAG_BIN_DATA (1<<4)
bd1fa0ec90be717c3b7796d74b6f243f40178d16Sumit Bose
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březinastatic errno_t get_valid_certs_keys(TALLOC_CTX *mem_ctx,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina struct ssh_ctx *ssh_ctx,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina struct ldb_message_element *el_cert,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina struct ldb_message_element **_el_res)
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina{
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina TALLOC_CTX *tmp_ctx;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina uint8_t *key;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina size_t key_len;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina char *cert_verification_opts;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina struct cert_verify_opts *cert_verify_opts;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina int ret;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina struct ldb_message_element *el_res;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina size_t d;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (el_cert == NULL) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina DEBUG(SSSDBG_TRACE_ALL, "Mssing element, nothing to do.\n");
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina return EOK;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina tmp_ctx = talloc_new(NULL);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (tmp_ctx == NULL) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina return ENOMEM;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina ret = confdb_get_string(ssh_ctx->rctx->cdb, tmp_ctx,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina CONFDB_MONITOR_CONF_ENTRY,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina CONFDB_MONITOR_CERT_VERIFICATION, NULL,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina &cert_verification_opts);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (ret != EOK) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina DEBUG(SSSDBG_CRIT_FAILURE,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina "Failed to read p11_child_timeout from confdb: [%d] %s\n",
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina ret, sss_strerror(ret));
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina goto done;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina ret = parse_cert_verify_opts(tmp_ctx, cert_verification_opts,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina &cert_verify_opts);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (ret != EOK) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina DEBUG(SSSDBG_FATAL_FAILURE,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina "Failed to parse verifiy option.\n");
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina goto done;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina el_res = talloc_zero(tmp_ctx, struct ldb_message_element);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (el_res == NULL) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n");
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina ret = ENOMEM;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina goto done;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina el_res->values = talloc_array(el_res, struct ldb_val, el_cert->num_values);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (el_res->values == NULL) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n");
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina ret = ENOMEM;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina goto done;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina for (d = 0; d < el_cert->num_values; d++) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina ret = cert_to_ssh_key(tmp_ctx, ssh_ctx->ca_db,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina el_cert->values[d].data,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina el_cert->values[d].length,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina cert_verify_opts, &key, &key_len);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (ret != EOK) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina DEBUG(SSSDBG_OP_FAILURE, "cert_to_ssh_key failed, ignoring.\n");
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina continue;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina el_res->values[el_res->num_values].data =
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina talloc_steal(el_res->values, key);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina el_res->values[el_res->num_values].length = key_len;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina el_res->num_values++;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (el_res->num_values == 0) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina *_el_res = NULL;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina } else {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina *_el_res = talloc_steal(mem_ctx, el_res);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina ret = EOK;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březinadone:
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina talloc_free(tmp_ctx);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina return ret;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina}
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březinastatic errno_t decode_and_add_base64_data(struct sss_packet *packet,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina struct ldb_message_element *el,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina bool skip_base64_decode,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina size_t fqname_len,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina const char *fqname,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina size_t *c)
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina{
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina uint8_t *key;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina size_t key_len;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina uint8_t *body;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina size_t body_len;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina int ret;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina size_t d;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina TALLOC_CTX *tmp_ctx;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (el == NULL) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina DEBUG(SSSDBG_TRACE_ALL, "Mssing element, nothing to do.\n");
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina return EOK;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina tmp_ctx = talloc_new(NULL);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (tmp_ctx == NULL) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina return ENOMEM;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina for (d = 0; d < el->num_values; d++) {
bd1fa0ec90be717c3b7796d74b6f243f40178d16Sumit Bose if (skip_base64_decode || (el->flags & SSS_EL_FLAG_BIN_DATA)) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina key = el->values[d].data;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina key_len = el->values[d].length;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina } else {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina key = sss_base64_decode(tmp_ctx, (const char *) el->values[d].data,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina &key_len);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (key == NULL) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina DEBUG(SSSDBG_OP_FAILURE, "sss_base64_decode failed.\n");
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina ret = ENOMEM;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina goto done;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina ret = sss_packet_grow(packet,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina 3*sizeof(uint32_t) + key_len + fqname_len);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (ret != EOK) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina DEBUG(SSSDBG_OP_FAILURE, "sss_packet_grow failed.\n");
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina goto done;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina sss_packet_get_body(packet, &body, &body_len);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina SAFEALIGN_SET_UINT32(body+(*c), 0, c);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina SAFEALIGN_SET_UINT32(body+(*c), fqname_len, c);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina safealign_memcpy(body+(*c), fqname, fqname_len, c);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina SAFEALIGN_SET_UINT32(body+(*c), key_len, c);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina safealign_memcpy(body+(*c), key, key_len, c);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina ret = EOK;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březinadone:
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina talloc_free(tmp_ctx);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina return ret;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina}
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březinastatic errno_t
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březinassh_get_output_keys(TALLOC_CTX *mem_ctx,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina struct ssh_ctx *ssh_ctx,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina struct sss_domain_info *domain,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina struct ldb_message *msg,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina struct ldb_message_element ***_elements,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina uint32_t *_num_keys)
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina{
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina struct ldb_message_element **elements;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina struct ldb_message_element *user_cert;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina uint32_t num_keys = 0;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina uint32_t i = 0;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina errno_t ret;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
1b5d6b1afc9c3dc696b7b45f2d73b2634f42800aSumit Bose elements = talloc_zero_array(mem_ctx, struct ldb_message_element *, 6);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (elements == NULL) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina return ENOMEM;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina elements[i] = ldb_msg_find_element(msg, SYSDB_SSH_PUBKEY);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (elements[i] != NULL) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina num_keys += elements[i]->num_values;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina i++;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina elements[i] = ldb_msg_find_element(msg, ORIGINALAD_PREFIX SYSDB_SSH_PUBKEY);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (elements[i] != NULL) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina num_keys += elements[i]->num_values;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina i++;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (DOM_HAS_VIEWS(domain)) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina elements[i] = ldb_msg_find_element(msg, OVERRIDE_PREFIX SYSDB_SSH_PUBKEY);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (elements[i] != NULL) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina num_keys += elements[i]->num_values;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina i++;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina user_cert = ldb_msg_find_element(msg, SYSDB_USER_CERT);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (user_cert != NULL) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina ret = get_valid_certs_keys(elements, ssh_ctx, user_cert, &elements[i]);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (ret != EOK) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina DEBUG(SSSDBG_OP_FAILURE, "get_valid_certs_keys failed.\n");
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina goto done;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (elements[i] != NULL) {
bd1fa0ec90be717c3b7796d74b6f243f40178d16Sumit Bose elements[i]->flags |= SSS_EL_FLAG_BIN_DATA;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina num_keys += elements[i]->num_values;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina i++;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
1b5d6b1afc9c3dc696b7b45f2d73b2634f42800aSumit Bose if (DOM_HAS_VIEWS(domain)) {
1b5d6b1afc9c3dc696b7b45f2d73b2634f42800aSumit Bose user_cert = ldb_msg_find_element(msg, OVERRIDE_PREFIX SYSDB_USER_CERT);
1b5d6b1afc9c3dc696b7b45f2d73b2634f42800aSumit Bose if (user_cert != NULL) {
1b5d6b1afc9c3dc696b7b45f2d73b2634f42800aSumit Bose ret = get_valid_certs_keys(elements, ssh_ctx, user_cert,
1b5d6b1afc9c3dc696b7b45f2d73b2634f42800aSumit Bose &elements[i]);
1b5d6b1afc9c3dc696b7b45f2d73b2634f42800aSumit Bose if (ret != EOK) {
1b5d6b1afc9c3dc696b7b45f2d73b2634f42800aSumit Bose DEBUG(SSSDBG_OP_FAILURE, "get_valid_certs_keys failed.\n");
1b5d6b1afc9c3dc696b7b45f2d73b2634f42800aSumit Bose goto done;
1b5d6b1afc9c3dc696b7b45f2d73b2634f42800aSumit Bose }
1b5d6b1afc9c3dc696b7b45f2d73b2634f42800aSumit Bose
1b5d6b1afc9c3dc696b7b45f2d73b2634f42800aSumit Bose if (elements[i] != NULL) {
1b5d6b1afc9c3dc696b7b45f2d73b2634f42800aSumit Bose elements[i]->flags |= SSS_EL_FLAG_BIN_DATA;
1b5d6b1afc9c3dc696b7b45f2d73b2634f42800aSumit Bose num_keys += elements[i]->num_values;
1b5d6b1afc9c3dc696b7b45f2d73b2634f42800aSumit Bose i++;
1b5d6b1afc9c3dc696b7b45f2d73b2634f42800aSumit Bose }
1b5d6b1afc9c3dc696b7b45f2d73b2634f42800aSumit Bose }
1b5d6b1afc9c3dc696b7b45f2d73b2634f42800aSumit Bose }
1b5d6b1afc9c3dc696b7b45f2d73b2634f42800aSumit Bose
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina *_elements = elements;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina *_num_keys = num_keys;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina ret = EOK;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březinadone:
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (ret != EOK) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina talloc_free(elements);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina return ret;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina}
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březinastatic errno_t
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březinassh_get_name(struct ldb_message *msg,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina struct sized_string *sz_name)
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina{
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina const char *name;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (name == NULL) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina DEBUG(SSSDBG_OP_FAILURE, "Got unnamed result!\n");
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina return ENOENT;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina to_sized_string(sz_name, name);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina return EOK;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina}
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březinaerrno_t
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březinassh_protocol_build_reply(struct sss_packet *packet,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina struct ssh_ctx *ssh_ctx,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina struct cache_req_result *result)
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina{
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina TALLOC_CTX *tmp_ctx;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina struct ldb_message_element **elements;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina struct sized_string name;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina uint32_t num_keys;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina size_t body_len;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina uint8_t *body;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina size_t c = 0;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina errno_t ret;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina int i;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina tmp_ctx = talloc_new(NULL);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (tmp_ctx == NULL) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n");
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina return ENOMEM;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina ret = ssh_get_output_keys(tmp_ctx, ssh_ctx, result->domain,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina result->msgs[0], &elements, &num_keys);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (ret != EOK) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina goto done;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina ret = ssh_get_name(result->msgs[0], &name);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (ret != EOK) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina goto done;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina ret = sss_packet_grow(packet, 2 * sizeof(uint32_t));
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (ret != EOK) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina goto done;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina sss_packet_get_body(packet, &body, &body_len);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina SAFEALIGN_SET_UINT32(&body[c], num_keys, &c);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina SAFEALIGN_SET_UINT32(&body[c], 0, &c);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (num_keys == 0) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina ret = EOK;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina goto done;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina for (i = 0; elements[i] != NULL; i++) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina ret = decode_and_add_base64_data(packet, elements[i], false,
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina name.len, name.str, &c);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina if (ret != EOK) {
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina DEBUG(SSSDBG_OP_FAILURE, "decode_and_add_base64_data failed.\n");
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina goto done;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina }
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina ret = EOK;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březinadone:
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina talloc_free(tmp_ctx);
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina return ret;
a8191ce7ad5364801ad9458c3194075a7ca77b8aPavel Březina}