mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
s4-dsdb: Populate new GKDI root keys from the server configuration object
This honours MS-GKDI 3.1.4.1.1 Creating a New Root Key Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
This commit is contained in:
parent
565314f448
commit
3687bf22aa
@ -37,6 +37,8 @@ enum KdfAlgorithmId {
|
||||
KDF_ALGORITHM_SP800_108_CTR_HMAC,
|
||||
};
|
||||
|
||||
#define SP800_108_CTR_HMAC "SP800_108_CTR_HMAC"
|
||||
|
||||
enum KdfSp800_108Param {
|
||||
KDF_PARAM_SHA1,
|
||||
KDF_PARAM_SHA256,
|
||||
|
@ -17,7 +17,3 @@
|
||||
^samba\.tests\.krb5\.gkdi_tests\.samba\.tests\.krb5\.gkdi_tests\.GkdiImplicitRootKeyTests\.test_request_default_seed_key\(ad_dc\)$
|
||||
^samba\.tests\.krb5\.gkdi_tests\.samba\.tests\.krb5\.gkdi_tests\.GkdiImplicitRootKeyTests\.test_request_l0_seed_key\(ad_dc\)$
|
||||
^samba\.tests\.krb5\.gkdi_tests\.samba\.tests\.krb5\.gkdi_tests\.GkdiImplicitRootKeyTests\.test_request_l1_seed_key\(ad_dc\)$
|
||||
^samba.tests.dsdb_quiet_provision_tests.samba.tests.dsdb_quiet_provision_tests.DsdbQuietProvisionTests.test_gkdi_create_root_key_4096
|
||||
^samba.tests.dsdb_quiet_provision_tests.samba.tests.dsdb_quiet_provision_tests.DsdbQuietProvisionTests.test_gkdi_create_root_key_bad_alg
|
||||
^samba.tests.dsdb_quiet_provision_tests.samba.tests.dsdb_quiet_provision_tests.DsdbQuietProvisionTests.test_gkdi_create_root_key_priv_1024
|
||||
^samba.tests.dsdb_quiet_provision_tests.samba.tests.dsdb_quiet_provision_tests.DsdbQuietProvisionTests.test_gkdi_create_root_key_wrong_version
|
||||
|
@ -1325,9 +1325,9 @@ struct ldb_dn *samdb_extended_rights_dn(struct ldb_context *sam_ctx, TALLOC_CTX
|
||||
return new_dn;
|
||||
}
|
||||
|
||||
static struct ldb_dn *samdb_configuration_dn(struct ldb_context *sam_ctx,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const char *dn_str)
|
||||
struct ldb_dn *samdb_configuration_dn(struct ldb_context *sam_ctx,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const char *dn_str)
|
||||
{
|
||||
struct ldb_dn *config_dn = NULL;
|
||||
struct ldb_dn *child_dn = NULL;
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "dsdb/gmsa/gkdi.h"
|
||||
#include "dsdb/samdb/ldb_modules/util.h"
|
||||
#include "dsdb/samdb/samdb.h"
|
||||
#include "dsdb/common/proto.h"
|
||||
|
||||
static int gkdi_create_root_key(TALLOC_CTX *mem_ctx,
|
||||
struct ldb_context *const ldb,
|
||||
@ -40,10 +41,33 @@ static int gkdi_create_root_key(TALLOC_CTX *mem_ctx,
|
||||
{
|
||||
TALLOC_CTX *tmp_ctx = NULL;
|
||||
struct GUID root_key_id;
|
||||
struct ldb_dn *server_config_dn = NULL;
|
||||
struct ldb_result *server_config_res = NULL;
|
||||
struct ldb_message *server_config_msg = NULL;
|
||||
uint64_t server_config_version;
|
||||
const struct ldb_val *server_config_version_val = NULL;
|
||||
const char *server_config_KDFAlgorithmID = NULL;
|
||||
const struct ldb_val *server_config_KDFParam = NULL;
|
||||
const char *server_config_SecretAgreementAlgorithmID = NULL;
|
||||
const struct ldb_val *server_config_SecretAgreementParam = NULL;
|
||||
uint64_t server_config_PublicKeyLength;
|
||||
uint64_t server_config_PrivateKeyLength;
|
||||
struct KdfAlgorithm kdf_algorithm;
|
||||
struct ldb_message *add_msg = NULL;
|
||||
NTSTATUS status = NT_STATUS_OK;
|
||||
int ret = LDB_SUCCESS;
|
||||
|
||||
static const char *server_config_attrs[] = {
|
||||
"msKds-Version",
|
||||
"msKds-KDFAlgorithmID",
|
||||
"msKds-SecretAgreementAlgorithmID",
|
||||
"msKds-SecretAgreementParam",
|
||||
"msKds-PublicKeyLength",
|
||||
"msKds-PrivateKeyLength",
|
||||
"msKds-KDFParam",
|
||||
NULL
|
||||
};
|
||||
|
||||
*root_key_dn_out = NULL;
|
||||
|
||||
tmp_ctx = talloc_new(mem_ctx);
|
||||
@ -52,6 +76,179 @@ static int gkdi_create_root_key(TALLOC_CTX *mem_ctx,
|
||||
goto out;
|
||||
}
|
||||
|
||||
server_config_dn = samdb_configuration_dn(ldb,
|
||||
mem_ctx,
|
||||
"CN=Group Key Distribution Service Server Configuration,"
|
||||
"CN=Server Configuration,"
|
||||
"CN=Group Key Distribution Service,"
|
||||
"CN=Services");
|
||||
if (server_config_dn == NULL) {
|
||||
ret = ldb_oom(ldb);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = dsdb_search_dn(ldb,
|
||||
tmp_ctx,
|
||||
&server_config_res,
|
||||
server_config_dn,
|
||||
server_config_attrs,
|
||||
DSDB_SEARCH_ONE_ONLY);
|
||||
|
||||
if (ret == LDB_ERR_NO_SUCH_OBJECT) {
|
||||
ldb_asprintf_errstring(ldb, "Unable to create new GKDI root key as we do not have a GKDI server configuration at %s",
|
||||
ldb_dn_get_linearized(server_config_dn));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ret != LDB_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
server_config_msg = server_config_res->msgs[0];
|
||||
|
||||
server_config_version_val
|
||||
= ldb_msg_find_ldb_val(server_config_msg,
|
||||
"msKds-Version");
|
||||
server_config_version
|
||||
= ldb_msg_find_attr_as_uint64(server_config_msg,
|
||||
"msKds-Version",
|
||||
0);
|
||||
|
||||
/* These values we assert on, so we don't create keys we can't use */
|
||||
if (server_config_version_val == NULL) {
|
||||
/*
|
||||
* The systemMustContain msKds-Version attribute
|
||||
* cannot be read, so if absent we just fail with
|
||||
* permission denied, as that is all that this can
|
||||
* mean
|
||||
*/
|
||||
ldb_asprintf_errstring(ldb,
|
||||
"Unwilling to create new GKDI root key as "
|
||||
"msKds-Version is not readable on %s\n",
|
||||
ldb_dn_get_linearized(server_config_dn));
|
||||
ret = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
|
||||
goto out;
|
||||
} else if (server_config_version != 1) {
|
||||
ldb_asprintf_errstring(ldb,
|
||||
"Unwilling to create new GKDI root key as "
|
||||
"%s has msKds-Version = %s "
|
||||
"and we only support version 1\n",
|
||||
ldb_dn_get_linearized(server_config_dn),
|
||||
ldb_msg_find_attr_as_string(server_config_msg, "msKds-Version", "(missing)"));
|
||||
ret = LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
goto out;
|
||||
}
|
||||
|
||||
server_config_KDFAlgorithmID
|
||||
= ldb_msg_find_attr_as_string(server_config_msg,
|
||||
"msKds-KDFAlgorithmID",
|
||||
SP800_108_CTR_HMAC
|
||||
);
|
||||
|
||||
server_config_KDFParam
|
||||
= ldb_msg_find_ldb_val(server_config_msg,
|
||||
"msKds-KDFParam");
|
||||
if (server_config_KDFParam == NULL) {
|
||||
static const uint8_t kdf_parameters[] = {
|
||||
0, 0, 0, 0, 1, 0, 0, 0, 14, 0,
|
||||
0, 0, 0, 0, 0, 0, 'S', 0, 'H', 0,
|
||||
'A', 0, '5', 0, '1', 0, '2', 0, 0, 0,
|
||||
};
|
||||
static const DATA_BLOB kdf_parameters_blob = {
|
||||
discard_const_p(uint8_t, kdf_parameters),
|
||||
sizeof kdf_parameters};
|
||||
server_config_KDFParam = &kdf_parameters_blob;
|
||||
}
|
||||
|
||||
status = kdf_algorithm_from_params(server_config_KDFAlgorithmID,
|
||||
server_config_KDFParam,
|
||||
&kdf_algorithm);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
ldb_asprintf_errstring(ldb,
|
||||
"Unwilling to create new GKDI root key as "
|
||||
"%s has an unsupported msKds-KDFAlgorithmID / msKds-KDFParam combination set: %s\n",
|
||||
ldb_dn_get_linearized(server_config_dn),
|
||||
nt_errstr(status));
|
||||
ret = LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
goto out;
|
||||
}
|
||||
|
||||
server_config_SecretAgreementAlgorithmID
|
||||
= ldb_msg_find_attr_as_string(server_config_msg,
|
||||
"msKds-SecretAgreementAlgorithmID",
|
||||
"DH");
|
||||
|
||||
/* Optional in msKds-ProvRootKey */
|
||||
server_config_SecretAgreementParam
|
||||
= ldb_msg_find_ldb_val(server_config_msg,
|
||||
"msKds-SecretAgreementParam");
|
||||
if (server_config_SecretAgreementParam == NULL) {
|
||||
static const uint8_t ffc_dh_parameters[] = {
|
||||
12, 2, 0, 0, 68, 72, 80, 77, 0, 1, 0,
|
||||
0, 135, 168, 230, 29, 180, 182, 102, 60, 255, 187,
|
||||
209, 156, 101, 25, 89, 153, 140, 238, 246, 8, 102,
|
||||
13, 208, 242, 93, 44, 238, 212, 67, 94, 59, 0,
|
||||
224, 13, 248, 241, 214, 25, 87, 212, 250, 247, 223,
|
||||
69, 97, 178, 170, 48, 22, 195, 217, 17, 52, 9,
|
||||
111, 170, 59, 244, 41, 109, 131, 14, 154, 124, 32,
|
||||
158, 12, 100, 151, 81, 122, 189, 90, 138, 157, 48,
|
||||
107, 207, 103, 237, 145, 249, 230, 114, 91, 71, 88,
|
||||
192, 34, 224, 177, 239, 66, 117, 191, 123, 108, 91,
|
||||
252, 17, 212, 95, 144, 136, 185, 65, 245, 78, 177,
|
||||
229, 155, 184, 188, 57, 160, 191, 18, 48, 127, 92,
|
||||
79, 219, 112, 197, 129, 178, 63, 118, 182, 58, 202,
|
||||
225, 202, 166, 183, 144, 45, 82, 82, 103, 53, 72,
|
||||
138, 14, 241, 60, 109, 154, 81, 191, 164, 171, 58,
|
||||
216, 52, 119, 150, 82, 77, 142, 246, 161, 103, 181,
|
||||
164, 24, 37, 217, 103, 225, 68, 229, 20, 5, 100,
|
||||
37, 28, 202, 203, 131, 230, 180, 134, 246, 179, 202,
|
||||
63, 121, 113, 80, 96, 38, 192, 184, 87, 246, 137,
|
||||
150, 40, 86, 222, 212, 1, 10, 189, 11, 230, 33,
|
||||
195, 163, 150, 10, 84, 231, 16, 195, 117, 242, 99,
|
||||
117, 215, 1, 65, 3, 164, 181, 67, 48, 193, 152,
|
||||
175, 18, 97, 22, 210, 39, 110, 17, 113, 95, 105,
|
||||
56, 119, 250, 215, 239, 9, 202, 219, 9, 74, 233,
|
||||
30, 26, 21, 151, 63, 179, 44, 155, 115, 19, 77,
|
||||
11, 46, 119, 80, 102, 96, 237, 189, 72, 76, 167,
|
||||
177, 143, 33, 239, 32, 84, 7, 244, 121, 58, 26,
|
||||
11, 161, 37, 16, 219, 193, 80, 119, 190, 70, 63,
|
||||
255, 79, 237, 74, 172, 11, 181, 85, 190, 58, 108,
|
||||
27, 12, 107, 71, 177, 188, 55, 115, 191, 126, 140,
|
||||
111, 98, 144, 18, 40, 248, 194, 140, 187, 24, 165,
|
||||
90, 227, 19, 65, 0, 10, 101, 1, 150, 249, 49,
|
||||
199, 122, 87, 242, 221, 244, 99, 229, 233, 236, 20,
|
||||
75, 119, 125, 230, 42, 170, 184, 168, 98, 138, 195,
|
||||
118, 210, 130, 214, 237, 56, 100, 230, 121, 130, 66,
|
||||
142, 188, 131, 29, 20, 52, 143, 111, 47, 145, 147,
|
||||
181, 4, 90, 242, 118, 113, 100, 225, 223, 201, 103,
|
||||
193, 251, 63, 46, 85, 164, 189, 27, 255, 232, 59,
|
||||
156, 128, 208, 82, 185, 133, 209, 130, 234, 10, 219,
|
||||
42, 59, 115, 19, 211, 254, 20, 200, 72, 75, 30,
|
||||
5, 37, 136, 185, 183, 210, 187, 210, 223, 1, 97,
|
||||
153, 236, 208, 110, 21, 87, 205, 9, 21, 179, 53,
|
||||
59, 187, 100, 224, 236, 55, 127, 208, 40, 55, 13,
|
||||
249, 43, 82, 199, 137, 20, 40, 205, 198, 126, 182,
|
||||
24, 75, 82, 61, 29, 178, 70, 195, 47, 99, 7,
|
||||
132, 144, 240, 14, 248, 214, 71, 209, 72, 212, 121,
|
||||
84, 81, 94, 35, 39, 207, 239, 152, 197, 130, 102,
|
||||
75, 76, 15, 108, 196, 22, 89};
|
||||
static const DATA_BLOB ffc_dh_parameters_blob = {
|
||||
discard_const_p(uint8_t, ffc_dh_parameters),
|
||||
sizeof ffc_dh_parameters};
|
||||
|
||||
server_config_SecretAgreementParam = &ffc_dh_parameters_blob;
|
||||
}
|
||||
|
||||
server_config_PublicKeyLength
|
||||
= ldb_msg_find_attr_as_uint64(server_config_msg,
|
||||
"msKds-PublicKeyLength",
|
||||
2048);
|
||||
|
||||
server_config_PrivateKeyLength
|
||||
= ldb_msg_find_attr_as_uint64(server_config_msg,
|
||||
"msKds-PrivateKeyLength",
|
||||
256);
|
||||
|
||||
add_msg = ldb_msg_new(tmp_ctx);
|
||||
if (add_msg == NULL) {
|
||||
ret = ldb_oom(ldb);
|
||||
@ -119,128 +316,67 @@ static int gkdi_create_root_key(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
ret = ldb_msg_append_string(add_msg,
|
||||
"msKds-Version",
|
||||
"1",
|
||||
LDB_FLAG_MOD_ADD);
|
||||
ret = samdb_msg_append_uint64(ldb,
|
||||
tmp_ctx,
|
||||
add_msg,
|
||||
"msKds-Version",
|
||||
server_config_version,
|
||||
LDB_FLAG_MOD_ADD);
|
||||
if (ret) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = ldb_msg_append_string(add_msg,
|
||||
"msKds-KDFAlgorithmID",
|
||||
"SP800_108_CTR_HMAC",
|
||||
server_config_KDFAlgorithmID,
|
||||
LDB_FLAG_MOD_ADD);
|
||||
if (ret) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = ldb_msg_append_string(add_msg,
|
||||
"msKds-SecretAgreementAlgorithmID",
|
||||
"DH",
|
||||
LDB_FLAG_MOD_ADD);
|
||||
"msKds-SecretAgreementAlgorithmID",
|
||||
server_config_SecretAgreementAlgorithmID,
|
||||
LDB_FLAG_MOD_ADD);
|
||||
if (ret) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
{
|
||||
static const uint8_t ffc_dh_parameters[] = {
|
||||
12, 2, 0, 0, 68, 72, 80, 77, 0, 1, 0,
|
||||
0, 135, 168, 230, 29, 180, 182, 102, 60, 255, 187,
|
||||
209, 156, 101, 25, 89, 153, 140, 238, 246, 8, 102,
|
||||
13, 208, 242, 93, 44, 238, 212, 67, 94, 59, 0,
|
||||
224, 13, 248, 241, 214, 25, 87, 212, 250, 247, 223,
|
||||
69, 97, 178, 170, 48, 22, 195, 217, 17, 52, 9,
|
||||
111, 170, 59, 244, 41, 109, 131, 14, 154, 124, 32,
|
||||
158, 12, 100, 151, 81, 122, 189, 90, 138, 157, 48,
|
||||
107, 207, 103, 237, 145, 249, 230, 114, 91, 71, 88,
|
||||
192, 34, 224, 177, 239, 66, 117, 191, 123, 108, 91,
|
||||
252, 17, 212, 95, 144, 136, 185, 65, 245, 78, 177,
|
||||
229, 155, 184, 188, 57, 160, 191, 18, 48, 127, 92,
|
||||
79, 219, 112, 197, 129, 178, 63, 118, 182, 58, 202,
|
||||
225, 202, 166, 183, 144, 45, 82, 82, 103, 53, 72,
|
||||
138, 14, 241, 60, 109, 154, 81, 191, 164, 171, 58,
|
||||
216, 52, 119, 150, 82, 77, 142, 246, 161, 103, 181,
|
||||
164, 24, 37, 217, 103, 225, 68, 229, 20, 5, 100,
|
||||
37, 28, 202, 203, 131, 230, 180, 134, 246, 179, 202,
|
||||
63, 121, 113, 80, 96, 38, 192, 184, 87, 246, 137,
|
||||
150, 40, 86, 222, 212, 1, 10, 189, 11, 230, 33,
|
||||
195, 163, 150, 10, 84, 231, 16, 195, 117, 242, 99,
|
||||
117, 215, 1, 65, 3, 164, 181, 67, 48, 193, 152,
|
||||
175, 18, 97, 22, 210, 39, 110, 17, 113, 95, 105,
|
||||
56, 119, 250, 215, 239, 9, 202, 219, 9, 74, 233,
|
||||
30, 26, 21, 151, 63, 179, 44, 155, 115, 19, 77,
|
||||
11, 46, 119, 80, 102, 96, 237, 189, 72, 76, 167,
|
||||
177, 143, 33, 239, 32, 84, 7, 244, 121, 58, 26,
|
||||
11, 161, 37, 16, 219, 193, 80, 119, 190, 70, 63,
|
||||
255, 79, 237, 74, 172, 11, 181, 85, 190, 58, 108,
|
||||
27, 12, 107, 71, 177, 188, 55, 115, 191, 126, 140,
|
||||
111, 98, 144, 18, 40, 248, 194, 140, 187, 24, 165,
|
||||
90, 227, 19, 65, 0, 10, 101, 1, 150, 249, 49,
|
||||
199, 122, 87, 242, 221, 244, 99, 229, 233, 236, 20,
|
||||
75, 119, 125, 230, 42, 170, 184, 168, 98, 138, 195,
|
||||
118, 210, 130, 214, 237, 56, 100, 230, 121, 130, 66,
|
||||
142, 188, 131, 29, 20, 52, 143, 111, 47, 145, 147,
|
||||
181, 4, 90, 242, 118, 113, 100, 225, 223, 201, 103,
|
||||
193, 251, 63, 46, 85, 164, 189, 27, 255, 232, 59,
|
||||
156, 128, 208, 82, 185, 133, 209, 130, 234, 10, 219,
|
||||
42, 59, 115, 19, 211, 254, 20, 200, 72, 75, 30,
|
||||
5, 37, 136, 185, 183, 210, 187, 210, 223, 1, 97,
|
||||
153, 236, 208, 110, 21, 87, 205, 9, 21, 179, 53,
|
||||
59, 187, 100, 224, 236, 55, 127, 208, 40, 55, 13,
|
||||
249, 43, 82, 199, 137, 20, 40, 205, 198, 126, 182,
|
||||
24, 75, 82, 61, 29, 178, 70, 195, 47, 99, 7,
|
||||
132, 144, 240, 14, 248, 214, 71, 209, 72, 212, 121,
|
||||
84, 81, 94, 35, 39, 207, 239, 152, 197, 130, 102,
|
||||
75, 76, 15, 108, 196, 22, 89};
|
||||
const DATA_BLOB ffc_dh_parameters_blob = {
|
||||
discard_const_p(uint8_t, ffc_dh_parameters),
|
||||
sizeof ffc_dh_parameters};
|
||||
|
||||
if (server_config_SecretAgreementParam != NULL) {
|
||||
ret = ldb_msg_append_value(add_msg,
|
||||
"msKds-SecretAgreementParam",
|
||||
&ffc_dh_parameters_blob,
|
||||
server_config_SecretAgreementParam,
|
||||
LDB_FLAG_MOD_ADD);
|
||||
if (ret) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = ldb_msg_append_string(add_msg,
|
||||
"msKds-PublicKeyLength",
|
||||
"2048",
|
||||
LDB_FLAG_MOD_ADD);
|
||||
ret = samdb_msg_append_uint64(ldb,
|
||||
tmp_ctx,
|
||||
add_msg,
|
||||
"msKds-PublicKeyLength",
|
||||
server_config_PublicKeyLength,
|
||||
LDB_FLAG_MOD_ADD);
|
||||
if (ret) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = ldb_msg_append_string(add_msg,
|
||||
"msKds-PrivateKeyLength",
|
||||
"512",
|
||||
LDB_FLAG_MOD_ADD);
|
||||
ret = samdb_msg_append_uint64(ldb,
|
||||
tmp_ctx,
|
||||
add_msg,
|
||||
"msKds-PrivateKeyLength",
|
||||
server_config_PrivateKeyLength,
|
||||
LDB_FLAG_MOD_ADD);
|
||||
|
||||
ret = ldb_msg_append_value(add_msg,
|
||||
"msKds-KDFParam",
|
||||
server_config_KDFParam,
|
||||
LDB_FLAG_MOD_ADD);
|
||||
if (ret) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
{
|
||||
static const uint8_t kdf_parameters[] = {
|
||||
0, 0, 0, 0, 1, 0, 0, 0, 14, 0,
|
||||
0, 0, 0, 0, 0, 0, 'S', 0, 'H', 0,
|
||||
'A', 0, '5', 0, '1', 0, '2', 0, 0, 0,
|
||||
};
|
||||
const DATA_BLOB kdf_parameters_blob = {
|
||||
discard_const_p(uint8_t, kdf_parameters),
|
||||
sizeof kdf_parameters};
|
||||
|
||||
ret = ldb_msg_append_value(add_msg,
|
||||
"msKds-KDFParam",
|
||||
&kdf_parameters_blob,
|
||||
LDB_FLAG_MOD_ADD);
|
||||
if (ret) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
uint8_t guid_buf[sizeof((struct GUID_ndr_buf){}.buf)];
|
||||
const DATA_BLOB guid_blob = {.data = guid_buf,
|
||||
|
Loading…
Reference in New Issue
Block a user