1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00

s3-registry: move regf based reg_api calls into own file.

Guenther
This commit is contained in:
Günther Deschner 2010-09-20 02:10:43 +02:00
parent 323f729df0
commit 91e8f8ded2
4 changed files with 313 additions and 276 deletions

View File

@ -620,6 +620,8 @@ REG_INIT_FULL_OBJ = registry/reg_init_full.o
REGFIO_OBJ = registry/regfio.o \
$(REG_PARSE_PRS_OBJ)
REG_API_REGF_OBJ = registry/reg_api_regf.o
REGOBJS_OBJ = registry/reg_objects.o
REG_BACKENDS_BASE_OBJ = registry/reg_backend_db.o
@ -638,7 +640,6 @@ REG_BACKENDS_EXTRA_OBJ = registry/reg_backend_printing.o \
REG_BASE_OBJ = registry/reg_api.o \
registry/reg_dispatcher.o \
registry/reg_cachehook.o \
$(REGFIO_OBJ) \
$(REGOBJS_OBJ) \
registry/reg_util_internal.o \
lib/util_nttoken.o \
@ -756,7 +757,8 @@ PROFILES_OBJ = utils/profiles.o \
$(LIBSMB_ERR_OBJ) \
$(PARAM_OBJ) \
$(LIB_OBJ) $(LIB_DUMMY_OBJ) \
$(POPT_LIB_OBJ)
$(POPT_LIB_OBJ) \
$(REGFIO_OBJ)
OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o \
smbd/oplock_onefs.o
@ -904,6 +906,8 @@ SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \
$(SMBLDAP_OBJ) $(LIBNET_OBJ) \
$(LIBSMBCONF_OBJ) \
$(PRIVILEGES_BASIC_OBJ) \
$(REGFIO_OBJ) \
$(REG_API_REGF_OBJ) \
$(LIBNDR_XATTR_OBJ)
PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/print_aix.o \
@ -1164,6 +1168,7 @@ NET_OBJ = $(NET_OBJ1) \
$(REG_SMBCONF_OBJ) \
$(LIBNET_OBJ) $(LIBNET_DSSYNC_OBJ) $(LIBNET_SAMSYNC_OBJ) \
$(LIBSMBCONF_OBJ) \
$(REGFIO_OBJ) \
$(PRIVILEGES_BASIC_OBJ) \
$(LIB_EVENTLOG_OBJ) localedir.o

View File

