mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
r3338: More work on the winreg RPC server. Opening hives is now supported, most other calls
return WERR_NOT_SUPPORTED for now.
Hive backends can be set like this:
registry:HKEY_LOCAL_MACHINE = ldb:tdb://registry.tdb
registry:HKEY_CURRENT_USER = gconf
registry:HKEY_USERS = dir:/tmp/registry
registry:HKEY_CLASSES_ROOT = nt4:/path/to/NTUSER.DAT
registry:HKEY_PERFORMANCE_DATA = w95:/path/to/USER.DAT
(This used to be commit 42844a4e34
)
This commit is contained in:
parent
195f48dcbf
commit
858f176322
@ -896,7 +896,7 @@ static void init_globals(void)
|
|||||||
do_parameter("fstype", FSTYPE_STRING);
|
do_parameter("fstype", FSTYPE_STRING);
|
||||||
do_parameter("ntvfs handler", "unixuid default");
|
do_parameter("ntvfs handler", "unixuid default");
|
||||||
|
|
||||||
do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi");
|
do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg");
|
||||||
do_parameter("server services", "smb rpc");
|
do_parameter("server services", "smb rpc");
|
||||||
do_parameter("auth methods", "guest sam_ignoredomain");
|
do_parameter("auth methods", "guest sam_ignoredomain");
|
||||||
do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE);
|
do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE);
|
||||||
|
@ -23,62 +23,47 @@
|
|||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
#include "rpc_server/common/common.h"
|
#include "rpc_server/common/common.h"
|
||||||
|
|
||||||
/**
|
enum handle_types { HTYPE_REGVAL, HTYPE_REGKEY };
|
||||||
* General notes for the current implementation:
|
|
||||||
*
|
|
||||||
* - All hives are currently openened as subkeys of one single registry file
|
|
||||||
* (e.g. HKCR from \HKEY_CURRENT_USER, etc). This might be changed in
|
|
||||||
* the future and we might want to make it possible to configure
|
|
||||||
* what registries are behind which hives (e.g.
|
|
||||||
* \HKEY_CURRENT_USER -> gconf,
|
|
||||||
* \HKEY_LOCAL_MACHINE -> tdb,
|
|
||||||
* etc
|
|
||||||
*/
|
|
||||||
|
|
||||||
enum handle_types { HTYPE_REGKEY, HTYPE_REGVAL };
|
static void winreg_destroy_hive(struct dcesrv_connection *c, struct dcesrv_handle *h)
|
||||||
|
|
||||||
struct _privatedata {
|
|
||||||
struct registry_context *registry;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* this function is called when the client disconnects the endpoint */
|
|
||||||
static void winreg_unbind(struct dcesrv_connection *dc, const struct dcesrv_interface *di)
|
|
||||||
{
|
{
|
||||||
|
/* FIXME: Free ((struct registry_key *)h->data)->root->hive->reg_ctx */
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS winreg_bind(struct dcesrv_call_state *dc, const struct dcesrv_interface *di)
|
static WERROR winreg_openhive (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, const char *hivename, struct policy_handle **outh)
|
||||||
{
|
{
|
||||||
struct _privatedata *data;
|
struct registry_context *ctx;
|
||||||
|
struct dcesrv_handle *h;
|
||||||
WERROR error;
|
WERROR error;
|
||||||
data = talloc_p(dc->conn, struct _privatedata);
|
const char *conf = lp_parm_string(-1, "registry", hivename);
|
||||||
error = reg_create(&data->registry);
|
char *backend, *location;
|
||||||
|
|
||||||
|
if (!conf) {
|
||||||
|
return WERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: This should happen somewhere after configuration... */
|
backend = talloc_strdup(mem_ctx, conf);
|
||||||
reg_import_hive(data->registry, "nt4", "NTUSER.DAT", "", "HKEY_CURRENT_USER");
|
location = strchr(backend, ':');
|
||||||
reg_import_hive(data->registry, "ldb", "ldb:///", "", "HKEY_LOCAL_MACHINE");
|
|
||||||
|
|
||||||
if(!W_ERROR_IS_OK(error)) return werror_to_ntstatus(error);
|
if (location) {
|
||||||
dc->conn->private = data;
|
*location = '\0';
|
||||||
return NT_STATUS_OK;
|
location++;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = reg_open(&ctx, backend, location, NULL);
|
||||||
|
if(!W_ERROR_IS_OK(error)) return error;
|
||||||
|
|
||||||
|
h = dcesrv_handle_new(dce_call->conn, HTYPE_REGKEY);
|
||||||
|
h->data = ctx->hives[0]->root;
|
||||||
|
SMB_ASSERT(h->data);
|
||||||
|
h->destroy = winreg_destroy_hive;
|
||||||
|
*outh = &h->wire_handle;
|
||||||
|
return WERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DCESRV_INTERFACE_WINREG_BIND winreg_bind
|
|
||||||
#define DCESRV_INTERFACE_WINREG_UNBIND winreg_unbind
|
|
||||||
|
|
||||||
#define func_winreg_OpenHive(k,n) static WERROR winreg_Open ## k (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_Open ## k *r) \
|
#define func_winreg_OpenHive(k,n) static WERROR winreg_Open ## k (struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct winreg_Open ## k *r) \
|
||||||
{ \
|
{ \
|
||||||
struct _privatedata *data = dce_call->conn->private; \
|
return winreg_openhive (dce_call, mem_ctx, n, &r->out.handle);\
|
||||||
struct registry_key *root; \
|
|
||||||
struct dcesrv_handle *h; \
|
|
||||||
WERROR error = reg_get_hive(data->registry, n, &root); \
|
|
||||||
if(!W_ERROR_IS_OK(error)) return error; \
|
|
||||||
\
|
|
||||||
h = dcesrv_handle_new(dce_call->conn, HTYPE_REGKEY); \
|
|
||||||
DCESRV_CHECK_HANDLE(h); \
|
|
||||||
h->data = root; \
|
|
||||||
r->out.handle = &h->wire_handle; \
|
|
||||||
return WERR_OK; \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func_winreg_OpenHive(HKCR,"HKEY_CLASSES_ROOT")
|
func_winreg_OpenHive(HKCR,"HKEY_CLASSES_ROOT")
|
||||||
@ -97,8 +82,9 @@ func_winreg_OpenHive(HKPN,"HKEY_PN")
|
|||||||
static WERROR winreg_CloseKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
static WERROR winreg_CloseKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||||
struct winreg_CloseKey *r)
|
struct winreg_CloseKey *r)
|
||||||
{
|
{
|
||||||
struct dcesrv_handle *h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
|
struct dcesrv_handle *h;
|
||||||
|
|
||||||
|
h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
|
||||||
DCESRV_CHECK_HANDLE(h);
|
DCESRV_CHECK_HANDLE(h);
|
||||||
|
|
||||||
dcesrv_handle_destroy(dce_call->conn, h);
|
dcesrv_handle_destroy(dce_call->conn, h);
|
||||||
@ -113,19 +99,23 @@ static WERROR winreg_CloseKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *me
|
|||||||
static WERROR winreg_CreateKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
static WERROR winreg_CreateKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||||
struct winreg_CreateKey *r)
|
struct winreg_CreateKey *r)
|
||||||
{
|
{
|
||||||
struct dcesrv_handle *h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
|
struct dcesrv_handle *h, *newh;
|
||||||
WERROR error;
|
WERROR error;
|
||||||
struct registry_key *parent;
|
|
||||||
|
|
||||||
|
h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
|
||||||
DCESRV_CHECK_HANDLE(h);
|
DCESRV_CHECK_HANDLE(h);
|
||||||
|
|
||||||
|
newh = dcesrv_handle_new(dce_call->conn, HTYPE_REGKEY);
|
||||||
|
|
||||||
|
error = reg_key_add_name(newh, (struct registry_key *)h->data, r->in.key.name,
|
||||||
|
r->in.access_mask,
|
||||||
|
r->in.sec_desc?r->in.sec_desc->sd:NULL,
|
||||||
|
(struct registry_key **)&newh->data);
|
||||||
|
|
||||||
parent = h->data;
|
|
||||||
error = reg_key_add_name_recursive(parent, r->in.key.name);
|
|
||||||
if(W_ERROR_IS_OK(error)) {
|
if(W_ERROR_IS_OK(error)) {
|
||||||
struct dcesrv_handle *newh = dcesrv_handle_new(dce_call->conn, HTYPE_REGKEY);
|
r->out.handle = &newh->wire_handle;
|
||||||
error = reg_open_key(parent->hive->reg_ctx->mem_ctx, parent, r->in.key.name, (struct registry_key **)&newh->data);
|
} else {
|
||||||
if(W_ERROR_IS_OK(error)) r->out.handle = &newh->wire_handle;
|
dcesrv_handle_destroy(dce_call->conn, newh);
|
||||||
else dcesrv_handle_destroy(dce_call->conn, newh);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
@ -138,14 +128,14 @@ static WERROR winreg_CreateKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
|
|||||||
static WERROR winreg_DeleteKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
static WERROR winreg_DeleteKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||||
struct winreg_DeleteKey *r)
|
struct winreg_DeleteKey *r)
|
||||||
{
|
{
|
||||||
struct dcesrv_handle *h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
|
struct dcesrv_handle *h;
|
||||||
struct registry_key *parent, *key;
|
struct registry_key *key;
|
||||||
WERROR result;
|
WERROR result;
|
||||||
|
|
||||||
|
h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
|
||||||
DCESRV_CHECK_HANDLE(h);
|
DCESRV_CHECK_HANDLE(h);
|
||||||
|
|
||||||
parent = h->data;
|
result = reg_open_key(mem_ctx, (struct registry_key *)h->data, r->in.key.name, &key);
|
||||||
result = reg_open_key(parent->hive->reg_ctx->mem_ctx, parent, r->in.key.name, &key);
|
|
||||||
|
|
||||||
if (W_ERROR_IS_OK(result)) {
|
if (W_ERROR_IS_OK(result)) {
|
||||||
return reg_key_del(key);
|
return reg_key_del(key);
|
||||||
@ -161,6 +151,16 @@ static WERROR winreg_DeleteKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *m
|
|||||||
static WERROR winreg_DeleteValue(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
static WERROR winreg_DeleteValue(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||||
struct winreg_DeleteValue *r)
|
struct winreg_DeleteValue *r)
|
||||||
{
|
{
|
||||||
|
struct dcesrv_handle *h;
|
||||||
|
struct registry_value *value;
|
||||||
|
|
||||||
|
h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGVAL);
|
||||||
|
DCESRV_CHECK_HANDLE(h);
|
||||||
|
|
||||||
|
value = h->data;
|
||||||
|
|
||||||
|
/* FIXME */
|
||||||
|
|
||||||
return WERR_NOT_SUPPORTED;
|
return WERR_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,9 +171,10 @@ static WERROR winreg_DeleteValue(struct dcesrv_call_state *dce_call, TALLOC_CTX
|
|||||||
static WERROR winreg_EnumKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
static WERROR winreg_EnumKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||||
struct winreg_EnumKey *r)
|
struct winreg_EnumKey *r)
|
||||||
{
|
{
|
||||||
struct dcesrv_handle *h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
|
struct dcesrv_handle *h;
|
||||||
struct registry_key *key;
|
struct registry_key *key;
|
||||||
|
|
||||||
|
h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
|
||||||
DCESRV_CHECK_HANDLE(h);
|
DCESRV_CHECK_HANDLE(h);
|
||||||
|
|
||||||
key = h->data;
|
key = h->data;
|
||||||
@ -188,6 +189,7 @@ static WERROR winreg_EnumKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem
|
|||||||
static WERROR winreg_EnumValue(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
static WERROR winreg_EnumValue(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||||
struct winreg_EnumValue *r)
|
struct winreg_EnumValue *r)
|
||||||
{
|
{
|
||||||
|
|
||||||
return WERR_NOT_SUPPORTED;
|
return WERR_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,19 +240,21 @@ static WERROR winreg_NotifyChangeKeyValue(struct dcesrv_call_state *dce_call, TA
|
|||||||
static WERROR winreg_OpenKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
static WERROR winreg_OpenKey(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
|
||||||
struct winreg_OpenKey *r)
|
struct winreg_OpenKey *r)
|
||||||
{
|
{
|
||||||
struct dcesrv_handle *h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
|
struct dcesrv_handle *h, *newh;
|
||||||
struct registry_key *k, *subkey;
|
|
||||||
WERROR result;
|
WERROR result;
|
||||||
|
|
||||||
|
h = dcesrv_handle_fetch(dce_call->conn, r->in.handle, HTYPE_REGKEY);
|
||||||
DCESRV_CHECK_HANDLE(h);
|
DCESRV_CHECK_HANDLE(h);
|
||||||
|
|
||||||
k = h->data;
|
newh = dcesrv_handle_new(dce_call->conn, HTYPE_REGKEY);
|
||||||
|
|
||||||
|
result = reg_open_key(newh, (struct registry_key *)h->data,
|
||||||
|
r->in.keyname.name, (struct registry_key **)&newh->data);
|
||||||
|
|
||||||
result = reg_open_key(k->hive->reg_ctx->mem_ctx, k, r->in.keyname.name, &subkey);
|
|
||||||
if (W_ERROR_IS_OK(result)) {
|
if (W_ERROR_IS_OK(result)) {
|
||||||
h->data = subkey;
|
r->out.handle = &newh->wire_handle;
|
||||||
r->out.handle = &h->wire_handle;
|
} else {
|
||||||
|
dcesrv_handle_destroy(dce_call->conn, newh);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
Loading…
Reference in New Issue
Block a user