1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

Add support for security descriptors. Also patched the regf backend to support this.

Did not touch the ldb, dir and rpc backends yet.
(This used to be commit c4626f21a8)
This commit is contained in:
Wilco Baan Hofman 2008-04-14 22:52:51 +02:00
parent 212644b5a1
commit 12147fca2b
7 changed files with 164 additions and 42 deletions

View File

@ -143,6 +143,24 @@ WERROR hive_get_value_by_index(TALLOC_CTX *mem_ctx,
return key->ops->enum_value(mem_ctx, key, idx, name, type, data);
}
WERROR hive_get_sec_desc(TALLOC_CTX *mem_ctx,
struct hive_key *key,
struct security_descriptor **security)
{
if (key->ops->get_sec_desc == NULL)
return WERR_NOT_SUPPORTED;
return key->ops->get_sec_desc(mem_ctx, key, security);
}
WERROR hive_set_sec_desc(struct hive_key *key,
const struct security_descriptor *security)
{
if (key->ops->set_sec_desc == NULL)
return WERR_NOT_SUPPORTED;
return key->ops->set_sec_desc(key, security);
}
WERROR hive_key_del_value(struct hive_key *key, const char *name)
{

View File

@ -249,10 +249,10 @@ _PUBLIC_ WERROR reg_get_sec_desc(TALLOC_CTX *ctx,
return WERR_INVALID_PARAM;
/* A 'real' set function has preference */
if (key->context->ops->get_security == NULL)
if (key->context->ops->get_sec_desc == NULL)
return WERR_NOT_SUPPORTED;
return key->context->ops->get_security(ctx, key, secdesc);
return key->context->ops->get_sec_desc(ctx, key, secdesc);
}
/**
@ -283,27 +283,14 @@ _PUBLIC_ WERROR reg_key_flush(struct registry_key *key)
return key->context->ops->flush_key(key);
}
_PUBLIC_ WERROR reg_get_security(TALLOC_CTX *mem_ctx,
const struct registry_key *key,
struct security_descriptor **security)
{
if (key == NULL)
return WERR_INVALID_PARAM;
if (key->context->ops->get_security == NULL)
return WERR_NOT_SUPPORTED;
return key->context->ops->get_security(mem_ctx, key, security);
}
_PUBLIC_ WERROR reg_set_security(struct registry_key *key,
_PUBLIC_ WERROR reg_set_sec_desc(struct registry_key *key,
struct security_descriptor *security)
{
if (key == NULL)
return WERR_INVALID_PARAM;
if (key->context->ops->set_security == NULL)
if (key->context->ops->set_sec_desc == NULL)
return WERR_NOT_SUPPORTED;
return key->context->ops->set_security(key, security);
return key->context->ops->set_sec_desc(key, security);
}

View File

@ -278,7 +278,21 @@ static WERROR local_get_key_info(TALLOC_CTX *mem_ctx,
last_change_time, max_subkeynamelen,
max_valnamelen, max_valbufsize);
}
static WERROR local_get_sec_desc(TALLOC_CTX *mem_ctx,
const struct registry_key *key,
struct security_descriptor **security)
{
const struct local_key *local = (const struct local_key *)key;
return hive_get_sec_desc(mem_ctx, local->hive_key, security);
}
static WERROR local_set_sec_desc(struct registry_key *key,
const struct security_descriptor *security)
{
const struct local_key *local = (const struct local_key *)key;
return hive_set_sec_desc(local->hive_key, security);
}
const static struct registry_operations local_ops = {
.name = "local",
.open_key = local_open_key,
@ -292,6 +306,8 @@ const static struct registry_operations local_ops = {
.delete_value = local_delete_value,
.flush_key = local_flush_key,
.get_key_info = local_get_key_info,
.get_sec_desc = local_get_sec_desc,
.set_sec_desc = local_set_sec_desc,
};
WERROR reg_open_local(TALLOC_CTX *mem_ctx, struct registry_context **ctx,

View File

@ -25,6 +25,8 @@
#include "librpc/gen_ndr/winreg.h"
#include "param/param.h"
#include "lib/registry/registry.h"
#include "libcli/security/security.h"
static struct hive_operations reg_backend_regf;
@ -1915,9 +1917,12 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx,
{
struct regf_data *regf;
struct regf_hdr *regf_hdr;
int i;
struct nk_block nk;
struct sk_block sk;
WERROR error;
DATA_BLOB data;
struct security_descriptor *sd;
uint32_t sk_offset;
regf = (struct regf_data *)talloc_zero(NULL, struct regf_data);
@ -1945,20 +1950,17 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx,
regf_hdr->version.minor = minor_version;
regf_hdr->last_block = 0x1000; /* Block size */
regf_hdr->description = talloc_strdup(regf_hdr,
"registry created by Samba 4");
"Registry created by Samba 4");
W_ERROR_HAVE_NO_MEMORY(regf_hdr->description);
regf_hdr->chksum = 0;
regf->header = regf_hdr;
i = 0;
/* Create all hbin blocks */
regf->hbins = talloc_array(regf, struct hbin_block *, 1);
W_ERROR_HAVE_NO_MEMORY(regf->hbins);
regf->hbins[0] = NULL;
regf_hdr->data_offset = -1; /* FIXME */
nk.header = "nk";
nk.type = REG_SUB_KEY;
unix_to_nt_time(&nk.last_change, time(NULL));
@ -1971,27 +1973,67 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx,
nk.num_values = 0;
nk.values_offset = -1;
memset(nk.unk3, 0, 5);
nk.clsname_offset = -1; /* FIXME: fill in */
nk.clsname_offset = -1;
nk.clsname_length = 0;
nk.key_name = "";
nk.sk_offset = 0x80;
nk.key_name = "SambaRootKey";
nk.sk_offset = -1; /* FIXME: fill in */
/*
* It should be noted that changing the key_name to something shorter
* creates a shorter nk block, which makes the position of the sk block
* change. All Windows registries I've seen have the sk at 0x80.
* I therefore recommend that our regf files share that offset -- Wilco
*/
/* Create a security descriptor. */
sd = security_descriptor_dacl_create(regf,
0,
NULL, NULL,
SID_NT_AUTHENTICATED_USERS,
SEC_ACE_TYPE_ACCESS_ALLOWED,
SEC_GENERIC_ALL,
SEC_ACE_FLAG_OBJECT_INHERIT,
NULL);
/* Push the security descriptor to a blob */
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_struct_blob(&data, regf, NULL,
sd, (ndr_push_flags_fn_t)ndr_push_security_descriptor))) {
DEBUG(0, ("Unable to push security descriptor\n"));
return WERR_GENERAL_FAILURE;
}
ZERO_STRUCT(sk);
sk.header = "sk";
sk.prev_offset = 0x80;
sk.next_offset = 0x80;
sk.ref_cnt = 1;
sk.rec_size = data.length;
sk.sec_desc = data.data;
/* Store the new nk key */
regf->header->data_offset = hbin_store_tdr(regf,
(tdr_push_fn_t)tdr_push_nk_block,
&nk);
/* Store the sk block */
sk_offset = hbin_store_tdr(regf,
(tdr_push_fn_t) tdr_push_sk_block,
&sk);
if (sk_offset != 0x80) {
DEBUG(0, ("Error storing sk block, should be at 0x80, stored at 0x%x\n", nk.sk_offset));
return WERR_GENERAL_FAILURE;
}
*key = (struct hive_key *)regf_get_key(parent_ctx, regf,
regf->header->data_offset);
/* We can drop our own reference now that *key will have created one */
talloc_free(regf);
error = regf_save_hbin(regf);
if (!W_ERROR_IS_OK(error)) {
return error;
}
/* We can drop our own reference now that *key will have created one */
talloc_free(regf);
return WERR_OK;
}