@ -169,8 +169,6 @@ WERROR reg_getkeysecurity(TALLOC_CTX *mem_ctx, struct registry_key *key,
WERROR reg_setkeysecurity(struct registry_key *key,
struct security_descriptor *psecdesc);
WERROR reg_getversion(uint32_t *version);
WERROR reg_restorekey(struct registry_key *key, const char *fname);
WERROR reg_savekey(struct registry_key *key, const char *fname);
WERROR reg_deleteallvalues(struct registry_key *key);
WERROR reg_open_path(TALLOC_CTX *mem_ctx, const char *orig_path,
uint32 desired_access, const struct security_token *token,
@ -189,6 +187,11 @@ WERROR reg_create_path(TALLOC_CTX *mem_ctx, const char *orig_path,
WERROR reg_delete_path(const struct security_token *token,
const char *orig_path);
/* The following definitions come from registry/reg_api_regf.c */
WERROR reg_restorekey(struct registry_key *key, const char *fname);
WERROR reg_savekey(struct registry_key *key, const char *fname);
/* The following definitions come from registry/reg_init_basic.c */
WERROR registry_init_common(void);

View File

@ -65,7 +65,6 @@
#include "includes.h"
#include "registry.h"
#include "reg_cachehook.h"
#include "regfio.h"
#include "reg_util_internal.h"
#include "reg_backend_db.h"
#include "reg_dispatcher.h"
@ -748,277 +747,6 @@ WERROR reg_getversion(uint32_t *version)
return WERR_OK;
}
/*******************************************************************
Note: topkeypat is the *full* path that this *key will be
loaded into (including the name of the key)
********************************************************************/
static WERROR reg_load_tree(REGF_FILE *regfile, const char *topkeypath,
REGF_NK_REC *key)
{
REGF_NK_REC *subkey;
struct registry_key_handle registry_key;
struct regval_ctr *values;
struct regsubkey_ctr *subkeys;
int i;
char *path = NULL;
WERROR result = WERR_OK;
/* initialize the struct registry_key_handle structure */
registry_key.ops = reghook_cache_find(topkeypath);
if (!registry_key.ops) {
DEBUG(0, ("reg_load_tree: Failed to assign registry_ops "
"to [%s]\n", topkeypath));
return WERR_BADFILE;
}
registry_key.name = talloc_strdup(regfile->mem_ctx, topkeypath);
if (!registry_key.name) {
DEBUG(0, ("reg_load_tree: Talloc failed for reg_key.name!\n"));
return WERR_NOMEM;
}
/* now start parsing the values and subkeys */
result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys);
W_ERROR_NOT_OK_RETURN(result);
result = regval_ctr_init(subkeys, &values);
W_ERROR_NOT_OK_RETURN(result);
/* copy values into the struct regval_ctr */
for (i=0; i<key->num_values; i++) {
regval_ctr_addvalue(values, key->values[i].valuename,
key->values[i].type,
key->values[i].data,
(key->values[i].data_size & ~VK_DATA_IN_OFFSET));
}
/* copy subkeys into the struct regsubkey_ctr */
key->subkey_index = 0;
while ((subkey = regfio_fetch_subkey( regfile, key ))) {
result = regsubkey_ctr_addkey(subkeys, subkey->keyname);
if (!W_ERROR_IS_OK(result)) {
TALLOC_FREE(subkeys);
return result;
}
}
/* write this key and values out */
if (!store_reg_values(&registry_key, values)
|| !store_reg_keys(&registry_key, subkeys))
{
DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath));
result = WERR_REG_IO_FAILURE;
}
TALLOC_FREE(subkeys);
if (!W_ERROR_IS_OK(result)) {
return result;
}
/* now continue to load each subkey registry tree */
key->subkey_index = 0;
while ((subkey = regfio_fetch_subkey(regfile, key))) {
path = talloc_asprintf(regfile->mem_ctx,
"%s\\%s",
topkeypath,
subkey->keyname);
if (path == NULL) {
return WERR_NOMEM;
}
result = reg_load_tree(regfile, path, subkey);
if (!W_ERROR_IS_OK(result)) {
break;
}
}
return result;
}
/*******************************************************************
********************************************************************/
static WERROR restore_registry_key(struct registry_key_handle *krecord,
const char *fname)
{
REGF_FILE *regfile;
REGF_NK_REC *rootkey;
WERROR result;
/* open the registry file....fail if the file already exists */
regfile = regfio_open(fname, (O_RDONLY), 0);
if (regfile == NULL) {
DEBUG(0, ("restore_registry_key: failed to open \"%s\" (%s)\n",
fname, strerror(errno)));
return ntstatus_to_werror(map_nt_error_from_unix(errno));
}
/* get the rootkey from the regf file and then load the tree
via recursive calls */
if (!(rootkey = regfio_rootkey(regfile))) {
regfio_close(regfile);
return WERR_REG_FILE_INVALID;
}
result = reg_load_tree(regfile, krecord->name, rootkey);
/* cleanup */
regfio_close(regfile);
return result;
}
WERROR reg_restorekey(struct registry_key *key, const char *fname)
{
return restore_registry_key(key->key, fname);
}
/********************************************************************
********************************************************************/
static WERROR reg_write_tree(REGF_FILE *regfile, const char *keypath,
REGF_NK_REC *parent)
{
REGF_NK_REC *key;
struct regval_ctr *values;
struct regsubkey_ctr *subkeys;
int i, num_subkeys;
char *key_tmp = NULL;
char *keyname, *parentpath;
char *subkeypath = NULL;
char *subkeyname;
struct registry_key_handle registry_key;
WERROR result = WERR_OK;
struct security_descriptor *sec_desc = NULL;
if (!regfile) {
return WERR_GENERAL_FAILURE;
}
if (!keypath) {
return WERR_OBJECT_PATH_INVALID;
}
/* split up the registry key path */
key_tmp = talloc_strdup(regfile->mem_ctx, keypath);
if (!key_tmp) {
return WERR_NOMEM;
}
if (!reg_split_key(key_tmp, &parentpath, &keyname)) {
return WERR_OBJECT_PATH_INVALID;
}
if (!keyname) {
keyname = parentpath;
}
/* we need a registry_key_handle object here to enumerate subkeys and values */
ZERO_STRUCT(registry_key);
registry_key.name = talloc_strdup(regfile->mem_ctx, keypath);
if (registry_key.name == NULL) {
return WERR_NOMEM;
}
registry_key.ops = reghook_cache_find(registry_key.name);
if (registry_key.ops == NULL) {
return WERR_BADFILE;
}
/* lookup the values and subkeys */
result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys);
W_ERROR_NOT_OK_RETURN(result);
result = regval_ctr_init(subkeys, &values);
W_ERROR_NOT_OK_RETURN(result);
fetch_reg_keys(&registry_key, subkeys);
fetch_reg_values(&registry_key, values);
result = regkey_get_secdesc(regfile->mem_ctx, &registry_key, &sec_desc);
if (!W_ERROR_IS_OK(result)) {
goto done;
}
/* write out this key */
key = regfio_write_key(regfile, keyname, values, subkeys, sec_desc,
parent);
if (key == NULL) {
result = WERR_CAN_NOT_COMPLETE;
goto done;
}
/* write each one of the subkeys out */
num_subkeys = regsubkey_ctr_numkeys(subkeys);
for (i=0; i<num_subkeys; i++) {
subkeyname = regsubkey_ctr_specific_key(subkeys, i);
subkeypath = talloc_asprintf(regfile->mem_ctx, "%s\\%s",
keypath, subkeyname);
if (subkeypath == NULL) {
result = WERR_NOMEM;
goto done;
}
result = reg_write_tree(regfile, subkeypath, key);
if (!W_ERROR_IS_OK(result))
goto done;
}
DEBUG(6, ("reg_write_tree: wrote key [%s]\n", keypath));
done:
TALLOC_FREE(subkeys);
TALLOC_FREE(registry_key.name);
return result;
}
static WERROR backup_registry_key(struct registry_key_handle *krecord,
const char *fname)
{
REGF_FILE *regfile;
WERROR result;
/* open the registry file....fail if the file already exists */
regfile = regfio_open(fname, (O_RDWR|O_CREAT|O_EXCL),
(S_IREAD|S_IWRITE));
if (regfile == NULL) {
DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n",
fname, strerror(errno) ));
return ntstatus_to_werror(map_nt_error_from_unix(errno));
}
/* write the registry tree to the file */
result = reg_write_tree(regfile, krecord->name, NULL);
/* cleanup */
regfio_close(regfile);
return result;
}
WERROR reg_savekey(struct registry_key *key, const char *fname)
{
return backup_registry_key(key->key, fname);
}
/**********************************************************************
* Higher level utility functions
**********************************************************************/

