sssd-2.4.0.5 - improve kcm performance
This commit is contained in:
parent
e67274864c
commit
d86ed3a2a2
File diff suppressed because it is too large
Load Diff
53
0001-kcm-fix-typos-in-debug-messages.patch
Normal file
53
0001-kcm-fix-typos-in-debug-messages.patch
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
From b768a37d3f908a37f4c490a30df6559bc14c7451 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||||
|
Date: Mon, 14 Sep 2020 12:44:57 +0200
|
||||||
|
Subject: [PATCH 01/19] kcm: fix typos in debug messages
|
||||||
|
|
||||||
|
---
|
||||||
|
src/responder/kcm/kcmsrv_ccache_json.c | 2 +-
|
||||||
|
src/responder/kcm/kcmsrv_cmd.c | 2 +-
|
||||||
|
src/responder/kcm/kcmsrv_ops.c | 2 +-
|
||||||
|
3 files changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache_json.c b/src/responder/kcm/kcmsrv_ccache_json.c
|
||||||
|
index f78e9f58cee750f13d1085c3eb4a76235a4bcbb5..38ec53c408c3b9d44f37d102c4a0c976ef32bdfe 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ccache_json.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache_json.c
|
||||||
|
@@ -911,7 +911,7 @@ errno_t sec_kv_to_ccache(TALLOC_CTX *mem_ctx,
|
||||||
|
ret = sec_value_to_json(sec_value, &root);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_CRIT_FAILURE,
|
||||||
|
- "Cannot store secret to JSN [%d]: %s\n",
|
||||||
|
+ "Cannot store secret to JSON [%d]: %s\n",
|
||||||
|
ret, sss_strerror(ret));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_cmd.c b/src/responder/kcm/kcmsrv_cmd.c
|
||||||
|
index 421bf4bc5bb14d0ab9de6cd3be0e9d34d871ed9c..99980050f205730169f5907db4018e4fe57b046d 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_cmd.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_cmd.c
|
||||||
|
@@ -314,7 +314,7 @@ static void kcm_reply_error(struct cli_ctx *cctx,
|
||||||
|
krb5_error_code kerr;
|
||||||
|
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
- "KCM operation returs failure [%d]: %s\n",
|
||||||
|
+ "KCM operation returns failure [%d]: %s\n",
|
||||||
|
retcode, sss_strerror(retcode));
|
||||||
|
kerr = sss2krb5_error(retcode);
|
||||||
|
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ops.c b/src/responder/kcm/kcmsrv_ops.c
|
||||||
|
index 6ac66c15090422ae83a2f51dbc80144a315a27f4..1e8e4d6a3b4feba5bac3eb0a5fa6a22a588ba985 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ops.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ops.c
|
||||||
|
@@ -1468,7 +1468,7 @@ static void kcm_op_get_cache_by_uuid_done(struct tevent_req *subreq)
|
||||||
|
talloc_zfree(subreq);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
- "Cannot get ccahe by UUID [%d]: %s\n",
|
||||||
|
+ "Cannot get ccache by UUID [%d]: %s\n",
|
||||||
|
ret, sss_strerror(ret));
|
||||||
|
tevent_req_error(req, ret);
|
||||||
|
return;
|
||||||
|
--
|
||||||
|
2.25.4
|
||||||
|
|
@ -1,293 +0,0 @@
|
|||||||
From cb9ad222358a84e2b2ea148c2950c2389f81de2c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lukas Slebodnik <lslebodn@redhat.com>
|
|
||||||
Date: Mon, 27 Jul 2020 04:01:19 +0000
|
|
||||||
Subject: [PATCH] DEBUG-TESTS: Fix warnings format not a string literal and no
|
|
||||||
format arguments
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
e.g.
|
|
||||||
src/tests/resolv-tests.c: In function ‘test_timeout’:
|
|
||||||
src/tests/resolv-tests.c:942:5: error: format not a string literal and no format arguments [-Werror=format-security]
|
|
||||||
942 | ck_leaks_pop(tmp_ctx);
|
|
||||||
|
|
|
||||||
|
|
||||||
src/tests/debug-tests.c:413:9: error: format not a string literal and no format arguments [-Werror=format-security]
|
|
||||||
413 | fail_if(result == DEBUG_TEST_NOK_TS, msg);
|
|
||||||
| ^~~~~~~
|
|
||||||
|
|
||||||
src/tests/debug-tests.c: In function ‘test_debug_is_notset_timestamp_microseconds_fn’:
|
|
||||||
src/tests/debug-tests.c:603:13: error: format not a string literal and no format arguments [-Werror=format-security]
|
|
||||||
603 | fail(error_msg);
|
|
||||||
|
|
|
||||||
|
|
||||||
src/tests/debug-tests.c: In function ‘test_debug_is_set_false_fn’:
|
|
||||||
src/tests/debug-tests.c:671:9: error: format not a string literal and no format arguments [-Werror=format-security]
|
|
||||||
671 | fail_unless(result == 0, msg);
|
|
||||||
|
|
|
||||||
---
|
|
||||||
src/tests/common_check.h | 2 +-
|
|
||||||
src/tests/debug-tests.c | 128 +++++++++++++++------------------------
|
|
||||||
2 files changed, 49 insertions(+), 81 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/tests/common_check.h b/src/tests/common_check.h
|
|
||||||
index 51c3c3f49..ac92d0a74 100644
|
|
||||||
--- a/src/tests/common_check.h
|
|
||||||
+++ b/src/tests/common_check.h
|
|
||||||
@@ -31,6 +31,6 @@ void ck_leak_check_setup(void);
|
|
||||||
void ck_leak_check_teardown(void);
|
|
||||||
|
|
||||||
#define ck_leaks_push(ctx) check_leaks_push(ctx)
|
|
||||||
-#define ck_leaks_pop(ctx) fail_unless(check_leaks_pop(ctx) == true, check_leaks_err_msg())
|
|
||||||
+#define ck_leaks_pop(ctx) fail_unless(check_leaks_pop(ctx) == true, "%s", check_leaks_err_msg())
|
|
||||||
|
|
||||||
#endif /* __TESTS_COMMON_CHECK_H__ */
|
|
||||||
diff --git a/src/tests/debug-tests.c b/src/tests/debug-tests.c
|
|
||||||
index 1e78f506e..092ccf684 100644
|
|
||||||
--- a/src/tests/debug-tests.c
|
|
||||||
+++ b/src/tests/debug-tests.c
|
|
||||||
@@ -55,10 +55,8 @@ START_TEST(test_debug_convert_old_level_old_format)
|
|
||||||
for (old_level = 0; old_level < N_ELEMENTS(levels); old_level++) {
|
|
||||||
expected_level |= levels[old_level];
|
|
||||||
|
|
||||||
- char *msg = NULL;
|
|
||||||
- msg = talloc_asprintf(NULL, "Invalid conversion of %d", old_level);
|
|
||||||
- fail_unless(debug_convert_old_level(old_level) == expected_level, msg);
|
|
||||||
- talloc_free(msg);
|
|
||||||
+ fail_unless(debug_convert_old_level(old_level) == expected_level,
|
|
||||||
+ "Invalid conversion of %d", old_level);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
END_TEST
|
|
||||||
@@ -343,7 +341,6 @@ START_TEST(test_debug_is_set_single_no_timestamp)
|
|
||||||
SSSDBG_TRACE_ALL,
|
|
||||||
SSSDBG_TRACE_LDB
|
|
||||||
};
|
|
||||||
- char *error_msg;
|
|
||||||
|
|
||||||
debug_timestamps = 0;
|
|
||||||
debug_microseconds = 0;
|
|
||||||
@@ -357,15 +354,13 @@ START_TEST(test_debug_is_set_single_no_timestamp)
|
|
||||||
errno = 0;
|
|
||||||
result = test_helper_debug_check_message(levels[i]);
|
|
||||||
|
|
||||||
- if (result == DEBUG_TEST_ERROR) {
|
|
||||||
- error_msg = strerror(errno);
|
|
||||||
- fail(error_msg);
|
|
||||||
- }
|
|
||||||
+ fail_if(result == DEBUG_TEST_ERROR,
|
|
||||||
+ "Expecting DEBUG_TEST_ERROR, got: %d, error: %s",
|
|
||||||
+ result, strerror(errno));
|
|
||||||
|
|
||||||
- char *msg = NULL;
|
|
||||||
- msg = talloc_asprintf(NULL, "Test of level %#.4x failed - message don't match", levels[i]);
|
|
||||||
- fail_unless(result == EOK, msg);
|
|
||||||
- talloc_free(msg);
|
|
||||||
+ fail_unless(result == EOK,
|
|
||||||
+ "Test of level %#.4x failed - message don't match",
|
|
||||||
+ levels[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
END_TEST
|
|
||||||
@@ -387,7 +382,6 @@ START_TEST(test_debug_is_set_single_timestamp)
|
|
||||||
SSSDBG_TRACE_ALL,
|
|
||||||
SSSDBG_TRACE_LDB
|
|
||||||
};
|
|
||||||
- char *error_msg;
|
|
||||||
|
|
||||||
debug_timestamps = 1;
|
|
||||||
debug_microseconds = 0;
|
|
||||||
@@ -402,20 +396,16 @@ START_TEST(test_debug_is_set_single_timestamp)
|
|
||||||
errno = 0;
|
|
||||||
result = test_helper_debug_check_message(levels[i]);
|
|
||||||
|
|
||||||
- if (result == DEBUG_TEST_ERROR) {
|
|
||||||
- error_msg = strerror(errno);
|
|
||||||
- fail(error_msg);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- char *msg = NULL;
|
|
||||||
+ fail_if(result == DEBUG_TEST_ERROR,
|
|
||||||
+ "Expecting DEBUG_TEST_ERROR, got: %d, error: %s",
|
|
||||||
+ result, strerror(errno));
|
|
||||||
|
|
||||||
- msg = talloc_asprintf(NULL, "Test of level %#.4x failed - invalid timestamp", levels[i]);
|
|
||||||
- fail_if(result == DEBUG_TEST_NOK_TS, msg);
|
|
||||||
- talloc_free(msg);
|
|
||||||
+ fail_if(result == DEBUG_TEST_NOK_TS,
|
|
||||||
+ "Test of level %#.4x failed - invalid timestamp", levels[i]);
|
|
||||||
|
|
||||||
- msg = talloc_asprintf(NULL, "Test of level %#.4x failed - message don't match", levels[i]);
|
|
||||||
- fail_unless(result == EOK, msg);
|
|
||||||
- talloc_free(msg);
|
|
||||||
+ fail_unless(result == EOK,
|
|
||||||
+ "Test of level %#.4x failed - message don't match",
|
|
||||||
+ levels[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
END_TEST
|
|
||||||
@@ -437,7 +427,6 @@ START_TEST(test_debug_is_set_single_timestamp_microseconds)
|
|
||||||
SSSDBG_TRACE_ALL,
|
|
||||||
SSSDBG_TRACE_LDB
|
|
||||||
};
|
|
||||||
- char *error_msg;
|
|
||||||
|
|
||||||
debug_timestamps = 1;
|
|
||||||
debug_microseconds = 1;
|
|
||||||
@@ -452,20 +441,16 @@ START_TEST(test_debug_is_set_single_timestamp_microseconds)
|
|
||||||
errno = 0;
|
|
||||||
result = test_helper_debug_check_message(levels[i]);
|
|
||||||
|
|
||||||
- if (result == DEBUG_TEST_ERROR) {
|
|
||||||
- error_msg = strerror(errno);
|
|
||||||
- fail(error_msg);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- char *msg = NULL;
|
|
||||||
+ fail_if(result == DEBUG_TEST_ERROR,
|
|
||||||
+ "Expecting DEBUG_TEST_ERROR, got: %d, error: %s",
|
|
||||||
+ result, strerror(errno));
|
|
||||||
|
|
||||||
- msg = talloc_asprintf(NULL, "Test of level %#.4x failed - invalid timestamp", levels[i]);
|
|
||||||
- fail_if(result == DEBUG_TEST_NOK_TS, msg);
|
|
||||||
- talloc_free(msg);
|
|
||||||
+ fail_if(result == DEBUG_TEST_NOK_TS,
|
|
||||||
+ "Test of level %#.4x failed - invalid timestamp", levels[i]);
|
|
||||||
|
|
||||||
- msg = talloc_asprintf(NULL, "Test of level %#.4x failed - message don't match", levels[i]);
|
|
||||||
- fail_unless(result == EOK, msg);
|
|
||||||
- talloc_free(msg);
|
|
||||||
+ fail_unless(result == EOK,
|
|
||||||
+ "Test of level %#.4x failed - message don't match",
|
|
||||||
+ levels[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
END_TEST
|
|
||||||
@@ -488,7 +473,6 @@ START_TEST(test_debug_is_notset_no_timestamp)
|
|
||||||
SSSDBG_TRACE_ALL,
|
|
||||||
SSSDBG_TRACE_LDB
|
|
||||||
};
|
|
||||||
- char *error_msg;
|
|
||||||
|
|
||||||
debug_timestamps = 0;
|
|
||||||
debug_microseconds = 0;
|
|
||||||
@@ -503,17 +487,13 @@ START_TEST(test_debug_is_notset_no_timestamp)
|
|
||||||
errno = 0;
|
|
||||||
result = test_helper_debug_is_empty_message(levels[i]);
|
|
||||||
|
|
||||||
- if (result == DEBUG_TEST_ERROR) {
|
|
||||||
- error_msg = strerror(errno);
|
|
||||||
- fail(error_msg);
|
|
||||||
- }
|
|
||||||
+ fail_if(result == DEBUG_TEST_ERROR,
|
|
||||||
+ "Expecting DEBUG_TEST_ERROR, got: %d, error: %s",
|
|
||||||
+ result, strerror(errno));
|
|
||||||
|
|
||||||
- char *msg = NULL;
|
|
||||||
- msg = talloc_asprintf(NULL,
|
|
||||||
- "Test of level %#.4x failed - message has been written",
|
|
||||||
- levels[i]);
|
|
||||||
- fail_unless(result == EOK, msg);
|
|
||||||
- talloc_free(msg);
|
|
||||||
+ fail_unless(result == EOK,
|
|
||||||
+ "Test of level %#.4x failed - message has been written",
|
|
||||||
+ levels[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
END_TEST
|
|
||||||
@@ -536,7 +516,6 @@ START_TEST(test_debug_is_notset_timestamp)
|
|
||||||
SSSDBG_TRACE_ALL,
|
|
||||||
SSSDBG_TRACE_LDB
|
|
||||||
};
|
|
||||||
- char *error_msg;
|
|
||||||
|
|
||||||
debug_timestamps = 0;
|
|
||||||
debug_microseconds = 0;
|
|
||||||
@@ -551,17 +530,13 @@ START_TEST(test_debug_is_notset_timestamp)
|
|
||||||
errno = 0;
|
|
||||||
result = test_helper_debug_is_empty_message(levels[i]);
|
|
||||||
|
|
||||||
- if (result == DEBUG_TEST_ERROR) {
|
|
||||||
- error_msg = strerror(errno);
|
|
||||||
- fail(error_msg);
|
|
||||||
- }
|
|
||||||
+ fail_if(result == DEBUG_TEST_ERROR,
|
|
||||||
+ "Expecting DEBUG_TEST_ERROR, got: %d, error: %s",
|
|
||||||
+ result, strerror(errno));
|
|
||||||
|
|
||||||
- char *msg = NULL;
|
|
||||||
- msg = talloc_asprintf(NULL,
|
|
||||||
- "Test of level %#.4x failed - message has been written",
|
|
||||||
- levels[i]);
|
|
||||||
- fail_unless(result == EOK, msg);
|
|
||||||
- talloc_free(msg);
|
|
||||||
+ fail_unless(result == EOK,
|
|
||||||
+ "Test of level %#.4x failed - message has been written",
|
|
||||||
+ levels[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
END_TEST
|
|
||||||
@@ -584,7 +559,6 @@ START_TEST(test_debug_is_notset_timestamp_microseconds)
|
|
||||||
SSSDBG_TRACE_ALL,
|
|
||||||
SSSDBG_TRACE_LDB
|
|
||||||
};
|
|
||||||
- char *error_msg;
|
|
||||||
|
|
||||||
debug_timestamps = 0;
|
|
||||||
debug_microseconds = 1;
|
|
||||||
@@ -598,17 +572,13 @@ START_TEST(test_debug_is_notset_timestamp_microseconds)
|
|
||||||
errno = 0;
|
|
||||||
result = test_helper_debug_is_empty_message(levels[i]);
|
|
||||||
|
|
||||||
- if (result == DEBUG_TEST_ERROR) {
|
|
||||||
- error_msg = strerror(errno);
|
|
||||||
- fail(error_msg);
|
|
||||||
- }
|
|
||||||
+ fail_if(result == DEBUG_TEST_ERROR,
|
|
||||||
+ "Expecting DEBUG_TEST_ERROR, got: %d, error: %s",
|
|
||||||
+ result, strerror(errno));
|
|
||||||
|
|
||||||
- char *msg = NULL;
|
|
||||||
- msg = talloc_asprintf(NULL,
|
|
||||||
- "Test of level %#.4x failed - message has been written",
|
|
||||||
- levels[i]);
|
|
||||||
- fail_unless(result == EOK, msg);
|
|
||||||
- talloc_free(msg);
|
|
||||||
+ fail_unless(result == EOK,
|
|
||||||
+ "Test of level %#.4x failed - message has been written",
|
|
||||||
+ levels[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
END_TEST
|
|
||||||
@@ -635,10 +605,9 @@ START_TEST(test_debug_is_set_true)
|
|
||||||
|
|
||||||
for (i = 0; i < N_ELEMENTS(levels); i++) {
|
|
||||||
result = DEBUG_IS_SET(levels[i]);
|
|
||||||
- char *msg = NULL;
|
|
||||||
- msg = talloc_asprintf(NULL, "Test of level %#.4x failed - result is 0x%.4x", levels[i], result);
|
|
||||||
- fail_unless(result > 0, msg);
|
|
||||||
- talloc_free(msg);
|
|
||||||
+ fail_unless(result > 0,
|
|
||||||
+ "Test of level %#.4x failed - result is 0x%.4x",
|
|
||||||
+ levels[i], result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
END_TEST
|
|
||||||
@@ -666,10 +635,9 @@ START_TEST(test_debug_is_set_false)
|
|
||||||
debug_level = all_set & ~levels[i];
|
|
||||||
|
|
||||||
result = DEBUG_IS_SET(levels[i]);
|
|
||||||
- char *msg = NULL;
|
|
||||||
- msg = talloc_asprintf(NULL, "Test of level %#.4x failed - result is 0x%.4x", levels[i], result);
|
|
||||||
- fail_unless(result == 0, msg);
|
|
||||||
- talloc_free(msg);
|
|
||||||
+ fail_unless(result == 0,
|
|
||||||
+ "Test of level %#.4x failed - result is 0x%.4x",
|
|
||||||
+ levels[i], result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
END_TEST
|
|
||||||
--
|
|
||||||
2.28.0.rc2
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
|||||||
|
From a0e3759b733a5b5db82bea2ef35e1519ea8a9b1c Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||||
|
Date: Fri, 16 Oct 2020 15:33:42 +0200
|
||||||
|
Subject: [PATCH 02/19] kcm: avoid name confusion in GET_CRED_UUID_LIST
|
||||||
|
handlers
|
||||||
|
|
||||||
|
The function name did not follow best practices and it got easily confused
|
||||||
|
with `kcm_op_get_cred_by_uuid_getbyname_done`.
|
||||||
|
|
||||||
|
```
|
||||||
|
kcm_op_get_cred_uuid_getbyname_done
|
||||||
|
kcm_op_get_cred_by_uuid_getbyname_done
|
||||||
|
```
|
||||||
|
---
|
||||||
|
src/responder/kcm/kcmsrv_ops.c | 6 +++---
|
||||||
|
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ops.c b/src/responder/kcm/kcmsrv_ops.c
|
||||||
|
index 1e8e4d6a3b4feba5bac3eb0a5fa6a22a588ba985..7fc3b0a5c4e123a398ef103f3ce92b45bc68f5cf 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ops.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ops.c
|
||||||
|
@@ -1072,7 +1072,7 @@ static void kcm_op_get_principal_getbyname_done(struct tevent_req *subreq)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (name) -> (uuid, ...) */
|
||||||
|
-static void kcm_op_get_cred_uuid_getbyname_done(struct tevent_req *subreq);
|
||||||
|
+static void kcm_op_get_cred_uuid_list_getbyname_done(struct tevent_req *subreq);
|
||||||
|
|
||||||
|
static struct tevent_req *
|
||||||
|
kcm_op_get_cred_uuid_list_send(TALLOC_CTX *mem_ctx,
|
||||||
|
@@ -1106,7 +1106,7 @@ kcm_op_get_cred_uuid_list_send(TALLOC_CTX *mem_ctx,
|
||||||
|
ret = ENOMEM;
|
||||||
|
goto immediate;
|
||||||
|
}
|
||||||
|
- tevent_req_set_callback(subreq, kcm_op_get_cred_uuid_getbyname_done, req);
|
||||||
|
+ tevent_req_set_callback(subreq, kcm_op_get_cred_uuid_list_getbyname_done, req);
|
||||||
|
return req;
|
||||||
|
|
||||||
|
immediate:
|
||||||
|
@@ -1115,7 +1115,7 @@ immediate:
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void kcm_op_get_cred_uuid_getbyname_done(struct tevent_req *subreq)
|
||||||
|
+static void kcm_op_get_cred_uuid_list_getbyname_done(struct tevent_req *subreq)
|
||||||
|
{
|
||||||
|
errno_t ret;
|
||||||
|
struct kcm_ccache *cc;
|
||||||
|
--
|
||||||
|
2.25.4
|
||||||
|
|
509
0003-kcm-disable-encryption.patch
Normal file
509
0003-kcm-disable-encryption.patch
Normal file
@ -0,0 +1,509 @@
|
|||||||
|
From 426947971cd94cc93dd120ca8ad9bcbeb47059c4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||||
|
Date: Mon, 19 Oct 2020 12:59:48 +0200
|
||||||
|
Subject: [PATCH 03/19] kcm: disable encryption
|
||||||
|
|
||||||
|
Encryption was a huge bottleneck for the secdb backend. This is
|
||||||
|
backwards compatible and there is no need to destroy existing
|
||||||
|
ccache. It will be stored unencrypted at first write to the cache.
|
||||||
|
|
||||||
|
Note that the encryption did not provide any security as the cache
|
||||||
|
is accessible only by root and the master key is stored together
|
||||||
|
with the cache. So once someone gains access to the file it can
|
||||||
|
be easily decrypted. Additionaly, there was also no encryption at
|
||||||
|
the memory level.
|
||||||
|
|
||||||
|
Resolves: https://github.com/SSSD/sssd/issues/5349
|
||||||
|
---
|
||||||
|
src/responder/kcm/kcmsrv_ccache_secdb.c | 94 ++++-----------
|
||||||
|
src/responder/secrets/local.c | 2 +-
|
||||||
|
src/util/secrets/secrets.c | 149 +++++++++++++++++-------
|
||||||
|
src/util/secrets/secrets.h | 13 ++-
|
||||||
|
4 files changed, 146 insertions(+), 112 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache_secdb.c b/src/responder/kcm/kcmsrv_ccache_secdb.c
|
||||||
|
index ed1c8247febc0a49dfd35b99a788b60ce8dda109..e6f4f9b05d17956f771ed4db63dc4940be0a838b 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ccache_secdb.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache_secdb.c
|
||||||
|
@@ -35,15 +35,13 @@
|
||||||
|
#define KCM_SECDB_CCACHE_FMT KCM_SECDB_BASE_FMT"ccache/"
|
||||||
|
#define KCM_SECDB_DFL_FMT KCM_SECDB_BASE_FMT"default"
|
||||||
|
|
||||||
|
-static errno_t sec_get_b64(TALLOC_CTX *mem_ctx,
|
||||||
|
- struct sss_sec_req *req,
|
||||||
|
- struct sss_iobuf **_buf)
|
||||||
|
+static errno_t sec_get(TALLOC_CTX *mem_ctx,
|
||||||
|
+ struct sss_sec_req *req,
|
||||||
|
+ struct sss_iobuf **_buf)
|
||||||
|
{
|
||||||
|
errno_t ret;
|
||||||
|
TALLOC_CTX *tmp_ctx;
|
||||||
|
- char *b64_sec;
|
||||||
|
- uint8_t *data;
|
||||||
|
- size_t data_size;
|
||||||
|
+ char *secret;
|
||||||
|
struct sss_iobuf *buf;
|
||||||
|
|
||||||
|
tmp_ctx = talloc_new(mem_ctx);
|
||||||
|
@@ -51,21 +49,15 @@ static errno_t sec_get_b64(TALLOC_CTX *mem_ctx,
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = sss_sec_get(tmp_ctx, req, &b64_sec);
|
||||||
|
+ ret = sss_sec_get(tmp_ctx, req, &secret);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"Cannot retrieve the secret [%d]: %s\n", ret, sss_strerror(ret));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- data = sss_base64_decode(tmp_ctx, b64_sec, &data_size);
|
||||||
|
- if (data == NULL) {
|
||||||
|
- DEBUG(SSSDBG_CRIT_FAILURE, "Cannot decode secret from base64\n");
|
||||||
|
- ret = EIO;
|
||||||
|
- goto done;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- buf = sss_iobuf_init_readonly(tmp_ctx, data, data_size);
|
||||||
|
+ buf = sss_iobuf_init_readonly(tmp_ctx, (const uint8_t *)secret,
|
||||||
|
+ strlen(secret) + 1);
|
||||||
|
if (buf == NULL) {
|
||||||
|
DEBUG(SSSDBG_CRIT_FAILURE, "Cannot init the iobuf\n");
|
||||||
|
ret = EIO;
|
||||||
|
@@ -79,73 +71,35 @@ done:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static errno_t sec_put_b64(TALLOC_CTX *mem_ctx,
|
||||||
|
- struct sss_sec_req *req,
|
||||||
|
- struct sss_iobuf *buf)
|
||||||
|
+static errno_t sec_put(TALLOC_CTX *mem_ctx,
|
||||||
|
+ struct sss_sec_req *req,
|
||||||
|
+ struct sss_iobuf *buf)
|
||||||
|
{
|
||||||
|
errno_t ret;
|
||||||
|
- TALLOC_CTX *tmp_ctx;
|
||||||
|
- char *secret;
|
||||||
|
|
||||||
|
- tmp_ctx = talloc_new(mem_ctx);
|
||||||
|
- if (tmp_ctx == NULL) {
|
||||||
|
- return ENOMEM;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- secret = sss_base64_encode(tmp_ctx,
|
||||||
|
- sss_iobuf_get_data(buf),
|
||||||
|
- sss_iobuf_get_size(buf));
|
||||||
|
- if (secret == NULL) {
|
||||||
|
- DEBUG(SSSDBG_CRIT_FAILURE, "Cannot encode secret to base64\n");
|
||||||
|
- ret = EIO;
|
||||||
|
- goto done;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- ret = sss_sec_put(req, secret);
|
||||||
|
+ ret = sss_sec_put(req, (const char *)sss_iobuf_get_data(buf),
|
||||||
|
+ SSS_SEC_PLAINTEXT);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"Cannot write the secret [%d]: %s\n", ret, sss_strerror(ret));
|
||||||
|
- goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = EOK;
|
||||||
|
-done:
|
||||||
|
- talloc_free(tmp_ctx);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static errno_t sec_update_b64(TALLOC_CTX *mem_ctx,
|
||||||
|
- struct sss_sec_req *req,
|
||||||
|
- struct sss_iobuf *buf)
|
||||||
|
+static errno_t sec_update(TALLOC_CTX *mem_ctx,
|
||||||
|
+ struct sss_sec_req *req,
|
||||||
|
+ struct sss_iobuf *buf)
|
||||||
|
{
|
||||||
|
errno_t ret;
|
||||||
|
- TALLOC_CTX *tmp_ctx;
|
||||||
|
- char *secret;
|
||||||
|
|
||||||
|
- tmp_ctx = talloc_new(mem_ctx);
|
||||||
|
- if (tmp_ctx == NULL) {
|
||||||
|
- return ENOMEM;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- secret = sss_base64_encode(tmp_ctx,
|
||||||
|
- sss_iobuf_get_data(buf),
|
||||||
|
- sss_iobuf_get_size(buf));
|
||||||
|
- if (secret == NULL) {
|
||||||
|
- DEBUG(SSSDBG_CRIT_FAILURE, "Cannot encode secret to base64\n");
|
||||||
|
- ret = EIO;
|
||||||
|
- goto done;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- ret = sss_sec_update(req, secret);
|
||||||
|
+ ret = sss_sec_update(req, (const char *)sss_iobuf_get_data(buf),
|
||||||
|
+ SSS_SEC_PLAINTEXT);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"Cannot write the secret [%d]: %s\n", ret, sss_strerror(ret));
|
||||||
|
- goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = EOK;
|
||||||
|
-done:
|
||||||
|
- talloc_free(tmp_ctx);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -493,7 +447,7 @@ static errno_t secdb_get_cc(TALLOC_CTX *mem_ctx,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = sec_get_b64(tmp_ctx, sreq, &ccbuf);
|
||||||
|
+ ret = sec_get(tmp_ctx, sreq, &ccbuf);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"Cannot get the secret [%d][%s]\n", ret, sss_strerror(ret));
|
||||||
|
@@ -748,9 +702,9 @@ static struct tevent_req *ccdb_secdb_set_default_send(TALLOC_CTX *mem_ctx,
|
||||||
|
|
||||||
|
ret = sss_sec_get(state, sreq, &cur_default);
|
||||||
|
if (ret == ENOENT) {
|
||||||
|
- ret = sec_put_b64(state, sreq, iobuf);
|
||||||
|
+ ret = sec_put(state, sreq, iobuf);
|
||||||
|
} else if (ret == EOK) {
|
||||||
|
- ret = sec_update_b64(state, sreq, iobuf);
|
||||||
|
+ ret = sec_update(state, sreq, iobuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != EOK) {
|
||||||
|
@@ -804,7 +758,7 @@ static struct tevent_req *ccdb_secdb_get_default_send(TALLOC_CTX *mem_ctx,
|
||||||
|
goto immediate;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = sec_get_b64(state, sreq, &dfl_iobuf);
|
||||||
|
+ ret = sec_get(state, sreq, &dfl_iobuf);
|
||||||
|
if (ret == ENOENT) {
|
||||||
|
uuid_clear(state->uuid);
|
||||||
|
ret = EOK;
|
||||||
|
@@ -1230,7 +1184,7 @@ static struct tevent_req *ccdb_secdb_create_send(TALLOC_CTX *mem_ctx,
|
||||||
|
goto immediate;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = sec_put_b64(state, ccache_req, ccache_payload);
|
||||||
|
+ ret = sec_put(state, ccache_req, ccache_payload);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE, "Failed to add the payload\n");
|
||||||
|
goto immediate;
|
||||||
|
@@ -1308,7 +1262,7 @@ static struct tevent_req *ccdb_secdb_mod_send(TALLOC_CTX *mem_ctx,
|
||||||
|
goto immediate;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = sec_update_b64(state, sreq, payload);
|
||||||
|
+ ret = sec_update(state, sreq, payload);
|
||||||
|
if (ret != EOK) {
|
||||||
|
goto immediate;
|
||||||
|
}
|
||||||
|
@@ -1384,7 +1338,7 @@ static struct tevent_req *ccdb_secdb_store_cred_send(TALLOC_CTX *mem_ctx,
|
||||||
|
goto immediate;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = sec_update_b64(state, sreq, payload);
|
||||||
|
+ ret = sec_update(state, sreq, payload);
|
||||||
|
if (ret != EOK) {
|
||||||
|
goto immediate;
|
||||||
|
}
|
||||||
|
diff --git a/src/responder/secrets/local.c b/src/responder/secrets/local.c
|
||||||
|
index eb37c08b7337c6713c2e74a55363f79ecfefd8c0..815e7507ba6b3e210891c26dd243a2a67d8920f0 100644
|
||||||
|
--- a/src/responder/secrets/local.c
|
||||||
|
+++ b/src/responder/secrets/local.c
|
||||||
|
@@ -168,7 +168,7 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
|
||||||
|
}
|
||||||
|
if (ret) goto done;
|
||||||
|
|
||||||
|
- ret = sss_sec_put(ssec_req, secret);
|
||||||
|
+ ret = sss_sec_put(ssec_req, secret, SSS_SEC_MASTERKEY);
|
||||||
|
if (ret) goto done;
|
||||||
|
break;
|
||||||
|
|
||||||
|
diff --git a/src/util/secrets/secrets.c b/src/util/secrets/secrets.c
|
||||||
|
index d701face07aa3ea5dc62371066ba6947d7d496a9..b3d40fdcb4bc2aeeb6aae4e17654ae06b00db876 100644
|
||||||
|
--- a/src/util/secrets/secrets.c
|
||||||
|
+++ b/src/util/secrets/secrets.c
|
||||||
|
@@ -63,19 +63,53 @@ static struct sss_sec_quota default_kcm_quota = {
|
||||||
|
.containers_nest_level = DEFAULT_SEC_CONTAINERS_NEST_LEVEL,
|
||||||
|
};
|
||||||
|
|
||||||
|
+static const char *sss_sec_enctype_to_str(enum sss_sec_enctype enctype)
|
||||||
|
+{
|
||||||
|
+ switch (enctype) {
|
||||||
|
+ case SSS_SEC_PLAINTEXT:
|
||||||
|
+ return "plaintext";
|
||||||
|
+ case SSS_SEC_MASTERKEY:
|
||||||
|
+ return "masterkey";
|
||||||
|
+ case SSS_SEC_BASE64:
|
||||||
|
+ return "base64";
|
||||||
|
+ default:
|
||||||
|
+ DEBUG(SSSDBG_CRIT_FAILURE, "Bug: unknown encryption type %d\n",
|
||||||
|
+ enctype);
|
||||||
|
+ return "unknown";
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static enum sss_sec_enctype sss_sec_str_to_enctype(const char *str)
|
||||||
|
+{
|
||||||
|
+ if (strcmp("plaintext", str) == 0) {
|
||||||
|
+ return SSS_SEC_PLAINTEXT;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (strcmp("masterkey", str) == 0) {
|
||||||
|
+ return SSS_SEC_MASTERKEY;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (strcmp("base64", str) == 0) {
|
||||||
|
+ return SSS_SEC_BASE64;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return SSS_SEC_ENCTYPE_SENTINEL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int local_decrypt(struct sss_sec_ctx *sctx, TALLOC_CTX *mem_ctx,
|
||||||
|
- const char *secret, const char *enctype,
|
||||||
|
+ const char *secret, enum sss_sec_enctype enctype,
|
||||||
|
char **plain_secret)
|
||||||
|
{
|
||||||
|
+ struct sss_sec_data _secret;
|
||||||
|
+ size_t outlen;
|
||||||
|
char *output;
|
||||||
|
+ int ret;
|
||||||
|
|
||||||
|
- if (enctype && strcmp(enctype, "masterkey") == 0) {
|
||||||
|
- DEBUG(SSSDBG_TRACE_INTERNAL, "Decrypting with masterkey\n");
|
||||||
|
-
|
||||||
|
- struct sss_sec_data _secret;
|
||||||
|
- size_t outlen;
|
||||||
|
- int ret;
|
||||||
|
-
|
||||||
|
+ switch (enctype) {
|
||||||
|
+ case SSS_SEC_PLAINTEXT:
|
||||||
|
+ output = talloc_strdup(mem_ctx, secret);
|
||||||
|
+ break;
|
||||||
|
+ case SSS_SEC_MASTERKEY:
|
||||||
|
_secret.data = (char *)sss_base64_decode(mem_ctx, secret,
|
||||||
|
&_secret.length);
|
||||||
|
if (!_secret.data) {
|
||||||
|
@@ -83,6 +117,7 @@ static int local_decrypt(struct sss_sec_ctx *sctx, TALLOC_CTX *mem_ctx,
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ DEBUG(SSSDBG_TRACE_INTERNAL, "Decrypting with masterkey\n");
|
||||||
|
ret = sss_decrypt(mem_ctx, AES256CBC_HMAC_SHA256,
|
||||||
|
(uint8_t *)sctx->master_key.data,
|
||||||
|
sctx->master_key.length,
|
||||||
|
@@ -102,10 +137,17 @@ static int local_decrypt(struct sss_sec_ctx *sctx, TALLOC_CTX *mem_ctx,
|
||||||
|
talloc_free(output);
|
||||||
|
return EIO;
|
||||||
|
}
|
||||||
|
- } else {
|
||||||
|
- DEBUG(SSSDBG_TRACE_INTERNAL, "Unexpected enctype (not 'masterkey')\n");
|
||||||
|
- output = talloc_strdup(mem_ctx, secret);
|
||||||
|
- if (!output) return ENOMEM;
|
||||||
|
+ break;
|
||||||
|
+ case SSS_SEC_BASE64:
|
||||||
|
+ output = (char *)sss_base64_decode(mem_ctx, secret, &_secret.length);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unknown encryption type '%d'\n", enctype);
|
||||||
|
+ return EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (output == NULL) {
|
||||||
|
+ return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
*plain_secret = output;
|
||||||
|
@@ -113,39 +155,46 @@ static int local_decrypt(struct sss_sec_ctx *sctx, TALLOC_CTX *mem_ctx,
|
||||||
|
}
|
||||||
|
|
||||||
|
static int local_encrypt(struct sss_sec_ctx *sec_ctx, TALLOC_CTX *mem_ctx,
|
||||||
|
- const char *secret, const char *enctype,
|
||||||
|
+ const char *secret, enum sss_sec_enctype enctype,
|
||||||
|
char **ciphertext)
|
||||||
|
{
|
||||||
|
struct sss_sec_data _secret;
|
||||||
|
char *output;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
- if (enctype == NULL) {
|
||||||
|
- DEBUG(SSSDBG_CRIT_FAILURE, "No encryption type\n");
|
||||||
|
- return EINVAL;
|
||||||
|
- }
|
||||||
|
+ switch (enctype) {
|
||||||
|
+ case SSS_SEC_PLAINTEXT:
|
||||||
|
+ output = talloc_strdup(mem_ctx, secret);
|
||||||
|
+ break;
|
||||||
|
+ case SSS_SEC_MASTERKEY:
|
||||||
|
+ ret = sss_encrypt(mem_ctx, AES256CBC_HMAC_SHA256,
|
||||||
|
+ (uint8_t *)sec_ctx->master_key.data,
|
||||||
|
+ sec_ctx->master_key.length,
|
||||||
|
+ (const uint8_t *)secret, strlen(secret) + 1,
|
||||||
|
+ (uint8_t **)&_secret.data, &_secret.length);
|
||||||
|
+ if (ret) {
|
||||||
|
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
+ "sss_encrypt failed [%d]: %s\n", ret, sss_strerror(ret));
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (strcmp(enctype, "masterkey") != 0) {
|
||||||
|
- DEBUG(SSSDBG_CRIT_FAILURE, "Unknown encryption type '%s'\n", enctype);
|
||||||
|
+ output = sss_base64_encode(mem_ctx, (uint8_t *)_secret.data,
|
||||||
|
+ _secret.length);
|
||||||
|
+ talloc_free(_secret.data);
|
||||||
|
+ break;
|
||||||
|
+ case SSS_SEC_BASE64:
|
||||||
|
+ output = (char *)sss_base64_encode(mem_ctx, (const uint8_t *)secret,
|
||||||
|
+ strlen(secret) + 1);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unknown encryption type '%d'\n", enctype);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = sss_encrypt(mem_ctx, AES256CBC_HMAC_SHA256,
|
||||||
|
- (uint8_t *)sec_ctx->master_key.data,
|
||||||
|
- sec_ctx->master_key.length,
|
||||||
|
- (const uint8_t *)secret, strlen(secret) + 1,
|
||||||
|
- (uint8_t **)&_secret.data, &_secret.length);
|
||||||
|
- if (ret) {
|
||||||
|
- DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
- "sss_encrypt failed [%d]: %s\n", ret, sss_strerror(ret));
|
||||||
|
- return ret;
|
||||||
|
+ if (output == NULL) {
|
||||||
|
+ return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
- output = sss_base64_encode(mem_ctx,
|
||||||
|
- (uint8_t *)_secret.data, _secret.length);
|
||||||
|
- talloc_free(_secret.data);
|
||||||
|
- if (!output) return ENOMEM;
|
||||||
|
-
|
||||||
|
*ciphertext = output;
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
@@ -958,6 +1007,7 @@ errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
|
||||||
|
struct ldb_result *res;
|
||||||
|
const char *attr_secret;
|
||||||
|
const char *attr_enctype;
|
||||||
|
+ enum sss_sec_enctype enctype;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (req == NULL || _secret == NULL) {
|
||||||
|
@@ -1006,10 +1056,15 @@ errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
|
||||||
|
attr_enctype = ldb_msg_find_attr_as_string(res->msgs[0], "enctype", NULL);
|
||||||
|
|
||||||
|
if (attr_enctype) {
|
||||||
|
- ret = local_decrypt(req->sctx, mem_ctx, attr_secret, attr_enctype, _secret);
|
||||||
|
+ enctype = sss_sec_str_to_enctype(attr_enctype);
|
||||||
|
+ ret = local_decrypt(req->sctx, mem_ctx, attr_secret, enctype, _secret);
|
||||||
|
if (ret) goto done;
|
||||||
|
} else {
|
||||||
|
*_secret = talloc_strdup(mem_ctx, attr_secret);
|
||||||
|
+ if (*_secret == NULL) {
|
||||||
|
+ ret = ENOMEM;
|
||||||
|
+ goto done;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
ret = EOK;
|
||||||
|
|
||||||
|
@@ -1019,10 +1074,10 @@ done:
|
||||||
|
}
|
||||||
|
|
||||||
|
errno_t sss_sec_put(struct sss_sec_req *req,
|
||||||
|
- const char *secret)
|
||||||
|
+ const char *secret,
|
||||||
|
+ enum sss_sec_enctype enctype)
|
||||||
|
{
|
||||||
|
struct ldb_message *msg;
|
||||||
|
- const char *enctype = "masterkey";
|
||||||
|
char *enc_secret;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
@@ -1087,7 +1142,7 @@ errno_t sss_sec_put(struct sss_sec_req *req,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = ldb_msg_add_string(msg, "enctype", enctype);
|
||||||
|
+ ret = ldb_msg_add_string(msg, "enctype", sss_sec_enctype_to_str(enctype));
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"ldb_msg_add_string failed adding enctype [%d]: %s\n",
|
||||||
|
@@ -1132,10 +1187,10 @@ done:
|
||||||
|
}
|
||||||
|
|
||||||
|
errno_t sss_sec_update(struct sss_sec_req *req,
|
||||||
|
- const char *secret)
|
||||||
|
+ const char *secret,
|
||||||
|
+ enum sss_sec_enctype enctype)
|
||||||
|
{
|
||||||
|
struct ldb_message *msg;
|
||||||
|
- const char *enctype = "masterkey";
|
||||||
|
char *enc_secret;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
@@ -1192,6 +1247,22 @@ errno_t sss_sec_update(struct sss_sec_req *req,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ ret = ldb_msg_add_empty(msg, "enctype", LDB_FLAG_MOD_REPLACE, NULL);
|
||||||
|
+ if (ret != LDB_SUCCESS) {
|
||||||
|
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
||||||
|
+ "ldb_msg_add_empty failed: [%s]\n", ldb_strerror(ret));
|
||||||
|
+ ret = EIO;
|
||||||
|
+ goto done;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = ldb_msg_add_string(msg, "enctype", sss_sec_enctype_to_str(enctype));
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
+ "ldb_msg_add_string failed adding enctype [%d]: %s\n",
|
||||||
|
+ ret, sss_strerror(ret));
|
||||||
|
+ goto done;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* FIXME - should we have a lastUpdate timestamp? */
|
||||||
|
ret = ldb_msg_add_empty(msg, "secret", LDB_FLAG_MOD_REPLACE, NULL);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
diff --git a/src/util/secrets/secrets.h b/src/util/secrets/secrets.h
|
||||||
|
index 9cf3975162c40a27ec92691f732a5aca5a5a8473..73f40f7eb620904cec8f1cb7891765323ada08ad 100644
|
||||||
|
--- a/src/util/secrets/secrets.h
|
||||||
|
+++ b/src/util/secrets/secrets.h
|
||||||
|
@@ -43,6 +43,13 @@
|
||||||
|
#define DEFAULT_SEC_KCM_MAX_UID_SECRETS 64
|
||||||
|
#define DEFAULT_SEC_KCM_MAX_PAYLOAD_SIZE 65536
|
||||||
|
|
||||||
|
+enum sss_sec_enctype {
|
||||||
|
+ SSS_SEC_PLAINTEXT,
|
||||||
|
+ SSS_SEC_MASTERKEY,
|
||||||
|
+ SSS_SEC_BASE64,
|
||||||
|
+ SSS_SEC_ENCTYPE_SENTINEL
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
struct sss_sec_ctx;
|
||||||
|
|
||||||
|
struct sss_sec_req;
|
||||||
|
@@ -91,10 +98,12 @@ errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
|
||||||
|
char **_secret);
|
||||||
|
|
||||||
|
errno_t sss_sec_put(struct sss_sec_req *req,
|
||||||
|
- const char *secret);
|
||||||
|
+ const char *secret,
|
||||||
|
+ enum sss_sec_enctype enctype);
|
||||||
|
|
||||||
|
errno_t sss_sec_update(struct sss_sec_req *req,
|
||||||
|
- const char *secret);
|
||||||
|
+ const char *secret,
|
||||||
|
+ enum sss_sec_enctype enctype);
|
||||||
|
|
||||||
|
errno_t sss_sec_create_container(struct sss_sec_req *req);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.25.4
|
||||||
|
|
@ -0,0 +1,26 @@
|
|||||||
|
From b8dd3fa32cef423217859a1ef04ec30dfef30fb2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||||
|
Date: Tue, 27 Oct 2020 16:45:22 +0100
|
||||||
|
Subject: [PATCH 04/19] kcm: avoid multiple debug messages if sss_sec_put fails
|
||||||
|
|
||||||
|
sec_put() already logs a message if the underlaying function fails
|
||||||
|
so this debug message is really unnecessary.
|
||||||
|
---
|
||||||
|
src/responder/kcm/kcmsrv_ccache_secdb.c | 1 -
|
||||||
|
1 file changed, 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache_secdb.c b/src/responder/kcm/kcmsrv_ccache_secdb.c
|
||||||
|
index e6f4f9b05d17956f771ed4db63dc4940be0a838b..f3b9af840381881e99bbead70ea7edabf945a8e2 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ccache_secdb.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache_secdb.c
|
||||||
|
@@ -1186,7 +1186,6 @@ static struct tevent_req *ccdb_secdb_create_send(TALLOC_CTX *mem_ctx,
|
||||||
|
|
||||||
|
ret = sec_put(state, ccache_req, ccache_payload);
|
||||||
|
if (ret != EOK) {
|
||||||
|
- DEBUG(SSSDBG_OP_FAILURE, "Failed to add the payload\n");
|
||||||
|
goto immediate;
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.25.4
|
||||||
|
|
225
0005-secrets-allow-to-specify-secret-s-data-format.patch
Normal file
225
0005-secrets-allow-to-specify-secret-s-data-format.patch
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
From e05dfeca855986cd11674a64ef6333c2d67e9bc7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||||
|
Date: Thu, 22 Oct 2020 11:18:12 +0200
|
||||||
|
Subject: [PATCH 05/19] secrets: allow to specify secret's data format
|
||||||
|
|
||||||
|
Currently, both KCM and secrets responders store JSON formatted string
|
||||||
|
in the secrets database. One of the next commits makes KCM to store
|
||||||
|
binary format instead of JSON string to improve performance. We need
|
||||||
|
to be able to distinguish the formats to keep KCM update compatible
|
||||||
|
with existing ccache and also to keep secrets responder working.
|
||||||
|
---
|
||||||
|
src/responder/kcm/kcmsrv_ccache_secdb.c | 8 ++--
|
||||||
|
src/responder/secrets/local.c | 4 +-
|
||||||
|
src/util/secrets/secrets.c | 57 ++++++++++++++++++++-----
|
||||||
|
src/util/secrets/secrets.h | 9 ++--
|
||||||
|
4 files changed, 59 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache_secdb.c b/src/responder/kcm/kcmsrv_ccache_secdb.c
|
||||||
|
index f3b9af840381881e99bbead70ea7edabf945a8e2..8e5bd4f7376173fd075c1a64785a597bcf2f97ba 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ccache_secdb.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache_secdb.c
|
||||||
|
@@ -49,7 +49,7 @@ static errno_t sec_get(TALLOC_CTX *mem_ctx,
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = sss_sec_get(tmp_ctx, req, &secret);
|
||||||
|
+ ret = sss_sec_get(tmp_ctx, req, &secret, NULL);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"Cannot retrieve the secret [%d]: %s\n", ret, sss_strerror(ret));
|
||||||
|
@@ -78,7 +78,7 @@ static errno_t sec_put(TALLOC_CTX *mem_ctx,
|
||||||
|
errno_t ret;
|
||||||
|
|
||||||
|
ret = sss_sec_put(req, (const char *)sss_iobuf_get_data(buf),
|
||||||
|
- SSS_SEC_PLAINTEXT);
|
||||||
|
+ SSS_SEC_PLAINTEXT, "simple");
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"Cannot write the secret [%d]: %s\n", ret, sss_strerror(ret));
|
||||||
|
@@ -94,7 +94,7 @@ static errno_t sec_update(TALLOC_CTX *mem_ctx,
|
||||||
|
errno_t ret;
|
||||||
|
|
||||||
|
ret = sss_sec_update(req, (const char *)sss_iobuf_get_data(buf),
|
||||||
|
- SSS_SEC_PLAINTEXT);
|
||||||
|
+ SSS_SEC_PLAINTEXT, "simple");
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"Cannot write the secret [%d]: %s\n", ret, sss_strerror(ret));
|
||||||
|
@@ -700,7 +700,7 @@ static struct tevent_req *ccdb_secdb_set_default_send(TALLOC_CTX *mem_ctx,
|
||||||
|
goto immediate;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = sss_sec_get(state, sreq, &cur_default);
|
||||||
|
+ ret = sss_sec_get(state, sreq, &cur_default, NULL);
|
||||||
|
if (ret == ENOENT) {
|
||||||
|
ret = sec_put(state, sreq, iobuf);
|
||||||
|
} else if (ret == EOK) {
|
||||||
|
diff --git a/src/responder/secrets/local.c b/src/responder/secrets/local.c
|
||||||
|
index 815e7507ba6b3e210891c26dd243a2a67d8920f0..fee52674d73f6f8071b4d66ac91bed3b210c8e23 100644
|
||||||
|
--- a/src/responder/secrets/local.c
|
||||||
|
+++ b/src/responder/secrets/local.c
|
||||||
|
@@ -134,7 +134,7 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = sss_sec_get(state, ssec_req, &secret);
|
||||||
|
+ ret = sss_sec_get(state, ssec_req, &secret, NULL);
|
||||||
|
if (ret) goto done;
|
||||||
|
|
||||||
|
if (body_is_json) {
|
||||||
|
@@ -168,7 +168,7 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
|
||||||
|
}
|
||||||
|
if (ret) goto done;
|
||||||
|
|
||||||
|
- ret = sss_sec_put(ssec_req, secret, SSS_SEC_MASTERKEY);
|
||||||
|
+ ret = sss_sec_put(ssec_req, secret, SSS_SEC_MASTERKEY, "simple");
|
||||||
|
if (ret) goto done;
|
||||||
|
break;
|
||||||
|
|
||||||
|
diff --git a/src/util/secrets/secrets.c b/src/util/secrets/secrets.c
|
||||||
|
index b3d40fdcb4bc2aeeb6aae4e17654ae06b00db876..51fc85fb09934c25290c625fe2a2d8090285117d 100644
|
||||||
|
--- a/src/util/secrets/secrets.c
|
||||||
|
+++ b/src/util/secrets/secrets.c
|
||||||
|
@@ -1000,14 +1000,18 @@ done:
|
||||||
|
|
||||||
|
errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
|
||||||
|
struct sss_sec_req *req,
|
||||||
|
- char **_secret)
|
||||||
|
+ char **_secret,
|
||||||
|
+ char **_datatype)
|
||||||
|
{
|
||||||
|
TALLOC_CTX *tmp_ctx;
|
||||||
|
- static const char *attrs[] = { "secret", "enctype", NULL };
|
||||||
|
+ static const char *attrs[] = { "secret", "enctype", "type", NULL };
|
||||||
|
struct ldb_result *res;
|
||||||
|
const char *attr_secret;
|
||||||
|
const char *attr_enctype;
|
||||||
|
+ const char *attr_datatype;
|
||||||
|
enum sss_sec_enctype enctype;
|
||||||
|
+ char *datatype;
|
||||||
|
+ char *secret;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (req == NULL || _secret == NULL) {
|
||||||
|
@@ -1057,15 +1061,30 @@ errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
|
||||||
|
|
||||||
|
if (attr_enctype) {
|
||||||
|
enctype = sss_sec_str_to_enctype(attr_enctype);
|
||||||
|
- ret = local_decrypt(req->sctx, mem_ctx, attr_secret, enctype, _secret);
|
||||||
|
+ ret = local_decrypt(req->sctx, tmp_ctx, attr_secret, enctype, &secret);
|
||||||
|
if (ret) goto done;
|
||||||
|
} else {
|
||||||
|
- *_secret = talloc_strdup(mem_ctx, attr_secret);
|
||||||
|
- if (*_secret == NULL) {
|
||||||
|
+ secret = talloc_strdup(tmp_ctx, attr_secret);
|
||||||
|
+ if (secret == NULL) {
|
||||||
|
ret = ENOMEM;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ if (_datatype != NULL) {
|
||||||
|
+ attr_datatype = ldb_msg_find_attr_as_string(res->msgs[0], "type",
|
||||||
|
+ "simple");
|
||||||
|
+ datatype = talloc_strdup(tmp_ctx, attr_datatype);
|
||||||
|
+ if (datatype == NULL) {
|
||||||
|
+ ret = ENOMEM;
|
||||||
|
+ goto done;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *_datatype = talloc_steal(mem_ctx, datatype);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *_secret = talloc_steal(mem_ctx, secret);
|
||||||
|
+
|
||||||
|
ret = EOK;
|
||||||
|
|
||||||
|
done:
|
||||||
|
@@ -1075,7 +1094,8 @@ done:
|
||||||
|
|
||||||
|
errno_t sss_sec_put(struct sss_sec_req *req,
|
||||||
|
const char *secret,
|
||||||
|
- enum sss_sec_enctype enctype)
|
||||||
|
+ enum sss_sec_enctype enctype,
|
||||||
|
+ const char *datatype)
|
||||||
|
{
|
||||||
|
struct ldb_message *msg;
|
||||||
|
char *enc_secret;
|
||||||
|
@@ -1134,11 +1154,11 @@ errno_t sss_sec_put(struct sss_sec_req *req,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = ldb_msg_add_string(msg, "type", "simple");
|
||||||
|
+ ret = ldb_msg_add_string(msg, "type", datatype);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
- "ldb_msg_add_string failed adding type:simple [%d]: %s\n",
|
||||||
|
- ret, sss_strerror(ret));
|
||||||
|
+ "ldb_msg_add_string failed adding type:%s [%d]: %s\n",
|
||||||
|
+ datatype, ret, sss_strerror(ret));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1188,7 +1208,8 @@ done:
|
||||||
|
|
||||||
|
errno_t sss_sec_update(struct sss_sec_req *req,
|
||||||
|
const char *secret,
|
||||||
|
- enum sss_sec_enctype enctype)
|
||||||
|
+ enum sss_sec_enctype enctype,
|
||||||
|
+ const char *datatype)
|
||||||
|
{
|
||||||
|
struct ldb_message *msg;
|
||||||
|
char *enc_secret;
|
||||||
|
@@ -1263,6 +1284,22 @@ errno_t sss_sec_update(struct sss_sec_req *req,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ ret = ldb_msg_add_empty(msg, "type", LDB_FLAG_MOD_REPLACE, NULL);
|
||||||
|
+ if (ret != LDB_SUCCESS) {
|
||||||
|
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
||||||
|
+ "ldb_msg_add_empty failed: [%s]\n", ldb_strerror(ret));
|
||||||
|
+ ret = EIO;
|
||||||
|
+ goto done;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = ldb_msg_add_string(msg, "type", datatype);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
+ "ldb_msg_add_string failed adding type:%s [%d]: %s\n",
|
||||||
|
+ datatype, ret, sss_strerror(ret));
|
||||||
|
+ goto done;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* FIXME - should we have a lastUpdate timestamp? */
|
||||||
|
ret = ldb_msg_add_empty(msg, "secret", LDB_FLAG_MOD_REPLACE, NULL);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
diff --git a/src/util/secrets/secrets.h b/src/util/secrets/secrets.h
|
||||||
|
index 73f40f7eb620904cec8f1cb7891765323ada08ad..f73657629f1a0bb614ccd96728852da66cc18791 100644
|
||||||
|
--- a/src/util/secrets/secrets.h
|
||||||
|
+++ b/src/util/secrets/secrets.h
|
||||||
|
@@ -95,15 +95,18 @@ errno_t sss_sec_list(TALLOC_CTX *mem_ctx,
|
||||||
|
|
||||||
|
errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
|
||||||
|
struct sss_sec_req *req,
|
||||||
|
- char **_secret);
|
||||||
|
+ char **_secret,
|
||||||
|
+ char **_datatype);
|
||||||
|
|
||||||
|
errno_t sss_sec_put(struct sss_sec_req *req,
|
||||||
|
const char *secret,
|
||||||
|
- enum sss_sec_enctype enctype);
|
||||||
|
+ enum sss_sec_enctype enctype,
|
||||||
|
+ const char *datatype);
|
||||||
|
|
||||||
|
errno_t sss_sec_update(struct sss_sec_req *req,
|
||||||
|
const char *secret,
|
||||||
|
- enum sss_sec_enctype enctype);
|
||||||
|
+ enum sss_sec_enctype enctype,
|
||||||
|
+ const char *datatype);
|
||||||
|
|
||||||
|
errno_t sss_sec_create_container(struct sss_sec_req *req);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.25.4
|
||||||
|
|
450
0006-secrets-accept-binary-data-instead-of-string.patch
Normal file
450
0006-secrets-accept-binary-data-instead-of-string.patch
Normal file
@ -0,0 +1,450 @@
|
|||||||
|
From 63cbb2aee2c6277ecd9e38fb32713e0ba3db4bb4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||||
|
Date: Thu, 22 Oct 2020 12:18:38 +0200
|
||||||
|
Subject: [PATCH 06/19] secrets: accept binary data instead of string
|
||||||
|
|
||||||
|
Currently, both KCM and secrets responders store JSON formatted string
|
||||||
|
in the secrets database. One of the next commits makes KCM to store
|
||||||
|
binary format instead of JSON string to improve performance. We need
|
||||||
|
to be able to distinguish the formats to keep KCM update compatible
|
||||||
|
with existing ccache and also to keep secrets responder working.
|
||||||
|
|
||||||
|
Secrets responder test had to be ammended to fit into a new maximum
|
||||||
|
payload which is now reduced by one byte for the secrets responder
|
||||||
|
to hold the ending zero of a secret string.
|
||||||
|
|
||||||
|
This is a corner case in a long deprecated responder that is not even
|
||||||
|
built by default and has no known consumers so it is fine to fast fix
|
||||||
|
the test.
|
||||||
|
---
|
||||||
|
src/responder/kcm/kcmsrv_ccache_secdb.c | 8 +-
|
||||||
|
src/responder/secrets/local.c | 5 +-
|
||||||
|
src/tests/intg/test_secrets.py | 3 +-
|
||||||
|
src/util/secrets/sec_pvt.h | 2 +-
|
||||||
|
src/util/secrets/secrets.c | 130 ++++++++++++++----------
|
||||||
|
src/util/secrets/secrets.h | 9 +-
|
||||||
|
6 files changed, 91 insertions(+), 66 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache_secdb.c b/src/responder/kcm/kcmsrv_ccache_secdb.c
|
||||||
|
index 8e5bd4f7376173fd075c1a64785a597bcf2f97ba..f0143e686826e3bf637619efc799e0d2f0715ba4 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ccache_secdb.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache_secdb.c
|
||||||
|
@@ -49,7 +49,7 @@ static errno_t sec_get(TALLOC_CTX *mem_ctx,
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = sss_sec_get(tmp_ctx, req, &secret, NULL);
|
||||||
|
+ ret = sss_sec_get(tmp_ctx, req, (uint8_t **)&secret, NULL, NULL);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"Cannot retrieve the secret [%d]: %s\n", ret, sss_strerror(ret));
|
||||||
|
@@ -77,7 +77,7 @@ static errno_t sec_put(TALLOC_CTX *mem_ctx,
|
||||||
|
{
|
||||||
|
errno_t ret;
|
||||||
|
|
||||||
|
- ret = sss_sec_put(req, (const char *)sss_iobuf_get_data(buf),
|
||||||
|
+ ret = sss_sec_put(req, sss_iobuf_get_data(buf), sss_iobuf_get_size(buf),
|
||||||
|
SSS_SEC_PLAINTEXT, "simple");
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
@@ -93,7 +93,7 @@ static errno_t sec_update(TALLOC_CTX *mem_ctx,
|
||||||
|
{
|
||||||
|
errno_t ret;
|
||||||
|
|
||||||
|
- ret = sss_sec_update(req, (const char *)sss_iobuf_get_data(buf),
|
||||||
|
+ ret = sss_sec_update(req, sss_iobuf_get_data(buf), sss_iobuf_get_size(buf),
|
||||||
|
SSS_SEC_PLAINTEXT, "simple");
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
@@ -700,7 +700,7 @@ static struct tevent_req *ccdb_secdb_set_default_send(TALLOC_CTX *mem_ctx,
|
||||||
|
goto immediate;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = sss_sec_get(state, sreq, &cur_default, NULL);
|
||||||
|
+ ret = sss_sec_get(state, sreq, (uint8_t**)&cur_default, NULL, NULL);
|
||||||
|
if (ret == ENOENT) {
|
||||||
|
ret = sec_put(state, sreq, iobuf);
|
||||||
|
} else if (ret == EOK) {
|
||||||
|
diff --git a/src/responder/secrets/local.c b/src/responder/secrets/local.c
|
||||||
|
index fee52674d73f6f8071b4d66ac91bed3b210c8e23..252ef3a1de7ff28b0e9f37479c658a6c59e830f7 100644
|
||||||
|
--- a/src/responder/secrets/local.c
|
||||||
|
+++ b/src/responder/secrets/local.c
|
||||||
|
@@ -134,7 +134,7 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = sss_sec_get(state, ssec_req, &secret, NULL);
|
||||||
|
+ ret = sss_sec_get(state, ssec_req, (uint8_t**)&secret, NULL, NULL);
|
||||||
|
if (ret) goto done;
|
||||||
|
|
||||||
|
if (body_is_json) {
|
||||||
|
@@ -168,7 +168,8 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
|
||||||
|
}
|
||||||
|
if (ret) goto done;
|
||||||
|
|
||||||
|
- ret = sss_sec_put(ssec_req, secret, SSS_SEC_MASTERKEY, "simple");
|
||||||
|
+ ret = sss_sec_put(ssec_req, (uint8_t *)secret, strlen(secret) + 1,
|
||||||
|
+ SSS_SEC_MASTERKEY, "simple");
|
||||||
|
if (ret) goto done;
|
||||||
|
break;
|
||||||
|
|
||||||
|
diff --git a/src/tests/intg/test_secrets.py b/src/tests/intg/test_secrets.py
|
||||||
|
index 00933fb346516898448d4285c5c5c9373c48a2a9..18d722c13f36c58423e5caf81881f9ec167faa1e 100644
|
||||||
|
--- a/src/tests/intg/test_secrets.py
|
||||||
|
+++ b/src/tests/intg/test_secrets.py
|
||||||
|
@@ -438,7 +438,8 @@ def run_quota_test(cli, max_secrets, max_payload_size):
|
||||||
|
KILOBYTE = 1024
|
||||||
|
kb_payload_size = max_payload_size * KILOBYTE
|
||||||
|
|
||||||
|
- sec_value = "x" * kb_payload_size
|
||||||
|
+ # Adjust payload size to hold terminal zero byte.
|
||||||
|
+ sec_value = "x" * (kb_payload_size - 1)
|
||||||
|
|
||||||
|
cli.set_secret("foo", sec_value)
|
||||||
|
|
||||||
|
diff --git a/src/util/secrets/sec_pvt.h b/src/util/secrets/sec_pvt.h
|
||||||
|
index 92e2b8b259fd7b20e974d5bd4dc41d96ea36ecf1..0e77a660e91ff9e18cce68a7994e3dbbf868c7aa 100644
|
||||||
|
--- a/src/util/secrets/sec_pvt.h
|
||||||
|
+++ b/src/util/secrets/sec_pvt.h
|
||||||
|
@@ -33,7 +33,7 @@
|
||||||
|
#define SSS_SEC_KCM_BASEPATH "/kcm/"
|
||||||
|
|
||||||
|
struct sss_sec_data {
|
||||||
|
- char *data;
|
||||||
|
+ uint8_t *data;
|
||||||
|
size_t length;
|
||||||
|
};
|
||||||
|
|
||||||
|
diff --git a/src/util/secrets/secrets.c b/src/util/secrets/secrets.c
|
||||||
|
index 51fc85fb09934c25290c625fe2a2d8090285117d..2a7149ae8b1c88623784ffd4f3e7f908be15c662 100644
|
||||||
|
--- a/src/util/secrets/secrets.c
|
||||||
|
+++ b/src/util/secrets/secrets.c
|
||||||
|
@@ -96,22 +96,28 @@ static enum sss_sec_enctype sss_sec_str_to_enctype(const char *str)
|
||||||
|
return SSS_SEC_ENCTYPE_SENTINEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int local_decrypt(struct sss_sec_ctx *sctx, TALLOC_CTX *mem_ctx,
|
||||||
|
- const char *secret, enum sss_sec_enctype enctype,
|
||||||
|
- char **plain_secret)
|
||||||
|
+static int local_decrypt(struct sss_sec_ctx *sctx,
|
||||||
|
+ TALLOC_CTX *mem_ctx,
|
||||||
|
+ uint8_t *secret,
|
||||||
|
+ size_t secret_len,
|
||||||
|
+ enum sss_sec_enctype enctype,
|
||||||
|
+ uint8_t **_output,
|
||||||
|
+ size_t *_output_len)
|
||||||
|
{
|
||||||
|
struct sss_sec_data _secret;
|
||||||
|
- size_t outlen;
|
||||||
|
- char *output;
|
||||||
|
+ uint8_t *output;
|
||||||
|
+ size_t output_len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
switch (enctype) {
|
||||||
|
case SSS_SEC_PLAINTEXT:
|
||||||
|
- output = talloc_strdup(mem_ctx, secret);
|
||||||
|
+ output = talloc_memdup(mem_ctx, secret, secret_len);
|
||||||
|
+ output_len = secret_len;
|
||||||
|
break;
|
||||||
|
case SSS_SEC_MASTERKEY:
|
||||||
|
- _secret.data = (char *)sss_base64_decode(mem_ctx, secret,
|
||||||
|
- &_secret.length);
|
||||||
|
+ _secret.data = (uint8_t *)sss_base64_decode(mem_ctx,
|
||||||
|
+ (const char *)secret,
|
||||||
|
+ &_secret.length);
|
||||||
|
if (!_secret.data) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE, "sss_base64_decode failed\n");
|
||||||
|
return EINVAL;
|
||||||
|
@@ -119,27 +125,20 @@ static int local_decrypt(struct sss_sec_ctx *sctx, TALLOC_CTX *mem_ctx,
|
||||||
|
|
||||||
|
DEBUG(SSSDBG_TRACE_INTERNAL, "Decrypting with masterkey\n");
|
||||||
|
ret = sss_decrypt(mem_ctx, AES256CBC_HMAC_SHA256,
|
||||||
|
- (uint8_t *)sctx->master_key.data,
|
||||||
|
+ sctx->master_key.data,
|
||||||
|
sctx->master_key.length,
|
||||||
|
- (uint8_t *)_secret.data, _secret.length,
|
||||||
|
- (uint8_t **)&output, &outlen);
|
||||||
|
+ _secret.data, _secret.length,
|
||||||
|
+ &output, &output_len);
|
||||||
|
talloc_free(_secret.data);
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"sss_decrypt failed [%d]: %s\n", ret, sss_strerror(ret));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- if (((strnlen(output, outlen) + 1) != outlen) ||
|
||||||
|
- output[outlen - 1] != '\0') {
|
||||||
|
- DEBUG(SSSDBG_CRIT_FAILURE,
|
||||||
|
- "Output length mismatch or output not NULL-terminated\n");
|
||||||
|
- talloc_free(output);
|
||||||
|
- return EIO;
|
||||||
|
- }
|
||||||
|
break;
|
||||||
|
case SSS_SEC_BASE64:
|
||||||
|
- output = (char *)sss_base64_decode(mem_ctx, secret, &_secret.length);
|
||||||
|
+ output = (uint8_t *)sss_base64_decode(mem_ctx, (const char *)secret,
|
||||||
|
+ &output_len);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DEBUG(SSSDBG_CRIT_FAILURE, "Unknown encryption type '%d'\n", enctype);
|
||||||
|
@@ -150,41 +149,52 @@ static int local_decrypt(struct sss_sec_ctx *sctx, TALLOC_CTX *mem_ctx,
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
- *plain_secret = output;
|
||||||
|
+ *_output = output;
|
||||||
|
+ *_output_len = output_len;
|
||||||
|
+
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int local_encrypt(struct sss_sec_ctx *sec_ctx, TALLOC_CTX *mem_ctx,
|
||||||
|
- const char *secret, enum sss_sec_enctype enctype,
|
||||||
|
- char **ciphertext)
|
||||||
|
+static int local_encrypt(struct sss_sec_ctx *sec_ctx,
|
||||||
|
+ TALLOC_CTX *mem_ctx,
|
||||||
|
+ uint8_t *secret,
|
||||||
|
+ size_t secret_len,
|
||||||
|
+ enum sss_sec_enctype enctype,
|
||||||
|
+ uint8_t **_output,
|
||||||
|
+ size_t *_output_len)
|
||||||
|
{
|
||||||
|
struct sss_sec_data _secret;
|
||||||
|
- char *output;
|
||||||
|
+ uint8_t *output;
|
||||||
|
+ size_t output_len;
|
||||||
|
+ char *b64;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
switch (enctype) {
|
||||||
|
case SSS_SEC_PLAINTEXT:
|
||||||
|
- output = talloc_strdup(mem_ctx, secret);
|
||||||
|
+ output = talloc_memdup(mem_ctx, secret, secret_len);
|
||||||
|
+ output_len = secret_len;
|
||||||
|
break;
|
||||||
|
case SSS_SEC_MASTERKEY:
|
||||||
|
ret = sss_encrypt(mem_ctx, AES256CBC_HMAC_SHA256,
|
||||||
|
- (uint8_t *)sec_ctx->master_key.data,
|
||||||
|
- sec_ctx->master_key.length,
|
||||||
|
- (const uint8_t *)secret, strlen(secret) + 1,
|
||||||
|
- (uint8_t **)&_secret.data, &_secret.length);
|
||||||
|
+ sec_ctx->master_key.data,
|
||||||
|
+ sec_ctx->master_key.length,
|
||||||
|
+ secret, secret_len,
|
||||||
|
+ &_secret.data, &_secret.length);
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"sss_encrypt failed [%d]: %s\n", ret, sss_strerror(ret));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
- output = sss_base64_encode(mem_ctx, (uint8_t *)_secret.data,
|
||||||
|
- _secret.length);
|
||||||
|
+ b64 = sss_base64_encode(mem_ctx, _secret.data, _secret.length);
|
||||||
|
+ output = (uint8_t*)b64;
|
||||||
|
+ output_len = strlen(b64) + 1;
|
||||||
|
talloc_free(_secret.data);
|
||||||
|
break;
|
||||||
|
case SSS_SEC_BASE64:
|
||||||
|
- output = (char *)sss_base64_encode(mem_ctx, (const uint8_t *)secret,
|
||||||
|
- strlen(secret) + 1);
|
||||||
|
+ b64 = sss_base64_encode(mem_ctx, secret, secret_len);
|
||||||
|
+ output = (uint8_t*)b64;
|
||||||
|
+ output_len = strlen(b64) + 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DEBUG(SSSDBG_CRIT_FAILURE, "Unknown encryption type '%d'\n", enctype);
|
||||||
|
@@ -195,7 +205,9 @@ static int local_encrypt(struct sss_sec_ctx *sec_ctx, TALLOC_CTX *mem_ctx,
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
- *ciphertext = output;
|
||||||
|
+ *_output = output;
|
||||||
|
+ *_output_len = output_len;
|
||||||
|
+
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1000,18 +1012,20 @@ done:
|
||||||
|
|
||||||
|
errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
|
||||||
|
struct sss_sec_req *req,
|
||||||
|
- char **_secret,
|
||||||
|
+ uint8_t **_secret,
|
||||||
|
+ size_t *_secret_len,
|
||||||
|
char **_datatype)
|
||||||
|
{
|
||||||
|
TALLOC_CTX *tmp_ctx;
|
||||||
|
static const char *attrs[] = { "secret", "enctype", "type", NULL };
|
||||||
|
struct ldb_result *res;
|
||||||
|
- const char *attr_secret;
|
||||||
|
+ const struct ldb_val *attr_secret;
|
||||||
|
const char *attr_enctype;
|
||||||
|
const char *attr_datatype;
|
||||||
|
enum sss_sec_enctype enctype;
|
||||||
|
char *datatype;
|
||||||
|
- char *secret;
|
||||||
|
+ uint8_t *secret;
|
||||||
|
+ size_t secret_len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (req == NULL || _secret == NULL) {
|
||||||
|
@@ -1050,7 +1064,7 @@ errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- attr_secret = ldb_msg_find_attr_as_string(res->msgs[0], "secret", NULL);
|
||||||
|
+ attr_secret = ldb_msg_find_ldb_val(res->msgs[0], "secret");
|
||||||
|
if (!attr_secret) {
|
||||||
|
DEBUG(SSSDBG_CRIT_FAILURE, "The 'secret' attribute is missing\n");
|
||||||
|
ret = ENOENT;
|
||||||
|
@@ -1061,14 +1075,12 @@ errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
|
||||||
|
|
||||||
|
if (attr_enctype) {
|
||||||
|
enctype = sss_sec_str_to_enctype(attr_enctype);
|
||||||
|
- ret = local_decrypt(req->sctx, tmp_ctx, attr_secret, enctype, &secret);
|
||||||
|
+ ret = local_decrypt(req->sctx, tmp_ctx, attr_secret->data,
|
||||||
|
+ attr_secret->length, enctype, &secret, &secret_len);
|
||||||
|
if (ret) goto done;
|
||||||
|
} else {
|
||||||
|
- secret = talloc_strdup(tmp_ctx, attr_secret);
|
||||||
|
- if (secret == NULL) {
|
||||||
|
- ret = ENOMEM;
|
||||||
|
- goto done;
|
||||||
|
- }
|
||||||
|
+ secret = talloc_steal(tmp_ctx, attr_secret->data);
|
||||||
|
+ secret_len = attr_secret->length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_datatype != NULL) {
|
||||||
|
@@ -1085,6 +1097,10 @@ errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
|
||||||
|
|
||||||
|
*_secret = talloc_steal(mem_ctx, secret);
|
||||||
|
|
||||||
|
+ if (_secret_len) {
|
||||||
|
+ *_secret_len = secret_len;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
ret = EOK;
|
||||||
|
|
||||||
|
done:
|
||||||
|
@@ -1093,12 +1109,13 @@ done:
|
||||||
|
}
|
||||||
|
|
||||||
|
errno_t sss_sec_put(struct sss_sec_req *req,
|
||||||
|
- const char *secret,
|
||||||
|
+ uint8_t *secret,
|
||||||
|
+ size_t secret_len,
|
||||||
|
enum sss_sec_enctype enctype,
|
||||||
|
const char *datatype)
|
||||||
|
{
|
||||||
|
struct ldb_message *msg;
|
||||||
|
- char *enc_secret;
|
||||||
|
+ struct ldb_val enc_secret;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (req == NULL || secret == NULL) {
|
||||||
|
@@ -1139,7 +1156,7 @@ errno_t sss_sec_put(struct sss_sec_req *req,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = local_check_max_payload_size(req, strlen(secret));
|
||||||
|
+ ret = local_check_max_payload_size(req, secret_len);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"local_check_max_payload_size failed [%d]: %s\n",
|
||||||
|
@@ -1147,7 +1164,8 @@ errno_t sss_sec_put(struct sss_sec_req *req,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = local_encrypt(req->sctx, msg, secret, enctype, &enc_secret);
|
||||||
|
+ ret = local_encrypt(req->sctx, msg, secret, secret_len, enctype,
|
||||||
|
+ &enc_secret.data, &enc_secret.length);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"local_encrypt failed [%d]: %s\n", ret, sss_strerror(ret));
|
||||||
|
@@ -1170,7 +1188,7 @@ errno_t sss_sec_put(struct sss_sec_req *req,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = ldb_msg_add_string(msg, "secret", enc_secret);
|
||||||
|
+ ret = ldb_msg_add_value(msg, "secret", &enc_secret, NULL);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"ldb_msg_add_string failed adding secret [%d]: %s\n",
|
||||||
|
@@ -1207,12 +1225,13 @@ done:
|
||||||
|
}
|
||||||
|
|
||||||
|
errno_t sss_sec_update(struct sss_sec_req *req,
|
||||||
|
- const char *secret,
|
||||||
|
+ uint8_t *secret,
|
||||||
|
+ size_t secret_len,
|
||||||
|
enum sss_sec_enctype enctype,
|
||||||
|
const char *datatype)
|
||||||
|
{
|
||||||
|
struct ldb_message *msg;
|
||||||
|
- char *enc_secret;
|
||||||
|
+ struct ldb_val enc_secret;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (req == NULL || secret == NULL) {
|
||||||
|
@@ -1253,7 +1272,7 @@ errno_t sss_sec_update(struct sss_sec_req *req,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = local_check_max_payload_size(req, strlen(secret));
|
||||||
|
+ ret = local_check_max_payload_size(req, secret_len);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"local_check_max_payload_size failed [%d]: %s\n",
|
||||||
|
@@ -1261,7 +1280,8 @@ errno_t sss_sec_update(struct sss_sec_req *req,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = local_encrypt(req->sctx, msg, secret, enctype, &enc_secret);
|
||||||
|
+ ret = local_encrypt(req->sctx, msg, secret, secret_len, enctype,
|
||||||
|
+ &enc_secret.data, &enc_secret.length);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"local_encrypt failed [%d]: %s\n", ret, sss_strerror(ret));
|
||||||
|
@@ -1309,7 +1329,7 @@ errno_t sss_sec_update(struct sss_sec_req *req,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = ldb_msg_add_string(msg, "secret", enc_secret);
|
||||||
|
+ ret = ldb_msg_add_value(msg, "secret", &enc_secret, NULL);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
DEBUG(SSSDBG_MINOR_FAILURE,
|
||||||
|
"ldb_msg_add_string failed: [%s]\n", ldb_strerror(ret));
|
||||||
|
diff --git a/src/util/secrets/secrets.h b/src/util/secrets/secrets.h
|
||||||
|
index f73657629f1a0bb614ccd96728852da66cc18791..f8caa53eec376bb0c8d52615ce9111efbbb26393 100644
|
||||||
|
--- a/src/util/secrets/secrets.h
|
||||||
|
+++ b/src/util/secrets/secrets.h
|
||||||
|
@@ -95,16 +95,19 @@ errno_t sss_sec_list(TALLOC_CTX *mem_ctx,
|
||||||
|
|
||||||
|
errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
|
||||||
|
struct sss_sec_req *req,
|
||||||
|
- char **_secret,
|
||||||
|
+ uint8_t **_secret,
|
||||||
|
+ size_t *_secret_len,
|
||||||
|
char **_datatype);
|
||||||
|
|
||||||
|
errno_t sss_sec_put(struct sss_sec_req *req,
|
||||||
|
- const char *secret,
|
||||||
|
+ uint8_t *secret,
|
||||||
|
+ size_t secret_len,
|
||||||
|
enum sss_sec_enctype enctype,
|
||||||
|
const char *datatype);
|
||||||
|
|
||||||
|
errno_t sss_sec_update(struct sss_sec_req *req,
|
||||||
|
- const char *secret,
|
||||||
|
+ uint8_t *secret,
|
||||||
|
+ size_t secret_len,
|
||||||
|
enum sss_sec_enctype enctype,
|
||||||
|
const char *datatype);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.25.4
|
||||||
|
|
265
0007-iobuf-add-more-iobuf-functions.patch
Normal file
265
0007-iobuf-add-more-iobuf-functions.patch
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
From 51c8dda998c5b7bfa08362a13915fcff265a6f8f Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||||
|
Date: Fri, 23 Oct 2020 13:10:13 +0200
|
||||||
|
Subject: [PATCH 07/19] iobuf: add more iobuf functions
|
||||||
|
|
||||||
|
These will be used in later patches.
|
||||||
|
---
|
||||||
|
src/shared/safealign.h | 4 ++
|
||||||
|
src/util/sss_iobuf.c | 141 +++++++++++++++++++++++++++++++++++++++++
|
||||||
|
src/util/sss_iobuf.h | 46 ++++++++++++++
|
||||||
|
3 files changed, 191 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/shared/safealign.h b/src/shared/safealign.h
|
||||||
|
index b00c37f5b98bd4bf7ff6cea8e1208d80c77f0228..35909faa25967cefd296808431620f51232f67e2 100644
|
||||||
|
--- a/src/shared/safealign.h
|
||||||
|
+++ b/src/shared/safealign.h
|
||||||
|
@@ -97,6 +97,10 @@ safealign_memcpy(void *dest, const void *src, size_t n, size_t *counter)
|
||||||
|
#define SAFEALIGN_SETMEM_UINT16(dest, value, pctr) \
|
||||||
|
SAFEALIGN_SETMEM_VALUE(dest, value, uint16_t, pctr)
|
||||||
|
|
||||||
|
+/* SAFEALIGN_SETMEM_UINT8(void *dest, uint8_t value, size_t *pctr) */
|
||||||
|
+#define SAFEALIGN_SETMEM_UINT8(dest, value, pctr) \
|
||||||
|
+ SAFEALIGN_SETMEM_VALUE(dest, value, uint8_t, pctr)
|
||||||
|
+
|
||||||
|
/* These macros are the same as their equivalents without _CHECK suffix,
|
||||||
|
* but additionally make the caller return EINVAL immediately if *pctr
|
||||||
|
* would exceed len. */
|
||||||
|
diff --git a/src/util/sss_iobuf.c b/src/util/sss_iobuf.c
|
||||||
|
index 518713e4cc3dd99627a3a4450f235cbbc69ed3a2..3056a7b0db38746cfed154179787e53622e1a041 100644
|
||||||
|
--- a/src/util/sss_iobuf.c
|
||||||
|
+++ b/src/util/sss_iobuf.c
|
||||||
|
@@ -66,6 +66,30 @@ struct sss_iobuf *sss_iobuf_init_readonly(TALLOC_CTX *mem_ctx,
|
||||||
|
return iobuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
+struct sss_iobuf *sss_iobuf_init_steal(TALLOC_CTX *mem_ctx,
|
||||||
|
+ uint8_t *data,
|
||||||
|
+ size_t size)
|
||||||
|
+{
|
||||||
|
+ struct sss_iobuf *iobuf;
|
||||||
|
+
|
||||||
|
+ iobuf = talloc_zero(mem_ctx, struct sss_iobuf);
|
||||||
|
+ if (iobuf == NULL) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ iobuf->data = talloc_steal(iobuf, data);
|
||||||
|
+ iobuf->size = size;
|
||||||
|
+ iobuf->capacity = size;
|
||||||
|
+ iobuf->dp = 0;
|
||||||
|
+
|
||||||
|
+ return iobuf;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void sss_iobuf_cursor_reset(struct sss_iobuf *iobuf)
|
||||||
|
+{
|
||||||
|
+ iobuf->dp = 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
size_t sss_iobuf_get_len(struct sss_iobuf *iobuf)
|
||||||
|
{
|
||||||
|
if (iobuf == NULL) {
|
||||||
|
@@ -223,6 +247,109 @@ errno_t sss_iobuf_write_len(struct sss_iobuf *iobuf,
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
+errno_t sss_iobuf_read_varlen(TALLOC_CTX *mem_ctx,
|
||||||
|
+ struct sss_iobuf *iobuf,
|
||||||
|
+ uint8_t **_out,
|
||||||
|
+ size_t *_len)
|
||||||
|
+{
|
||||||
|
+ uint8_t *out;
|
||||||
|
+ uint32_t len;
|
||||||
|
+ size_t slen;
|
||||||
|
+ errno_t ret;
|
||||||
|
+
|
||||||
|
+ if (iobuf == NULL || _out == NULL || _len == NULL) {
|
||||||
|
+ return EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = sss_iobuf_read_uint32(iobuf, &len);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (len == 0) {
|
||||||
|
+ *_out = NULL;
|
||||||
|
+ *_len = 0;
|
||||||
|
+ return EOK;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ out = talloc_array(mem_ctx, uint8_t, len);
|
||||||
|
+ if (out == NULL) {
|
||||||
|
+ return ENOMEM;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ slen = len;
|
||||||
|
+ ret = sss_iobuf_read_len(iobuf, slen, out);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ talloc_free(out);
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *_out = out;
|
||||||
|
+ *_len = slen;
|
||||||
|
+
|
||||||
|
+ return EOK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+errno_t sss_iobuf_write_varlen(struct sss_iobuf *iobuf,
|
||||||
|
+ uint8_t *data,
|
||||||
|
+ size_t len)
|
||||||
|
+{
|
||||||
|
+ errno_t ret;
|
||||||
|
+
|
||||||
|
+ if (iobuf == NULL || (data == NULL && len != 0)) {
|
||||||
|
+ return EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = sss_iobuf_write_uint32(iobuf, len);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (len == 0) {
|
||||||
|
+ return EOK;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return sss_iobuf_write_len(iobuf, data, len);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+errno_t sss_iobuf_read_iobuf(TALLOC_CTX *mem_ctx,
|
||||||
|
+ struct sss_iobuf *iobuf,
|
||||||
|
+ struct sss_iobuf **_out)
|
||||||
|
+{
|
||||||
|
+ struct sss_iobuf *out;
|
||||||
|
+ uint8_t *data;
|
||||||
|
+ size_t len;
|
||||||
|
+ errno_t ret;
|
||||||
|
+
|
||||||
|
+ ret = sss_iobuf_read_varlen(NULL, iobuf, &data, &len);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ out = sss_iobuf_init_steal(mem_ctx, data, len);
|
||||||
|
+ if (out == NULL) {
|
||||||
|
+ return ENOMEM;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *_out = out;
|
||||||
|
+
|
||||||
|
+ return EOK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+errno_t sss_iobuf_write_iobuf(struct sss_iobuf *iobuf,
|
||||||
|
+ struct sss_iobuf *data)
|
||||||
|
+{
|
||||||
|
+ return sss_iobuf_write_varlen(iobuf, data->data, data->size);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+errno_t sss_iobuf_read_uint8(struct sss_iobuf *iobuf,
|
||||||
|
+ uint8_t *_val)
|
||||||
|
+{
|
||||||
|
+ SAFEALIGN_COPY_UINT8_CHECK(_val, iobuf_ptr(iobuf),
|
||||||
|
+ iobuf->capacity, &iobuf->dp);
|
||||||
|
+ return EOK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
errno_t sss_iobuf_read_uint32(struct sss_iobuf *iobuf,
|
||||||
|
uint32_t *_val)
|
||||||
|
{
|
||||||
|
@@ -239,6 +366,20 @@ errno_t sss_iobuf_read_int32(struct sss_iobuf *iobuf,
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
+errno_t sss_iobuf_write_uint8(struct sss_iobuf *iobuf,
|
||||||
|
+ uint8_t val)
|
||||||
|
+{
|
||||||
|
+ errno_t ret;
|
||||||
|
+
|
||||||
|
+ ret = ensure_bytes(iobuf, sizeof(uint8_t));
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ SAFEALIGN_SETMEM_UINT8(iobuf_ptr(iobuf), val, &iobuf->dp);
|
||||||
|
+ return EOK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
errno_t sss_iobuf_write_uint32(struct sss_iobuf *iobuf,
|
||||||
|
uint32_t val)
|
||||||
|
{
|
||||||
|
diff --git a/src/util/sss_iobuf.h b/src/util/sss_iobuf.h
|
||||||
|
index cc3dfd1e98eeb49b979ac321bd0253bffa8a6dff..159fbc0b9ff756ca996722a84a1a13635d1aa8de 100644
|
||||||
|
--- a/src/util/sss_iobuf.h
|
||||||
|
+++ b/src/util/sss_iobuf.h
|
||||||
|
@@ -50,6 +50,29 @@ struct sss_iobuf *sss_iobuf_init_readonly(TALLOC_CTX *mem_ctx,
|
||||||
|
const uint8_t *data,
|
||||||
|
size_t size);
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * @brief Allocate an IO buffer with a fixed size, stealing input data.
|
||||||
|
+ *
|
||||||
|
+ * This function is useful for parsing an input buffer from an existing
|
||||||
|
+ * buffer pointed to by data.
|
||||||
|
+ *
|
||||||
|
+ * The iobuf assumes ownership of the data buffer.
|
||||||
|
+ *
|
||||||
|
+ * @param[in] mem_ctx The talloc context that owns the iobuf
|
||||||
|
+ * @param[in] data The data to initialize the IO buffer with.
|
||||||
|
+ * @param[in] size The size of the data buffer
|
||||||
|
+ *
|
||||||
|
+ * @return The newly created buffer on success or NULL on an error.
|
||||||
|
+ */
|
||||||
|
+struct sss_iobuf *sss_iobuf_init_steal(TALLOC_CTX *mem_ctx,
|
||||||
|
+ uint8_t *data,
|
||||||
|
+ size_t size);
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * @brief Reset internal cursor of the IO buffer (seek to the start)
|
||||||
|
+ */
|
||||||
|
+void sss_iobuf_cursor_reset(struct sss_iobuf *iobuf);
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* @brief Returns the number of bytes currently stored in the iobuf
|
||||||
|
*
|
||||||
|
@@ -131,6 +154,28 @@ errno_t sss_iobuf_write_len(struct sss_iobuf *iobuf,
|
||||||
|
uint8_t *buf,
|
||||||
|
size_t len);
|
||||||
|
|
||||||
|
+errno_t sss_iobuf_read_varlen(TALLOC_CTX *mem_ctx,
|
||||||
|
+ struct sss_iobuf *iobuf,
|
||||||
|
+ uint8_t **_out,
|
||||||
|
+ size_t *_len);
|
||||||
|
+
|
||||||
|
+errno_t sss_iobuf_write_varlen(struct sss_iobuf *iobuf,
|
||||||
|
+ uint8_t *data,
|
||||||
|
+ size_t len);
|
||||||
|
+
|
||||||
|
+errno_t sss_iobuf_read_iobuf(TALLOC_CTX *mem_ctx,
|
||||||
|
+ struct sss_iobuf *iobuf,
|
||||||
|
+ struct sss_iobuf **_out);
|
||||||
|
+
|
||||||
|
+errno_t sss_iobuf_write_iobuf(struct sss_iobuf *iobuf,
|
||||||
|
+ struct sss_iobuf *data);
|
||||||
|
+
|
||||||
|
+errno_t sss_iobuf_read_uint8(struct sss_iobuf *iobuf,
|
||||||
|
+ uint8_t *_val);
|
||||||
|
+
|
||||||
|
+errno_t sss_iobuf_write_uint8(struct sss_iobuf *iobuf,
|
||||||
|
+ uint8_t val);
|
||||||
|
+
|
||||||
|
errno_t sss_iobuf_read_uint32(struct sss_iobuf *iobuf,
|
||||||
|
uint32_t *_val);
|
||||||
|
|
||||||
|
@@ -148,4 +193,5 @@ errno_t sss_iobuf_read_stringz(struct sss_iobuf *iobuf,
|
||||||
|
|
||||||
|
errno_t sss_iobuf_write_stringz(struct sss_iobuf *iobuf,
|
||||||
|
const char *str);
|
||||||
|
+
|
||||||
|
#endif /* __SSS_IOBUF_H_ */
|
||||||
|
--
|
||||||
|
2.25.4
|
||||||
|
|
292
0008-kcm-add-json-suffix-to-existing-searialization-funct.patch
Normal file
292
0008-kcm-add-json-suffix-to-existing-searialization-funct.patch
Normal file
@ -0,0 +1,292 @@
|
|||||||
|
From 27968f52eb57391ae64df57d29cf9911fc59d161 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||||
|
Date: Thu, 22 Oct 2020 13:34:52 +0200
|
||||||
|
Subject: [PATCH 08/19] kcm: add json suffix to existing searialization
|
||||||
|
functions
|
||||||
|
|
||||||
|
---
|
||||||
|
Makefile.am | 10 ++---
|
||||||
|
src/responder/kcm/kcmsrv_ccache.h | 18 ++++-----
|
||||||
|
src/responder/kcm/kcmsrv_ccache_json.c | 18 ++++-----
|
||||||
|
src/responder/kcm/kcmsrv_ccache_secdb.c | 14 +++----
|
||||||
|
src/responder/kcm/kcmsrv_ccache_secrets.c | 9 ++---
|
||||||
|
...n_marshalling.c => test_kcm_marshalling.c} | 39 ++++++-------------
|
||||||
|
6 files changed, 44 insertions(+), 64 deletions(-)
|
||||||
|
rename src/tests/cmocka/{test_kcm_json_marshalling.c => test_kcm_marshalling.c} (90%)
|
||||||
|
|
||||||
|
diff --git a/Makefile.am b/Makefile.am
|
||||||
|
index 97aa1ec661268aaa7a3f09b5022c5677df19d9da..8ca46bf2f9add08155bfb824444437532c97909c 100644
|
||||||
|
--- a/Makefile.am
|
||||||
|
+++ b/Makefile.am
|
||||||
|
@@ -311,7 +311,7 @@ endif # HAVE_INOTIFY
|
||||||
|
|
||||||
|
if BUILD_KCM
|
||||||
|
non_interactive_cmocka_based_tests += \
|
||||||
|
- test_kcm_json \
|
||||||
|
+ test_kcm_marshalling \
|
||||||
|
test_kcm_queue \
|
||||||
|
$(NULL)
|
||||||
|
endif # BUILD_KCM
|
||||||
|
@@ -3927,18 +3927,18 @@ test_sssd_krb5_locator_plugin_LDADD = \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
if BUILD_KCM
|
||||||
|
-test_kcm_json_SOURCES = \
|
||||||
|
- src/tests/cmocka/test_kcm_json_marshalling.c \
|
||||||
|
+test_kcm_marshalling_SOURCES = \
|
||||||
|
+ src/tests/cmocka/test_kcm_marshalling.c \
|
||||||
|
src/responder/kcm/kcmsrv_ccache_json.c \
|
||||||
|
src/responder/kcm/kcmsrv_ccache.c \
|
||||||
|
src/util/sss_krb5.c \
|
||||||
|
src/util/sss_iobuf.c \
|
||||||
|
$(NULL)
|
||||||
|
-test_kcm_json_CFLAGS = \
|
||||||
|
+test_kcm_marshalling_CFLAGS = \
|
||||||
|
$(AM_CFLAGS) \
|
||||||
|
$(UUID_CFLAGS) \
|
||||||
|
$(NULL)
|
||||||
|
-test_kcm_json_LDADD = \
|
||||||
|
+test_kcm_marshalling_LDADD = \
|
||||||
|
$(JANSSON_LIBS) \
|
||||||
|
$(UUID_LIBS) \
|
||||||
|
$(KRB5_LIBS) \
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache.h b/src/responder/kcm/kcmsrv_ccache.h
|
||||||
|
index d629923fa140bd30d8a59f56443dea7ce101c33e..5aaded0524d0765dea6bfb962a83cf625f0e85f4 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ccache.h
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache.h
|
||||||
|
@@ -333,16 +333,16 @@ const char *sec_key_create(TALLOC_CTX *mem_ctx,
|
||||||
|
* sec_key is a concatenation of the ccache's UUID and name
|
||||||
|
* sec_value is the JSON dump of the ccache contents
|
||||||
|
*/
|
||||||
|
-errno_t sec_kv_to_ccache(TALLOC_CTX *mem_ctx,
|
||||||
|
- const char *sec_key,
|
||||||
|
- const char *sec_value,
|
||||||
|
- struct cli_creds *client,
|
||||||
|
- struct kcm_ccache **_cc);
|
||||||
|
+errno_t sec_kv_to_ccache_json(TALLOC_CTX *mem_ctx,
|
||||||
|
+ const char *sec_key,
|
||||||
|
+ const char *sec_value,
|
||||||
|
+ struct cli_creds *client,
|
||||||
|
+ struct kcm_ccache **_cc);
|
||||||
|
|
||||||
|
/* Convert a kcm_ccache to a key-value pair to be stored in secrets */
|
||||||
|
-errno_t kcm_ccache_to_sec_input(TALLOC_CTX *mem_ctx,
|
||||||
|
- struct kcm_ccache *cc,
|
||||||
|
- struct cli_creds *client,
|
||||||
|
- struct sss_iobuf **_payload);
|
||||||
|
+errno_t kcm_ccache_to_sec_input_json(TALLOC_CTX *mem_ctx,
|
||||||
|
+ struct kcm_ccache *cc,
|
||||||
|
+ struct cli_creds *client,
|
||||||
|
+ struct sss_iobuf **_payload);
|
||||||
|
|
||||||
|
#endif /* _KCMSRV_CCACHE_H_ */
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache_json.c b/src/responder/kcm/kcmsrv_ccache_json.c
|
||||||
|
index 38ec53c408c3b9d44f37d102c4a0c976ef32bdfe..8101f5ddc148bfff83cc02cf9b19a3566209e781 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ccache_json.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache_json.c
|
||||||
|
@@ -460,10 +460,10 @@ static errno_t ccache_to_sec_val(TALLOC_CTX *mem_ctx,
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
-errno_t kcm_ccache_to_sec_input(TALLOC_CTX *mem_ctx,
|
||||||
|
- struct kcm_ccache *cc,
|
||||||
|
- struct cli_creds *client,
|
||||||
|
- struct sss_iobuf **_payload)
|
||||||
|
+errno_t kcm_ccache_to_sec_input_json(TALLOC_CTX *mem_ctx,
|
||||||
|
+ struct kcm_ccache *cc,
|
||||||
|
+ struct cli_creds *client,
|
||||||
|
+ struct sss_iobuf **_payload)
|
||||||
|
{
|
||||||
|
errno_t ret;
|
||||||
|
const char *value;
|
||||||
|
@@ -897,11 +897,11 @@ static errno_t sec_json_value_to_ccache(struct kcm_ccache *cc,
|
||||||
|
* sec_key is a concatenation of the ccache's UUID and name
|
||||||
|
* sec_value is the JSON dump of the ccache contents
|
||||||
|
*/
|
||||||
|
-errno_t sec_kv_to_ccache(TALLOC_CTX *mem_ctx,
|
||||||
|
- const char *sec_key,
|
||||||
|
- const char *sec_value,
|
||||||
|
- struct cli_creds *client,
|
||||||
|
- struct kcm_ccache **_cc)
|
||||||
|
+errno_t sec_kv_to_ccache_json(TALLOC_CTX *mem_ctx,
|
||||||
|
+ const char *sec_key,
|
||||||
|
+ const char *sec_value,
|
||||||
|
+ struct cli_creds *client,
|
||||||
|
+ struct kcm_ccache **_cc)
|
||||||
|
{
|
||||||
|
errno_t ret;
|
||||||
|
json_t *root = NULL;
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache_secdb.c b/src/responder/kcm/kcmsrv_ccache_secdb.c
|
||||||
|
index f0143e686826e3bf637619efc799e0d2f0715ba4..f5cfe47a7c6deac17031788105ac4235a6aaa9ff 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ccache_secdb.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache_secdb.c
|
||||||
|
@@ -160,7 +160,7 @@ static errno_t kcm_ccache_to_secdb_kv(TALLOC_CTX *mem_ctx,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = kcm_ccache_to_sec_input(mem_ctx, cc, client, &payload);
|
||||||
|
+ ret = kcm_ccache_to_sec_input_json(mem_ctx, cc, client, &payload);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_CRIT_FAILURE,
|
||||||
|
"Cannot convert ccache to a secret [%d][%s]\n", ret, sss_strerror(ret));
|
||||||
|
@@ -454,11 +454,9 @@ static errno_t secdb_get_cc(TALLOC_CTX *mem_ctx,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = sec_kv_to_ccache(tmp_ctx,
|
||||||
|
- secdb_key,
|
||||||
|
- (const char *) sss_iobuf_get_data(ccbuf),
|
||||||
|
- client,
|
||||||
|
- &cc);
|
||||||
|
+ ret = sec_kv_to_ccache_json(tmp_ctx, secdb_key,
|
||||||
|
+ (const char *)sss_iobuf_get_data(ccbuf),
|
||||||
|
+ client, &cc);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"Cannot convert JSON keyval to ccache blob [%d]: %s\n",
|
||||||
|
@@ -1251,7 +1249,7 @@ static struct tevent_req *ccdb_secdb_mod_send(TALLOC_CTX *mem_ctx,
|
||||||
|
goto immediate;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = kcm_ccache_to_sec_input(state, cc, client, &payload);
|
||||||
|
+ ret = kcm_ccache_to_sec_input_json(state, cc, client, &payload);
|
||||||
|
if (ret != EOK) {
|
||||||
|
goto immediate;
|
||||||
|
}
|
||||||
|
@@ -1327,7 +1325,7 @@ static struct tevent_req *ccdb_secdb_store_cred_send(TALLOC_CTX *mem_ctx,
|
||||||
|
goto immediate;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = kcm_ccache_to_sec_input(state, cc, client, &payload);
|
||||||
|
+ ret = kcm_ccache_to_sec_input_json(state, cc, client, &payload);
|
||||||
|
if (ret != EOK) {
|
||||||
|
goto immediate;
|
||||||
|
}
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache_secrets.c b/src/responder/kcm/kcmsrv_ccache_secrets.c
|
||||||
|
index 440ab3bb99dd983ba0343f371c0c6470bbd53afc..9d1fe8cad2dc6ed3ab43e181d0db52673d4759cc 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ccache_secrets.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache_secrets.c
|
||||||
|
@@ -195,7 +195,7 @@ static errno_t kcm_ccache_to_sec_kv(TALLOC_CTX *mem_ctx,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = kcm_ccache_to_sec_input(mem_ctx, cc, client, &payload);
|
||||||
|
+ ret = kcm_ccache_to_sec_input_json(mem_ctx, cc, client, &payload);
|
||||||
|
if (ret != EOK) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
@@ -489,11 +489,8 @@ static void sec_get_done(struct tevent_req *subreq)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = sec_kv_to_ccache(state,
|
||||||
|
- state->sec_key,
|
||||||
|
- sec_value,
|
||||||
|
- state->client,
|
||||||
|
- &state->cc);
|
||||||
|
+ ret = sec_kv_to_ccache_json(state, state->sec_key, sec_value, state->client,
|
||||||
|
+ &state->cc);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"Cannot convert JSON keyval to ccache blob [%d]: %s\n",
|
||||||
|
diff --git a/src/tests/cmocka/test_kcm_json_marshalling.c b/src/tests/cmocka/test_kcm_marshalling.c
|
||||||
|
similarity index 90%
|
||||||
|
rename from src/tests/cmocka/test_kcm_json_marshalling.c
|
||||||
|
rename to src/tests/cmocka/test_kcm_marshalling.c
|
||||||
|
index 48ee92bd675780b023b5c8275e5713b91388d06a..f82129974787bba6883662a732311f3370bcc4f1 100644
|
||||||
|
--- a/src/tests/cmocka/test_kcm_json_marshalling.c
|
||||||
|
+++ b/src/tests/cmocka/test_kcm_marshalling.c
|
||||||
|
@@ -154,7 +154,7 @@ static void assert_cc_equal(struct kcm_ccache *cc1,
|
||||||
|
assert_cc_offset_equal(cc1, cc2);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void test_kcm_ccache_marshall_unmarshall(void **state)
|
||||||
|
+static void test_kcm_ccache_marshall_unmarshall_json(void **state)
|
||||||
|
{
|
||||||
|
struct kcm_marshalling_test_ctx *test_ctx = talloc_get_type(*state,
|
||||||
|
struct kcm_marshalling_test_ctx);
|
||||||
|
@@ -182,10 +182,7 @@ static void test_kcm_ccache_marshall_unmarshall(void **state)
|
||||||
|
&cc);
|
||||||
|
assert_int_equal(ret, EOK);
|
||||||
|
|
||||||
|
- ret = kcm_ccache_to_sec_input(test_ctx,
|
||||||
|
- cc,
|
||||||
|
- &owner,
|
||||||
|
- &payload);
|
||||||
|
+ ret = kcm_ccache_to_sec_input_json(test_ctx, cc, &owner, &payload);
|
||||||
|
assert_int_equal(ret, EOK);
|
||||||
|
|
||||||
|
data = sss_iobuf_get_data(payload);
|
||||||
|
@@ -196,25 +193,19 @@ static void test_kcm_ccache_marshall_unmarshall(void **state)
|
||||||
|
key = sec_key_create(test_ctx, name, uuid);
|
||||||
|
assert_non_null(key);
|
||||||
|
|
||||||
|
- ret = sec_kv_to_ccache(test_ctx,
|
||||||
|
- key,
|
||||||
|
- (const char *) data,
|
||||||
|
- &owner,
|
||||||
|
- &cc2);
|
||||||
|
+ ret = sec_kv_to_ccache_json(test_ctx, key, (const char *)data, &owner,
|
||||||
|
+ &cc2);
|
||||||
|
assert_int_equal(ret, EOK);
|
||||||
|
|
||||||
|
assert_cc_equal(cc, cc2);
|
||||||
|
|
||||||
|
/* This key is exactly one byte shorter than it should be */
|
||||||
|
- ret = sec_kv_to_ccache(test_ctx,
|
||||||
|
- TEST_UUID_STR"-",
|
||||||
|
- (const char *) data,
|
||||||
|
- &owner,
|
||||||
|
- &cc2);
|
||||||
|
+ ret = sec_kv_to_ccache_json(test_ctx, TEST_UUID_STR "-", (const char *)data,
|
||||||
|
+ &owner, &cc2);
|
||||||
|
assert_int_equal(ret, EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void test_kcm_ccache_no_princ(void **state)
|
||||||
|
+static void test_kcm_ccache_no_princ_json(void **state)
|
||||||
|
{
|
||||||
|
struct kcm_marshalling_test_ctx *test_ctx = talloc_get_type(*state,
|
||||||
|
struct kcm_marshalling_test_ctx);
|
||||||
|
@@ -246,10 +237,7 @@ static void test_kcm_ccache_no_princ(void **state)
|
||||||
|
princ = kcm_cc_get_client_principal(cc);
|
||||||
|
assert_null(princ);
|
||||||
|
|
||||||
|
- ret = kcm_ccache_to_sec_input(test_ctx,
|
||||||
|
- cc,
|
||||||
|
- &owner,
|
||||||
|
- &payload);
|
||||||
|
+ ret = kcm_ccache_to_sec_input_json(test_ctx, cc, &owner, &payload);
|
||||||
|
assert_int_equal(ret, EOK);
|
||||||
|
|
||||||
|
data = sss_iobuf_get_data(payload);
|
||||||
|
@@ -260,11 +248,8 @@ static void test_kcm_ccache_no_princ(void **state)
|
||||||
|
key = sec_key_create(test_ctx, name, uuid);
|
||||||
|
assert_non_null(key);
|
||||||
|
|
||||||
|
- ret = sec_kv_to_ccache(test_ctx,
|
||||||
|
- key,
|
||||||
|
- (const char *) data,
|
||||||
|
- &owner,
|
||||||
|
- &cc2);
|
||||||
|
+ ret = sec_kv_to_ccache_json(test_ctx, key, (const char *)data, &owner,
|
||||||
|
+ &cc2);
|
||||||
|
assert_int_equal(ret, EOK);
|
||||||
|
|
||||||
|
assert_cc_equal(cc, cc2);
|
||||||
|
@@ -340,10 +325,10 @@ int main(int argc, const char *argv[])
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct CMUnitTest tests[] = {
|
||||||
|
- cmocka_unit_test_setup_teardown(test_kcm_ccache_marshall_unmarshall,
|
||||||
|
+ cmocka_unit_test_setup_teardown(test_kcm_ccache_marshall_unmarshall_json,
|
||||||
|
setup_kcm_marshalling,
|
||||||
|
teardown_kcm_marshalling),
|
||||||
|
- cmocka_unit_test_setup_teardown(test_kcm_ccache_no_princ,
|
||||||
|
+ cmocka_unit_test_setup_teardown(test_kcm_ccache_no_princ_json,
|
||||||
|
setup_kcm_marshalling,
|
||||||
|
teardown_kcm_marshalling),
|
||||||
|
cmocka_unit_test(test_sec_key_get_uuid),
|
||||||
|
--
|
||||||
|
2.25.4
|
||||||
|
|
404
0009-kcm-move-sec-key-parser-to-separate-file-so-it-can-b.patch
Normal file
404
0009-kcm-move-sec-key-parser-to-separate-file-so-it-can-b.patch
Normal file
@ -0,0 +1,404 @@
|
|||||||
|
From 23273319b546d034d31ffe3824b954659d20d104 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||||
|
Date: Tue, 27 Oct 2020 16:18:11 +0100
|
||||||
|
Subject: [PATCH 09/19] kcm: move sec key parser to separate file so it can be
|
||||||
|
shared
|
||||||
|
|
||||||
|
---
|
||||||
|
Makefile.am | 2 +
|
||||||
|
src/responder/kcm/kcmsrv_ccache.c | 20 ++++
|
||||||
|
src/responder/kcm/kcmsrv_ccache.h | 10 ++
|
||||||
|
src/responder/kcm/kcmsrv_ccache_json.c | 130 +---------------------
|
||||||
|
src/responder/kcm/kcmsrv_ccache_key.c | 145 +++++++++++++++++++++++++
|
||||||
|
5 files changed, 179 insertions(+), 128 deletions(-)
|
||||||
|
create mode 100644 src/responder/kcm/kcmsrv_ccache_key.c
|
||||||
|
|
||||||
|
diff --git a/Makefile.am b/Makefile.am
|
||||||
|
index 8ca46bf2f9add08155bfb824444437532c97909c..ae9bc540a86f2e291dd5b5f66e1ce4f0aacbaf61 100644
|
||||||
|
--- a/Makefile.am
|
||||||
|
+++ b/Makefile.am
|
||||||
|
@@ -1819,6 +1819,7 @@ sssd_kcm_SOURCES = \
|
||||||
|
src/responder/kcm/kcmsrv_ccache.c \
|
||||||
|
src/responder/kcm/kcmsrv_ccache_mem.c \
|
||||||
|
src/responder/kcm/kcmsrv_ccache_json.c \
|
||||||
|
+ src/responder/kcm/kcmsrv_ccache_key.c \
|
||||||
|
src/responder/kcm/kcmsrv_ccache_secdb.c \
|
||||||
|
src/responder/kcm/kcmsrv_ops.c \
|
||||||
|
src/responder/kcm/kcmsrv_op_queue.c \
|
||||||
|
@@ -3930,6 +3931,7 @@ if BUILD_KCM
|
||||||
|
test_kcm_marshalling_SOURCES = \
|
||||||
|
src/tests/cmocka/test_kcm_marshalling.c \
|
||||||
|
src/responder/kcm/kcmsrv_ccache_json.c \
|
||||||
|
+ src/responder/kcm/kcmsrv_ccache_key.c \
|
||||||
|
src/responder/kcm/kcmsrv_ccache.c \
|
||||||
|
src/util/sss_krb5.c \
|
||||||
|
src/util/sss_iobuf.c \
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache.c b/src/responder/kcm/kcmsrv_ccache.c
|
||||||
|
index 66e2752ba755af3ef1c6c1b21036021a608a94c1..59f8a7293fa7422c199ca2916c8e6ae6039d9312 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ccache.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache.c
|
||||||
|
@@ -213,6 +213,26 @@ errno_t kcm_cc_store_creds(struct kcm_ccache *cc,
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
+errno_t kcm_cc_set_header(struct kcm_ccache *cc,
|
||||||
|
+ const char *sec_key,
|
||||||
|
+ struct cli_creds *client)
|
||||||
|
+{
|
||||||
|
+ errno_t ret;
|
||||||
|
+
|
||||||
|
+ ret = sec_key_parse(cc, sec_key, &cc->name, cc->uuid);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* We rely on sssd-secrets only searching the user's subtree so we
|
||||||
|
+ * set the ownership to the client
|
||||||
|
+ */
|
||||||
|
+ cc->owner.uid = cli_creds_get_uid(client);
|
||||||
|
+ cc->owner.gid = cli_creds_get_gid(client);
|
||||||
|
+
|
||||||
|
+ return EOK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
errno_t kcm_cred_get_uuid(struct kcm_cred *crd, uuid_t _uuid)
|
||||||
|
{
|
||||||
|
if (crd == NULL) {
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache.h b/src/responder/kcm/kcmsrv_ccache.h
|
||||||
|
index 5aaded0524d0765dea6bfb962a83cf625f0e85f4..892067f3170b19c0e55ceaa75b0c01f772c49d3d 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ccache.h
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache.h
|
||||||
|
@@ -100,6 +100,11 @@ struct kcm_cred *kcm_cred_new(TALLOC_CTX *mem_ctx,
|
||||||
|
errno_t kcm_cc_store_creds(struct kcm_ccache *cc,
|
||||||
|
struct kcm_cred *crd);
|
||||||
|
|
||||||
|
+/* Set cc header information from sec key and client */
|
||||||
|
+errno_t kcm_cc_set_header(struct kcm_ccache *cc,
|
||||||
|
+ const char *sec_key,
|
||||||
|
+ struct cli_creds *client);
|
||||||
|
+
|
||||||
|
errno_t kcm_cred_get_uuid(struct kcm_cred *crd, uuid_t uuid);
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -320,6 +325,11 @@ bool sec_key_match_name(const char *sec_key,
|
||||||
|
bool sec_key_match_uuid(const char *sec_key,
|
||||||
|
uuid_t uuid);
|
||||||
|
|
||||||
|
+errno_t sec_key_parse(TALLOC_CTX *mem_ctx,
|
||||||
|
+ const char *sec_key,
|
||||||
|
+ const char **_name,
|
||||||
|
+ uuid_t uuid);
|
||||||
|
+
|
||||||
|
const char *sec_key_get_name(const char *sec_key);
|
||||||
|
|
||||||
|
errno_t sec_key_get_uuid(const char *sec_key,
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache_json.c b/src/responder/kcm/kcmsrv_ccache_json.c
|
||||||
|
index 8101f5ddc148bfff83cc02cf9b19a3566209e781..7f73b56bf6c27417271876a989695ff917c3886e 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ccache_json.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache_json.c
|
||||||
|
@@ -37,12 +37,6 @@
|
||||||
|
*/
|
||||||
|
#define KS_JSON_VERSION 1
|
||||||
|
|
||||||
|
-/*
|
||||||
|
- * The secrets store is a key-value store at heart. We store the UUID
|
||||||
|
- * and the name in the key to allow easy lookups be either key
|
||||||
|
- */
|
||||||
|
-#define SEC_KEY_SEPARATOR '-'
|
||||||
|
-
|
||||||
|
/* Compat definition of json_array_foreach for older systems */
|
||||||
|
#ifndef json_array_foreach
|
||||||
|
#define json_array_foreach(array, idx, value) \
|
||||||
|
@@ -51,119 +45,6 @@
|
||||||
|
idx++)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-const char *sec_key_create(TALLOC_CTX *mem_ctx,
|
||||||
|
- const char *name,
|
||||||
|
- uuid_t uuid)
|
||||||
|
-{
|
||||||
|
- char uuid_str[UUID_STR_SIZE];
|
||||||
|
-
|
||||||
|
- uuid_unparse(uuid, uuid_str);
|
||||||
|
- return talloc_asprintf(mem_ctx,
|
||||||
|
- "%s%c%s", uuid_str, SEC_KEY_SEPARATOR, name);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static bool sec_key_valid(const char *sec_key)
|
||||||
|
-{
|
||||||
|
- if (sec_key == NULL) {
|
||||||
|
- return false;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (strlen(sec_key) < UUID_STR_SIZE + 1) {
|
||||||
|
- /* One char for separator (at UUID_STR_SIZE, because strlen doesn't
|
||||||
|
- * include the '\0', but UUID_STR_SIZE does) and at least one for
|
||||||
|
- * the name */
|
||||||
|
- DEBUG(SSSDBG_CRIT_FAILURE, "Key %s is too short\n", sec_key);
|
||||||
|
- return false;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (sec_key[UUID_STR_SIZE - 1] != SEC_KEY_SEPARATOR) {
|
||||||
|
- DEBUG(SSSDBG_CRIT_FAILURE, "Key doesn't contain the separator\n");
|
||||||
|
- return false;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return true;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static errno_t sec_key_parse(TALLOC_CTX *mem_ctx,
|
||||||
|
- const char *sec_key,
|
||||||
|
- const char **_name,
|
||||||
|
- uuid_t uuid)
|
||||||
|
-{
|
||||||
|
- char uuid_str[UUID_STR_SIZE];
|
||||||
|
-
|
||||||
|
- if (!sec_key_valid(sec_key)) {
|
||||||
|
- return EINVAL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- strncpy(uuid_str, sec_key, sizeof(uuid_str)-1);
|
||||||
|
- if (sec_key[UUID_STR_SIZE - 1] != SEC_KEY_SEPARATOR) {
|
||||||
|
- DEBUG(SSSDBG_CRIT_FAILURE, "Key doesn't contain the separator\n");
|
||||||
|
- return EINVAL;
|
||||||
|
- }
|
||||||
|
- uuid_str[UUID_STR_SIZE-1] = '\0';
|
||||||
|
-
|
||||||
|
- *_name = talloc_strdup(mem_ctx, sec_key + UUID_STR_SIZE);
|
||||||
|
- if (*_name == NULL) {
|
||||||
|
- return ENOMEM;
|
||||||
|
- }
|
||||||
|
- uuid_parse(uuid_str, uuid);
|
||||||
|
-
|
||||||
|
- return EOK;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-errno_t sec_key_get_uuid(const char *sec_key,
|
||||||
|
- uuid_t uuid)
|
||||||
|
-{
|
||||||
|
- char uuid_str[UUID_STR_SIZE];
|
||||||
|
-
|
||||||
|
- if (!sec_key_valid(sec_key)) {
|
||||||
|
- return EINVAL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- strncpy(uuid_str, sec_key, UUID_STR_SIZE-1);
|
||||||
|
- uuid_str[UUID_STR_SIZE-1] = '\0';
|
||||||
|
- uuid_parse(uuid_str, uuid);
|
||||||
|
- return EOK;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-const char *sec_key_get_name(const char *sec_key)
|
||||||
|
-{
|
||||||
|
- if (!sec_key_valid(sec_key)) {
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return sec_key + UUID_STR_SIZE;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-bool sec_key_match_name(const char *sec_key,
|
||||||
|
- const char *name)
|
||||||
|
-{
|
||||||
|
- if (!sec_key_valid(sec_key) || name == NULL) {
|
||||||
|
- return false;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return strcmp(sec_key + UUID_STR_SIZE, name) == 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-bool sec_key_match_uuid(const char *sec_key,
|
||||||
|
- uuid_t uuid)
|
||||||
|
-{
|
||||||
|
- errno_t ret;
|
||||||
|
- uuid_t key_uuid;
|
||||||
|
-
|
||||||
|
- /* `key_uuid` is output arg and isn't read in sec_key_get_uuid() but
|
||||||
|
- * since libuuid is opaque for cppcheck it generates false positive here
|
||||||
|
- */
|
||||||
|
- /* cppcheck-suppress uninitvar */
|
||||||
|
- ret = sec_key_get_uuid(sec_key, key_uuid);
|
||||||
|
- if (ret != EOK) {
|
||||||
|
- DEBUG(SSSDBG_MINOR_FAILURE, "Cannot convert key to UUID\n");
|
||||||
|
- return false;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- return uuid_compare(key_uuid, uuid) == 0;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* Creates an array of principal elements that will be used later
|
||||||
|
* in the form of:
|
||||||
|
@@ -928,16 +809,9 @@ errno_t sec_kv_to_ccache_json(TALLOC_CTX *mem_ctx,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* We rely on sssd-secrets only searching the user's subtree so we
|
||||||
|
- * set the ownership to the client
|
||||||
|
- */
|
||||||
|
- cc->owner.uid = cli_creds_get_uid(client);
|
||||||
|
- cc->owner.gid = cli_creds_get_gid(client);
|
||||||
|
-
|
||||||
|
- ret = sec_key_parse(cc, sec_key, &cc->name, cc->uuid);
|
||||||
|
+ ret = kcm_cc_set_header(cc, sec_key, client);
|
||||||
|
if (ret != EOK) {
|
||||||
|
- DEBUG(SSSDBG_CRIT_FAILURE,
|
||||||
|
- "Cannt parse secret key [%d]: %s\n",
|
||||||
|
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot store ccache header [%d]: %s\n",
|
||||||
|
ret, sss_strerror(ret));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache_key.c b/src/responder/kcm/kcmsrv_ccache_key.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..ba64f2128c0bba62434b4f84d81514e6b52bc2b6
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache_key.c
|
||||||
|
@@ -0,0 +1,145 @@
|
||||||
|
+/*
|
||||||
|
+ SSSD
|
||||||
|
+
|
||||||
|
+ Copyright (C) Red Hat, 2020
|
||||||
|
+
|
||||||
|
+ This program is free software; you can redistribute it and/or modify
|
||||||
|
+ it under the terms of the GNU General Public License as published by
|
||||||
|
+ the Free Software Foundation; either version 3 of the License, or
|
||||||
|
+ (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ This program is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
+ GNU General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU General Public License
|
||||||
|
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
+*/
|
||||||
|
+
|
||||||
|
+#include "config.h"
|
||||||
|
+
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <talloc.h>
|
||||||
|
+
|
||||||
|
+#include "util/util.h"
|
||||||
|
+#include "responder/kcm/kcmsrv_ccache_pvt.h"
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * The secrets store is a key-value store at heart. We store the UUID
|
||||||
|
+ * and the name in the key to allow easy lookups by either part.
|
||||||
|
+ */
|
||||||
|
+#define SEC_KEY_SEPARATOR '-'
|
||||||
|
+
|
||||||
|
+const char *sec_key_create(TALLOC_CTX *mem_ctx,
|
||||||
|
+ const char *name,
|
||||||
|
+ uuid_t uuid)
|
||||||
|
+{
|
||||||
|
+ char uuid_str[UUID_STR_SIZE];
|
||||||
|
+
|
||||||
|
+ uuid_unparse(uuid, uuid_str);
|
||||||
|
+ return talloc_asprintf(mem_ctx,
|
||||||
|
+ "%s%c%s", uuid_str, SEC_KEY_SEPARATOR, name);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static bool sec_key_valid(const char *sec_key)
|
||||||
|
+{
|
||||||
|
+ if (sec_key == NULL) {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (strlen(sec_key) < UUID_STR_SIZE + 1) {
|
||||||
|
+ /* One char for separator (at UUID_STR_SIZE, because strlen doesn't
|
||||||
|
+ * include the '\0', but UUID_STR_SIZE does) and at least one for
|
||||||
|
+ * the name */
|
||||||
|
+ DEBUG(SSSDBG_CRIT_FAILURE, "Key %s is too short\n", sec_key);
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (sec_key[UUID_STR_SIZE - 1] != SEC_KEY_SEPARATOR) {
|
||||||
|
+ DEBUG(SSSDBG_CRIT_FAILURE, "Key doesn't contain the separator\n");
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+errno_t sec_key_parse(TALLOC_CTX *mem_ctx,
|
||||||
|
+ const char *sec_key,
|
||||||
|
+ const char **_name,
|
||||||
|
+ uuid_t uuid)
|
||||||
|
+{
|
||||||
|
+ char uuid_str[UUID_STR_SIZE];
|
||||||
|
+
|
||||||
|
+ if (!sec_key_valid(sec_key)) {
|
||||||
|
+ return EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ strncpy(uuid_str, sec_key, sizeof(uuid_str)-1);
|
||||||
|
+ if (sec_key[UUID_STR_SIZE - 1] != SEC_KEY_SEPARATOR) {
|
||||||
|
+ DEBUG(SSSDBG_CRIT_FAILURE, "Key doesn't contain the separator\n");
|
||||||
|
+ return EINVAL;
|
||||||
|
+ }
|
||||||
|
+ uuid_str[UUID_STR_SIZE-1] = '\0';
|
||||||
|
+
|
||||||
|
+ *_name = talloc_strdup(mem_ctx, sec_key + UUID_STR_SIZE);
|
||||||
|
+ if (*_name == NULL) {
|
||||||
|
+ return ENOMEM;
|
||||||
|
+ }
|
||||||
|
+ uuid_parse(uuid_str, uuid);
|
||||||
|
+
|
||||||
|
+ return EOK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+errno_t sec_key_get_uuid(const char *sec_key,
|
||||||
|
+ uuid_t uuid)
|
||||||
|
+{
|
||||||
|
+ char uuid_str[UUID_STR_SIZE];
|
||||||
|
+
|
||||||
|
+ if (!sec_key_valid(sec_key)) {
|
||||||
|
+ return EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ strncpy(uuid_str, sec_key, UUID_STR_SIZE-1);
|
||||||
|
+ uuid_str[UUID_STR_SIZE-1] = '\0';
|
||||||
|
+ uuid_parse(uuid_str, uuid);
|
||||||
|
+ return EOK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+const char *sec_key_get_name(const char *sec_key)
|
||||||
|
+{
|
||||||
|
+ if (!sec_key_valid(sec_key)) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return sec_key + UUID_STR_SIZE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+bool sec_key_match_name(const char *sec_key,
|
||||||
|
+ const char *name)
|
||||||
|
+{
|
||||||
|
+ if (!sec_key_valid(sec_key) || name == NULL) {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return strcmp(sec_key + UUID_STR_SIZE, name) == 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+bool sec_key_match_uuid(const char *sec_key,
|
||||||
|
+ uuid_t uuid)
|
||||||
|
+{
|
||||||
|
+ errno_t ret;
|
||||||
|
+ uuid_t key_uuid;
|
||||||
|
+
|
||||||
|
+ /* `key_uuid` is output arg and isn't read in sec_key_get_uuid() but
|
||||||
|
+ * since libuuid is opaque for cppcheck it generates false positive here
|
||||||
|
+ */
|
||||||
|
+ /* cppcheck-suppress uninitvar */
|
||||||
|
+ ret = sec_key_get_uuid(sec_key, key_uuid);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ DEBUG(SSSDBG_MINOR_FAILURE, "Cannot convert key to UUID\n");
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return uuid_compare(key_uuid, uuid) == 0;
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.25.4
|
||||||
|
|
30
0010-kcm-avoid-suppression-of-cppcheck-warning.patch
Normal file
30
0010-kcm-avoid-suppression-of-cppcheck-warning.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
From efd57d2a6001b7015095f7ff5bbd0c55764e22ab Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||||
|
Date: Tue, 27 Oct 2020 16:37:05 +0100
|
||||||
|
Subject: [PATCH 10/19] kcm: avoid suppression of cppcheck warning
|
||||||
|
|
||||||
|
---
|
||||||
|
src/responder/kcm/kcmsrv_ccache_key.c | 7 +++----
|
||||||
|
1 file changed, 3 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache_key.c b/src/responder/kcm/kcmsrv_ccache_key.c
|
||||||
|
index ba64f2128c0bba62434b4f84d81514e6b52bc2b6..4a24c38d45918632201740bfc82579a2449aa8f7 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ccache_key.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache_key.c
|
||||||
|
@@ -131,10 +131,9 @@ bool sec_key_match_uuid(const char *sec_key,
|
||||||
|
errno_t ret;
|
||||||
|
uuid_t key_uuid;
|
||||||
|
|
||||||
|
- /* `key_uuid` is output arg and isn't read in sec_key_get_uuid() but
|
||||||
|
- * since libuuid is opaque for cppcheck it generates false positive here
|
||||||
|
- */
|
||||||
|
- /* cppcheck-suppress uninitvar */
|
||||||
|
+ /* Clear uuid value to avoid cppcheck warning. */
|
||||||
|
+ uuid_clear(key_uuid);
|
||||||
|
+
|
||||||
|
ret = sec_key_get_uuid(sec_key, key_uuid);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_MINOR_FAILURE, "Cannot convert key to UUID\n");
|
||||||
|
--
|
||||||
|
2.25.4
|
||||||
|
|
@ -0,0 +1,42 @@
|
|||||||
|
From d51819e51fca80675b9915863e72d835c9e0a0fe Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||||
|
Date: Tue, 27 Oct 2020 17:09:43 +0100
|
||||||
|
Subject: [PATCH 11/19] kcm: add spaces around operators in kcmsrv_ccache_key.c
|
||||||
|
|
||||||
|
---
|
||||||
|
src/responder/kcm/kcmsrv_ccache_key.c | 8 ++++----
|
||||||
|
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache_key.c b/src/responder/kcm/kcmsrv_ccache_key.c
|
||||||
|
index 4a24c38d45918632201740bfc82579a2449aa8f7..59d60453c5d5e28ccda8f98c63125954640d0e8b 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ccache_key.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache_key.c
|
||||||
|
@@ -75,12 +75,12 @@ errno_t sec_key_parse(TALLOC_CTX *mem_ctx,
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- strncpy(uuid_str, sec_key, sizeof(uuid_str)-1);
|
||||||
|
+ strncpy(uuid_str, sec_key, sizeof(uuid_str) - 1);
|
||||||
|
if (sec_key[UUID_STR_SIZE - 1] != SEC_KEY_SEPARATOR) {
|
||||||
|
DEBUG(SSSDBG_CRIT_FAILURE, "Key doesn't contain the separator\n");
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
- uuid_str[UUID_STR_SIZE-1] = '\0';
|
||||||
|
+ uuid_str[UUID_STR_SIZE - 1] = '\0';
|
||||||
|
|
||||||
|
*_name = talloc_strdup(mem_ctx, sec_key + UUID_STR_SIZE);
|
||||||
|
if (*_name == NULL) {
|
||||||
|
@@ -100,8 +100,8 @@ errno_t sec_key_get_uuid(const char *sec_key,
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- strncpy(uuid_str, sec_key, UUID_STR_SIZE-1);
|
||||||
|
- uuid_str[UUID_STR_SIZE-1] = '\0';
|
||||||
|
+ strncpy(uuid_str, sec_key, UUID_STR_SIZE - 1);
|
||||||
|
+ uuid_str[UUID_STR_SIZE - 1] = '\0';
|
||||||
|
uuid_parse(uuid_str, uuid);
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.25.4
|
||||||
|
|
741
0012-kcm-use-binary-format-to-store-ccache-instead-of-jso.patch
Normal file
741
0012-kcm-use-binary-format-to-store-ccache-instead-of-jso.patch
Normal file
@ -0,0 +1,741 @@
|
|||||||
|
From 94ceb85465dbf052f681bbd6c8ebced4d2d97f92 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||||
|
Date: Tue, 27 Oct 2020 16:21:31 +0100
|
||||||
|
Subject: [PATCH 12/19] kcm: use binary format to store ccache instead of json
|
||||||
|
|
||||||
|
JSON is computationally complex and the parser is a bottleneck which
|
||||||
|
consumes about 10% of time. It also create the ccache unnecessary
|
||||||
|
large because it requires lots of unneded character and base64
|
||||||
|
encoding.
|
||||||
|
|
||||||
|
Binary format is fast, simple and small.
|
||||||
|
|
||||||
|
This is backwards compatible and there is no need to destroy existing
|
||||||
|
ccache. It will be stored in binary format at first write to the cache.
|
||||||
|
|
||||||
|
Resolves: https://github.com/SSSD/sssd/issues/5349
|
||||||
|
---
|
||||||
|
Makefile.am | 2 +
|
||||||
|
src/responder/kcm/kcmsrv_ccache.h | 16 +-
|
||||||
|
src/responder/kcm/kcmsrv_ccache_binary.c | 308 ++++++++++++++++++++++
|
||||||
|
src/responder/kcm/kcmsrv_ccache_json.c | 1 -
|
||||||
|
src/responder/kcm/kcmsrv_ccache_secdb.c | 49 ++--
|
||||||
|
src/responder/kcm/kcmsrv_ccache_secrets.c | 2 +-
|
||||||
|
src/tests/cmocka/test_kcm_marshalling.c | 112 +++++++-
|
||||||
|
src/tests/multihost/basic/test_kcm.py | 12 +-
|
||||||
|
src/util/secrets/secrets.c | 2 +-
|
||||||
|
9 files changed, 476 insertions(+), 28 deletions(-)
|
||||||
|
create mode 100644 src/responder/kcm/kcmsrv_ccache_binary.c
|
||||||
|
|
||||||
|
diff --git a/Makefile.am b/Makefile.am
|
||||||
|
index ae9bc540a86f2e291dd5b5f66e1ce4f0aacbaf61..430b4e8424d6bde0c7de919c6aceabf3839e3a23 100644
|
||||||
|
--- a/Makefile.am
|
||||||
|
+++ b/Makefile.am
|
||||||
|
@@ -1817,6 +1817,7 @@ sssd_kcm_SOURCES = \
|
||||||
|
src/responder/kcm/kcm.c \
|
||||||
|
src/responder/kcm/kcmsrv_cmd.c \
|
||||||
|
src/responder/kcm/kcmsrv_ccache.c \
|
||||||
|
+ src/responder/kcm/kcmsrv_ccache_binary.c \
|
||||||
|
src/responder/kcm/kcmsrv_ccache_mem.c \
|
||||||
|
src/responder/kcm/kcmsrv_ccache_json.c \
|
||||||
|
src/responder/kcm/kcmsrv_ccache_key.c \
|
||||||
|
@@ -3930,6 +3931,7 @@ test_sssd_krb5_locator_plugin_LDADD = \
|
||||||
|
if BUILD_KCM
|
||||||
|
test_kcm_marshalling_SOURCES = \
|
||||||
|
src/tests/cmocka/test_kcm_marshalling.c \
|
||||||
|
+ src/responder/kcm/kcmsrv_ccache_binary.c \
|
||||||
|
src/responder/kcm/kcmsrv_ccache_json.c \
|
||||||
|
src/responder/kcm/kcmsrv_ccache_key.c \
|
||||||
|
src/responder/kcm/kcmsrv_ccache.c \
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache.h b/src/responder/kcm/kcmsrv_ccache.h
|
||||||
|
index 892067f3170b19c0e55ceaa75b0c01f772c49d3d..b0a7acb9fed8a8f89a3d0e2239ab28c7ce80fa23 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ccache.h
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache.h
|
||||||
|
@@ -352,7 +352,21 @@ errno_t sec_kv_to_ccache_json(TALLOC_CTX *mem_ctx,
|
||||||
|
/* Convert a kcm_ccache to a key-value pair to be stored in secrets */
|
||||||
|
errno_t kcm_ccache_to_sec_input_json(TALLOC_CTX *mem_ctx,
|
||||||
|
struct kcm_ccache *cc,
|
||||||
|
- struct cli_creds *client,
|
||||||
|
struct sss_iobuf **_payload);
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * sec_key is a concatenation of the ccache's UUID and name
|
||||||
|
+ * sec_value is the binary representation of ccache.
|
||||||
|
+ */
|
||||||
|
+errno_t sec_kv_to_ccache_binary(TALLOC_CTX *mem_ctx,
|
||||||
|
+ const char *sec_key,
|
||||||
|
+ struct sss_iobuf *sec_value,
|
||||||
|
+ struct cli_creds *client,
|
||||||
|
+ struct kcm_ccache **_cc);
|
||||||
|
+
|
||||||
|
+/* Convert a kcm_ccache to its binary representation. */
|
||||||
|
+errno_t kcm_ccache_to_sec_input_binary(TALLOC_CTX *mem_ctx,
|
||||||
|
+ struct kcm_ccache *cc,
|
||||||
|
+ struct sss_iobuf **_payload);
|
||||||
|
+
|
||||||
|
#endif /* _KCMSRV_CCACHE_H_ */
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache_binary.c b/src/responder/kcm/kcmsrv_ccache_binary.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..7bfdbf13bfeaa7d45de6352e7b51b781b713b8f2
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache_binary.c
|
||||||
|
@@ -0,0 +1,308 @@
|
||||||
|
+/*
|
||||||
|
+ Authors:
|
||||||
|
+ Pavel Březina <pbrezina@redhat.com>
|
||||||
|
+
|
||||||
|
+ Copyright (C) 2020 Red Hat
|
||||||
|
+
|
||||||
|
+ This program is free software; you can redistribute it and/or modify
|
||||||
|
+ it under the terms of the GNU General Public License as published by
|
||||||
|
+ the Free Software Foundation; either version 3 of the License, or
|
||||||
|
+ (at your option) any later version.
|
||||||
|
+
|
||||||
|
+ This program is distributed in the hope that it will be useful,
|
||||||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
+ GNU General Public License for more details.
|
||||||
|
+
|
||||||
|
+ You should have received a copy of the GNU General Public License
|
||||||
|
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
+*/
|
||||||
|
+
|
||||||
|
+#include "config.h"
|
||||||
|
+
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <talloc.h>
|
||||||
|
+
|
||||||
|
+#include "util/util.h"
|
||||||
|
+#include "util/util_creds.h"
|
||||||
|
+#include "util/crypto/sss_crypto.h"
|
||||||
|
+#include "responder/kcm/kcmsrv_ccache_pvt.h"
|
||||||
|
+
|
||||||
|
+static errno_t krb_data_to_bin(krb5_data *data, struct sss_iobuf *buf)
|
||||||
|
+{
|
||||||
|
+ return sss_iobuf_write_varlen(buf, (uint8_t *)data->data, data->length);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static errno_t princ_to_bin(krb5_principal princ, struct sss_iobuf *buf)
|
||||||
|
+{
|
||||||
|
+ errno_t ret;
|
||||||
|
+
|
||||||
|
+ if (princ == NULL) {
|
||||||
|
+ return sss_iobuf_write_uint8(buf, 0);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Mark that principal is not empty. */
|
||||||
|
+ ret = sss_iobuf_write_uint8(buf, 1);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = krb_data_to_bin(&princ->realm, buf);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = sss_iobuf_write_int32(buf, princ->type);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = sss_iobuf_write_int32(buf, princ->length);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (krb5_int32 i = 0; i < princ->length; i++) {
|
||||||
|
+ ret = krb_data_to_bin(&princ->data[i], buf);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return EOK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static errno_t creds_to_bin(struct kcm_cred *creds, struct sss_iobuf *buf)
|
||||||
|
+{
|
||||||
|
+ struct kcm_cred *crd;
|
||||||
|
+ uint32_t count = 0;
|
||||||
|
+ errno_t ret;
|
||||||
|
+
|
||||||
|
+ DLIST_FOR_EACH(crd, creds) {
|
||||||
|
+ count++;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = sss_iobuf_write_uint32(buf, count);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ DLIST_FOR_EACH(crd, creds) {
|
||||||
|
+ ret = sss_iobuf_write_len(buf, (uint8_t *)crd->uuid, sizeof(uuid_t));
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = sss_iobuf_write_iobuf(buf, crd->cred_blob);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return EOK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+errno_t kcm_ccache_to_sec_input_binary(TALLOC_CTX *mem_ctx,
|
||||||
|
+ struct kcm_ccache *cc,
|
||||||
|
+ struct sss_iobuf **_payload)
|
||||||
|
+{
|
||||||
|
+ struct sss_iobuf *buf;
|
||||||
|
+ errno_t ret;
|
||||||
|
+
|
||||||
|
+ buf = sss_iobuf_init_empty(mem_ctx, sizeof(krb5_principal_data), 0);
|
||||||
|
+ if (buf == NULL) {
|
||||||
|
+ return ENOMEM;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = sss_iobuf_write_int32(buf, cc->kdc_offset);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ goto done;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = princ_to_bin(cc->client, buf);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ goto done;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = creds_to_bin(cc->creds, buf);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ goto done;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *_payload = buf;
|
||||||
|
+
|
||||||
|
+ ret = EOK;
|
||||||
|
+
|
||||||
|
+done:
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ talloc_free(buf);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static errno_t bin_to_krb_data(TALLOC_CTX *mem_ctx,
|
||||||
|
+ struct sss_iobuf *buf,
|
||||||
|
+ krb5_data *out)
|
||||||
|
+{
|
||||||
|
+ uint8_t *data;
|
||||||
|
+ size_t len;
|
||||||
|
+ errno_t ret;
|
||||||
|
+
|
||||||
|
+ ret = sss_iobuf_read_varlen(mem_ctx, buf, &data, &len);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ out->magic = 0;
|
||||||
|
+ out->data = (char*)data;
|
||||||
|
+ out->length = len;
|
||||||
|
+
|
||||||
|
+ return EOK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static errno_t bin_to_princ(TALLOC_CTX *mem_ctx,
|
||||||
|
+ struct sss_iobuf *buf,
|
||||||
|
+ krb5_principal *_princ)
|
||||||
|
+{
|
||||||
|
+ krb5_principal princ;
|
||||||
|
+ uint8_t non_empty;
|
||||||
|
+ krb5_int32 i;
|
||||||
|
+ errno_t ret;
|
||||||
|
+
|
||||||
|
+ ret = sss_iobuf_read_uint8(buf, &non_empty);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (non_empty == 0) {
|
||||||
|
+ *_princ = NULL;
|
||||||
|
+ return EOK;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ princ = talloc_zero(mem_ctx, struct krb5_principal_data);
|
||||||
|
+ if (princ == NULL) {
|
||||||
|
+ return ENOMEM;
|
||||||
|
+ }
|
||||||
|
+ princ->magic = KV5M_PRINCIPAL;
|
||||||
|
+
|
||||||
|
+ ret = bin_to_krb_data(princ, buf, &princ->realm);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = sss_iobuf_read_int32(buf, &princ->type);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = sss_iobuf_read_int32(buf, &princ->length);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ princ->data = talloc_zero_array(princ, krb5_data, princ->length);
|
||||||
|
+ if (princ->length > 0 && princ->data == NULL) {
|
||||||
|
+ return ENOMEM;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < princ->length; i++) {
|
||||||
|
+ ret = bin_to_krb_data(princ, buf, &princ->data[i]);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *_princ = princ;
|
||||||
|
+
|
||||||
|
+ return EOK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static errno_t bin_to_creds(TALLOC_CTX *mem_ctx,
|
||||||
|
+ struct sss_iobuf *buf,
|
||||||
|
+ struct kcm_cred **_creds)
|
||||||
|
+{
|
||||||
|
+ struct kcm_cred *creds = NULL;
|
||||||
|
+ struct kcm_cred *crd;
|
||||||
|
+ struct sss_iobuf *cred_blob;
|
||||||
|
+ uint32_t count;
|
||||||
|
+ uuid_t uuid;
|
||||||
|
+ errno_t ret;
|
||||||
|
+
|
||||||
|
+ ret = sss_iobuf_read_uint32(buf, &count);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (uint32_t i = 0; i < count; i++) {
|
||||||
|
+ ret = sss_iobuf_read_len(buf, sizeof(uuid_t), (uint8_t*)uuid);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = sss_iobuf_read_iobuf(NULL, buf, &cred_blob);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ crd = kcm_cred_new(mem_ctx, uuid, cred_blob);
|
||||||
|
+ if (crd == NULL) {
|
||||||
|
+ talloc_free(cred_blob);
|
||||||
|
+ return ENOMEM;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ DLIST_ADD(creds, crd);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *_creds = creds;
|
||||||
|
+
|
||||||
|
+ return EOK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+errno_t sec_kv_to_ccache_binary(TALLOC_CTX *mem_ctx,
|
||||||
|
+ const char *sec_key,
|
||||||
|
+ struct sss_iobuf *sec_value,
|
||||||
|
+ struct cli_creds *client,
|
||||||
|
+ struct kcm_ccache **_cc)
|
||||||
|
+{
|
||||||
|
+ struct kcm_ccache *cc;
|
||||||
|
+ errno_t ret;
|
||||||
|
+
|
||||||
|
+ cc = talloc_zero(mem_ctx, struct kcm_ccache);
|
||||||
|
+ if (cc == NULL) {
|
||||||
|
+ return ENOMEM;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = kcm_cc_set_header(cc, sec_key, client);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot store ccache header [%d]: %s\n",
|
||||||
|
+ ret, sss_strerror(ret));
|
||||||
|
+ goto done;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = sss_iobuf_read_int32(sec_value, &cc->kdc_offset);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ goto done;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = bin_to_princ(cc, sec_value, &cc->client);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ goto done;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = bin_to_creds(cc, sec_value, &cc->creds);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ goto done;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *_cc = cc;
|
||||||
|
+
|
||||||
|
+ ret = EOK;
|
||||||
|
+
|
||||||
|
+done:
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ talloc_free(cc);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache_json.c b/src/responder/kcm/kcmsrv_ccache_json.c
|
||||||
|
index 7f73b56bf6c27417271876a989695ff917c3886e..e790cbea36d57d2ba0d4e25fc8fc249a4e653c3c 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ccache_json.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache_json.c
|
||||||
|
@@ -343,7 +343,6 @@ static errno_t ccache_to_sec_val(TALLOC_CTX *mem_ctx,
|
||||||
|
|
||||||
|
errno_t kcm_ccache_to_sec_input_json(TALLOC_CTX *mem_ctx,
|
||||||
|
struct kcm_ccache *cc,
|
||||||
|
- struct cli_creds *client,
|
||||||
|
struct sss_iobuf **_payload)
|
||||||
|
{
|
||||||
|
errno_t ret;
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache_secdb.c b/src/responder/kcm/kcmsrv_ccache_secdb.c
|
||||||
|
index f5cfe47a7c6deac17031788105ac4235a6aaa9ff..726711ac441c40a6bfc84045e9b3e5b85505c7e0 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ccache_secdb.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache_secdb.c
|
||||||
|
@@ -37,11 +37,14 @@
|
||||||
|
|
||||||
|
static errno_t sec_get(TALLOC_CTX *mem_ctx,
|
||||||
|
struct sss_sec_req *req,
|
||||||
|
- struct sss_iobuf **_buf)
|
||||||
|
+ struct sss_iobuf **_buf,
|
||||||
|
+ char **_datatype)
|
||||||
|
{
|
||||||
|
errno_t ret;
|
||||||
|
TALLOC_CTX *tmp_ctx;
|
||||||
|
- char *secret;
|
||||||
|
+ char *datatype;
|
||||||
|
+ uint8_t *data;
|
||||||
|
+ size_t len;
|
||||||
|
struct sss_iobuf *buf;
|
||||||
|
|
||||||
|
tmp_ctx = talloc_new(mem_ctx);
|
||||||
|
@@ -49,23 +52,27 @@ static errno_t sec_get(TALLOC_CTX *mem_ctx,
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = sss_sec_get(tmp_ctx, req, (uint8_t **)&secret, NULL, NULL);
|
||||||
|
+ ret = sss_sec_get(tmp_ctx, req, &data, &len, &datatype);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"Cannot retrieve the secret [%d]: %s\n", ret, sss_strerror(ret));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- buf = sss_iobuf_init_readonly(tmp_ctx, (const uint8_t *)secret,
|
||||||
|
- strlen(secret) + 1);
|
||||||
|
+ buf = sss_iobuf_init_steal(tmp_ctx, data, len);
|
||||||
|
if (buf == NULL) {
|
||||||
|
DEBUG(SSSDBG_CRIT_FAILURE, "Cannot init the iobuf\n");
|
||||||
|
ret = EIO;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = EOK;
|
||||||
|
*_buf = talloc_steal(mem_ctx, buf);
|
||||||
|
+ if (_datatype != NULL) {
|
||||||
|
+ *_datatype = talloc_steal(mem_ctx, datatype);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = EOK;
|
||||||
|
+
|
||||||
|
done:
|
||||||
|
talloc_free(tmp_ctx);
|
||||||
|
return ret;
|
||||||
|
@@ -78,7 +85,7 @@ static errno_t sec_put(TALLOC_CTX *mem_ctx,
|
||||||
|
errno_t ret;
|
||||||
|
|
||||||
|
ret = sss_sec_put(req, sss_iobuf_get_data(buf), sss_iobuf_get_size(buf),
|
||||||
|
- SSS_SEC_PLAINTEXT, "simple");
|
||||||
|
+ SSS_SEC_PLAINTEXT, "binary");
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"Cannot write the secret [%d]: %s\n", ret, sss_strerror(ret));
|
||||||
|
@@ -94,7 +101,7 @@ static errno_t sec_update(TALLOC_CTX *mem_ctx,
|
||||||
|
errno_t ret;
|
||||||
|
|
||||||
|
ret = sss_sec_update(req, sss_iobuf_get_data(buf), sss_iobuf_get_size(buf),
|
||||||
|
- SSS_SEC_PLAINTEXT, "simple");
|
||||||
|
+ SSS_SEC_PLAINTEXT, "binary");
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"Cannot write the secret [%d]: %s\n", ret, sss_strerror(ret));
|
||||||
|
@@ -160,7 +167,7 @@ static errno_t kcm_ccache_to_secdb_kv(TALLOC_CTX *mem_ctx,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = kcm_ccache_to_sec_input_json(mem_ctx, cc, client, &payload);
|
||||||
|
+ ret = kcm_ccache_to_sec_input_binary(mem_ctx, cc, &payload);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_CRIT_FAILURE,
|
||||||
|
"Cannot convert ccache to a secret [%d][%s]\n", ret, sss_strerror(ret));
|
||||||
|
@@ -434,6 +441,7 @@ static errno_t secdb_get_cc(TALLOC_CTX *mem_ctx,
|
||||||
|
struct kcm_ccache *cc = NULL;
|
||||||
|
struct sss_sec_req *sreq = NULL;
|
||||||
|
struct sss_iobuf *ccbuf;
|
||||||
|
+ char *datatype;
|
||||||
|
|
||||||
|
tmp_ctx = talloc_new(mem_ctx);
|
||||||
|
if (tmp_ctx == NULL) {
|
||||||
|
@@ -447,20 +455,23 @@ static errno_t secdb_get_cc(TALLOC_CTX *mem_ctx,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = sec_get(tmp_ctx, sreq, &ccbuf);
|
||||||
|
+ ret = sec_get(tmp_ctx, sreq, &ccbuf, &datatype);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"Cannot get the secret [%d][%s]\n", ret, sss_strerror(ret));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = sec_kv_to_ccache_json(tmp_ctx, secdb_key,
|
||||||
|
- (const char *)sss_iobuf_get_data(ccbuf),
|
||||||
|
- client, &cc);
|
||||||
|
+ if (strcmp(datatype, "binary") == 0) {
|
||||||
|
+ ret = sec_kv_to_ccache_binary(tmp_ctx, secdb_key, ccbuf, client, &cc);
|
||||||
|
+ } else {
|
||||||
|
+ ret = sec_kv_to_ccache_json(tmp_ctx, secdb_key,
|
||||||
|
+ (const char *)sss_iobuf_get_data(ccbuf),
|
||||||
|
+ client, &cc);
|
||||||
|
+ }
|
||||||
|
if (ret != EOK) {
|
||||||
|
- DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
- "Cannot convert JSON keyval to ccache blob [%d]: %s\n",
|
||||||
|
- ret, sss_strerror(ret));
|
||||||
|
+ DEBUG(SSSDBG_OP_FAILURE, "Cannot convert %s data to ccache "
|
||||||
|
+ "[%d]: %s\n", datatype, ret, sss_strerror(ret));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -756,7 +767,7 @@ static struct tevent_req *ccdb_secdb_get_default_send(TALLOC_CTX *mem_ctx,
|
||||||
|
goto immediate;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = sec_get(state, sreq, &dfl_iobuf);
|
||||||
|
+ ret = sec_get(state, sreq, &dfl_iobuf, NULL);
|
||||||
|
if (ret == ENOENT) {
|
||||||
|
uuid_clear(state->uuid);
|
||||||
|
ret = EOK;
|
||||||
|
@@ -1249,7 +1260,7 @@ static struct tevent_req *ccdb_secdb_mod_send(TALLOC_CTX *mem_ctx,
|
||||||
|
goto immediate;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = kcm_ccache_to_sec_input_json(state, cc, client, &payload);
|
||||||
|
+ ret = kcm_ccache_to_sec_input_binary(state, cc, &payload);
|
||||||
|
if (ret != EOK) {
|
||||||
|
goto immediate;
|
||||||
|
}
|
||||||
|
@@ -1325,7 +1336,7 @@ static struct tevent_req *ccdb_secdb_store_cred_send(TALLOC_CTX *mem_ctx,
|
||||||
|
goto immediate;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = kcm_ccache_to_sec_input_json(state, cc, client, &payload);
|
||||||
|
+ ret = kcm_ccache_to_sec_input_binary(state, cc, &payload);
|
||||||
|
if (ret != EOK) {
|
||||||
|
goto immediate;
|
||||||
|
}
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache_secrets.c b/src/responder/kcm/kcmsrv_ccache_secrets.c
|
||||||
|
index 9d1fe8cad2dc6ed3ab43e181d0db52673d4759cc..f3d69842cf8c230800aaf4fc6554495fcf03f57d 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ccache_secrets.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache_secrets.c
|
||||||
|
@@ -195,7 +195,7 @@ static errno_t kcm_ccache_to_sec_kv(TALLOC_CTX *mem_ctx,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = kcm_ccache_to_sec_input_json(mem_ctx, cc, client, &payload);
|
||||||
|
+ ret = kcm_ccache_to_sec_input_json(mem_ctx, cc, &payload);
|
||||||
|
if (ret != EOK) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
diff --git a/src/tests/cmocka/test_kcm_marshalling.c b/src/tests/cmocka/test_kcm_marshalling.c
|
||||||
|
index f82129974787bba6883662a732311f3370bcc4f1..cebebac804b0a8a109084b35f58d4aab21e28da2 100644
|
||||||
|
--- a/src/tests/cmocka/test_kcm_marshalling.c
|
||||||
|
+++ b/src/tests/cmocka/test_kcm_marshalling.c
|
||||||
|
@@ -182,7 +182,7 @@ static void test_kcm_ccache_marshall_unmarshall_json(void **state)
|
||||||
|
&cc);
|
||||||
|
assert_int_equal(ret, EOK);
|
||||||
|
|
||||||
|
- ret = kcm_ccache_to_sec_input_json(test_ctx, cc, &owner, &payload);
|
||||||
|
+ ret = kcm_ccache_to_sec_input_json(test_ctx, cc, &payload);
|
||||||
|
assert_int_equal(ret, EOK);
|
||||||
|
|
||||||
|
data = sss_iobuf_get_data(payload);
|
||||||
|
@@ -237,7 +237,7 @@ static void test_kcm_ccache_no_princ_json(void **state)
|
||||||
|
princ = kcm_cc_get_client_principal(cc);
|
||||||
|
assert_null(princ);
|
||||||
|
|
||||||
|
- ret = kcm_ccache_to_sec_input_json(test_ctx, cc, &owner, &payload);
|
||||||
|
+ ret = kcm_ccache_to_sec_input_json(test_ctx, cc, &payload);
|
||||||
|
assert_int_equal(ret, EOK);
|
||||||
|
|
||||||
|
data = sss_iobuf_get_data(payload);
|
||||||
|
@@ -255,6 +255,108 @@ static void test_kcm_ccache_no_princ_json(void **state)
|
||||||
|
assert_cc_equal(cc, cc2);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void test_kcm_ccache_marshall_unmarshall_binary(void **state)
|
||||||
|
+{
|
||||||
|
+ struct kcm_marshalling_test_ctx *test_ctx = talloc_get_type(*state,
|
||||||
|
+ struct kcm_marshalling_test_ctx);
|
||||||
|
+ errno_t ret;
|
||||||
|
+ struct cli_creds owner;
|
||||||
|
+ struct kcm_ccache *cc;
|
||||||
|
+ struct kcm_ccache *cc2;
|
||||||
|
+ struct sss_iobuf *payload;
|
||||||
|
+ const char *name;
|
||||||
|
+ const char *key;
|
||||||
|
+ uint8_t *data;
|
||||||
|
+ uuid_t uuid;
|
||||||
|
+
|
||||||
|
+ owner.ucred.uid = getuid();
|
||||||
|
+ owner.ucred.gid = getuid();
|
||||||
|
+
|
||||||
|
+ name = talloc_asprintf(test_ctx, "%"SPRIuid, getuid());
|
||||||
|
+ assert_non_null(name);
|
||||||
|
+
|
||||||
|
+ ret = kcm_cc_new(test_ctx,
|
||||||
|
+ test_ctx->kctx,
|
||||||
|
+ &owner,
|
||||||
|
+ name,
|
||||||
|
+ test_ctx->princ,
|
||||||
|
+ &cc);
|
||||||
|
+ assert_int_equal(ret, EOK);
|
||||||
|
+
|
||||||
|
+ ret = kcm_ccache_to_sec_input_binary(test_ctx, cc, &payload);
|
||||||
|
+ assert_int_equal(ret, EOK);
|
||||||
|
+
|
||||||
|
+ data = sss_iobuf_get_data(payload);
|
||||||
|
+ assert_non_null(data);
|
||||||
|
+
|
||||||
|
+ ret = kcm_cc_get_uuid(cc, uuid);
|
||||||
|
+ assert_int_equal(ret, EOK);
|
||||||
|
+ key = sec_key_create(test_ctx, name, uuid);
|
||||||
|
+ assert_non_null(key);
|
||||||
|
+
|
||||||
|
+ sss_iobuf_cursor_reset(payload);
|
||||||
|
+ ret = sec_kv_to_ccache_binary(test_ctx, key, payload, &owner, &cc2);
|
||||||
|
+ assert_int_equal(ret, EOK);
|
||||||
|
+
|
||||||
|
+ assert_cc_equal(cc, cc2);
|
||||||
|
+
|
||||||
|
+ /* This key is exactly one byte shorter than it should be */
|
||||||
|
+ sss_iobuf_cursor_reset(payload);
|
||||||
|
+ ret = sec_kv_to_ccache_binary(test_ctx, TEST_UUID_STR "-", payload, &owner,
|
||||||
|
+ &cc2);
|
||||||
|
+ assert_int_equal(ret, EINVAL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void test_kcm_ccache_no_princ_binary(void **state)
|
||||||
|
+{
|
||||||
|
+ struct kcm_marshalling_test_ctx *test_ctx = talloc_get_type(*state,
|
||||||
|
+ struct kcm_marshalling_test_ctx);
|
||||||
|
+ errno_t ret;
|
||||||
|
+ struct cli_creds owner;
|
||||||
|
+ const char *name;
|
||||||
|
+ struct kcm_ccache *cc;
|
||||||
|
+ krb5_principal princ;
|
||||||
|
+ struct kcm_ccache *cc2;
|
||||||
|
+ struct sss_iobuf *payload;
|
||||||
|
+ const char *key;
|
||||||
|
+ uint8_t *data;
|
||||||
|
+ uuid_t uuid;
|
||||||
|
+
|
||||||
|
+ owner.ucred.uid = getuid();
|
||||||
|
+ owner.ucred.gid = getuid();
|
||||||
|
+
|
||||||
|
+ name = talloc_asprintf(test_ctx, "%"SPRIuid, getuid());
|
||||||
|
+ assert_non_null(name);
|
||||||
|
+
|
||||||
|
+ ret = kcm_cc_new(test_ctx,
|
||||||
|
+ test_ctx->kctx,
|
||||||
|
+ &owner,
|
||||||
|
+ name,
|
||||||
|
+ NULL,
|
||||||
|
+ &cc);
|
||||||
|
+ assert_int_equal(ret, EOK);
|
||||||
|
+
|
||||||
|
+ princ = kcm_cc_get_client_principal(cc);
|
||||||
|
+ assert_null(princ);
|
||||||
|
+
|
||||||
|
+ ret = kcm_ccache_to_sec_input_binary(test_ctx, cc, &payload);
|
||||||
|
+ assert_int_equal(ret, EOK);
|
||||||
|
+
|
||||||
|
+ data = sss_iobuf_get_data(payload);
|
||||||
|
+ assert_non_null(data);
|
||||||
|
+
|
||||||
|
+ ret = kcm_cc_get_uuid(cc, uuid);
|
||||||
|
+ assert_int_equal(ret, EOK);
|
||||||
|
+ key = sec_key_create(test_ctx, name, uuid);
|
||||||
|
+ assert_non_null(key);
|
||||||
|
+
|
||||||
|
+ sss_iobuf_cursor_reset(payload);
|
||||||
|
+ ret = sec_kv_to_ccache_binary(test_ctx, key, payload, &owner, &cc2);
|
||||||
|
+ assert_int_equal(ret, EOK);
|
||||||
|
+
|
||||||
|
+ assert_cc_equal(cc, cc2);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void test_sec_key_get_uuid(void **state)
|
||||||
|
{
|
||||||
|
errno_t ret;
|
||||||
|
@@ -325,6 +427,12 @@ int main(int argc, const char *argv[])
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct CMUnitTest tests[] = {
|
||||||
|
+ cmocka_unit_test_setup_teardown(test_kcm_ccache_marshall_unmarshall_binary,
|
||||||
|
+ setup_kcm_marshalling,
|
||||||
|
+ teardown_kcm_marshalling),
|
||||||
|
+ cmocka_unit_test_setup_teardown(test_kcm_ccache_no_princ_binary,
|
||||||
|
+ setup_kcm_marshalling,
|
||||||
|
+ teardown_kcm_marshalling),
|
||||||
|
cmocka_unit_test_setup_teardown(test_kcm_ccache_marshall_unmarshall_json,
|
||||||
|
setup_kcm_marshalling,
|
||||||
|
teardown_kcm_marshalling),
|
||||||
|
diff --git a/src/tests/multihost/basic/test_kcm.py b/src/tests/multihost/basic/test_kcm.py
|
||||||
|
index e5d315827b31f205216d6a20768533ef50983537..6f65431f88b0e77110c3a89c24363d28027390f6 100644
|
||||||
|
--- a/src/tests/multihost/basic/test_kcm.py
|
||||||
|
+++ b/src/tests/multihost/basic/test_kcm.py
|
||||||
|
@@ -310,6 +310,12 @@ class TestSanityKCM(object):
|
||||||
|
set_param(multihost, 'kcm', 'max_ccache_size', '1')
|
||||||
|
self._restart_kcm(multihost)
|
||||||
|
|
||||||
|
- with pytest.raises(paramiko.ssh_exception.AuthenticationException):
|
||||||
|
- ssh_foo3 = SSHClient(multihost.master[0].sys_hostname,
|
||||||
|
- username='foo3', password='Secret123')
|
||||||
|
+ # We use kinit to exceed the maximum ccache size as it creates payload
|
||||||
|
+ # of 1280 bytes by acquiring tgt and also some control credentials.
|
||||||
|
+ # SSH authentication is not sufficient as it stores only tgt.
|
||||||
|
+ ssh_foo3 = SSHClient(multihost.master[0].sys_hostname,
|
||||||
|
+ username='foo3', password='Secret123')
|
||||||
|
+ (_, _, exit_status) = ssh_foo3.execute_cmd(
|
||||||
|
+ 'kinit foo3@EXAMPLE.TEST', 'Secret123'
|
||||||
|
+ )
|
||||||
|
+ assert exit_status != 0
|
||||||
|
diff --git a/src/util/secrets/secrets.c b/src/util/secrets/secrets.c
|
||||||
|
index 2a7149ae8b1c88623784ffd4f3e7f908be15c662..6fd9e0af5bd9986052efdb8e244ddeb9e4fa50ff 100644
|
||||||
|
--- a/src/util/secrets/secrets.c
|
||||||
|
+++ b/src/util/secrets/secrets.c
|
||||||
|
@@ -36,7 +36,7 @@
|
||||||
|
#define SECRETS_BASEDN "cn=secrets"
|
||||||
|
#define KCM_BASEDN "cn=kcm"
|
||||||
|
|
||||||
|
-#define LOCAL_SIMPLE_FILTER "(type=simple)"
|
||||||
|
+#define LOCAL_SIMPLE_FILTER "(|(type=simple)(type=binary))"
|
||||||
|
#define LOCAL_CONTAINER_FILTER "(type=container)"
|
||||||
|
|
||||||
|
typedef int (*url_mapper_fn)(TALLOC_CTX *mem_ctx,
|
||||||
|
--
|
||||||
|
2.25.4
|
||||||
|
|
131
0013-kcm-add-per-connection-data-to-be-shared-between-req.patch
Normal file
131
0013-kcm-add-per-connection-data-to-be-shared-between-req.patch
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
From ae6898e7dc60d7067f0d71212c7ed28fc9e8e285 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||||
|
Date: Fri, 16 Oct 2020 15:36:51 +0200
|
||||||
|
Subject: [PATCH 13/19] kcm: add per-connection data to be shared between
|
||||||
|
requests
|
||||||
|
|
||||||
|
Resolves: https://github.com/SSSD/sssd/issues/5349
|
||||||
|
---
|
||||||
|
src/responder/kcm/kcmsrv_cmd.c | 21 +++++++++++++++++----
|
||||||
|
src/responder/kcm/kcmsrv_ops.c | 3 +++
|
||||||
|
src/responder/kcm/kcmsrv_ops.h | 5 +++++
|
||||||
|
3 files changed, 25 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_cmd.c b/src/responder/kcm/kcmsrv_cmd.c
|
||||||
|
index 99980050f205730169f5907db4018e4fe57b046d..a1aa9aa20f7c2b5cd972bd944995286de5e7c1e2 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_cmd.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_cmd.c
|
||||||
|
@@ -373,13 +373,16 @@ static errno_t kcm_cmd_dispatch(struct kcm_ctx *kctx,
|
||||||
|
{
|
||||||
|
struct tevent_req *req;
|
||||||
|
struct cli_ctx *cctx;
|
||||||
|
+ struct kcm_conn_data *conn_data;
|
||||||
|
|
||||||
|
cctx = req_ctx->cctx;
|
||||||
|
+ conn_data = talloc_get_type(cctx->state_ctx, struct kcm_conn_data);
|
||||||
|
|
||||||
|
req = kcm_cmd_send(req_ctx,
|
||||||
|
cctx->ev,
|
||||||
|
kctx->qctx,
|
||||||
|
req_ctx->kctx->kcm_data,
|
||||||
|
+ conn_data,
|
||||||
|
req_ctx->cctx->creds,
|
||||||
|
&req_ctx->op_io.request,
|
||||||
|
req_ctx->op_io.op);
|
||||||
|
@@ -492,7 +495,7 @@ static void kcm_recv(struct cli_ctx *cctx)
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
kctx = talloc_get_type(cctx->rctx->pvt_ctx, struct kcm_ctx);
|
||||||
|
- req = talloc_get_type(cctx->state_ctx, struct kcm_req_ctx);
|
||||||
|
+ req = talloc_get_type(cctx->protocol_ctx, struct kcm_req_ctx);
|
||||||
|
if (req == NULL) {
|
||||||
|
/* A new request comes in, setup data structures. */
|
||||||
|
req = kcm_new_req(cctx, kctx);
|
||||||
|
@@ -503,7 +506,17 @@ static void kcm_recv(struct cli_ctx *cctx)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- cctx->state_ctx = req;
|
||||||
|
+ cctx->protocol_ctx = req;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Shared data between requests that originates in the same connection. */
|
||||||
|
+ if (cctx->state_ctx == NULL) {
|
||||||
|
+ cctx->state_ctx = talloc_zero(cctx, struct kcm_conn_data);
|
||||||
|
+ if (cctx->state_ctx == NULL) {
|
||||||
|
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot set up client state\n");
|
||||||
|
+ talloc_free(cctx);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = kcm_recv_data(req, cctx->cfd, &req->reqbuf);
|
||||||
|
@@ -558,7 +571,7 @@ static int kcm_send_data(struct cli_ctx *cctx)
|
||||||
|
struct kcm_req_ctx *req;
|
||||||
|
errno_t ret;
|
||||||
|
|
||||||
|
- req = talloc_get_type(cctx->state_ctx, struct kcm_req_ctx);
|
||||||
|
+ req = talloc_get_type(cctx->protocol_ctx, struct kcm_req_ctx);
|
||||||
|
|
||||||
|
ret = kcm_write_iovec(cctx->cfd, &req->repbuf.v_len);
|
||||||
|
if (ret != EOK) {
|
||||||
|
@@ -604,7 +617,7 @@ static void kcm_send(struct cli_ctx *cctx)
|
||||||
|
DEBUG(SSSDBG_TRACE_INTERNAL, "All data sent!\n");
|
||||||
|
TEVENT_FD_NOT_WRITEABLE(cctx->cfde);
|
||||||
|
TEVENT_FD_READABLE(cctx->cfde);
|
||||||
|
- talloc_zfree(cctx->state_ctx);
|
||||||
|
+ talloc_zfree(cctx->protocol_ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ops.c b/src/responder/kcm/kcmsrv_ops.c
|
||||||
|
index 7fc3b0a5c4e123a398ef103f3ce92b45bc68f5cf..6ae1f0c647f4d385477ddeadbad93287cba05c55 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ops.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ops.c
|
||||||
|
@@ -38,6 +38,7 @@
|
||||||
|
|
||||||
|
struct kcm_op_ctx {
|
||||||
|
struct kcm_resp_ctx *kcm_data;
|
||||||
|
+ struct kcm_conn_data *conn_data;
|
||||||
|
struct cli_creds *client;
|
||||||
|
|
||||||
|
struct sss_iobuf *input;
|
||||||
|
@@ -86,6 +87,7 @@ struct tevent_req *kcm_cmd_send(TALLOC_CTX *mem_ctx,
|
||||||
|
struct tevent_context *ev,
|
||||||
|
struct kcm_ops_queue_ctx *qctx,
|
||||||
|
struct kcm_resp_ctx *kcm_data,
|
||||||
|
+ struct kcm_conn_data *conn_data,
|
||||||
|
struct cli_creds *client,
|
||||||
|
struct kcm_data *input,
|
||||||
|
struct kcm_op *op)
|
||||||
|
@@ -135,6 +137,7 @@ struct tevent_req *kcm_cmd_send(TALLOC_CTX *mem_ctx,
|
||||||
|
}
|
||||||
|
|
||||||
|
state->op_ctx->kcm_data = kcm_data;
|
||||||
|
+ state->op_ctx->conn_data = conn_data;
|
||||||
|
state->op_ctx->client = client;
|
||||||
|
|
||||||
|
state->op_ctx->input = sss_iobuf_init_readonly(state->op_ctx,
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ops.h b/src/responder/kcm/kcmsrv_ops.h
|
||||||
|
index 67d9f86026bf949548471f2280c130ebefd2f865..fd2dd03c9da3660e0c1346752e4db59c7cbe2c41 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ops.h
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ops.h
|
||||||
|
@@ -32,10 +32,15 @@ struct kcm_op;
|
||||||
|
struct kcm_op *kcm_get_opt(uint16_t opcode);
|
||||||
|
const char *kcm_opt_name(struct kcm_op *op);
|
||||||
|
|
||||||
|
+struct kcm_conn_data {
|
||||||
|
+ void *data;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
struct tevent_req *kcm_cmd_send(TALLOC_CTX *mem_ctx,
|
||||||
|
struct tevent_context *ev,
|
||||||
|
struct kcm_ops_queue_ctx *qctx,
|
||||||
|
struct kcm_resp_ctx *kcm_data,
|
||||||
|
+ struct kcm_conn_data *conn_data,
|
||||||
|
struct cli_creds *client,
|
||||||
|
struct kcm_data *input,
|
||||||
|
struct kcm_op *op);
|
||||||
|
--
|
||||||
|
2.25.4
|
||||||
|
|
165
0014-sss_ptr_hash-fix-double-free-for-circular-dependenci.patch
Normal file
165
0014-sss_ptr_hash-fix-double-free-for-circular-dependenci.patch
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
From f1db05d8839b39fd48471dcb29881c12ed27a434 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||||
|
Date: Thu, 29 Oct 2020 14:57:53 +0100
|
||||||
|
Subject: [PATCH 14/19] sss_ptr_hash: fix double free for circular dependencies
|
||||||
|
|
||||||
|
If the hash table delete callback deletes the stored item,
|
||||||
|
we can end up in double free in case when we try to override
|
||||||
|
an existing item (hash_enter(key) where key already exists).
|
||||||
|
|
||||||
|
```c
|
||||||
|
static void delete_cb(hash_entry_t *item,
|
||||||
|
hash_destroy_enum deltype,
|
||||||
|
void *pvt)
|
||||||
|
{
|
||||||
|
talloc_free(item->value.ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
hash_enter(key);
|
||||||
|
hash_enter(key);
|
||||||
|
```
|
||||||
|
|
||||||
|
The doble free it self is fine, since it is done via talloc destructor
|
||||||
|
and talloc can cope with that. However, the hash table fails to store
|
||||||
|
the new entry because hash_delete is called twice.
|
||||||
|
|
||||||
|
```
|
||||||
|
_sss_ptr_hash_add -> hash_enter -> hash_delete(old) -> delete_cb -> sss_ptr_hash_value_destructor -> hash_delete
|
||||||
|
```
|
||||||
|
---
|
||||||
|
src/tests/cmocka/test_sss_ptr_hash.c | 39 ++++++++++++++++++++++++++++
|
||||||
|
src/tests/cmocka/test_utils.c | 3 +++
|
||||||
|
src/tests/cmocka/test_utils.h | 1 +
|
||||||
|
src/util/sss_ptr_hash.c | 20 ++++++++++++++
|
||||||
|
4 files changed, 63 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/tests/cmocka/test_sss_ptr_hash.c b/src/tests/cmocka/test_sss_ptr_hash.c
|
||||||
|
index 1458238f537970d0ecde80bd36830b28970ca364..31cf8b705367498822094f8811b393c1b35e12bc 100644
|
||||||
|
--- a/src/tests/cmocka/test_sss_ptr_hash.c
|
||||||
|
+++ b/src/tests/cmocka/test_sss_ptr_hash.c
|
||||||
|
@@ -91,6 +91,45 @@ void test_sss_ptr_hash_with_free_cb(void **state)
|
||||||
|
assert_int_equal(free_counter, MAX_ENTRIES_AMOUNT*2);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void test_sss_ptr_hash_overwrite_with_free_cb(void **state)
|
||||||
|
+{
|
||||||
|
+ hash_table_t *table;
|
||||||
|
+ int free_counter = 0;
|
||||||
|
+ unsigned long count;
|
||||||
|
+ char *payload;
|
||||||
|
+ char *value;
|
||||||
|
+ errno_t ret;
|
||||||
|
+
|
||||||
|
+ table = sss_ptr_hash_create(global_talloc_context,
|
||||||
|
+ free_payload_cb,
|
||||||
|
+ &free_counter);
|
||||||
|
+ assert_non_null(table);
|
||||||
|
+
|
||||||
|
+ payload = talloc_strdup(table, "test_value1");
|
||||||
|
+ assert_non_null(payload);
|
||||||
|
+ talloc_set_name_const(payload, "char");
|
||||||
|
+ ret = sss_ptr_hash_add_or_override(table, "test", payload, char);
|
||||||
|
+ assert_int_equal(ret, 0);
|
||||||
|
+ count = hash_count(table);
|
||||||
|
+ assert_int_equal(count, 1);
|
||||||
|
+ value = sss_ptr_hash_lookup(table, "test", char);
|
||||||
|
+ assert_ptr_equal(value, payload);
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ payload = talloc_strdup(table, "test_value2");
|
||||||
|
+ assert_non_null(payload);
|
||||||
|
+ talloc_set_name_const(payload, "char");
|
||||||
|
+ ret = sss_ptr_hash_add_or_override(table, "test", payload, char);
|
||||||
|
+ assert_int_equal(ret, 0);
|
||||||
|
+ count = hash_count(table);
|
||||||
|
+ assert_int_equal(count, 1);
|
||||||
|
+ value = sss_ptr_hash_lookup(table, "test", char);
|
||||||
|
+ assert_ptr_equal(value, payload);
|
||||||
|
+
|
||||||
|
+ talloc_free(table);
|
||||||
|
+ assert_int_equal(free_counter, 2);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
struct table_wrapper
|
||||||
|
{
|
||||||
|
hash_table_t **table;
|
||||||
|
diff --git a/src/tests/cmocka/test_utils.c b/src/tests/cmocka/test_utils.c
|
||||||
|
index d77a972c1bc93638085c3d49131247fefb333d56..d258622fb50e849a3efabb123960db410eb399e1 100644
|
||||||
|
--- a/src/tests/cmocka/test_utils.c
|
||||||
|
+++ b/src/tests/cmocka/test_utils.c
|
||||||
|
@@ -2144,6 +2144,9 @@ int main(int argc, const char *argv[])
|
||||||
|
cmocka_unit_test_setup_teardown(test_sss_ptr_hash_with_free_cb,
|
||||||
|
setup_leak_tests,
|
||||||
|
teardown_leak_tests),
|
||||||
|
+ cmocka_unit_test_setup_teardown(test_sss_ptr_hash_overwrite_with_free_cb,
|
||||||
|
+ setup_leak_tests,
|
||||||
|
+ teardown_leak_tests),
|
||||||
|
cmocka_unit_test_setup_teardown(test_sss_ptr_hash_with_lookup_cb,
|
||||||
|
setup_leak_tests,
|
||||||
|
teardown_leak_tests),
|
||||||
|
diff --git a/src/tests/cmocka/test_utils.h b/src/tests/cmocka/test_utils.h
|
||||||
|
index 44b9479f965ee830ea0937c0fd89b87e35796598..458bcb750569c1f5f346917f29aa8b5500891988 100644
|
||||||
|
--- a/src/tests/cmocka/test_utils.h
|
||||||
|
+++ b/src/tests/cmocka/test_utils.h
|
||||||
|
@@ -35,6 +35,7 @@ void test_concatenate_string_array(void **state);
|
||||||
|
|
||||||
|
/* from src/tests/cmocka/test_sss_ptr_hash.c */
|
||||||
|
void test_sss_ptr_hash_with_free_cb(void **state);
|
||||||
|
+void test_sss_ptr_hash_overwrite_with_free_cb(void **state);
|
||||||
|
void test_sss_ptr_hash_with_lookup_cb(void **state);
|
||||||
|
void test_sss_ptr_hash_without_cb(void **state);
|
||||||
|
|
||||||
|
diff --git a/src/util/sss_ptr_hash.c b/src/util/sss_ptr_hash.c
|
||||||
|
index 6409236c782bac729ec51502019c04c83bce7cab..e3805dac4052b587d395b7163f5c45e1ba0aa6dc 100644
|
||||||
|
--- a/src/util/sss_ptr_hash.c
|
||||||
|
+++ b/src/util/sss_ptr_hash.c
|
||||||
|
@@ -54,6 +54,7 @@ struct sss_ptr_hash_value {
|
||||||
|
hash_table_t *table;
|
||||||
|
const char *key;
|
||||||
|
void *payload;
|
||||||
|
+ bool delete_in_progress;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
@@ -61,12 +62,22 @@ sss_ptr_hash_value_destructor(struct sss_ptr_hash_value *value)
|
||||||
|
{
|
||||||
|
hash_key_t table_key;
|
||||||
|
|
||||||
|
+ /* Do not call hash_delete() if we got here from hash delete callback when
|
||||||
|
+ * the callback calls talloc_free(payload) which frees the value. This
|
||||||
|
+ * should not happen since talloc will avoid circular free but let's be
|
||||||
|
+ * over protective here. */
|
||||||
|
+ if (value->delete_in_progress) {
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ value->delete_in_progress = true;
|
||||||
|
if (value->table && value->key) {
|
||||||
|
table_key.type = HASH_KEY_STRING;
|
||||||
|
table_key.str = discard_const_p(char, value->key);
|
||||||
|
if (hash_delete(value->table, &table_key) != HASH_SUCCESS) {
|
||||||
|
DEBUG(SSSDBG_CRIT_FAILURE,
|
||||||
|
"failed to delete entry with key '%s'\n", value->key);
|
||||||
|
+ value->delete_in_progress = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -127,6 +138,15 @@ sss_ptr_hash_delete_cb(hash_entry_t *item,
|
||||||
|
callback_entry.key = item->key;
|
||||||
|
callback_entry.value.type = HASH_VALUE_PTR;
|
||||||
|
callback_entry.value.ptr = value->payload;
|
||||||
|
+
|
||||||
|
+ /* Delete the value in case this callback has been called directly
|
||||||
|
+ * from dhash (overwriting existing entry) instead of hash_delete()
|
||||||
|
+ * in value's destructor. */
|
||||||
|
+ if (!value->delete_in_progress) {
|
||||||
|
+ talloc_set_destructor(value, NULL);
|
||||||
|
+ talloc_free(value);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* Even if execution is already in the context of
|
||||||
|
* talloc_free(payload) -> talloc_free(value) -> ...
|
||||||
|
* there still might be legitimate reasons to execute callback.
|
||||||
|
--
|
||||||
|
2.25.4
|
||||||
|
|
551
0015-kcm-store-credentials-list-in-hash-table-to-avoid-ca.patch
Normal file
551
0015-kcm-store-credentials-list-in-hash-table-to-avoid-ca.patch
Normal file
@ -0,0 +1,551 @@
|
|||||||
|
From 9ffc2c6447f2177ff406a9f4d17d8413967ab7ad Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||||
|
Date: Mon, 19 Oct 2020 12:40:07 +0200
|
||||||
|
Subject: [PATCH 15/19] kcm: store credentials list in hash table to avoid
|
||||||
|
cache lookups
|
||||||
|
|
||||||
|
Iteration over ccache requires CRED_UUID_LIST and then calling
|
||||||
|
CRED_BY_UUID for each uuid in the obtained list. Each CRED_BY_UUID
|
||||||
|
operation invoked ldb_search and decryption. This was a substantional
|
||||||
|
bottle neck.
|
||||||
|
|
||||||
|
Resolves: https://github.com/SSSD/sssd/issues/5349
|
||||||
|
|
||||||
|
:fixes: KCM performance has improved dramatically for cases where
|
||||||
|
large amount of credentials are stored in the ccache.
|
||||||
|
---
|
||||||
|
src/responder/kcm/kcmsrv_ccache.c | 46 +++++
|
||||||
|
src/responder/kcm/kcmsrv_ccache.h | 7 +
|
||||||
|
src/responder/kcm/kcmsrv_ccache_mem.c | 30 ++--
|
||||||
|
src/responder/kcm/kcmsrv_ops.c | 245 +++++++++++++++++++-------
|
||||||
|
src/responder/kcm/kcmsrv_ops.h | 5 +-
|
||||||
|
5 files changed, 249 insertions(+), 84 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache.c b/src/responder/kcm/kcmsrv_ccache.c
|
||||||
|
index 59f8a7293fa7422c199ca2916c8e6ae6039d9312..60eacd4516b1269168caea744d91377686ab03f6 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ccache.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache.c
|
||||||
|
@@ -28,6 +28,9 @@
|
||||||
|
#include "responder/kcm/kcmsrv_ccache_pvt.h"
|
||||||
|
#include "responder/kcm/kcmsrv_ccache_be.h"
|
||||||
|
|
||||||
|
+static struct kcm_cred *kcm_cred_dup(TALLOC_CTX *mem_ctx,
|
||||||
|
+ struct kcm_cred *crd);
|
||||||
|
+
|
||||||
|
static int kcm_cc_destructor(struct kcm_ccache *cc)
|
||||||
|
{
|
||||||
|
if (cc == NULL) {
|
||||||
|
@@ -94,6 +97,33 @@ done:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
+struct kcm_ccache *kcm_cc_dup(TALLOC_CTX *mem_ctx,
|
||||||
|
+ const struct kcm_ccache *cc)
|
||||||
|
+{
|
||||||
|
+ struct kcm_ccache *dup;
|
||||||
|
+ struct kcm_cred *crd_dup;
|
||||||
|
+ struct kcm_cred *crd;
|
||||||
|
+
|
||||||
|
+ dup = talloc_zero(mem_ctx, struct kcm_ccache);
|
||||||
|
+ if (dup == NULL) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+ memcpy(dup, cc, sizeof(struct kcm_ccache));
|
||||||
|
+
|
||||||
|
+ dup->creds = NULL;
|
||||||
|
+ DLIST_FOR_EACH(crd, cc->creds) {
|
||||||
|
+ crd_dup = kcm_cred_dup(dup, crd);
|
||||||
|
+ if (crd_dup == NULL) {
|
||||||
|
+ talloc_free(dup);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ DLIST_ADD(dup->creds, crd_dup);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return dup;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
const char *kcm_cc_get_name(struct kcm_ccache *cc)
|
||||||
|
{
|
||||||
|
return cc ? cc->name : NULL;
|
||||||
|
@@ -204,6 +234,22 @@ struct kcm_cred *kcm_cred_new(TALLOC_CTX *mem_ctx,
|
||||||
|
return kcreds;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static struct kcm_cred *kcm_cred_dup(TALLOC_CTX *mem_ctx,
|
||||||
|
+ struct kcm_cred *crd)
|
||||||
|
+{
|
||||||
|
+ struct kcm_cred *dup;
|
||||||
|
+
|
||||||
|
+ dup = talloc_zero(mem_ctx, struct kcm_cred);
|
||||||
|
+ if (dup == NULL) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ uuid_copy(dup->uuid, crd->uuid);
|
||||||
|
+ dup->cred_blob = crd->cred_blob;
|
||||||
|
+
|
||||||
|
+ return dup;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Add a cred to ccache */
|
||||||
|
errno_t kcm_cc_store_creds(struct kcm_ccache *cc,
|
||||||
|
struct kcm_cred *crd)
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache.h b/src/responder/kcm/kcmsrv_ccache.h
|
||||||
|
index b0a7acb9fed8a8f89a3d0e2239ab28c7ce80fa23..77cf8f61d563d29afe00d8a04e8053b24547746d 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ccache.h
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache.h
|
||||||
|
@@ -72,6 +72,13 @@ errno_t kcm_cc_new(TALLOC_CTX *mem_ctx,
|
||||||
|
krb5_principal princ,
|
||||||
|
struct kcm_ccache **_cc);
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Duplicate the ccache. Only ccache and credentials are duplicated,
|
||||||
|
+ * but their data are a shallow copy.
|
||||||
|
+ */
|
||||||
|
+struct kcm_ccache *kcm_cc_dup(TALLOC_CTX *mem_ctx,
|
||||||
|
+ const struct kcm_ccache *cc);
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Returns true if a client can access a ccache.
|
||||||
|
*
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ccache_mem.c b/src/responder/kcm/kcmsrv_ccache_mem.c
|
||||||
|
index baa698054fa4c6952b41b0f25dfdfa825f8e675b..0e3a7b239eda83c9fdec3b116231d4ec1444ef10 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ccache_mem.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ccache_mem.c
|
||||||
|
@@ -49,24 +49,6 @@ struct ccdb_mem {
|
||||||
|
unsigned int nextid;
|
||||||
|
};
|
||||||
|
|
||||||
|
-/* In order to provide a consistent interface, we need to let the caller
|
||||||
|
- * of getbyXXX own the ccache, therefore the memory back end returns a shallow
|
||||||
|
- * copy of the ccache
|
||||||
|
- */
|
||||||
|
-static struct kcm_ccache *kcm_ccache_dup(TALLOC_CTX *mem_ctx,
|
||||||
|
- struct kcm_ccache *in)
|
||||||
|
-{
|
||||||
|
- struct kcm_ccache *out;
|
||||||
|
-
|
||||||
|
- out = talloc_zero(mem_ctx, struct kcm_ccache);
|
||||||
|
- if (out == NULL) {
|
||||||
|
- return NULL;
|
||||||
|
- }
|
||||||
|
- memcpy(out, in, sizeof(struct kcm_ccache));
|
||||||
|
-
|
||||||
|
- return out;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static struct ccache_mem_wrap *memdb_get_by_uuid(struct ccdb_mem *memdb,
|
||||||
|
struct cli_creds *client,
|
||||||
|
uuid_t uuid)
|
||||||
|
@@ -417,7 +399,11 @@ static struct tevent_req *ccdb_mem_getbyuuid_send(TALLOC_CTX *mem_ctx,
|
||||||
|
|
||||||
|
ccwrap = memdb_get_by_uuid(memdb, client, uuid);
|
||||||
|
if (ccwrap != NULL) {
|
||||||
|
- state->cc = kcm_ccache_dup(state, ccwrap->cc);
|
||||||
|
+ /* In order to provide a consistent interface, we need to let the caller
|
||||||
|
+ * of getbyXXX own the ccache, therefore the memory back end returns a shallow
|
||||||
|
+ * copy of the ccache
|
||||||
|
+ */
|
||||||
|
+ state->cc = kcm_cc_dup(state, ccwrap->cc);
|
||||||
|
if (state->cc == NULL) {
|
||||||
|
ret = ENOMEM;
|
||||||
|
goto immediate;
|
||||||
|
@@ -470,7 +456,11 @@ static struct tevent_req *ccdb_mem_getbyname_send(TALLOC_CTX *mem_ctx,
|
||||||
|
|
||||||
|
ccwrap = memdb_get_by_name(memdb, client, name);
|
||||||
|
if (ccwrap != NULL) {
|
||||||
|
- state->cc = kcm_ccache_dup(state, ccwrap->cc);
|
||||||
|
+ /* In order to provide a consistent interface, we need to let the caller
|
||||||
|
+ * of getbyXXX own the ccache, therefore the memory back end returns a shallow
|
||||||
|
+ * copy of the ccache
|
||||||
|
+ */
|
||||||
|
+ state->cc = kcm_cc_dup(state, ccwrap->cc);
|
||||||
|
if (state->cc == NULL) {
|
||||||
|
ret = ENOMEM;
|
||||||
|
goto immediate;
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ops.c b/src/responder/kcm/kcmsrv_ops.c
|
||||||
|
index 6ae1f0c647f4d385477ddeadbad93287cba05c55..f458c724b0eaa3d43df4ad30baa3f896b8d87965 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ops.c
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ops.c
|
||||||
|
@@ -22,9 +22,11 @@
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <krb5/krb5.h>
|
||||||
|
+#include <dhash.h>
|
||||||
|
|
||||||
|
#include "util/sss_iobuf.h"
|
||||||
|
#include "util/sss_krb5.h"
|
||||||
|
+#include "util/sss_ptr_hash.h"
|
||||||
|
#include "util/util_creds.h"
|
||||||
|
#include "responder/kcm/kcm.h"
|
||||||
|
#include "responder/kcm/kcmsrv_pvt.h"
|
||||||
|
@@ -1074,6 +1076,73 @@ static void kcm_op_get_principal_getbyname_done(struct tevent_req *subreq)
|
||||||
|
tevent_req_done(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void
|
||||||
|
+kcm_creds_table_delete_cb(hash_entry_t *item,
|
||||||
|
+ hash_destroy_enum deltype,
|
||||||
|
+ void *pvt)
|
||||||
|
+{
|
||||||
|
+ /* Delete the old credential if it is being overwritten. */
|
||||||
|
+ talloc_free(item->value.ptr);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Store credentials in a hash table.
|
||||||
|
+ *
|
||||||
|
+ * If the table already exist we add the new credentials to the table and
|
||||||
|
+ * overwrite the ones that already exist. This allows us to correctly serve
|
||||||
|
+ * also parallel GET_CRED_UUID_LIST requests from the same connection since
|
||||||
|
+ * it will have its own uuid list and cursor on the client side and we make
|
||||||
|
+ * all uuid (old, updated and newly added) available.
|
||||||
|
+ */
|
||||||
|
+static errno_t
|
||||||
|
+kcm_creds_to_table(TALLOC_CTX *mem_ctx,
|
||||||
|
+ struct kcm_cred *creds,
|
||||||
|
+ hash_table_t **_table)
|
||||||
|
+{
|
||||||
|
+ char str[UUID_STR_SIZE];
|
||||||
|
+ uuid_t uuid;
|
||||||
|
+ errno_t ret;
|
||||||
|
+
|
||||||
|
+ if (*_table == NULL) {
|
||||||
|
+ *_table = sss_ptr_hash_create(mem_ctx, kcm_creds_table_delete_cb, NULL);
|
||||||
|
+ if (*_table == NULL) {
|
||||||
|
+ return ENOMEM;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (struct kcm_cred *crd = creds;
|
||||||
|
+ crd != NULL;
|
||||||
|
+ crd = kcm_cc_next_cred(crd)) {
|
||||||
|
+ ret = kcm_cred_get_uuid(crd, uuid);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ DEBUG(SSSDBG_MINOR_FAILURE, "Credential has no UUID, skipping\n");
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ uuid_unparse(uuid, str);
|
||||||
|
+
|
||||||
|
+ ret = sss_ptr_hash_add_or_override(*_table, str, crd, struct kcm_cred);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ talloc_steal(*_table, crd);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return EOK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static struct kcm_cred *
|
||||||
|
+kcm_creds_lookup(hash_table_t *table, uuid_t uuid)
|
||||||
|
+{
|
||||||
|
+ char str[UUID_STR_SIZE];
|
||||||
|
+
|
||||||
|
+ if (uuid == NULL) {
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ uuid_unparse(uuid, str);
|
||||||
|
+ return sss_ptr_hash_lookup(table, str, struct kcm_cred);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* (name) -> (uuid, ...) */
|
||||||
|
static void kcm_op_get_cred_uuid_list_getbyname_done(struct tevent_req *subreq);
|
||||||
|
|
||||||
|
@@ -1123,12 +1192,15 @@ static void kcm_op_get_cred_uuid_list_getbyname_done(struct tevent_req *subreq)
|
||||||
|
errno_t ret;
|
||||||
|
struct kcm_ccache *cc;
|
||||||
|
struct kcm_cred *crd;
|
||||||
|
+ struct kcm_conn_data *conn_data;
|
||||||
|
uuid_t uuid;
|
||||||
|
struct tevent_req *req = tevent_req_callback_data(subreq,
|
||||||
|
struct tevent_req);
|
||||||
|
struct kcm_op_common_state *state = tevent_req_data(req,
|
||||||
|
struct kcm_op_common_state);
|
||||||
|
|
||||||
|
+ conn_data = state->op_ctx->conn_data;
|
||||||
|
+
|
||||||
|
ret = kcm_ccdb_getbyname_recv(subreq, state, &cc);
|
||||||
|
talloc_zfree(subreq);
|
||||||
|
if (ret != EOK) {
|
||||||
|
@@ -1140,12 +1212,20 @@ static void kcm_op_get_cred_uuid_list_getbyname_done(struct tevent_req *subreq)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cc == NULL) {
|
||||||
|
- DEBUG(SSSDBG_MINOR_FAILURE, "No credentials by that UUID\n");
|
||||||
|
+ DEBUG(SSSDBG_MINOR_FAILURE, "No ccache by that name\n");
|
||||||
|
state->op_ret = ERR_NO_CREDS;
|
||||||
|
tevent_req_done(req);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ ret = kcm_creds_to_table(conn_data, kcm_cc_get_cred(cc), &conn_data->creds);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to build credentials hash table "
|
||||||
|
+ "[%d]: %s\n", ret, sss_strerror(ret));
|
||||||
|
+ tevent_req_error(req, ret);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
for (crd = kcm_cc_get_cred(cc);
|
||||||
|
crd != NULL;
|
||||||
|
crd = kcm_cc_next_cred(crd)) {
|
||||||
|
@@ -1172,6 +1252,34 @@ static void kcm_op_get_cred_uuid_list_getbyname_done(struct tevent_req *subreq)
|
||||||
|
tevent_req_done(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static errno_t
|
||||||
|
+kcm_op_get_cred_by_uuid_reply(struct kcm_cred *crd,
|
||||||
|
+ struct sss_iobuf *reply)
|
||||||
|
+{
|
||||||
|
+ struct sss_iobuf *cred_blob;
|
||||||
|
+ errno_t ret;
|
||||||
|
+
|
||||||
|
+ cred_blob = kcm_cred_get_creds(crd);
|
||||||
|
+ if (cred_blob == NULL) {
|
||||||
|
+ DEBUG(SSSDBG_CRIT_FAILURE, "Credentials lack the creds blob\n");
|
||||||
|
+ return ERR_NO_CREDS;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ret = sss_iobuf_write_len(reply, sss_iobuf_get_data(cred_blob),
|
||||||
|
+ sss_iobuf_get_size(cred_blob));
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ DEBUG(SSSDBG_OP_FAILURE, "Cannot write ccache blob [%d]: %s\n",
|
||||||
|
+ ret, sss_strerror(ret));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+struct kcm_op_get_cred_by_uuid_state {
|
||||||
|
+ struct kcm_op_common_state common;
|
||||||
|
+ uuid_t uuid;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
/* (name, uuid) -> (cred) */
|
||||||
|
static void kcm_op_get_cred_by_uuid_getbyname_done(struct tevent_req *subreq);
|
||||||
|
|
||||||
|
@@ -1182,20 +1290,51 @@ kcm_op_get_cred_by_uuid_send(TALLOC_CTX *mem_ctx,
|
||||||
|
{
|
||||||
|
struct tevent_req *req = NULL;
|
||||||
|
struct tevent_req *subreq = NULL;
|
||||||
|
- struct kcm_op_common_state *state = NULL;
|
||||||
|
+ struct kcm_op_get_cred_by_uuid_state *state;
|
||||||
|
+ struct kcm_cred *crd;
|
||||||
|
errno_t ret;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
- req = tevent_req_create(mem_ctx, &state, struct kcm_op_common_state);
|
||||||
|
+ req = tevent_req_create(mem_ctx, &state,
|
||||||
|
+ struct kcm_op_get_cred_by_uuid_state);
|
||||||
|
if (req == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
- state->op_ctx = op_ctx;
|
||||||
|
+ state->common.op_ctx = op_ctx;
|
||||||
|
|
||||||
|
ret = sss_iobuf_read_stringz(op_ctx->input, &name);
|
||||||
|
if (ret != EOK) {
|
||||||
|
goto immediate;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ ret = sss_iobuf_read_len(state->common.op_ctx->input, UUID_BYTES,
|
||||||
|
+ state->uuid);
|
||||||
|
+ if (ret != EOK) {
|
||||||
|
+ DEBUG(SSSDBG_OP_FAILURE, "Cannot read input UUID [%d]: %s\n",
|
||||||
|
+ ret, sss_strerror(ret));
|
||||||
|
+ goto immediate;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (op_ctx->conn_data->creds != NULL) {
|
||||||
|
+ crd = kcm_creds_lookup(op_ctx->conn_data->creds, state->uuid);
|
||||||
|
+ if (crd == NULL) {
|
||||||
|
+ /* This should not happen, it can only happen if wrong UUID was
|
||||||
|
+ * requested which suggests bug in the caller application. */
|
||||||
|
+ DEBUG(SSSDBG_MINOR_FAILURE, "No credentials by that UUID\n");
|
||||||
|
+ kcm_debug_uuid(state->uuid);
|
||||||
|
+ state->common.op_ret = ERR_KCM_CC_END;
|
||||||
|
+ ret = EOK;
|
||||||
|
+ goto immediate;
|
||||||
|
+ } else {
|
||||||
|
+ ret = kcm_op_get_cred_by_uuid_reply(crd, op_ctx->reply);
|
||||||
|
+ if (ret == ERR_NO_CREDS) {
|
||||||
|
+ state->common.op_ret = ret;
|
||||||
|
+ ret = EOK;
|
||||||
|
+ }
|
||||||
|
+ goto immediate;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
DEBUG(SSSDBG_TRACE_LIBS, "Returning creds by UUID for %s\n", name);
|
||||||
|
|
||||||
|
subreq = kcm_ccdb_getbyname_send(state, ev,
|
||||||
|
@@ -1210,7 +1349,11 @@ kcm_op_get_cred_by_uuid_send(TALLOC_CTX *mem_ctx,
|
||||||
|
return req;
|
||||||
|
|
||||||
|
immediate:
|
||||||
|
- tevent_req_error(req, ret);
|
||||||
|
+ if (ret == EOK) {
|
||||||
|
+ tevent_req_done(req);
|
||||||
|
+ } else {
|
||||||
|
+ tevent_req_error(req, ret);
|
||||||
|
+ }
|
||||||
|
tevent_req_post(req, ev);
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
@@ -1219,14 +1362,14 @@ static void kcm_op_get_cred_by_uuid_getbyname_done(struct tevent_req *subreq)
|
||||||
|
{
|
||||||
|
struct tevent_req *req = tevent_req_callback_data(subreq,
|
||||||
|
struct tevent_req);
|
||||||
|
- struct kcm_op_common_state *state = tevent_req_data(req,
|
||||||
|
- struct kcm_op_common_state);
|
||||||
|
+ struct kcm_op_get_cred_by_uuid_state *state = tevent_req_data(req,
|
||||||
|
+ struct kcm_op_get_cred_by_uuid_state);
|
||||||
|
errno_t ret;
|
||||||
|
struct kcm_ccache *cc;
|
||||||
|
struct kcm_cred *crd;
|
||||||
|
- uuid_t uuid_in;
|
||||||
|
- uuid_t uuid;
|
||||||
|
- struct sss_iobuf *cred_blob;
|
||||||
|
+ struct kcm_conn_data *conn_data;
|
||||||
|
+
|
||||||
|
+ conn_data = state->common.op_ctx->conn_data;
|
||||||
|
|
||||||
|
ret = kcm_ccdb_getbyname_recv(subreq, state, &cc);
|
||||||
|
talloc_zfree(subreq);
|
||||||
|
@@ -1238,69 +1381,45 @@ static void kcm_op_get_cred_by_uuid_getbyname_done(struct tevent_req *subreq)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (cc == NULL) {
|
||||||
|
- DEBUG(SSSDBG_MINOR_FAILURE, "No credentials by that name\n");
|
||||||
|
- state->op_ret = ERR_NO_MATCHING_CREDS;
|
||||||
|
- tevent_req_done(req);
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- ret = sss_iobuf_read_len(state->op_ctx->input,
|
||||||
|
- UUID_BYTES, uuid_in);
|
||||||
|
+ ret = kcm_creds_to_table(conn_data, kcm_cc_get_cred(cc), &conn_data->creds);
|
||||||
|
if (ret != EOK) {
|
||||||
|
- DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
- "Cannot read input UUID [%d]: %s\n",
|
||||||
|
- ret, sss_strerror(ret));
|
||||||
|
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to build credentials hash table "
|
||||||
|
+ "[%d]: %s\n", ret, sss_strerror(ret));
|
||||||
|
tevent_req_error(req, ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- for (crd = kcm_cc_get_cred(cc);
|
||||||
|
- crd != NULL;
|
||||||
|
- crd = kcm_cc_next_cred(crd)) {
|
||||||
|
- ret = kcm_cred_get_uuid(crd, uuid);
|
||||||
|
- if (ret != EOK) {
|
||||||
|
- DEBUG(SSSDBG_MINOR_FAILURE,
|
||||||
|
- "Cannot get UUID from creds, skipping\n");
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (uuid_compare(uuid, uuid_in) == 0) {
|
||||||
|
- break;
|
||||||
|
+ if (conn_data->creds != NULL) {
|
||||||
|
+ crd = kcm_creds_lookup(conn_data->creds, state->uuid);
|
||||||
|
+ if (crd == NULL) {
|
||||||
|
+ DEBUG(SSSDBG_MINOR_FAILURE, "No credentials by that UUID\n");
|
||||||
|
+ kcm_debug_uuid(state->uuid);
|
||||||
|
+ state->common.op_ret = ERR_KCM_CC_END;
|
||||||
|
+ } else {
|
||||||
|
+ ret = kcm_op_get_cred_by_uuid_reply(crd, state->common.op_ctx->reply);
|
||||||
|
+ if (ret != EOK && ret != ERR_NO_CREDS) {
|
||||||
|
+ tevent_req_error(req, ret);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ state->common.op_ret = ret;
|
||||||
|
}
|
||||||
|
- kcm_debug_uuid(uuid);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (crd == NULL) {
|
||||||
|
- state->op_ret = ERR_KCM_CC_END;
|
||||||
|
- DEBUG(SSSDBG_MINOR_FAILURE, "No credentials by that UUID\n");
|
||||||
|
- tevent_req_done(req);
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- cred_blob = kcm_cred_get_creds(crd);
|
||||||
|
- if (cred_blob == NULL) {
|
||||||
|
- DEBUG(SSSDBG_CRIT_FAILURE, "Credentials lack the creds blob\n");
|
||||||
|
- state->op_ret = ERR_NO_CREDS;
|
||||||
|
- tevent_req_done(req);
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- ret = sss_iobuf_write_len(state->op_ctx->reply,
|
||||||
|
- sss_iobuf_get_data(cred_blob),
|
||||||
|
- sss_iobuf_get_size(cred_blob));
|
||||||
|
- if (ret != EOK) {
|
||||||
|
- DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
- "Cannot write ccache blob [%d]: %s\n",
|
||||||
|
- ret, sss_strerror(ret));
|
||||||
|
- tevent_req_error(req, ret);
|
||||||
|
- return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- state->op_ret = EOK;
|
||||||
|
tevent_req_done(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static errno_t kcm_op_get_cred_by_uuid_recv(struct tevent_req *req,
|
||||||
|
+ uint32_t *_op_ret)
|
||||||
|
+{
|
||||||
|
+ struct kcm_op_get_cred_by_uuid_state *state;
|
||||||
|
+
|
||||||
|
+ state = tevent_req_data(req, struct kcm_op_get_cred_by_uuid_state);
|
||||||
|
+
|
||||||
|
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
||||||
|
+ *_op_ret = state->common.op_ret;
|
||||||
|
+ return EOK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* (name, flags, credtag) -> () */
|
||||||
|
/* FIXME */
|
||||||
|
static struct tevent_req *
|
||||||
|
@@ -2156,7 +2275,7 @@ static struct kcm_op kcm_optable[] = {
|
||||||
|
{ "RETRIEVE", NULL, NULL },
|
||||||
|
{ "GET_PRINCIPAL", kcm_op_get_principal_send, NULL },
|
||||||
|
{ "GET_CRED_UUID_LIST", kcm_op_get_cred_uuid_list_send, NULL },
|
||||||
|
- { "GET_CRED_BY_UUID", kcm_op_get_cred_by_uuid_send, NULL },
|
||||||
|
+ { "GET_CRED_BY_UUID", kcm_op_get_cred_by_uuid_send, kcm_op_get_cred_by_uuid_recv },
|
||||||
|
{ "REMOVE_CRED", kcm_op_remove_cred_send, NULL },
|
||||||
|
{ "SET_FLAGS", NULL, NULL },
|
||||||
|
{ "CHOWN", NULL, NULL },
|
||||||
|
diff --git a/src/responder/kcm/kcmsrv_ops.h b/src/responder/kcm/kcmsrv_ops.h
|
||||||
|
index fd2dd03c9da3660e0c1346752e4db59c7cbe2c41..ab6c13791baa43837cf84ebd523735b622a24020 100644
|
||||||
|
--- a/src/responder/kcm/kcmsrv_ops.h
|
||||||
|
+++ b/src/responder/kcm/kcmsrv_ops.h
|
||||||
|
@@ -24,6 +24,7 @@
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
+#include <dhash.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include "util/sss_iobuf.h"
|
||||||
|
#include "responder/kcm/kcmsrv_pvt.h"
|
||||||
|
@@ -33,7 +34,9 @@ struct kcm_op *kcm_get_opt(uint16_t opcode);
|
||||||
|
const char *kcm_opt_name(struct kcm_op *op);
|
||||||
|
|
||||||
|
struct kcm_conn_data {
|
||||||
|
- void *data;
|
||||||
|
+ /* Credentials obtained by GET_CRED_UUID_LIST. We use to improve performance
|
||||||
|
+ * by avoiding ccache lookups in GET_CRED_BY_UUID. */
|
||||||
|
+ hash_table_t *creds;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tevent_req *kcm_cmd_send(TALLOC_CTX *mem_ctx,
|
||||||
|
--
|
||||||
|
2.25.4
|
||||||
|
|
@ -0,0 +1,38 @@
|
|||||||
|
From 24a6888e38fb9d11bf173eb06e400678388bce49 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||||
|
Date: Tue, 3 Nov 2020 13:35:33 +0100
|
||||||
|
Subject: [PATCH 16/19] secrets: fix may_payload_size exceeded debug message
|
||||||
|
|
||||||
|
The unit is bytes (B) not bits (b) and the conversion of the input
|
||||||
|
payload size to KiB was wrong (multiplying bytes * 1024).
|
||||||
|
---
|
||||||
|
src/util/secrets/secrets.c | 10 +++++-----
|
||||||
|
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/util/secrets/secrets.c b/src/util/secrets/secrets.c
|
||||||
|
index 6fd9e0af5bd9986052efdb8e244ddeb9e4fa50ff..1000757228bea75bb2d5c48aceb717c9bfe35ffb 100644
|
||||||
|
--- a/src/util/secrets/secrets.c
|
||||||
|
+++ b/src/util/secrets/secrets.c
|
||||||
|
@@ -399,14 +399,14 @@ static int local_check_max_payload_size(struct sss_sec_req *req,
|
||||||
|
return EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
- max_payload_size = req->quota->max_payload_size * 1024; /* kb */
|
||||||
|
+ max_payload_size = req->quota->max_payload_size * 1024; /* KiB */
|
||||||
|
if (payload_size > max_payload_size) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
- "Secrets' payload size [%d kb (%d)] exceeds the maximum allowed "
|
||||||
|
- "payload size [%d kb (%d)]\n",
|
||||||
|
- payload_size * 1024, /* kb */
|
||||||
|
+ "Secrets' payload size [%d KiB (%d B)] exceeds the maximum "
|
||||||
|
+ "allowed payload size [%d KiB (%d B)]\n",
|
||||||
|
+ payload_size / 1024, /* KiB */
|
||||||
|
payload_size,
|
||||||
|
- req->quota->max_payload_size, /* kb */
|
||||||
|
+ req->quota->max_payload_size, /* KiB */
|
||||||
|
max_payload_size);
|
||||||
|
|
||||||
|
return ERR_SEC_PAYLOAD_SIZE_IS_TOO_LARGE;
|
||||||
|
--
|
||||||
|
2.25.4
|
||||||
|
|
@ -0,0 +1,43 @@
|
|||||||
|
From 36e4dc6c9a48ee62345839a9df14e0494c99bf59 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||||
|
Date: Thu, 26 Nov 2020 11:47:24 +0100
|
||||||
|
Subject: [PATCH 17/19] secrets: default to "plaintext" if "enctype" attr is
|
||||||
|
missing
|
||||||
|
|
||||||
|
This is a sane fallback behavior, however it should not happen since
|
||||||
|
the attribute should be always present.
|
||||||
|
---
|
||||||
|
src/util/secrets/secrets.c | 17 ++++++-----------
|
||||||
|
1 file changed, 6 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/util/secrets/secrets.c b/src/util/secrets/secrets.c
|
||||||
|
index 1000757228bea75bb2d5c48aceb717c9bfe35ffb..58c96e18f03865df0249c4c899ad88e385b782c8 100644
|
||||||
|
--- a/src/util/secrets/secrets.c
|
||||||
|
+++ b/src/util/secrets/secrets.c
|
||||||
|
@@ -1071,17 +1071,12 @@ errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- attr_enctype = ldb_msg_find_attr_as_string(res->msgs[0], "enctype", NULL);
|
||||||
|
-
|
||||||
|
- if (attr_enctype) {
|
||||||
|
- enctype = sss_sec_str_to_enctype(attr_enctype);
|
||||||
|
- ret = local_decrypt(req->sctx, tmp_ctx, attr_secret->data,
|
||||||
|
- attr_secret->length, enctype, &secret, &secret_len);
|
||||||
|
- if (ret) goto done;
|
||||||
|
- } else {
|
||||||
|
- secret = talloc_steal(tmp_ctx, attr_secret->data);
|
||||||
|
- secret_len = attr_secret->length;
|
||||||
|
- }
|
||||||
|
+ attr_enctype = ldb_msg_find_attr_as_string(res->msgs[0], "enctype",
|
||||||
|
+ "plaintext");
|
||||||
|
+ enctype = sss_sec_str_to_enctype(attr_enctype);
|
||||||
|
+ ret = local_decrypt(req->sctx, tmp_ctx, attr_secret->data,
|
||||||
|
+ attr_secret->length, enctype, &secret, &secret_len);
|
||||||
|
+ if (ret) goto done;
|
||||||
|
|
||||||
|
if (_datatype != NULL) {
|
||||||
|
attr_datatype = ldb_msg_find_attr_as_string(res->msgs[0], "type",
|
||||||
|
--
|
||||||
|
2.25.4
|
||||||
|
|
183
0018-secrets-move-attrs-names-to-macros.patch
Normal file
183
0018-secrets-move-attrs-names-to-macros.patch
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
From b18f0f87948d44f1d99dd4da0ac1affcbb8c53e8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||||
|
Date: Thu, 26 Nov 2020 11:55:39 +0100
|
||||||
|
Subject: [PATCH 18/19] secrets: move attrs names to macros
|
||||||
|
|
||||||
|
---
|
||||||
|
src/util/secrets/secrets.c | 42 +++++++++++++++++++++++---------------
|
||||||
|
1 file changed, 25 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/util/secrets/secrets.c b/src/util/secrets/secrets.c
|
||||||
|
index 58c96e18f03865df0249c4c899ad88e385b782c8..ae9c7c83f335c8c2d9d97a736700fbcdaf0d36af 100644
|
||||||
|
--- a/src/util/secrets/secrets.c
|
||||||
|
+++ b/src/util/secrets/secrets.c
|
||||||
|
@@ -39,6 +39,11 @@
|
||||||
|
#define LOCAL_SIMPLE_FILTER "(|(type=simple)(type=binary))"
|
||||||
|
#define LOCAL_CONTAINER_FILTER "(type=container)"
|
||||||
|
|
||||||
|
+#define SEC_ATTR_SECRET "secret"
|
||||||
|
+#define SEC_ATTR_ENCTYPE "enctype"
|
||||||
|
+#define SEC_ATTR_TYPE "type"
|
||||||
|
+#define SEC_ATTR_CTIME "creationTime"
|
||||||
|
+
|
||||||
|
typedef int (*url_mapper_fn)(TALLOC_CTX *mem_ctx,
|
||||||
|
const char *url,
|
||||||
|
uid_t client,
|
||||||
|
@@ -465,7 +470,7 @@ static int local_db_create(struct sss_sec_req *req)
|
||||||
|
ret = local_db_check_containers_nest_level(req, msg->dn);
|
||||||
|
if (ret != EOK) goto done;
|
||||||
|
|
||||||
|
- ret = ldb_msg_add_string(msg, "type", "container");
|
||||||
|
+ ret = ldb_msg_add_string(msg, SEC_ATTR_TYPE, "container");
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"ldb_msg_add_string failed adding type:container [%d]: %s\n",
|
||||||
|
@@ -473,7 +478,7 @@ static int local_db_create(struct sss_sec_req *req)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = ldb_msg_add_fmt(msg, "creationTime", "%lu", time(NULL));
|
||||||
|
+ ret = ldb_msg_add_fmt(msg, SEC_ATTR_CTIME, "%lu", time(NULL));
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"ldb_msg_add_string failed adding creationTime [%d]: %s\n",
|
||||||
|
@@ -953,7 +958,7 @@ errno_t sss_sec_list(TALLOC_CTX *mem_ctx,
|
||||||
|
size_t *_num_keys)
|
||||||
|
{
|
||||||
|
TALLOC_CTX *tmp_ctx;
|
||||||
|
- static const char *attrs[] = { "secret", NULL };
|
||||||
|
+ static const char *attrs[] = { SEC_ATTR_SECRET, NULL };
|
||||||
|
struct ldb_result *res;
|
||||||
|
char **keys;
|
||||||
|
int ret;
|
||||||
|
@@ -1017,7 +1022,8 @@ errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
|
||||||
|
char **_datatype)
|
||||||
|
{
|
||||||
|
TALLOC_CTX *tmp_ctx;
|
||||||
|
- static const char *attrs[] = { "secret", "enctype", "type", NULL };
|
||||||
|
+ static const char *attrs[] = { SEC_ATTR_SECRET, SEC_ATTR_ENCTYPE,
|
||||||
|
+ SEC_ATTR_TYPE, NULL };
|
||||||
|
struct ldb_result *res;
|
||||||
|
const struct ldb_val *attr_secret;
|
||||||
|
const char *attr_enctype;
|
||||||
|
@@ -1064,14 +1070,14 @@ errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- attr_secret = ldb_msg_find_ldb_val(res->msgs[0], "secret");
|
||||||
|
+ attr_secret = ldb_msg_find_ldb_val(res->msgs[0], SEC_ATTR_SECRET);
|
||||||
|
if (!attr_secret) {
|
||||||
|
DEBUG(SSSDBG_CRIT_FAILURE, "The 'secret' attribute is missing\n");
|
||||||
|
ret = ENOENT;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- attr_enctype = ldb_msg_find_attr_as_string(res->msgs[0], "enctype",
|
||||||
|
+ attr_enctype = ldb_msg_find_attr_as_string(res->msgs[0], SEC_ATTR_ENCTYPE,
|
||||||
|
"plaintext");
|
||||||
|
enctype = sss_sec_str_to_enctype(attr_enctype);
|
||||||
|
ret = local_decrypt(req->sctx, tmp_ctx, attr_secret->data,
|
||||||
|
@@ -1079,7 +1085,7 @@ errno_t sss_sec_get(TALLOC_CTX *mem_ctx,
|
||||||
|
if (ret) goto done;
|
||||||
|
|
||||||
|
if (_datatype != NULL) {
|
||||||
|
- attr_datatype = ldb_msg_find_attr_as_string(res->msgs[0], "type",
|
||||||
|
+ attr_datatype = ldb_msg_find_attr_as_string(res->msgs[0], SEC_ATTR_TYPE,
|
||||||
|
"simple");
|
||||||
|
datatype = talloc_strdup(tmp_ctx, attr_datatype);
|
||||||
|
if (datatype == NULL) {
|
||||||
|
@@ -1167,7 +1173,7 @@ errno_t sss_sec_put(struct sss_sec_req *req,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = ldb_msg_add_string(msg, "type", datatype);
|
||||||
|
+ ret = ldb_msg_add_string(msg, SEC_ATTR_TYPE, datatype);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"ldb_msg_add_string failed adding type:%s [%d]: %s\n",
|
||||||
|
@@ -1175,7 +1181,8 @@ errno_t sss_sec_put(struct sss_sec_req *req,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = ldb_msg_add_string(msg, "enctype", sss_sec_enctype_to_str(enctype));
|
||||||
|
+ ret = ldb_msg_add_string(msg, SEC_ATTR_ENCTYPE,
|
||||||
|
+ sss_sec_enctype_to_str(enctype));
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"ldb_msg_add_string failed adding enctype [%d]: %s\n",
|
||||||
|
@@ -1183,7 +1190,7 @@ errno_t sss_sec_put(struct sss_sec_req *req,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = ldb_msg_add_value(msg, "secret", &enc_secret, NULL);
|
||||||
|
+ ret = ldb_msg_add_value(msg, SEC_ATTR_SECRET, &enc_secret, NULL);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"ldb_msg_add_string failed adding secret [%d]: %s\n",
|
||||||
|
@@ -1191,7 +1198,7 @@ errno_t sss_sec_put(struct sss_sec_req *req,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = ldb_msg_add_fmt(msg, "creationTime", "%lu", time(NULL));
|
||||||
|
+ ret = ldb_msg_add_fmt(msg, SEC_ATTR_CTIME, "%lu", time(NULL));
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"ldb_msg_add_string failed adding creationTime [%d]: %s\n",
|
||||||
|
@@ -1283,7 +1290,7 @@ errno_t sss_sec_update(struct sss_sec_req *req,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = ldb_msg_add_empty(msg, "enctype", LDB_FLAG_MOD_REPLACE, NULL);
|
||||||
|
+ ret = ldb_msg_add_empty(msg, SEC_ATTR_ENCTYPE, LDB_FLAG_MOD_REPLACE, NULL);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
DEBUG(SSSDBG_MINOR_FAILURE,
|
||||||
|
"ldb_msg_add_empty failed: [%s]\n", ldb_strerror(ret));
|
||||||
|
@@ -1291,7 +1298,8 @@ errno_t sss_sec_update(struct sss_sec_req *req,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = ldb_msg_add_string(msg, "enctype", sss_sec_enctype_to_str(enctype));
|
||||||
|
+ ret = ldb_msg_add_string(msg, SEC_ATTR_ENCTYPE,
|
||||||
|
+ sss_sec_enctype_to_str(enctype));
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"ldb_msg_add_string failed adding enctype [%d]: %s\n",
|
||||||
|
@@ -1299,7 +1307,7 @@ errno_t sss_sec_update(struct sss_sec_req *req,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = ldb_msg_add_empty(msg, "type", LDB_FLAG_MOD_REPLACE, NULL);
|
||||||
|
+ ret = ldb_msg_add_empty(msg, SEC_ATTR_TYPE, LDB_FLAG_MOD_REPLACE, NULL);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
DEBUG(SSSDBG_MINOR_FAILURE,
|
||||||
|
"ldb_msg_add_empty failed: [%s]\n", ldb_strerror(ret));
|
||||||
|
@@ -1307,7 +1315,7 @@ errno_t sss_sec_update(struct sss_sec_req *req,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = ldb_msg_add_string(msg, "type", datatype);
|
||||||
|
+ ret = ldb_msg_add_string(msg, SEC_ATTR_TYPE, datatype);
|
||||||
|
if (ret != EOK) {
|
||||||
|
DEBUG(SSSDBG_OP_FAILURE,
|
||||||
|
"ldb_msg_add_string failed adding type:%s [%d]: %s\n",
|
||||||
|
@@ -1316,7 +1324,7 @@ errno_t sss_sec_update(struct sss_sec_req *req,
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME - should we have a lastUpdate timestamp? */
|
||||||
|
- ret = ldb_msg_add_empty(msg, "secret", LDB_FLAG_MOD_REPLACE, NULL);
|
||||||
|
+ ret = ldb_msg_add_empty(msg, SEC_ATTR_SECRET, LDB_FLAG_MOD_REPLACE, NULL);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
DEBUG(SSSDBG_MINOR_FAILURE,
|
||||||
|
"ldb_msg_add_empty failed: [%s]\n", ldb_strerror(ret));
|
||||||
|
@@ -1324,7 +1332,7 @@ errno_t sss_sec_update(struct sss_sec_req *req,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = ldb_msg_add_value(msg, "secret", &enc_secret, NULL);
|
||||||
|
+ ret = ldb_msg_add_value(msg, SEC_ATTR_SECRET, &enc_secret, NULL);
|
||||||
|
if (ret != LDB_SUCCESS) {
|
||||||
|
DEBUG(SSSDBG_MINOR_FAILURE,
|
||||||
|
"ldb_msg_add_string failed: [%s]\n", ldb_strerror(ret));
|
||||||
|
--
|
||||||
|
2.25.4
|
||||||
|
|
75
0019-secrets-remove-base64-enctype.patch
Normal file
75
0019-secrets-remove-base64-enctype.patch
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
From bca694200748354c7ee3e51084586d30b9b0164b Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||||
|
Date: Thu, 26 Nov 2020 12:07:06 +0100
|
||||||
|
Subject: [PATCH 19/19] secrets: remove base64 enctype
|
||||||
|
|
||||||
|
This was added as part of KCM performance improvements but never used.
|
||||||
|
Ldb is fully capable of holding binary data without the need for base64
|
||||||
|
encoding so this is not needed.
|
||||||
|
---
|
||||||
|
src/util/secrets/secrets.c | 15 ---------------
|
||||||
|
src/util/secrets/secrets.h | 1 -
|
||||||
|
2 files changed, 16 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/util/secrets/secrets.c b/src/util/secrets/secrets.c
|
||||||
|
index ae9c7c83f335c8c2d9d97a736700fbcdaf0d36af..c6310b58526d6f4c063d028cd0e78b5e4f2e12db 100644
|
||||||
|
--- a/src/util/secrets/secrets.c
|
||||||
|
+++ b/src/util/secrets/secrets.c
|
||||||
|
@@ -75,8 +75,6 @@ static const char *sss_sec_enctype_to_str(enum sss_sec_enctype enctype)
|
||||||
|
return "plaintext";
|
||||||
|
case SSS_SEC_MASTERKEY:
|
||||||
|
return "masterkey";
|
||||||
|
- case SSS_SEC_BASE64:
|
||||||
|
- return "base64";
|
||||||
|
default:
|
||||||
|
DEBUG(SSSDBG_CRIT_FAILURE, "Bug: unknown encryption type %d\n",
|
||||||
|
enctype);
|
||||||
|
@@ -94,10 +92,6 @@ static enum sss_sec_enctype sss_sec_str_to_enctype(const char *str)
|
||||||
|
return SSS_SEC_MASTERKEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (strcmp("base64", str) == 0) {
|
||||||
|
- return SSS_SEC_BASE64;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
return SSS_SEC_ENCTYPE_SENTINEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -141,10 +135,6 @@ static int local_decrypt(struct sss_sec_ctx *sctx,
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
- case SSS_SEC_BASE64:
|
||||||
|
- output = (uint8_t *)sss_base64_decode(mem_ctx, (const char *)secret,
|
||||||
|
- &output_len);
|
||||||
|
- break;
|
||||||
|
default:
|
||||||
|
DEBUG(SSSDBG_CRIT_FAILURE, "Unknown encryption type '%d'\n", enctype);
|
||||||
|
return EINVAL;
|
||||||
|
@@ -196,11 +186,6 @@ static int local_encrypt(struct sss_sec_ctx *sec_ctx,
|
||||||
|
output_len = strlen(b64) + 1;
|
||||||
|
talloc_free(_secret.data);
|
||||||
|
break;
|
||||||
|
- case SSS_SEC_BASE64:
|
||||||
|
- b64 = sss_base64_encode(mem_ctx, secret, secret_len);
|
||||||
|
- output = (uint8_t*)b64;
|
||||||
|
- output_len = strlen(b64) + 1;
|
||||||
|
- break;
|
||||||
|
default:
|
||||||
|
DEBUG(SSSDBG_CRIT_FAILURE, "Unknown encryption type '%d'\n", enctype);
|
||||||
|
return EINVAL;
|
||||||
|
diff --git a/src/util/secrets/secrets.h b/src/util/secrets/secrets.h
|
||||||
|
index f8caa53eec376bb0c8d52615ce9111efbbb26393..f79bfaa4b9dc2df577a815c03b86770e3066de75 100644
|
||||||
|
--- a/src/util/secrets/secrets.h
|
||||||
|
+++ b/src/util/secrets/secrets.h
|
||||||
|
@@ -46,7 +46,6 @@
|
||||||
|
enum sss_sec_enctype {
|
||||||
|
SSS_SEC_PLAINTEXT,
|
||||||
|
SSS_SEC_MASTERKEY,
|
||||||
|
- SSS_SEC_BASE64,
|
||||||
|
SSS_SEC_ENCTYPE_SENTINEL
|
||||||
|
};
|
||||||
|
|
||||||
|
--
|
||||||
|
2.25.4
|
||||||
|
|
24
sssd.spec
24
sssd.spec
@ -29,13 +29,32 @@
|
|||||||
|
|
||||||
Name: sssd
|
Name: sssd
|
||||||
Version: 2.4.0
|
Version: 2.4.0
|
||||||
Release: 4%{?dist}
|
Release: 5%{?dist}
|
||||||
Summary: System Security Services Daemon
|
Summary: System Security Services Daemon
|
||||||
License: GPLv3+
|
License: GPLv3+
|
||||||
URL: https://github.com/SSSD/sssd/
|
URL: https://github.com/SSSD/sssd/
|
||||||
Source0: https://github.com/SSSD/sssd/releases/download/sssd-2_4_0/sssd-2.4.0.tar.gz
|
Source0: https://github.com/SSSD/sssd/releases/download/sssd-2_4_0/sssd-2.4.0.tar.gz
|
||||||
|
|
||||||
### Patches ###
|
### Patches ###
|
||||||
|
Patch0001: 0001-kcm-fix-typos-in-debug-messages.patch
|
||||||
|
Patch0002: 0002-kcm-avoid-name-confusion-in-GET_CRED_UUID_LIST-handl.patch
|
||||||
|
Patch0003: 0003-kcm-disable-encryption.patch
|
||||||
|
Patch0004: 0004-kcm-avoid-multiple-debug-messages-if-sss_sec_put-fai.patch
|
||||||
|
Patch0005: 0005-secrets-allow-to-specify-secret-s-data-format.patch
|
||||||
|
Patch0006: 0006-secrets-accept-binary-data-instead-of-string.patch
|
||||||
|
Patch0007: 0007-iobuf-add-more-iobuf-functions.patch
|
||||||
|
Patch0008: 0008-kcm-add-json-suffix-to-existing-searialization-funct.patch
|
||||||
|
Patch0009: 0009-kcm-move-sec-key-parser-to-separate-file-so-it-can-b.patch
|
||||||
|
Patch0010: 0010-kcm-avoid-suppression-of-cppcheck-warning.patch
|
||||||
|
Patch0011: 0011-kcm-add-spaces-around-operators-in-kcmsrv_ccache_key.patch
|
||||||
|
Patch0012: 0012-kcm-use-binary-format-to-store-ccache-instead-of-jso.patch
|
||||||
|
Patch0013: 0013-kcm-add-per-connection-data-to-be-shared-between-req.patch
|
||||||
|
Patch0014: 0014-sss_ptr_hash-fix-double-free-for-circular-dependenci.patch
|
||||||
|
Patch0015: 0015-kcm-store-credentials-list-in-hash-table-to-avoid-ca.patch
|
||||||
|
Patch0016: 0016-secrets-fix-may_payload_size-exceeded-debug-message.patch
|
||||||
|
Patch0017: 0017-secrets-default-to-plaintext-if-enctype-attr-is-miss.patch
|
||||||
|
Patch0018: 0018-secrets-move-attrs-names-to-macros.patch
|
||||||
|
Patch0019: 0019-secrets-remove-base64-enctype.patch
|
||||||
|
|
||||||
### Downstream only patches ###
|
### Downstream only patches ###
|
||||||
Patch0502: 0502-SYSTEMD-Use-capabilities.patch
|
Patch0502: 0502-SYSTEMD-Use-capabilities.patch
|
||||||
@ -1014,6 +1033,9 @@ fi
|
|||||||
%systemd_postun_with_restart sssd.service
|
%systemd_postun_with_restart sssd.service
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Dec 7 2020 Pavel Březina <pbrezina@redhat.com> - 2.4.0-5
|
||||||
|
- Improve sssd-kcm performance (rhbz#1645624)
|
||||||
|
|
||||||
* Mon Nov 30 2020 Stephen Gallagher <sgallagh@redhat.com> - 2.4.0-4
|
* Mon Nov 30 2020 Stephen Gallagher <sgallagh@redhat.com> - 2.4.0-4
|
||||||
- Rebuild for Fedora ELN
|
- Rebuild for Fedora ELN
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user