local.c revision e625eb47a3091d92eda2271b123f8aab06227b63
b355dcb54194f498921743ca33304eac35d89718Stephen Gallagher/*
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan SSSD
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan Secrets Responder
b355dcb54194f498921743ca33304eac35d89718Stephen Gallagher
b355dcb54194f498921743ca33304eac35d89718Stephen Gallagher Copyright (C) Simo Sorce <ssorce@redhat.com> 2016
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan This program is free software; you can redistribute it and/or modify
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan it under the terms of the GNU General Public License as published by
b355dcb54194f498921743ca33304eac35d89718Stephen Gallagher the Free Software Foundation; either version 3 of the License, or
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan (at your option) any later version.
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek This program is distributed in the hope that it will be useful,
e59e09b5010f262228bbdeb92a79b733bf5854b3Stephen Gallagher but WITHOUT ANY WARRANTY; without even the implied warranty of
b355dcb54194f498921743ca33304eac35d89718Stephen Gallagher MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher GNU General Public License for more details.
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan You should have received a copy of the GNU General Public License
b355dcb54194f498921743ca33304eac35d89718Stephen Gallagher along with this program. If not, see <http://www.gnu.org/licenses/>.
b355dcb54194f498921743ca33304eac35d89718Stephen Gallagher*/
7a14e8f66c0e932fe2954d792614a3b61d444bd1Jakub Hrozek
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan#include "responder/secrets/secsrv_private.h"
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher#include "util/crypto/sss_crypto.h"
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher#include <ldb.h>
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozek#define MKEY_SIZE (256 / 8)
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozek
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozekstruct local_context {
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozek struct ldb_context *ldb;
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozek struct sec_data master_key;
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher};
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivanint local_decrypt(struct local_context *lctx, TALLOC_CTX *mem_ctx,
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan const char *secret, const char *enctype,
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher char **plain_secret)
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan{
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan char *output;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (enctype && strcmp(enctype, "masterkey") == 0) {
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher struct sec_data _secret;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher size_t outlen;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher int ret;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher _secret.data = (char *)sss_base64_decode(mem_ctx, secret,
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozek &_secret.length);
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (!_secret.data) return EINVAL;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan ret = sss_decrypt(mem_ctx, AES256CBC_HMAC_SHA256,
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher (uint8_t *)lctx->master_key.data,
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan lctx->master_key.length,
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan (uint8_t *)_secret.data, _secret.length,
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan (uint8_t **)&output, &outlen);
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (ret) return ret;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (((strnlen(output, outlen) + 1) != outlen) ||
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan output[outlen - 1] != '\0') {
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher return EIO;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher }
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher } else {
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan output = talloc_strdup(mem_ctx, secret);
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher if (!output) return ENOMEM;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher }
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan *plain_secret = output;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher return EOK;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher}
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozekint local_encrypt(struct local_context *lctx, TALLOC_CTX *mem_ctx,
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozek const char *secret, const char *enctype,
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozek char **ciphertext)
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozek{
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozek struct sec_data _secret;
2ea6196484055397cc4bc011c5960f790431fa9dStephen Gallagher char *output;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan int ret;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (!enctype || strcmp(enctype, "masterkey") != 0) return EINVAL;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan ret = sss_encrypt(mem_ctx, AES256CBC_HMAC_SHA256,
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan (uint8_t *)lctx->master_key.data,
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan lctx->master_key.length,
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan (const uint8_t *)secret, strlen(secret) + 1,
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan (uint8_t **)&_secret.data, &_secret.length);
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan if (ret) return ret;
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan output = sss_base64_encode(mem_ctx,
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher (uint8_t *)_secret.data, _secret.length);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!output) return ENOMEM;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher *ciphertext = output;
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozek return EOK;
ea929f1b022fc2cb77dec89b0e12accef983ec85Jakub Hrozek}
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivanint local_db_dn(TALLOC_CTX *mem_ctx,
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan struct ldb_context *ldb,
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher const char *req_path,
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan struct ldb_dn **req_dn)
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan{
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher struct ldb_dn *dn;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher const char *s, *e;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan int ret;
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher dn = ldb_dn_new(mem_ctx, ldb, "cn=secrets");
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (!dn) {
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher ret = ENOMEM;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan goto done;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan }
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher s = req_path;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan while (s && *s) {
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher e = strchr(s, '/');
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher if (e) {
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan if (e == s) {
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan s++;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher continue;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan }
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (!ldb_dn_add_child_fmt(dn, "cn=%.*s", (int)(e - s), s)) {
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher ret = ENOMEM;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher goto done;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan }
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher s = e + 1;
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher } else {
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (!ldb_dn_add_child_fmt(dn, "cn=%s", s)) {
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher ret = ENOMEM;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan goto done;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan }
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher s = NULL;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher }
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan }
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher *req_dn = dn;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan ret = EOK;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivandone:
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan return ret;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan}
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagherchar *local_dn_to_path(TALLOC_CTX *mem_ctx,
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher struct ldb_dn *basedn,
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozek struct ldb_dn *dn)
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan{
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan int basecomps;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan int dncomps;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher char *path = NULL;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher
65a9065538fd85e6ead925d344e6b421900eb8c2Jakub Hrozek basecomps = ldb_dn_get_comp_num(basedn);
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan dncomps = ldb_dn_get_comp_num(dn);
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan for (int i = dncomps - basecomps; i > 0; i--) {
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher const struct ldb_val *val;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek val = ldb_dn_get_component_val(dn, i - 1);
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (!val) return NULL;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (path) {
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher path = talloc_strdup_append_buffer(path, "/");
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (!path) return NULL;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan path = talloc_strndup_append_buffer(path, (char *)val->data,
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan val->length);
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan } else {
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher path = talloc_strndup(mem_ctx, (char *)val->data, val->length);
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan }
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (!path) return NULL;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan }
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher return path;
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher}
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivanint local_db_get_simple(TALLOC_CTX *mem_ctx,
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan struct local_context *lctx,
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher const char *req_path,
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher char **secret)
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan{
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan TALLOC_CTX *tmp_ctx;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher static const char *attrs[] = { "secret", "enctype", NULL };
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan const char *filter = "(type=simple)";
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan struct ldb_result *res;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan struct ldb_dn *dn;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan const char *attr_secret;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher const char *attr_enctype;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher int ret;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan tmp_ctx = talloc_new(mem_ctx);
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan if (!tmp_ctx) return ENOMEM;
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher ret = local_db_dn(tmp_ctx, lctx->ldb, req_path, &dn);
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher if (ret != EOK) goto done;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE,
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan attrs, "%s", filter);
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (ret != EOK) {
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan ret = ENOENT;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan goto done;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan }
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan switch (res->count) {
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan case 0:
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher ret = ENOENT;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan goto done;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan case 1:
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan break;
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher default:
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan ret = E2BIG;
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher goto done;
7797e361155f7ce937085fd98e360469d7baf1b6Jakub Hrozek }
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher attr_secret = ldb_msg_find_attr_as_string(res->msgs[0], "secret", NULL);
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher if (!attr_secret) {
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan ret = ENOENT;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan goto done;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan }
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher attr_enctype = ldb_msg_find_attr_as_string(res->msgs[0], "enctype", NULL);
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (attr_enctype) {
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher ret = local_decrypt(lctx, mem_ctx, attr_secret, attr_enctype, secret);
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher if (ret) goto done;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan } else {
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan *secret = talloc_strdup(mem_ctx, attr_secret);
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan }
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan ret = EOK;
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivandone:
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan talloc_free(tmp_ctx);
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan return ret;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher}
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivanint local_db_list_keys(TALLOC_CTX *mem_ctx,
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan struct local_context *lctx,
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan const char *req_path,
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher char ***_keys,
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher int *num_keys)
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan{
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan TALLOC_CTX *tmp_ctx;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan static const char *attrs[] = { "secret", NULL };
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher const char *filter = "(type=simple)";
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek struct ldb_result *res;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan struct ldb_dn *dn;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan char **keys;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan int ret;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher tmp_ctx = talloc_new(mem_ctx);
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (!tmp_ctx) return ENOMEM;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan ret = local_db_dn(tmp_ctx, lctx->ldb, req_path, &dn);
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher if (ret != EOK) goto done;
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_SUBTREE,
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan attrs, "%s", filter);
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (ret != EOK) {
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan ret = ENOENT;
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan goto done;
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan }
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher if (res->count == 0) {
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher ret = ENOENT;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan goto done;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan }
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher keys = talloc_array(mem_ctx, char *, res->count);
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher if (!keys) {
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan ret = ENOMEM;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan goto done;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan }
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan for (unsigned i = 0; i < res->count; i++) {
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan keys[i] = local_dn_to_path(keys, dn, res->msgs[i]->dn);
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher if (!keys[i]) {
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher ret = ENOMEM;
056302a92862fda16351d7192600746746f38e5dStephen Gallagher goto done;
e59e09b5010f262228bbdeb92a79b733bf5854b3Stephen Gallagher }
e59e09b5010f262228bbdeb92a79b733bf5854b3Stephen Gallagher }
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher *_keys = keys;
056302a92862fda16351d7192600746746f38e5dStephen Gallagher *num_keys = res->count;
e59e09b5010f262228bbdeb92a79b733bf5854b3Stephen Gallagher ret = EOK;
e59e09b5010f262228bbdeb92a79b733bf5854b3Stephen Gallagher
7797e361155f7ce937085fd98e360469d7baf1b6Jakub Hrozekdone:
7797e361155f7ce937085fd98e360469d7baf1b6Jakub Hrozek talloc_free(tmp_ctx);
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan return ret;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher}
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivanint local_db_put_simple(TALLOC_CTX *mem_ctx,
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan struct local_context *lctx,
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan const char *req_path,
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher const char *secret)
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek{
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan struct ldb_message *msg;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan const char *enctype = "masterkey";
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan char *enc_secret;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan int ret;
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher msg = ldb_msg_new(mem_ctx);
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher if (!msg) {
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan ret = ENOMEM;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher goto done;
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek }
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan /* FIXME: verify containers (except for user's namespace) exists */
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher ret = local_encrypt(lctx, msg, secret, enctype, &enc_secret);
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher if (ret != EOK) goto done;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan ret = local_db_dn(msg, lctx->ldb, req_path, &msg->dn);
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (ret != EOK) goto done;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher ret = ldb_msg_add_string(msg, "type", "simple");
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (ret != EOK) goto done;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan ret = ldb_msg_add_string(msg, "enctype", enctype);
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (ret != EOK) goto done;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan ret = ldb_msg_add_string(msg, "secret", enc_secret);
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan if (ret != EOK) goto done;
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan ret = ldb_add(lctx->ldb, msg);
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher if (ret != EOK) {
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) ret = EEXIST;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan else ret = EIO;
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher goto done;
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek }
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan ret = EOK;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagherdone:
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher talloc_free(msg);
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan return ret;
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher}
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivanint local_db_delete(TALLOC_CTX *mem_ctx,
7797e361155f7ce937085fd98e360469d7baf1b6Jakub Hrozek struct local_context *lctx,
7797e361155f7ce937085fd98e360469d7baf1b6Jakub Hrozek const char *req_path)
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan{
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher struct ldb_dn *dn;
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek int ret;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek ret = local_db_dn(mem_ctx, lctx->ldb, req_path, &dn);
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek if (ret != EOK) goto done;
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan ret = ldb_delete(lctx->ldb, dn);
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek if (ret != EOK) {
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek ret = EIO;
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek }
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivandone:
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher return ret;
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek}
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivanint local_secrets_map_path(TALLOC_CTX *mem_ctx,
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan struct sec_req_ctx *secreq,
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher char **local_db_path)
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek{
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan int ret;
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher /* be strict for now */
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher if (secreq->parsed_url.fragment != NULL) {
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan DEBUG(SSSDBG_CRIT_FAILURE,
7797e361155f7ce937085fd98e360469d7baf1b6Jakub Hrozek "Unrecognized URI fragments: [%s]\n",
7797e361155f7ce937085fd98e360469d7baf1b6Jakub Hrozek secreq->parsed_url.fragment);
7797e361155f7ce937085fd98e360469d7baf1b6Jakub Hrozek return EINVAL;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan }
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek if (secreq->parsed_url.userinfo != NULL) {
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher DEBUG(SSSDBG_CRIT_FAILURE,
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher "Unrecognized URI userinfo: [%s]\n",
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher secreq->parsed_url.userinfo);
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher return EINVAL;
7797e361155f7ce937085fd98e360469d7baf1b6Jakub Hrozek }
7797e361155f7ce937085fd98e360469d7baf1b6Jakub Hrozek
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan /* only type simple for now */
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher if (secreq->parsed_url.query != NULL) {
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek ret = strcmp(secreq->parsed_url.query, "type=simple");
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (ret != 0) {
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan DEBUG(SSSDBG_CRIT_FAILURE,
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan "Invalid URI query: [%s]\n",
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher secreq->parsed_url.query);
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek return EINVAL;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan }
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan }
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan /* drop SEC_BASEPATH prefix */
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan *local_db_path =
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan talloc_strdup(mem_ctx, &secreq->mapped_path[sizeof(SEC_BASEPATH) - 1]);
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan if (!*local_db_path) {
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan DEBUG(SSSDBG_CRIT_FAILURE,
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan "Failed to map request to local db path\n");
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan return ENOMEM;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan }
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek return EOK;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan}
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivanstruct local_secret_state {
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan struct tevent_context *ev;
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan struct sec_req_ctx *secreq;
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan};
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagherstruct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek struct tevent_context *ev,
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan void *provider_ctx,
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan struct sec_req_ctx *secreq)
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan{
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan struct tevent_req *req;
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan struct local_secret_state *state;
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan struct local_context *lctx;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan struct sec_data body = { 0 };
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher const char *content_type;
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek bool body_is_json;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan char *req_path;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan char *secret;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan char **keys;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan int nkeys;
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan int ret;
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan req = tevent_req_create(mem_ctx, &state, struct local_secret_state);
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (!req) return NULL;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek state->ev = ev;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher state->secreq = secreq;
b355dcb54194f498921743ca33304eac35d89718Stephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher lctx = talloc_get_type(provider_ctx, struct local_context);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (!lctx) {
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek ret = EIO;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher goto done;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (sec_req_has_header(secreq, "Content-Type",
b355dcb54194f498921743ca33304eac35d89718Stephen Gallagher "application/json")) {
b355dcb54194f498921743ca33304eac35d89718Stephen Gallagher body_is_json = true;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher content_type = "application/json";
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } else if (sec_req_has_header(secreq, "Content-Type",
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek "application/octet-stream")) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher body_is_json = false;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher content_type = "application/octet-stream";
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher } else {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = EINVAL;
b355dcb54194f498921743ca33304eac35d89718Stephen Gallagher goto done;
b355dcb54194f498921743ca33304eac35d89718Stephen Gallagher }
b355dcb54194f498921743ca33304eac35d89718Stephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = local_secrets_map_path(state, secreq, &req_path);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (ret) goto done;
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher switch (secreq->method) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher case HTTP_GET:
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (req_path[strlen(req_path) - 1] == '/') {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = local_db_list_keys(state, lctx, req_path, &keys, &nkeys);
b355dcb54194f498921743ca33304eac35d89718Stephen Gallagher if (ret) goto done;
b355dcb54194f498921743ca33304eac35d89718Stephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = sec_array_to_json(state, keys, nkeys, &body.data);
e59e09b5010f262228bbdeb92a79b733bf5854b3Stephen Gallagher if (ret) goto done;
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek body.length = strlen(body.data);
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek break;
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek }
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek ret = local_db_get_simple(state, lctx, req_path, &secret);
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek if (ret) goto done;
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek if (body_is_json) {
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek ret = sec_simple_secret_to_json(state, secret, &body.data);
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek if (ret) goto done;
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek body.length = strlen(body.data);
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek } else {
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek body.data = (void *)sss_base64_decode(state, secret, &body.length);
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek ret = body.data ? EOK : ENOMEM;
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek }
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek if (ret) goto done;
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek break;
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek case HTTP_PUT:
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek if (body_is_json) {
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek ret = sec_json_to_simple_secret(state, secreq->body.data,
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek &secret);
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek } else {
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek secret = sss_base64_encode(state, (uint8_t *)secreq->body.data,
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek secreq->body.length);
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek ret = secret ? EOK : ENOMEM;
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek }
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek if (ret) goto done;
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek ret = local_db_put_simple(state, lctx, req_path, secret);
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek if (ret) goto done;
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek break;
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek case HTTP_DELETE:
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek ret = local_db_delete(state, lctx, req_path);
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek if (ret) goto done;
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek break;
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek default:
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek ret = EINVAL;
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek goto done;
e5c33e0bd03a2deb8e5011deeb3ae93f960910eeJakub Hrozek }
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek if (body.data) {
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek ret = sec_http_reply_with_body(secreq, &secreq->reply, STATUS_200,
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek content_type, &body);
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher } else {
dd3ba5c5b7d2a9d109963ae9e6c94fff34872221Stephen Gallagher ret = sec_http_status_reply(secreq, &secreq->reply, STATUS_200);
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan }
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivandone:
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (ret != EOK) {
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan tevent_req_error(req, ret);
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher } else {
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher /* shortcircuit the request here as all called functions are
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan * synchronous and final and no further subrequests are made */
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan tevent_req_done(req);
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan }
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan return tevent_req_post(req, state->ev);
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan}
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivanint generate_master_key(const char *filename, size_t size)
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher{
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek uint8_t buf[size];
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan ssize_t rsize;
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan int ret;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan int fd;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek ret = generate_csprng_buffer(buf, size);
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (ret) return ret;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan fd = open(filename, O_CREAT|O_EXCL|O_WRONLY, 0600);
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher if (fd == -1) return errno;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan rsize = sss_atomic_io_s(fd, buf, size, false);
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan close(fd);
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher if (rsize != size) {
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher unlink(filename);
c938f4ba417328fe62eded0806b2d9ca053f34a5Stephen Gallagher return EFAULT;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan }
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek return EOK;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan}
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivanint local_secrets_provider_handle(struct sec_ctx *sctx,
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher struct provider_handle **out_handle)
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek{
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan const char *mkey = SECRETS_DB_PATH"/.secrets.mkey";
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan const char *dbpath = SECRETS_DB_PATH"/secrets.ldb";
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan struct provider_handle *handle;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher struct local_context *lctx;
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek ssize_t size;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan int mfd;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan int ret;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher handle = talloc_zero(sctx, struct provider_handle);
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek if (!handle) return ENOMEM;
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan handle->name = "LOCAL";
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan handle->fn = local_secret_req;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek lctx = talloc_zero(handle, struct local_context);
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan if (!lctx) return ENOMEM;
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan lctx->ldb = ldb_init(lctx, NULL);
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher if (!lctx->ldb) return ENOMEM;
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek ret = ldb_connect(lctx->ldb, dbpath, 0, NULL);
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek if (ret != LDB_SUCCESS) {
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek talloc_free(lctx->ldb);
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan return EIO;
f9fdc87c80f2744780c6a0f2bf5b1b57bcbb095aYuri Chornoivan }
bde69429374859acff41273c0771d2b5f5c199b1Yuri Chornoivan
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher lctx->master_key.data = talloc_size(lctx, MKEY_SIZE);
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek if (!lctx->master_key.data) return ENOMEM;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher lctx->master_key.length = MKEY_SIZE;
b355dcb54194f498921743ca33304eac35d89718Stephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = check_and_open_readonly(mkey, &mfd, 0, 0,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher S_IFREG|S_IRUSR|S_IWUSR, 0);
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek if (ret == ENOENT) {
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher ret = generate_master_key(mkey, MKEY_SIZE);
b355dcb54194f498921743ca33304eac35d89718Stephen Gallagher if (ret) return EFAULT;
b355dcb54194f498921743ca33304eac35d89718Stephen Gallagher ret = check_and_open_readonly(mkey, &mfd, 0, 0,
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher S_IFREG|S_IRUSR|S_IWUSR, 0);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher }
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek if (ret) return EFAULT;
524ceecc11f3d458eb3c1cf1489c3ff6ccb22226Jakub Hrozek
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek size = sss_atomic_io_s(mfd, lctx->master_key.data,
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek lctx->master_key.length, true);
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek close(mfd);
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher if (size < 0 || size != lctx->master_key.length) return EIO;
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher
52261fe16203dec6e6f69177c6d0a810b47d073fStephen Gallagher handle->context = lctx;
cbe7c54c2caf718bdea7ca6660ba8193d759d2d5Stephen Gallagher
6463ed1dcdd45416468b3fa178bd856b5a9ed2c3Jakub Hrozek *out_handle = handle;
e59e09b5010f262228bbdeb92a79b733bf5854b3Stephen Gallagher return EOK;
e59e09b5010f262228bbdeb92a79b733bf5854b3Stephen Gallagher}
e59e09b5010f262228bbdeb92a79b733bf5854b3Stephen Gallagher