local.c revision 7171a7584dda534dde5409f3e7f4657e845ece15
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens SSSD
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens Secrets Responder
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock Copyright (C) Simo Sorce <ssorce@redhat.com> 2016
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens This program is free software; you can redistribute it and/or modify
fa9e4066f08beec538e775443c5be79dd423fcabahrens it under the terms of the GNU General Public License as published by
fa9e4066f08beec538e775443c5be79dd423fcabahrens the Free Software Foundation; either version 3 of the License, or
fa9e4066f08beec538e775443c5be79dd423fcabahrens (at your option) any later version.
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens This program is distributed in the hope that it will be useful,
fa9e4066f08beec538e775443c5be79dd423fcabahrens but WITHOUT ANY WARRANTY; without even the implied warranty of
fa9e4066f08beec538e775443c5be79dd423fcabahrens MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
fa9e4066f08beec538e775443c5be79dd423fcabahrens GNU General Public License for more details.
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens You should have received a copy of the GNU General Public License
fa9e4066f08beec538e775443c5be79dd423fcabahrens along with this program. If not, see <http://www.gnu.org/licenses/>.
fa9e4066f08beec538e775443c5be79dd423fcabahrens*/
fa9e4066f08beec538e775443c5be79dd423fcabahrens
27dd1e87cd3d939264769dd4af7e6a529cde001fMark Shellenbaum#include "responder/secrets/secsrv_private.h"
be6fd75a69ae679453d9cda5bff3326111e6d1caMatthew Ahrens#include "util/crypto/sss_crypto.h"
1eb4e906ec75b9bde421954ace46ef137b0fc9ebKevin Crowe#include <time.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <ldb.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define MKEY_SIZE (256 / 8)
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstruct local_context {
fa9e4066f08beec538e775443c5be79dd423fcabahrens struct ldb_context *ldb;
fa9e4066f08beec538e775443c5be79dd423fcabahrens struct sec_data master_key;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int containers_nest_level;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int max_secrets;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int max_payload_size;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw};
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int local_decrypt(struct local_context *lctx, TALLOC_CTX *mem_ctx,
fa9e4066f08beec538e775443c5be79dd423fcabahrens const char *secret, const char *enctype,
fa9e4066f08beec538e775443c5be79dd423fcabahrens char **plain_secret)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens char *output;
169cdae232f15e542d6af0a9ce30c3f84222bc0fmarks
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (enctype && strcmp(enctype, "masterkey") == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens DEBUG(SSSDBG_TRACE_INTERNAL, "Decrypting with masterkey\n");
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens struct sec_data _secret;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw size_t outlen;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ret;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens _secret.data = (char *)sss_base64_decode(mem_ctx, secret,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &_secret.length);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (!_secret.data) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens DEBUG(SSSDBG_OP_FAILURE, "sss_base64_decode failed\n");
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum return EINVAL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = sss_decrypt(mem_ctx, AES256CBC_HMAC_SHA256,
fa9e4066f08beec538e775443c5be79dd423fcabahrens (uint8_t *)lctx->master_key.data,
fa9e4066f08beec538e775443c5be79dd423fcabahrens lctx->master_key.length,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (uint8_t *)_secret.data, _secret.length,
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum (uint8_t **)&output, &outlen);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ret) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens DEBUG(SSSDBG_OP_FAILURE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "sss_decrypt failed [%d]: %s\n", ret, sss_strerror(ret));
fa9e4066f08beec538e775443c5be79dd423fcabahrens return ret;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (((strnlen(output, outlen) + 1) != outlen) ||
fa9e4066f08beec538e775443c5be79dd423fcabahrens output[outlen - 1] != '\0') {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_CRIT_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Output length mismatch or output not NULL-terminated\n");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return EIO;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw output = talloc_strdup(mem_ctx, secret);
f52e0e2bdbf77acd45e060be155f7a484e1bf1f9Mark Shellenbaum if (!output) return ENOMEM;
f52e0e2bdbf77acd45e060be155f7a484e1bf1f9Mark Shellenbaum }
f52e0e2bdbf77acd45e060be155f7a484e1bf1f9Mark Shellenbaum
f52e0e2bdbf77acd45e060be155f7a484e1bf1f9Mark Shellenbaum *plain_secret = output;
fa9e4066f08beec538e775443c5be79dd423fcabahrens return EOK;
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int local_encrypt(struct local_context *lctx, TALLOC_CTX *mem_ctx,
fa9e4066f08beec538e775443c5be79dd423fcabahrens const char *secret, const char *enctype,
fa9e4066f08beec538e775443c5be79dd423fcabahrens char **ciphertext)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens struct sec_data _secret;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *output;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ret;
b3d141f8c7a5335d670721a81f797b1834ee327bmarks
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (enctype == NULL) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_CRIT_FAILURE, "No encryption type\n");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return EINVAL;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (strcmp(enctype, "masterkey") != 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_CRIT_FAILURE, "Uknown encryption type '%s'\n", enctype);
4929fd5ef3f018b490359eb4a2d95d22152325fbTim Haley return EINVAL;
4929fd5ef3f018b490359eb4a2d95d22152325fbTim Haley }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = sss_encrypt(mem_ctx, AES256CBC_HMAC_SHA256,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (uint8_t *)lctx->master_key.data,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw lctx->master_key.length,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (const uint8_t *)secret, strlen(secret) + 1,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (uint8_t **)&_secret.data, &_secret.length);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_OP_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "sss_encrypt failed [%d]: %s\n", ret, sss_strerror(ret));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return ret;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw output = sss_base64_encode(mem_ctx,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (uint8_t *)_secret.data, _secret.length);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (!output) return ENOMEM;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *ciphertext = output;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return EOK;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int local_db_dn(TALLOC_CTX *mem_ctx,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct ldb_context *ldb,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw const char *req_path,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct ldb_dn **req_dn)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct ldb_dn *dn;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw const char *s, *e;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int ret;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw dn = ldb_dn_new(mem_ctx, ldb, "cn=secrets");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (!dn) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = ENOMEM;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw s = req_path;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (s && *s) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw e = strchr(s, '/');
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (e) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (e == s) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw s++;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw continue;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (!ldb_dn_add_child_fmt(dn, "cn=%.*s", (int)(e - s), s)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = ENOMEM;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw s = e + 1;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (!ldb_dn_add_child_fmt(dn, "cn=%s", s)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = ENOMEM;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw s = NULL;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_TRACE_INTERNAL,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Local path for [%s] is [%s]\n",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw req_path, ldb_dn_get_linearized(dn));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *req_dn = dn;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = EOK;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwdone:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return ret;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic char *local_dn_to_path(TALLOC_CTX *mem_ctx,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct ldb_dn *basedn,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct ldb_dn *dn)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int basecomps;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int dncomps;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *path = NULL;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw basecomps = ldb_dn_get_comp_num(basedn);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw dncomps = ldb_dn_get_comp_num(dn);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw for (int i = dncomps - basecomps; i > 0; i--) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw const struct ldb_val *val;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw val = ldb_dn_get_component_val(dn, i - 1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (!val) return NULL;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (path) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw path = talloc_strdup_append_buffer(path, "/");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (!path) return NULL;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw path = talloc_strndup_append_buffer(path, (char *)val->data,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw val->length);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw path = talloc_strndup(mem_ctx, (char *)val->data, val->length);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (!path) return NULL;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_TRACE_INTERNAL,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Secrets path for [%s] is [%s]\n",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ldb_dn_get_linearized(dn), path);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return path;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#define LOCAL_SIMPLE_FILTER "(type=simple)"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#define LOCAL_CONTAINER_FILTER "(type=container)"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int local_db_get_simple(TALLOC_CTX *mem_ctx,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct local_context *lctx,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw const char *req_path,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char **secret)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw TALLOC_CTX *tmp_ctx;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw static const char *attrs[] = { "secret", "enctype", NULL };
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct ldb_result *res;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct ldb_dn *dn;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw const char *attr_secret;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw const char *attr_enctype;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int ret;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_TRACE_FUNC, "Retrieving a secret from [%s]\n", req_path);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tmp_ctx = talloc_new(mem_ctx);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (!tmp_ctx) return ENOMEM;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = local_db_dn(tmp_ctx, lctx->ldb, req_path, &dn);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret != EOK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_OP_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "local_db_dn failed [%d]: %s\n", ret, sss_strerror(ret));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_TRACE_INTERNAL,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Searching for [%s] at [%s] with scope=base\n",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw LOCAL_SIMPLE_FILTER, ldb_dn_get_linearized(dn));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw attrs, "%s", LOCAL_SIMPLE_FILTER);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret != EOK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_TRACE_LIBS,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "ldb_search returned [%d]: %s\n", ret, ldb_strerror(ret));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = ENOENT;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (res->count) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case 0:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_TRACE_LIBS, "No secret found\n");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = ENOENT;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case 1:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw default:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_OP_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Too many secrets returned with BASE search\n");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = E2BIG;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw attr_secret = ldb_msg_find_attr_as_string(res->msgs[0], "secret", NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (!attr_secret) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_CRIT_FAILURE, "The 'secret' attribute is missing\n");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = ENOENT;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw attr_enctype = ldb_msg_find_attr_as_string(res->msgs[0], "enctype", NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (attr_enctype) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = local_decrypt(lctx, mem_ctx, attr_secret, attr_enctype, secret);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret) goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
1ab996781aab376b5ee79af025ab24ff42a0a3f0Mark Shellenbaum *secret = talloc_strdup(mem_ctx, attr_secret);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = EOK;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwdone:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw talloc_free(tmp_ctx);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return ret;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int local_db_list_keys(TALLOC_CTX *mem_ctx,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct local_context *lctx,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw const char *req_path,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char ***_keys,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int *num_keys)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw TALLOC_CTX *tmp_ctx;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw static const char *attrs[] = { "secret", NULL };
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct ldb_result *res;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct ldb_dn *dn;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char **keys;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int ret;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tmp_ctx = talloc_new(mem_ctx);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (!tmp_ctx) return ENOMEM;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_TRACE_FUNC, "Listing keys at [%s]\n", req_path);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = local_db_dn(tmp_ctx, lctx->ldb, req_path, &dn);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret != EOK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_OP_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "local_db_dn failed [%d]: %s\n", ret, sss_strerror(ret));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_TRACE_INTERNAL,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Searching for [%s] at [%s] with scope=subtree\n",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw LOCAL_SIMPLE_FILTER, ldb_dn_get_linearized(dn));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_SUBTREE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw attrs, "%s", LOCAL_SIMPLE_FILTER);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret != EOK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_TRACE_LIBS,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "ldb_search returned [%d]: %s\n", ret, ldb_strerror(ret));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = ENOENT;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (res->count == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_TRACE_LIBS, "No secrets found\n");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = ENOENT;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw keys = talloc_array(mem_ctx, char *, res->count);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (!keys) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = ENOMEM;
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum goto done;
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum }
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum for (unsigned i = 0; i < res->count; i++) {
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum keys[i] = local_dn_to_path(keys, dn, res->msgs[i]->dn);
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum if (!keys[i]) {
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum ret = ENOMEM;
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum goto done;
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum }
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum }
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum *_keys = keys;
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum DEBUG(SSSDBG_TRACE_LIBS, "Returning %d secrets\n", res->count);
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum *num_keys = res->count;
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum ret = EOK;
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaumdone:
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum talloc_free(tmp_ctx);
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum return ret;
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum}
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaumstatic int local_db_check_containers(TALLOC_CTX *mem_ctx,
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum struct local_context *lctx,
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum struct ldb_dn *leaf_dn)
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum{
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum TALLOC_CTX *tmp_ctx;
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum static const char *attrs[] = { NULL};
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum struct ldb_result *res = NULL;
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum struct ldb_dn *dn;
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum int num;
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum int ret;
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum tmp_ctx = talloc_new(mem_ctx);
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum if (!tmp_ctx) return ENOMEM;
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum dn = ldb_dn_copy(tmp_ctx, leaf_dn);
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum if (!dn) {
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum ret = ENOMEM;
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum goto done;
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum }
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum /* We need to exclude the leaf as that will be the new child entry,
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum * We also do not care for the synthetic containers that constitute the
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum * base path (cn=<uidnumber>,cn=users,cn=secrets), so in total we remove
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum * 4 components */
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum num = ldb_dn_get_comp_num(dn) - 4;
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum for (int i = 0; i < num; i++) {
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum /* remove the child first (we do not want to check the leaf) */
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum if (!ldb_dn_remove_child_components(dn, 1)) return EFAULT;
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum /* and check the parent container exists */
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum DEBUG(SSSDBG_TRACE_INTERNAL,
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum "Searching for [%s] at [%s] with scope=base\n",
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum LOCAL_CONTAINER_FILTER, ldb_dn_get_linearized(dn));
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE,
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum attrs, LOCAL_CONTAINER_FILTER);
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum if (ret != LDB_SUCCESS || res->count != 1) {
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum DEBUG(SSSDBG_TRACE_LIBS,
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum "DN [%s] does not exist\n", ldb_dn_get_linearized(dn));
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum return ENOENT;
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum }
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum }
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum ret = EOK;
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaumdone:
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum talloc_free(tmp_ctx);
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum return ret;
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum}
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaumstatic int local_db_check_containers_nest_level(struct local_context *lctx,
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum struct ldb_dn *leaf_dn)
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum{
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum int nest_level;
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum /* We need do not care for the synthetic containers that constitute the
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum * base path (cn=<uidnumber>,cn=user,cn=secrets). */
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum nest_level = ldb_dn_get_comp_num(leaf_dn) - 3;
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum if (nest_level > lctx->containers_nest_level) {
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum DEBUG(SSSDBG_OP_FAILURE,
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum "Cannot create a nested container of depth %d as the maximum"
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum "allowed number of nested containers is %d.\n",
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum nest_level, lctx->containers_nest_level);
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum return ERR_SEC_INVALID_CONTAINERS_NEST_LEVEL;
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum }
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum return EOK;
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum}
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaumstatic int local_db_check_number_of_secrets(TALLOC_CTX *mem_ctx,
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum struct local_context *lctx)
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum{
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum TALLOC_CTX *tmp_ctx;
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum static const char *attrs[] = { NULL };
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum struct ldb_result *res = NULL;
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum struct ldb_dn *dn;
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum int ret;
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum tmp_ctx = talloc_new(mem_ctx);
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum if (!tmp_ctx) return ENOMEM;
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum dn = ldb_dn_new(tmp_ctx, lctx->ldb, "cn=secrets");
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum if (!dn) {
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum ret = ENOMEM;
1412a1a223b7a94990edf5114c108b0a29c3f881Mark Shellenbaum goto done;
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum }
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_SUBTREE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw attrs, LOCAL_SIMPLE_FILTER);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (res->count >= lctx->max_secrets) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_OP_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Cannot store any more secrets as the maximum allowed limit (%d) "
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "has been reached\n", lctx->max_secrets);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = ERR_SEC_INVALID_TOO_MANY_SECRETS;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = EOK;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwdone:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw talloc_free(tmp_ctx);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return ret;
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int local_check_max_payload_size(struct local_context *lctx,
fa9e4066f08beec538e775443c5be79dd423fcabahrens int payload_size)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens int max_payload_size;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw max_payload_size = lctx->max_payload_size * 1024; /* kb */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (payload_size > max_payload_size) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_OP_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Secrets' payload size [%d kb (%d)] exceeds the maximum allowed "
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "payload size [%d kb (%d)]\n",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw payload_size * 1024, /* kb */
fa9e4066f08beec538e775443c5be79dd423fcabahrens payload_size,
fa9e4066f08beec538e775443c5be79dd423fcabahrens lctx->max_payload_size, /* kb */
fa9e4066f08beec538e775443c5be79dd423fcabahrens max_payload_size);
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return ERR_SEC_PAYLOAD_SIZE_IS_TOO_LARGE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return EOK;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int local_db_put_simple(TALLOC_CTX *mem_ctx,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct local_context *lctx,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw const char *req_path,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw const char *secret)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct ldb_message *msg;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw const char *enctype = "masterkey";
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *enc_secret;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int ret;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw msg = ldb_msg_new(mem_ctx);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (!msg) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = ENOMEM;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_TRACE_FUNC, "Adding a secret to [%s]\n", req_path);
2459a9eaca6b6525c76289d22ffe4c96be1956d6marks
2459a9eaca6b6525c76289d22ffe4c96be1956d6marks ret = local_db_dn(msg, lctx->ldb, req_path, &msg->dn);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ret != EOK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_OP_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "local_db_dn failed [%d]: %s\n", ret, sss_strerror(ret));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* make sure containers exist */
2459a9eaca6b6525c76289d22ffe4c96be1956d6marks ret = local_db_check_containers(msg, lctx, msg->dn);
2459a9eaca6b6525c76289d22ffe4c96be1956d6marks if (ret != EOK) {
2459a9eaca6b6525c76289d22ffe4c96be1956d6marks DEBUG(SSSDBG_OP_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "local_db_check_containers failed for [%s]: [%d]: %s\n",
2459a9eaca6b6525c76289d22ffe4c96be1956d6marks ldb_dn_get_linearized(msg->dn), ret, sss_strerror(ret));
2459a9eaca6b6525c76289d22ffe4c96be1956d6marks goto done;
2459a9eaca6b6525c76289d22ffe4c96be1956d6marks }
2459a9eaca6b6525c76289d22ffe4c96be1956d6marks
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = local_db_check_number_of_secrets(msg, lctx);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ret != EOK) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens DEBUG(SSSDBG_OP_FAILURE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "local_db_check_number_of_secrets failed [%d]: %s\n",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret, sss_strerror(ret));
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum goto done;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = local_check_max_payload_size(lctx, strlen(secret));
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum if (ret != EOK) {
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum DEBUG(SSSDBG_OP_FAILURE,
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum "local_check_max_payload_size failed [%d]: %s\n",
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum ret, sss_strerror(ret));
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum goto done;
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum }
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum ret = local_encrypt(lctx, msg, secret, enctype, &enc_secret);
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum if (ret != EOK) {
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum DEBUG(SSSDBG_OP_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "local_encrypt failed [%d]: %s\n", ret, sss_strerror(ret));
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum goto done;
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum ret = ldb_msg_add_string(msg, "type", "simple");
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum if (ret != EOK) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens DEBUG(SSSDBG_OP_FAILURE,
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum "ldb_msg_add_string failed adding type:simple [%d]: %s\n",
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum ret, sss_strerror(ret));
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum goto done;
169cdae232f15e542d6af0a9ce30c3f84222bc0fmarks }
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum
169cdae232f15e542d6af0a9ce30c3f84222bc0fmarks ret = ldb_msg_add_string(msg, "enctype", enctype);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ret != EOK) {
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum DEBUG(SSSDBG_OP_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "ldb_msg_add_string failed adding enctype [%d]: %s\n",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret, sss_strerror(ret));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = ldb_msg_add_string(msg, "secret", enc_secret);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret != EOK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_OP_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "ldb_msg_add_string failed adding secret [%d]: %s\n",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret, sss_strerror(ret));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum ret = ldb_msg_add_fmt(msg, "creationTime", "%lu", time(NULL));
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum if (ret != EOK) {
b249c65cf0a7400e86a36ddab5c3fce085809859marks DEBUG(SSSDBG_OP_FAILURE,
b249c65cf0a7400e86a36ddab5c3fce085809859marks "ldb_msg_add_string failed adding creationTime [%d]: %s\n",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret, sss_strerror(ret));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = ldb_add(lctx->ldb, msg);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret != EOK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_OP_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Secret %s already exists\n", ldb_dn_get_linearized(msg->dn));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = EEXIST;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_CRIT_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Failed to add secret [%s]: [%d]: %s\n",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ldb_dn_get_linearized(msg->dn), ret, ldb_strerror(ret));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = EIO;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum ret = EOK;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwdone:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw talloc_free(msg);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return ret;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int local_db_delete(TALLOC_CTX *mem_ctx,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct local_context *lctx,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw const char *req_path)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw TALLOC_CTX *tmp_ctx;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct ldb_dn *dn;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw static const char *attrs[] = { NULL };
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct ldb_result *res;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int ret;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_TRACE_FUNC, "Removing a secret from [%s]\n", req_path);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw tmp_ctx = talloc_new(mem_ctx);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (!tmp_ctx) return ENOMEM;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = local_db_dn(mem_ctx, lctx->ldb, req_path, &dn);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret != EOK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_OP_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "local_db_dn failed [%d]: %s\n", ret, sss_strerror(ret));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_TRACE_INTERNAL,
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum "Searching for [%s] at [%s] with scope=base\n",
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum LOCAL_CONTAINER_FILTER, ldb_dn_get_linearized(dn));
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE,
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum attrs, LOCAL_CONTAINER_FILTER);
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum if (ret != EOK) {
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum DEBUG(SSSDBG_TRACE_LIBS,
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum "ldb_search returned %d: %s\n", ret, ldb_strerror(ret));
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum goto done;
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum }
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum if (res->count == 1) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_TRACE_INTERNAL,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Searching for children of [%s]\n", ldb_dn_get_linearized(dn));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_ONELEVEL,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw attrs, NULL);
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum if (ret != EOK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_TRACE_LIBS,
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum "ldb_search returned %d: %s\n", ret, ldb_strerror(ret));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (res->count > 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = EEXIST;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_OP_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Failed to remove '%s': Container is not empty\n",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ldb_dn_get_linearized(dn));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = ldb_delete(lctx->ldb, dn);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret != EOK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_TRACE_LIBS,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "ldb_delete returned %d: %s\n", ret, ldb_strerror(ret));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* fallthrough */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = sysdb_error_to_errno(ret);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwdone:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw talloc_free(tmp_ctx);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return ret;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int local_db_create(TALLOC_CTX *mem_ctx,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct local_context *lctx,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw const char *req_path)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct ldb_message *msg;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int ret;
89459e17032b6bb1d59eebd2b7c0d06859d4657cMark Shellenbaum
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum msg = ldb_msg_new(mem_ctx);
89459e17032b6bb1d59eebd2b7c0d06859d4657cMark Shellenbaum if (!msg) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = ENOMEM;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_TRACE_FUNC, "Creating a container at [%s]\n", req_path);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = local_db_dn(msg, lctx->ldb, req_path, &msg->dn);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret != EOK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_OP_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "local_db_dn failed [%d]: %s\n", ret, sss_strerror(ret));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* make sure containers exist */
4c841f6070b4f88f9dc008de526b313bbebd4e32marks ret = local_db_check_containers(msg, lctx, msg->dn);
89459e17032b6bb1d59eebd2b7c0d06859d4657cMark Shellenbaum if (ret != EOK) {
89459e17032b6bb1d59eebd2b7c0d06859d4657cMark Shellenbaum DEBUG(SSSDBG_OP_FAILURE,
89459e17032b6bb1d59eebd2b7c0d06859d4657cMark Shellenbaum "local_db_check_containers failed for [%s]: [%d]: %s\n",
4c841f6070b4f88f9dc008de526b313bbebd4e32marks ldb_dn_get_linearized(msg->dn), ret, sss_strerror(ret));
4c841f6070b4f88f9dc008de526b313bbebd4e32marks goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = local_db_check_containers_nest_level(lctx, msg->dn);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret != EOK) goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
be6fd75a69ae679453d9cda5bff3326111e6d1caMatthew Ahrens ret = ldb_msg_add_string(msg, "type", "container");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret != EOK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_OP_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "ldb_msg_add_string failed adding type:container [%d]: %s\n",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret, sss_strerror(ret));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = ldb_msg_add_fmt(msg, "creationTime", "%lu", time(NULL));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret != EOK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_OP_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "ldb_msg_add_string failed adding creationTime [%d]: %s\n",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret, sss_strerror(ret));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = ldb_add(lctx->ldb, msg);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret != EOK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_OP_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Secret %s already exists\n", ldb_dn_get_linearized(msg->dn));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = EEXIST;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_CRIT_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Failed to add secret [%s]: [%d]: %s\n",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ldb_dn_get_linearized(msg->dn), ret, ldb_strerror(ret));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = EIO;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = EOK;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwdone:
bda89588bd7667394a834e8a9a34612cce2ae9c3jp talloc_free(msg);
bda89588bd7667394a834e8a9a34612cce2ae9c3jp return ret;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic int local_secrets_map_path(TALLOC_CTX *mem_ctx,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct sec_req_ctx *secreq,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char **local_db_path)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int ret;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* be strict for now */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (secreq->parsed_url.fragment != NULL) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_CRIT_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Unrecognized URI fragments: [%s]\n",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw secreq->parsed_url.fragment);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return EINVAL;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (secreq->parsed_url.userinfo != NULL) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_CRIT_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Unrecognized URI userinfo: [%s]\n",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw secreq->parsed_url.userinfo);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return EINVAL;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* only type simple for now */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (secreq->parsed_url.query != NULL) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = strcmp(secreq->parsed_url.query, "type=simple");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret != 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_CRIT_FAILURE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "Invalid URI query: [%s]\n",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw secreq->parsed_url.query);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return EINVAL;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* drop SEC_BASEPATH prefix */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *local_db_path =
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw talloc_strdup(mem_ctx, &secreq->mapped_path[sizeof(SEC_BASEPATH) - 1]);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (!*local_db_path) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_CRIT_FAILURE,
1ab996781aab376b5ee79af025ab24ff42a0a3f0Mark Shellenbaum "Failed to map request to local db path\n");
e0d35c4478bf9fd4080951b5b9d1f9a38948ba69marks return ENOMEM;
e0d35c4478bf9fd4080951b5b9d1f9a38948ba69marks }
e0d35c4478bf9fd4080951b5b9d1f9a38948ba69marks
e0d35c4478bf9fd4080951b5b9d1f9a38948ba69marks DEBUG(SSSDBG_TRACE_LIBS, "Local DB path is %s\n", *local_db_path);
e0d35c4478bf9fd4080951b5b9d1f9a38948ba69marks return EOK;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
e0d35c4478bf9fd4080951b5b9d1f9a38948ba69marks
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstruct local_secret_state {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct tevent_context *ev;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct sec_req_ctx *secreq;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw};
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct tevent_context *ev,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw void *provider_ctx,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct sec_req_ctx *secreq)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct tevent_req *req;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct local_secret_state *state;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct local_context *lctx;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct sec_data body = { 0 };
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw const char *content_type;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw bool body_is_json;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *req_path;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *secret;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char **keys;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int nkeys;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int plen;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int ret;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
be6fd75a69ae679453d9cda5bff3326111e6d1caMatthew Ahrens req = tevent_req_create(mem_ctx, &state, struct local_secret_state);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (!req) return NULL;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw state->ev = ev;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw state->secreq = secreq;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw lctx = talloc_get_type(provider_ctx, struct local_context);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (!lctx) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = EIO;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
89459e17032b6bb1d59eebd2b7c0d06859d4657cMark Shellenbaum }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_TRACE_INTERNAL, "Received a local secrets request\n");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (sec_req_has_header(secreq, "Content-Type",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "application/json")) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw body_is_json = true;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw content_type = "application/json";
2459a9eaca6b6525c76289d22ffe4c96be1956d6marks } else if (sec_req_has_header(secreq, "Content-Type",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw "application/octet-stream")) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw body_is_json = false;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw content_type = "application/octet-stream";
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_OP_FAILURE, "No or uknown Content-Type\n");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = EINVAL;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_TRACE_LIBS, "Content-Type: %s\n", content_type);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = local_secrets_map_path(state, secreq, &req_path);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret) goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (secreq->method) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case HTTP_GET:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_TRACE_LIBS, "Processing HTTP GET at [%s]\n", req_path);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (req_path[strlen(req_path) - 1] == '/') {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = local_db_list_keys(state, lctx, req_path, &keys, &nkeys);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret) goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = sec_array_to_json(state, keys, nkeys, &body.data);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret) goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
89459e17032b6bb1d59eebd2b7c0d06859d4657cMark Shellenbaum body.length = strlen(body.data);
89459e17032b6bb1d59eebd2b7c0d06859d4657cMark Shellenbaum break;
89459e17032b6bb1d59eebd2b7c0d06859d4657cMark Shellenbaum }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = local_db_get_simple(state, lctx, req_path, &secret);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret) goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (body_is_json) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = sec_simple_secret_to_json(state, secret, &body.data);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret) goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2459a9eaca6b6525c76289d22ffe4c96be1956d6marks body.length = strlen(body.data);
2459a9eaca6b6525c76289d22ffe4c96be1956d6marks } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw body.data = (void *)sss_base64_decode(state, secret, &body.length);
2459a9eaca6b6525c76289d22ffe4c96be1956d6marks ret = body.data ? EOK : ENOMEM;
2459a9eaca6b6525c76289d22ffe4c96be1956d6marks }
2459a9eaca6b6525c76289d22ffe4c96be1956d6marks if (ret) goto done;
2459a9eaca6b6525c76289d22ffe4c96be1956d6marks
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case HTTP_PUT:
fa9e4066f08beec538e775443c5be79dd423fcabahrens DEBUG(SSSDBG_TRACE_LIBS, "Processing HTTP PUT at [%s]\n", req_path);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (body_is_json) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = sec_json_to_simple_secret(state, secreq->body.data,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &secret);
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens secret = sss_base64_encode(state, (uint8_t *)secreq->body.data,
fa9e4066f08beec538e775443c5be79dd423fcabahrens secreq->body.length);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = secret ? EOK : ENOMEM;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret) goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = local_db_put_simple(state, lctx, req_path, secret);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ret) goto done;
fa9e4066f08beec538e775443c5be79dd423fcabahrens break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens case HTTP_DELETE:
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = local_db_delete(state, lctx, req_path);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret) goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case HTTP_POST:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_TRACE_LIBS, "Processing HTTP POST at [%s]\n", req_path);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw plen = strlen(req_path);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (req_path[plen - 1] != '/') {
1ab996781aab376b5ee79af025ab24ff42a0a3f0Mark Shellenbaum ret = EINVAL;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens req_path[plen - 1] = '\0';
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = local_db_create(state, lctx, req_path);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret) goto done;
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum break;
27dd1e87cd3d939264769dd4af7e6a529cde001fMark Shellenbaum
27dd1e87cd3d939264769dd4af7e6a529cde001fMark Shellenbaum default:
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = EINVAL;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw goto done;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (body.data) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = sec_http_reply_with_body(secreq, &secreq->reply, STATUS_200,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw content_type, &body);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
d47621a49c68c359358f6630aa45cc320762f51fTim Haley ret = sec_http_status_reply(secreq, &secreq->reply, STATUS_200);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum
fa9e4066f08beec538e775443c5be79dd423fcabahrensdone:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret != EOK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret == ENOENT) {
29a0b7379cd3103841d05e3ed04486412049acccmarks DEBUG(SSSDBG_TRACE_LIBS, "Did not find the requested data\n");
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum } else {
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum DEBUG(SSSDBG_OP_FAILURE,
003c2582df5b8a57cb0e6f04227f93ccd982f0e5Mark Shellenbaum "Local secrets request error [%d]: %s\n",
1ab996781aab376b5ee79af025ab24ff42a0a3f0Mark Shellenbaum ret, sss_strerror(ret));
1ab996781aab376b5ee79af025ab24ff42a0a3f0Mark Shellenbaum }
29a0b7379cd3103841d05e3ed04486412049acccmarks tevent_req_error(req, ret);
de0f1ddb598506a5d9a02946b67e9300b5f2a7cdAlbert Lee } else {
29a0b7379cd3103841d05e3ed04486412049acccmarks /* shortcircuit the request here as all called functions are
de0f1ddb598506a5d9a02946b67e9300b5f2a7cdAlbert Lee * synchronous and final and no further subrequests are made */
29a0b7379cd3103841d05e3ed04486412049acccmarks DEBUG(SSSDBG_TRACE_INTERNAL, "Local secrets request done\n");
29a0b7379cd3103841d05e3ed04486412049acccmarks tevent_req_done(req);
27dd1e87cd3d939264769dd4af7e6a529cde001fMark Shellenbaum }
27dd1e87cd3d939264769dd4af7e6a529cde001fMark Shellenbaum return tevent_req_post(req, state->ev);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int generate_master_key(const char *filename, size_t size)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
fa9e4066f08beec538e775443c5be79dd423fcabahrens uint8_t buf[size];
fa9e4066f08beec538e775443c5be79dd423fcabahrens ssize_t rsize;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ret;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int fd;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = generate_csprng_buffer(buf, size);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens DEBUG(SSSDBG_OP_FAILURE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "generate_csprng_buffer failed [%d]: %s\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret, sss_strerror(ret));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return ret;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw fd = open(filename, O_CREAT|O_EXCL|O_WRONLY, 0600);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (fd == -1) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = errno;
fa9e4066f08beec538e775443c5be79dd423fcabahrens DEBUG(SSSDBG_OP_FAILURE,
27dd1e87cd3d939264769dd4af7e6a529cde001fMark Shellenbaum "open(%s) failed [%d]: %s\n",
27dd1e87cd3d939264769dd4af7e6a529cde001fMark Shellenbaum filename, ret, strerror(ret));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return ret;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rsize = sss_atomic_write_s(fd, buf, size);
fa9e4066f08beec538e775443c5be79dd423fcabahrens close(fd);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (rsize != size) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = errno;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DEBUG(SSSDBG_OP_FAILURE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "sss_atomic_write_s failed [%d]: %s\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret, strerror(ret));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = unlink(filename);
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* non-fatal failure */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ret != EOK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ret = errno;
fa9e4066f08beec538e775443c5be79dd423fcabahrens DEBUG(SSSDBG_MINOR_FAILURE,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "Failed to remove file: %s - %d [%s]!\n",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw filename, ret, sss_strerror(ret));
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens return EFAULT;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return EOK;
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwint local_secrets_provider_handle(struct sec_ctx *sctx,
fa9e4066f08beec538e775443c5be79dd423fcabahrens struct provider_handle **out_handle)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens const char *mkey = SECRETS_DB_PATH"/.secrets.mkey";
fa9e4066f08beec538e775443c5be79dd423fcabahrens const char *dbpath = SECRETS_DB_PATH"/secrets.ldb";
fa9e4066f08beec538e775443c5be79dd423fcabahrens struct provider_handle *handle;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct local_context *lctx;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ssize_t size;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int mfd;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int ret;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens DEBUG(SSSDBG_TRACE_INTERNAL, "Creating a local provider handle\n");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
fa9e4066f08beec538e775443c5be79dd423fcabahrens handle = talloc_zero(sctx, struct provider_handle);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (!handle) return ENOMEM;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens handle->name = "LOCAL";
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw handle->fn = local_secret_req;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens lctx = talloc_zero(handle, struct local_context);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (!lctx) return ENOMEM;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens lctx->ldb = ldb_init(lctx, NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (!lctx->ldb) return ENOMEM;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = ldb_connect(lctx->ldb, dbpath, 0, NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret != LDB_SUCCESS) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens DEBUG(SSSDBG_TRACE_LIBS,
fa9e4066f08beec538e775443c5be79dd423fcabahrens "ldb_connect(%s) returned %d: %s\n",
fa9e4066f08beec538e775443c5be79dd423fcabahrens dbpath, ret, ldb_strerror(ret));
fa9e4066f08beec538e775443c5be79dd423fcabahrens talloc_free(lctx->ldb);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return EIO;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens lctx->containers_nest_level = sctx->containers_nest_level;
fa9e4066f08beec538e775443c5be79dd423fcabahrens lctx->max_secrets = sctx->max_secrets;
fa9e4066f08beec538e775443c5be79dd423fcabahrens lctx->max_payload_size = sctx->max_payload_size;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
fa9e4066f08beec538e775443c5be79dd423fcabahrens lctx->master_key.data = talloc_size(lctx, MKEY_SIZE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (!lctx->master_key.data) return ENOMEM;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw lctx->master_key.length = MKEY_SIZE;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = check_and_open_readonly(mkey, &mfd, 0, 0,
fa9e4066f08beec538e775443c5be79dd423fcabahrens S_IFREG|S_IRUSR|S_IWUSR, 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ret == ENOENT) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens DEBUG(SSSDBG_TRACE_FUNC, "No master key, generating a new one..\n");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = generate_master_key(mkey, MKEY_SIZE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ret) return EFAULT;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ret = check_and_open_readonly(mkey, &mfd, 0, 0,
fa9e4066f08beec538e775443c5be79dd423fcabahrens S_IFREG|S_IRUSR|S_IWUSR, 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ret) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens DEBUG(SSSDBG_OP_FAILURE, "Cannot generate a master key: %d\n", ret);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return EFAULT;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
d47621a49c68c359358f6630aa45cc320762f51fTim Haley size = sss_atomic_read_s(mfd, lctx->master_key.data,
d47621a49c68c359358f6630aa45cc320762f51fTim Haley lctx->master_key.length);
d47621a49c68c359358f6630aa45cc320762f51fTim Haley close(mfd);
d47621a49c68c359358f6630aa45cc320762f51fTim Haley if (size < 0 || size != lctx->master_key.length) {
d47621a49c68c359358f6630aa45cc320762f51fTim Haley DEBUG(SSSDBG_OP_FAILURE, "Cannot read a master key: %d\n", ret);
d47621a49c68c359358f6630aa45cc320762f51fTim Haley return EIO;
d47621a49c68c359358f6630aa45cc320762f51fTim Haley }
d47621a49c68c359358f6630aa45cc320762f51fTim Haley
fa9e4066f08beec538e775443c5be79dd423fcabahrens handle->context = lctx;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
d47621a49c68c359358f6630aa45cc320762f51fTim Haley *out_handle = handle;
4929fd5ef3f018b490359eb4a2d95d22152325fbTim Haley DEBUG(SSSDBG_TRACE_INTERNAL, "Local provider handle created\n");
4929fd5ef3f018b490359eb4a2d95d22152325fbTim Haley return EOK;
4929fd5ef3f018b490359eb4a2d95d22152325fbTim Haley}
4929fd5ef3f018b490359eb4a2d95d22152325fbTim Haley