View File

@ -184,6 +184,12 @@ WERROR hive_get_value_by_index(TALLOC_CTX *mem_ctx,
struct hive_key *key, uint32_t idx,
const char **name,
uint32_t *type, DATA_BLOB *data);
WERROR hive_get_sec_desc(TALLOC_CTX *mem_ctx,
struct hive_key *key,
struct security_descriptor **security);
WERROR hive_set_sec_desc(struct hive_key *key,
const struct security_descriptor *security);
WERROR hive_key_del_value(struct hive_key *key, const char *name);
@ -311,11 +317,11 @@ struct registry_operations {
uint32_t *type,
DATA_BLOB *data);
WERROR (*get_security) (TALLOC_CTX *mem_ctx,
WERROR (*get_sec_desc) (TALLOC_CTX *mem_ctx,
const struct registry_key *key,
struct security_descriptor **security);
WERROR (*set_security) (struct registry_key *key,
WERROR (*set_sec_desc) (struct registry_key *key,
const struct security_descriptor *security);
WERROR (*load_key) (struct registry_key *key,
@ -461,12 +467,8 @@ struct registry_key *reg_import_hive_key(struct registry_context *ctx,
struct hive_key *hive,
uint32_t predef_key,
const char **elements);
WERROR reg_get_security(TALLOC_CTX *mem_ctx,
const struct registry_key *key,
struct security_descriptor **security);
WERROR reg_set_security(struct registry_key *key,
struct security_descriptor *security);
WERROR reg_set_sec_desc(struct registry_key *key,
const struct security_descriptor *security);
struct reg_diff_callbacks {
WERROR (*add_key) (void *callback_data, const char *key_name);
@ -490,6 +492,9 @@ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename,
struct smb_iconv_convenience *iconv_convenience,
struct reg_diff_callbacks **callbacks,
void **callback_data);
WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename,
struct reg_diff_callbacks **callbacks,
void **callback_data);
WERROR reg_generate_diff_key(struct registry_key *oldkey,
struct registry_key *newkey,
const char *path,

View File

@ -26,6 +26,7 @@
#include "librpc/gen_ndr/winreg.h"
#include "system/filesys.h"
#include "param/param.h"
#include "libcli/security/security.h"
static bool test_del_nonexistant_key(struct torture_context *tctx,
const void *test_data)
@ -297,6 +298,57 @@ static bool test_list_values(struct torture_context *tctx,
return true;
}
static bool test_hive_security(struct torture_context *tctx, const void *_data)
{
struct hive_key *subkey = NULL;
const struct hive_key *root = _data;
WERROR error;
struct security_descriptor *osd, *nsd;
osd = security_descriptor_dacl_create(tctx,
0,
NULL, NULL,
SID_NT_AUTHENTICATED_USERS,
SEC_ACE_TYPE_ACCESS_ALLOWED,
SEC_GENERIC_ALL,
SEC_ACE_FLAG_OBJECT_INHERIT,
NULL);
error = hive_key_add_name(tctx, root, "SecurityKey", NULL,
osd, &subkey);
torture_assert_werr_ok(tctx, error, "hive_key_add_name");
error = hive_get_sec_desc(tctx, subkey, &nsd);
torture_assert_werr_ok (tctx, error, "getting security descriptor");
torture_assert(tctx, security_descriptor_equal(osd, nsd),
"security descriptor changed!");
/* Create a fresh security descriptor */
talloc_free(osd);
osd = security_descriptor_dacl_create(tctx,
0,
NULL, NULL,
SID_NT_AUTHENTICATED_USERS,
SEC_ACE_TYPE_ACCESS_ALLOWED,
SEC_GENERIC_ALL,
SEC_ACE_FLAG_OBJECT_INHERIT,
NULL);
error = hive_set_sec_desc(subkey, osd);
torture_assert_werr_ok(tctx, error, "setting security descriptor");
printf("The second one is done.\n");
error = hive_get_sec_desc(tctx, subkey, &nsd);
torture_assert_werr_ok (tctx, error, "getting security descriptor");
torture_assert(tctx, security_descriptor_equal(osd, nsd),
"security descriptor changed!");
return true;
}
static void tcase_add_tests(struct torture_tcase *tcase)
{
torture_tcase_add_simple_test_const(tcase, "del_nonexistant_key",
@ -324,6 +376,8 @@ static void tcase_add_tests(struct torture_tcase *tcase)
test_del_key);
torture_tcase_add_simple_test_const(tcase, "del_value",
test_del_value);
torture_tcase_add_simple_test_const(tcase, "check hive security",
test_hive_security);
}
static bool hive_setup_dir(struct torture_context *tctx, void **data)
@ -381,7 +435,7 @@ static bool hive_setup_regf(struct torture_context *tctx, void **data)
char *dirname;
NTSTATUS status;
status = torture_temp_dir(tctx, "hive-dir", &dirname);
status = torture_temp_dir(tctx, "hive-regf", &dirname);
if (!NT_STATUS_IS_OK(status))
return false;

View File

@ -387,11 +387,11 @@ static bool test_security(struct torture_context *tctx, void *_data)
SEC_ACE_FLAG_OBJECT_INHERIT,
NULL);
error = reg_set_security(subkey, osd);
torture_assert_werr_ok(tctx, error, "setting security");
error = reg_set_sec_desc(subkey, osd);
torture_assert_werr_ok(tctx, error, "setting security descriptor");
error = reg_get_security(tctx, subkey, &nsd);
torture_assert_werr_ok (tctx, error, "setting security");
error = reg_get_sec_desc(tctx, subkey, &nsd);
torture_assert_werr_ok (tctx, error, "getting security descriptor");
torture_assert(tctx, security_descriptor_equal(osd, nsd),
"security descriptor changed!");