View File

@ -0,0 +1,301 @@
/*
* Unix SMB/CIFS implementation.
* Virtual Windows Registry Layer
* Copyright (C) Volker Lendecke 2006
* Copyright (C) Michael Adam 2007-2008
*
* 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 "includes.h"
#include "registry.h"
#include "reg_cachehook.h"
#include "regfio.h"
#include "reg_util_internal.h"
#include "reg_dispatcher.h"
#include "reg_objects.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_REGISTRY
/*******************************************************************
Note: topkeypat is the *full* path that this *key will be
loaded into (including the name of the key)
********************************************************************/
static WERROR reg_load_tree(REGF_FILE *regfile, const char *topkeypath,
REGF_NK_REC *key)
{
REGF_NK_REC *subkey;
struct registry_key_handle registry_key;
struct regval_ctr *values;
struct regsubkey_ctr *subkeys;
int i;
char *path = NULL;
WERROR result = WERR_OK;
/* initialize the struct registry_key_handle structure */
registry_key.ops = reghook_cache_find(topkeypath);
if (!registry_key.ops) {
DEBUG(0, ("reg_load_tree: Failed to assign registry_ops "
"to [%s]\n", topkeypath));
return WERR_BADFILE;
}
registry_key.name = talloc_strdup(regfile->mem_ctx, topkeypath);
if (!registry_key.name) {
DEBUG(0, ("reg_load_tree: Talloc failed for reg_key.name!\n"));
return WERR_NOMEM;
}
/* now start parsing the values and subkeys */
result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys);
W_ERROR_NOT_OK_RETURN(result);
result = regval_ctr_init(subkeys, &values);
W_ERROR_NOT_OK_RETURN(result);
/* copy values into the struct regval_ctr */
for (i=0; i<key->num_values; i++) {
regval_ctr_addvalue(values, key->values[i].valuename,
key->values[i].type,
key->values[i].data,
(key->values[i].data_size & ~VK_DATA_IN_OFFSET));
}
/* copy subkeys into the struct regsubkey_ctr */
key->subkey_index = 0;
while ((subkey = regfio_fetch_subkey( regfile, key ))) {
result = regsubkey_ctr_addkey(subkeys, subkey->keyname);
if (!W_ERROR_IS_OK(result)) {
TALLOC_FREE(subkeys);
return result;
}
}
/* write this key and values out */
if (!store_reg_values(&registry_key, values)
|| !store_reg_keys(&registry_key, subkeys))
{
DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath));
result = WERR_REG_IO_FAILURE;
}
TALLOC_FREE(subkeys);
if (!W_ERROR_IS_OK(result)) {
return result;
}
/* now continue to load each subkey registry tree */
key->subkey_index = 0;
while ((subkey = regfio_fetch_subkey(regfile, key))) {
path = talloc_asprintf(regfile->mem_ctx,
"%s\\%s",
topkeypath,
subkey->keyname);
if (path == NULL) {
return WERR_NOMEM;
}
result = reg_load_tree(regfile, path, subkey);
if (!W_ERROR_IS_OK(result)) {
break;
}
}
return result;
}
/*******************************************************************
********************************************************************/
static WERROR restore_registry_key(struct registry_key_handle *krecord,
const char *fname)
{
REGF_FILE *regfile;
REGF_NK_REC *rootkey;
WERROR result;
/* open the registry file....fail if the file already exists */
regfile = regfio_open(fname, (O_RDONLY), 0);
if (regfile == NULL) {
DEBUG(0, ("restore_registry_key: failed to open \"%s\" (%s)\n",
fname, strerror(errno)));
return ntstatus_to_werror(map_nt_error_from_unix(errno));
}
/* get the rootkey from the regf file and then load the tree
via recursive calls */
if (!(rootkey = regfio_rootkey(regfile))) {
regfio_close(regfile);
return WERR_REG_FILE_INVALID;
}
result = reg_load_tree(regfile, krecord->name, rootkey);
/* cleanup */
regfio_close(regfile);
return result;
}
WERROR reg_restorekey(struct registry_key *key, const char *fname)
{
return restore_registry_key(key->key, fname);
}
/********************************************************************
********************************************************************/
static WERROR reg_write_tree(REGF_FILE *regfile, const char *keypath,
REGF_NK_REC *parent)
{
REGF_NK_REC *key;
struct regval_ctr *values;
struct regsubkey_ctr *subkeys;
int i, num_subkeys;
char *key_tmp = NULL;
char *keyname, *parentpath;
char *subkeypath = NULL;
char *subkeyname;
struct registry_key_handle registry_key;
WERROR result = WERR_OK;
struct security_descriptor *sec_desc = NULL;
if (!regfile) {
return WERR_GENERAL_FAILURE;
}
if (!keypath) {
return WERR_OBJECT_PATH_INVALID;
}
/* split up the registry key path */
key_tmp = talloc_strdup(regfile->mem_ctx, keypath);
if (!key_tmp) {
return WERR_NOMEM;
}
if (!reg_split_key(key_tmp, &parentpath, &keyname)) {
return WERR_OBJECT_PATH_INVALID;
}
if (!keyname) {
keyname = parentpath;
}
/* we need a registry_key_handle object here to enumerate subkeys and values */
ZERO_STRUCT(registry_key);
registry_key.name = talloc_strdup(regfile->mem_ctx, keypath);
if (registry_key.name == NULL) {
return WERR_NOMEM;
}
registry_key.ops = reghook_cache_find(registry_key.name);
if (registry_key.ops == NULL) {
return WERR_BADFILE;
}
/* lookup the values and subkeys */
result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys);
W_ERROR_NOT_OK_RETURN(result);
result = regval_ctr_init(subkeys, &values);
W_ERROR_NOT_OK_RETURN(result);
fetch_reg_keys(&registry_key, subkeys);
fetch_reg_values(&registry_key, values);
result = regkey_get_secdesc(regfile->mem_ctx, &registry_key, &sec_desc);
if (!W_ERROR_IS_OK(result)) {
goto done;
}
/* write out this key */
key = regfio_write_key(regfile, keyname, values, subkeys, sec_desc,
parent);
if (key == NULL) {
result = WERR_CAN_NOT_COMPLETE;
goto done;
}
/* write each one of the subkeys out */
num_subkeys = regsubkey_ctr_numkeys(subkeys);
for (i=0; i<num_subkeys; i++) {
subkeyname = regsubkey_ctr_specific_key(subkeys, i);
subkeypath = talloc_asprintf(regfile->mem_ctx, "%s\\%s",
keypath, subkeyname);
if (subkeypath == NULL) {
result = WERR_NOMEM;
goto done;
}
result = reg_write_tree(regfile, subkeypath, key);
if (!W_ERROR_IS_OK(result))
goto done;
}
DEBUG(6, ("reg_write_tree: wrote key [%s]\n", keypath));
done:
TALLOC_FREE(subkeys);
TALLOC_FREE(registry_key.name);
return result;
}
static WERROR backup_registry_key(struct registry_key_handle *krecord,
const char *fname)
{
REGF_FILE *regfile;
WERROR result;
/* open the registry file....fail if the file already exists */
regfile = regfio_open(fname, (O_RDWR|O_CREAT|O_EXCL),
(S_IREAD|S_IWRITE));
if (regfile == NULL) {
DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n",
fname, strerror(errno) ));
return ntstatus_to_werror(map_nt_error_from_unix(errno));
}
/* write the registry tree to the file */
result = reg_write_tree(regfile, krecord->name, NULL);
/* cleanup */
regfio_close(regfile);
return result;
}
WERROR reg_savekey(struct registry_key *key, const char *fname)
{
return backup_registry_key(key->key, fname);
}