summaryrefslogtreecommitdiff
path: root/source3/registry
diff options
context:
space:
mode:
Diffstat (limited to 'source3/registry')
-rw-r--r--source3/registry/reg_api.c231
-rw-r--r--source3/registry/reg_backend_current_version.c81
-rw-r--r--source3/registry/reg_backend_db.c (renamed from source3/registry/reg_db.c)71
-rw-r--r--source3/registry/reg_backend_hkpt_params.c70
-rw-r--r--source3/registry/reg_backend_netlogon_params.c57
-rw-r--r--source3/registry/reg_backend_perflib.c106
-rw-r--r--source3/registry/reg_backend_printing.c (renamed from source3/registry/reg_printing.c)9
-rw-r--r--source3/registry/reg_backend_prod_options.c70
-rw-r--r--source3/registry/reg_backend_shares.c (renamed from source3/registry/reg_shares.c)9
-rw-r--r--source3/registry/reg_backend_smbconf.c (renamed from source3/registry/reg_smbconf.c)14
-rw-r--r--source3/registry/reg_backend_tcpip_params.c67
-rw-r--r--source3/registry/reg_cachehook.c23
-rw-r--r--source3/registry/reg_dispatcher.c (renamed from source3/registry/reg_frontend_hilvl.c)85
-rw-r--r--source3/registry/reg_dynamic.c264
-rw-r--r--source3/registry/reg_frontend.c202
-rw-r--r--source3/registry/reg_init_full.c103
-rw-r--r--source3/registry/reg_init_smbconf.c97
-rw-r--r--source3/registry/reg_util_legacy.c47
-rw-r--r--source3/registry/regfio.c7
19 files changed, 1040 insertions, 573 deletions
diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c
index b3d024d7b4..9c4009368d 100644
--- a/source3/registry/reg_api.c
+++ b/source3/registry/reg_api.c
@@ -1,33 +1,83 @@
-/*
+/*
* 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/>.
*/
/* Attempt to wrap the existing API in a more winreg.idl-like way */
+/*
+ * Here is a list of winreg.idl functions and corresponding implementations
+ * provided here:
+ *
+ * 0x00 winreg_OpenHKCR
+ * 0x01 winreg_OpenHKCU
+ * 0x02 winreg_OpenHKLM
+ * 0x03 winreg_OpenHKPD
+ * 0x04 winreg_OpenHKU
+ * 0x05 winreg_CloseKey
+ * 0x06 winreg_CreateKey reg_createkey
+ * 0x07 winreg_DeleteKey reg_deletekey
+ * 0x08 winreg_DeleteValue reg_deletevalue
+ * 0x09 winreg_EnumKey reg_enumkey
+ * 0x0a winreg_EnumValue reg_enumvalue
+ * 0x0b winreg_FlushKey
+ * 0x0c winreg_GetKeySecurity reg_getkeysecurity
+ * 0x0d winreg_LoadKey
+ * 0x0e winreg_NotifyChangeKeyValue
+ * 0x0f winreg_OpenKey reg_openkey
+ * 0x10 winreg_QueryInfoKey reg_queryinfokey
+ * 0x11 winreg_QueryValue reg_queryvalue
+ * 0x12 winreg_ReplaceKey
+ * 0x13 winreg_RestoreKey
+ * 0x14 winreg_SaveKey
+ * 0x15 winreg_SetKeySecurity reg_setkeysecurity
+ * 0x16 winreg_SetValue reg_setvalue
+ * 0x17 winreg_UnLoadKey
+ * 0x18 winreg_InitiateSystemShutdown
+ * 0x19 winreg_AbortSystemShutdown
+ * 0x1a winreg_GetVersion reg_getversion
+ * 0x1b winreg_OpenHKCC
+ * 0x1c winreg_OpenHKDD
+ * 0x1d winreg_QueryMultipleValues
+ * 0x1e winreg_InitiateSystemShutdownEx
+ * 0x1f winreg_SaveKeyEx
+ * 0x20 winreg_OpenHKPT
+ * 0x21 winreg_OpenHKPN
+ * 0x22 winreg_QueryMultipleValues2
+ *
+ */
+
#include "includes.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_REGISTRY
+
+/**********************************************************************
+ * Helper functions
+ **********************************************************************/
+
static WERROR fill_value_cache(struct registry_key *key)
{
if (key->values != NULL) {
- return WERR_OK;
+ if (!reg_values_need_update(key->key, key->values)) {
+ return WERR_OK;
+ }
}
if (!(key->values = TALLOC_ZERO_P(key, REGVAL_CTR))) {
@@ -44,7 +94,9 @@ static WERROR fill_value_cache(struct registry_key *key)
static WERROR fill_subkey_cache(struct registry_key *key)
{
if (key->subkeys != NULL) {
- return WERR_OK;
+ if (!reg_subkeys_need_update(key->key, key->subkeys)) {
+ return WERR_OK;
+ }
}
if (!(key->subkeys = TALLOC_ZERO_P(key, REGSUBKEY_CTR))) {
@@ -131,12 +183,12 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx,
/* Look up the table of registry I/O operations */
if ( !(key->hook = reghook_cache_find( key->name )) ) {
- DEBUG(0,("reg_open_onelevel: Failed to assigned a "
+ DEBUG(0,("reg_open_onelevel: Failed to assign a "
"REGISTRY_HOOK to [%s]\n", key->name ));
result = WERR_BADFILE;
goto done;
}
-
+
/* check if the path really exists; failed is indicated by -1 */
/* if the subkey count failed, bail out */
@@ -149,7 +201,7 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx,
result = WERR_BADFILE;
goto done;
}
-
+
TALLOC_FREE( subkeys );
if ( !regkey_access_check( key, access_desired, &key->access_granted,
@@ -182,6 +234,11 @@ WERROR reg_openhive(TALLOC_CTX *mem_ctx, const char *hive,
pkey);
}
+
+/**********************************************************************
+ * The API functions
+ **********************************************************************/
+
WERROR reg_openkey(TALLOC_CTX *mem_ctx, struct registry_key *parent,
const char *name, uint32 desired_access,
struct registry_key **pkey)
@@ -298,7 +355,7 @@ WERROR reg_enumvalue(TALLOC_CTX *mem_ctx, struct registry_key *key,
SAFE_FREE(val);
return WERR_NOMEM;
}
-
+
*pval = val;
return WERR_OK;
}
@@ -378,7 +435,7 @@ WERROR reg_queryinfokey(struct registry_key *key, uint32_t *num_subkeys,
return err;
}
- *secdescsize = sec_desc_size(secdesc);
+ *secdescsize = ndr_size_security_descriptor(secdesc, 0);
TALLOC_FREE(mem_ctx);
*last_changed_time = 0;
@@ -396,7 +453,6 @@ WERROR reg_createkey(TALLOC_CTX *ctx, struct registry_key *parent,
TALLOC_CTX *mem_ctx;
char *path, *end;
WERROR err;
- REGSUBKEY_CTR *subkeys;
if (!(mem_ctx = talloc_new(ctx))) return WERR_NOMEM;
@@ -460,11 +516,6 @@ WERROR reg_createkey(TALLOC_CTX *ctx, struct registry_key *parent,
* Actually create the subkey
*/
- if (!(subkeys = TALLOC_ZERO_P(mem_ctx, REGSUBKEY_CTR))) {
- err = WERR_NOMEM;
- goto done;
- }
-
err = fill_subkey_cache(create_parent);
if (!W_ERROR_IS_OK(err)) goto done;
@@ -490,7 +541,6 @@ WERROR reg_createkey(TALLOC_CTX *ctx, struct registry_key *parent,
TALLOC_FREE(mem_ctx);
return err;
}
-
WERROR reg_deletekey(struct registry_key *parent, const char *path)
{
@@ -624,6 +674,32 @@ WERROR reg_deletevalue(struct registry_key *key, const char *name)
return WERR_OK;
}
+WERROR reg_getkeysecurity(TALLOC_CTX *mem_ctx, struct registry_key *key,
+ struct security_descriptor **psecdesc)
+{
+ return regkey_get_secdesc(mem_ctx, key->key, psecdesc);
+}
+
+WERROR reg_setkeysecurity(struct registry_key *key,
+ struct security_descriptor *psecdesc)
+{
+ return regkey_set_secdesc(key->key, psecdesc);
+}
+
+WERROR reg_getversion(uint32_t *version)
+{
+ if (version == NULL) {
+ return WERR_INVALID_PARAM;
+ }
+
+ *version = 0x00000005; /* Windows 2000 registry API version */
+ return WERR_OK;
+}
+
+/**********************************************************************
+ * Higher level utility functions
+ **********************************************************************/
+
WERROR reg_deleteallvalues(struct registry_key *key)
{
WERROR err;
@@ -708,14 +784,14 @@ WERROR reg_open_path(TALLOC_CTX *mem_ctx, const char *orig_path,
}
/*
- * Utility function to delete a registry key with all its subkeys.
- * Note that reg_deletekey returns ACCESS_DENIED when called on a
+ * Utility function to delete a registry key with all its subkeys.
+ * Note that reg_deletekey returns ACCESS_DENIED when called on a
* key that has subkeys.
*/
-WERROR reg_deletekey_recursive_internal(TALLOC_CTX *ctx,
- struct registry_key *parent,
- const char *path,
- bool del_key)
+static WERROR reg_deletekey_recursive_internal(TALLOC_CTX *ctx,
+ struct registry_key *parent,
+ const char *path,
+ bool del_key)
{
TALLOC_CTX *mem_ctx = NULL;
WERROR werr = WERR_OK;
@@ -729,17 +805,17 @@ WERROR reg_deletekey_recursive_internal(TALLOC_CTX *ctx,
}
/* recurse through subkeys first */
- werr = reg_openkey(mem_ctx, parent, path, REG_KEY_WRITE, &key);
+ werr = reg_openkey(mem_ctx, parent, path, REG_KEY_ALL, &key);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
while (W_ERROR_IS_OK(werr = reg_enumkey(mem_ctx, key, 0,
- &subkey_name, NULL)))
+ &subkey_name, NULL)))
{
werr = reg_deletekey_recursive_internal(mem_ctx, key,
subkey_name,
- True);
+ true);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
@@ -767,12 +843,111 @@ WERROR reg_deletekey_recursive(TALLOC_CTX *ctx,
struct registry_key *parent,
const char *path)
{
- return reg_deletekey_recursive_internal(ctx, parent, path, True);
+ return reg_deletekey_recursive_internal(ctx, parent, path, true);
}
WERROR reg_deletesubkeys_recursive(TALLOC_CTX *ctx,
struct registry_key *parent,
const char *path)
{
- return reg_deletekey_recursive_internal(ctx, parent, path, False);
+ return reg_deletekey_recursive_internal(ctx, parent, path, false);
+}
+
+#if 0
+/* these two functions are unused. */
+
+/**
+ * Utility function to create a registry key without opening the hive
+ * before. Assumes the hive already exists.
+ */
+
+WERROR reg_create_path(TALLOC_CTX *mem_ctx, const char *orig_path,
+ uint32 desired_access,
+ const struct nt_user_token *token,
+ enum winreg_CreateAction *paction,
+ struct registry_key **pkey)
+{
+ struct registry_key *hive;
+ char *path, *p;
+ WERROR err;
+
+ if (!(path = SMB_STRDUP(orig_path))) {
+ return WERR_NOMEM;
+ }
+
+ p = strchr(path, '\\');
+
+ if ((p == NULL) || (p[1] == '\0')) {
+ /*
+ * No key behind the hive, just return the hive
+ */
+
+ err = reg_openhive(mem_ctx, path, desired_access, token,
+ &hive);
+ if (!W_ERROR_IS_OK(err)) {
+ SAFE_FREE(path);
+ return err;
+ }
+ SAFE_FREE(path);
+ *pkey = hive;
+ *paction = REG_OPENED_EXISTING_KEY;
+ return WERR_OK;
+ }
+
+ *p = '\0';
+
+ err = reg_openhive(mem_ctx, path,
+ (strchr(p+1, '\\') != NULL) ?
+ SEC_RIGHTS_ENUM_SUBKEYS : SEC_RIGHTS_CREATE_SUBKEY,
+ token, &hive);
+ if (!W_ERROR_IS_OK(err)) {
+ SAFE_FREE(path);
+ return err;
+ }
+
+ err = reg_createkey(mem_ctx, hive, p+1, desired_access, pkey, paction);
+ SAFE_FREE(path);
+ TALLOC_FREE(hive);
+ return err;
+}
+
+/*
+ * Utility function to create a registry key without opening the hive
+ * before. Will not delete a hive.
+ */
+
+WERROR reg_delete_path(const struct nt_user_token *token,
+ const char *orig_path)
+{
+ struct registry_key *hive;
+ char *path, *p;
+ WERROR err;
+
+ if (!(path = SMB_STRDUP(orig_path))) {
+ return WERR_NOMEM;
+ }
+
+ p = strchr(path, '\\');
+
+ if ((p == NULL) || (p[1] == '\0')) {
+ SAFE_FREE(path);
+ return WERR_INVALID_PARAM;
+ }
+
+ *p = '\0';
+
+ err = reg_openhive(NULL, path,
+ (strchr(p+1, '\\') != NULL) ?
+ SEC_RIGHTS_ENUM_SUBKEYS : SEC_RIGHTS_CREATE_SUBKEY,
+ token, &hive);
+ if (!W_ERROR_IS_OK(err)) {
+ SAFE_FREE(path);
+ return err;
+ }
+
+ err = reg_deletekey(hive, p+1);
+ SAFE_FREE(path);
+ TALLOC_FREE(hive);
+ return err;
}
+#endif /* #if 0 */
diff --git a/source3/registry/reg_backend_current_version.c b/source3/registry/reg_backend_current_version.c
new file mode 100644
index 0000000000..a9d281c522
--- /dev/null
+++ b/source3/registry/reg_backend_current_version.c
@@ -0,0 +1,81 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Virtual Windows Registry Layer
+ * Copyright (C) Gerald Carter 2002-2005
+ * Copyright (C) Michael Adam 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/>.
+ */
+
+/*
+ * CurrentVersion registry backend.
+ *
+ * This is a virtual overlay, dynamically presenting version information.
+ */
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_REGISTRY
+
+extern REGISTRY_OPS regdb_ops;
+
+#define KEY_CURRENT_VERSION_NORM "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION"
+
+static int current_version_fetch_values(const char *key, REGVAL_CTR *values)
+{
+ const char *sysroot_string = "c:\\Windows";
+ fstring sysversion;
+ fstring value;
+ uint32 value_length;
+ char *path = NULL;
+ TALLOC_CTX *ctx = talloc_tos();
+
+ path = talloc_strdup(ctx, key);
+ if (path == NULL) {
+ return -1;
+ }
+ path = normalize_reg_path(ctx, path);
+ if (path == NULL) {
+ return -1;
+ }
+
+ if (strncmp(path, KEY_CURRENT_VERSION_NORM, strlen(path)) != 0) {
+ return 0;
+ }
+
+ value_length = push_ucs2(value, value, sysroot_string, sizeof(value),
+ STR_TERMINATE|STR_NOALIGN );
+ regval_ctr_addvalue(values, "SystemRoot", REG_SZ, value, value_length);
+
+ fstr_sprintf(sysversion, "%d.%d", lp_major_announce_version(),
+ lp_minor_announce_version());
+ value_length = push_ucs2(value, value, sysversion, sizeof(value),
+ STR_TERMINATE|STR_NOALIGN);
+ regval_ctr_addvalue(values, "CurrentVersion", REG_SZ, value,
+ value_length);
+
+ return regval_ctr_numvals(values);
+}
+
+static int current_version_fetch_subkeys(const char *key,
+ REGSUBKEY_CTR *subkey_ctr)
+{
+ return regdb_ops.fetch_subkeys(key, subkey_ctr);
+}
+
+REGISTRY_OPS current_version_reg_ops = {
+ .fetch_values = current_version_fetch_values,
+ .fetch_subkeys = current_version_fetch_subkeys,
+};
diff --git a/source3/registry/reg_db.c b/source3/registry/reg_backend_db.c
index 25c6557c87..e162fb587f 100644
--- a/source3/registry/reg_db.c
+++ b/source3/registry/reg_backend_db.c
@@ -44,17 +44,17 @@ static const char *builtin_registry_paths[] = {
KEY_SHARES,
KEY_EVENTLOG,
KEY_SMBCONF,
- "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib",
- "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009",
+ KEY_PERFLIB,
+ KEY_PERFLIB_009,
"HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors",
- "HKLM\\SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
+ KEY_PROD_OPTIONS,
"HKLM\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration",
- "HKLM\\SYSTEM\\CurrentControlSet\\Services\\TcpIp\\Parameters",
- "HKLM\\SYSTEM\\CurrentControlSet\\Services\\Netlogon\\Parameters",
- "HKU",
- "HKCR",
- "HKPD",
- "HKPT",
+ KEY_TCPIP_PARAMS,
+ KEY_NETLOGON_PARAMS,
+ KEY_HKU,
+ KEY_HKCR,
+ KEY_HKPD,
+ KEY_HKPT,
NULL };
struct builtin_regkey_value {
@@ -259,7 +259,7 @@ bool regdb_init( void )
uint32 vers_id;
if ( tdb_reg )
- return True;
+ return true;
if ( !(tdb_reg = tdb_wrap_open(NULL, state_path("registry.tdb"), 0, REG_TDB_FLAGS, O_RDWR, 0600)) )
{
@@ -267,7 +267,7 @@ bool regdb_init( void )
if ( !tdb_reg ) {
DEBUG(0,("regdb_init: Failed to open registry %s (%s)\n",
state_path("registry.tdb"), strerror(errno) ));
- return False;
+ return false;
}
DEBUG(10,("regdb_init: Successfully created registry tdb\n"));
@@ -286,11 +286,11 @@ bool regdb_init( void )
/* always setup the necessary keys and values */
if ( !init_registry_data() ) {
- DEBUG(0,("init_registry: Failed to initialize data in registry!\n"));
- return False;
+ DEBUG(0,("regdb_init: Failed to initialize data in registry!\n"));
+ return false;
}
- return True;
+ return true;
}
/***********************************************************************
@@ -329,6 +329,10 @@ WERROR regdb_open( void )
int regdb_close( void )
{
+ if (tdb_refcount == 0) {
+ return 0;
+ }
+
tdb_refcount--;
DEBUG(10,("regdb_close: decrementing refcount (%d)\n", tdb_refcount));
@@ -364,7 +368,7 @@ static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr)
uint8 *buffer = NULL;
int i = 0;
uint32 len, buflen;
- bool ret = True;
+ bool ret = true;
uint32 num_subkeys = regsubkey_ctr_numkeys(ctr);
char *keyname = NULL;
TALLOC_CTX *ctx = talloc_tos();
@@ -382,7 +386,7 @@ static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr)
/* allocate some initial memory */
if (!(buffer = (uint8 *)SMB_MALLOC(1024))) {
- return False;
+ return false;
}
buflen = 1024;
len = 0;
@@ -399,7 +403,7 @@ static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr)
/* allocate some extra space */
if ((buffer = (uint8 *)SMB_REALLOC( buffer, len*2 )) == NULL) {
DEBUG(0,("regdb_store_keys: Failed to realloc memory of size [%d]\n", len*2));
- ret = False;
+ ret = false;
goto done;
}
buflen = len*2;
@@ -413,7 +417,7 @@ static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr)
dbuf.dptr = buffer;
dbuf.dsize = len;
if ( tdb_store_bystring( tdb_reg->tdb, keyname, dbuf, TDB_REPLACE ) == -1) {
- ret = False;
+ ret = false;
goto done;
}
@@ -618,7 +622,15 @@ int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr)
}
strupper_m(path);
+ if (tdb_read_lock_bystring_with_timeout(tdb_reg->tdb, path, 10) == -1) {
+ return 0;
+ }
+
dbuf = tdb_fetch_bystring(tdb_reg->tdb, path);
+ ctr->seqnum = regdb_get_seqnum();
+
+ tdb_read_unlock_bystring(tdb_reg->tdb, path);
+
buf = dbuf.dptr;
buflen = dbuf.dsize;
@@ -746,7 +758,14 @@ int regdb_fetch_values( const char* key, REGVAL_CTR *values )
return 0;
}
+ if (tdb_read_lock_bystring_with_timeout(tdb_reg->tdb, keystr, 10) == -1) {
+ return 0;
+ }
+
data = tdb_fetch_bystring(tdb_reg->tdb, keystr);
+ values->seqnum = regdb_get_seqnum();
+
+ tdb_read_unlock_bystring(tdb_reg->tdb, keystr);
if (!data.dptr) {
/* all keys have zero values by default */
@@ -801,7 +820,7 @@ bool regdb_store_values( const char *key, REGVAL_CTR *values )
&& (memcmp(old_data.dptr, data.dptr, data.dsize) == 0)) {
SAFE_FREE(old_data.dptr);
SAFE_FREE(data.dptr);
- return True;
+ return true;
}
ret = tdb_trans_store_bystring(tdb_reg->tdb, keystr, data, TDB_REPLACE);
@@ -903,6 +922,16 @@ static WERROR regdb_set_secdesc(const char *key,
return err;
}
+bool regdb_subkeys_need_update(REGSUBKEY_CTR *subkeys)
+{
+ return (regdb_get_seqnum() != subkeys->seqnum);
+}
+
+bool regdb_values_need_update(REGVAL_CTR *values)
+{
+ return (regdb_get_seqnum() != values->seqnum);
+}
+
/*
* Table of function pointers for default access
*/
@@ -914,5 +943,7 @@ REGISTRY_OPS regdb_ops = {
regdb_store_values,
NULL,
regdb_get_secdesc,
- regdb_set_secdesc
+ regdb_set_secdesc,
+ regdb_subkeys_need_update,
+ regdb_values_need_update
};
diff --git a/source3/registry/reg_backend_hkpt_params.c b/source3/registry/reg_backend_hkpt_params.c
new file mode 100644
index 0000000000..2ed5e78e1c
--- /dev/null
+++ b/source3/registry/reg_backend_hkpt_params.c
@@ -0,0 +1,70 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Virtual Windows Registry Layer
+ * Copyright (C) Gerald Carter 2002-2005
+ * Copyright (C) Michael Adam 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/>.
+ */
+
+/*
+ * HKPT parameters registry backend.
+ *
+ * This replaces the former dynamic hkpt parameters overlay.
+ */
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_REGISTRY
+
+extern REGISTRY_OPS regdb_ops;
+
+static int hkpt_params_fetch_values(const char *key, REGVAL_CTR *regvals)
+{
+ uint32 base_index;
+ uint32 buffer_size;
+ char *buffer = NULL;
+
+ /* This is ALMOST the same as perflib_009_params, but HKPT has
+ a "Counters" entry instead of a "Counter" key. <Grrrr> */
+
+ base_index = reg_perfcount_get_base_index();
+ buffer_size = reg_perfcount_get_counter_names(base_index, &buffer);
+ regval_ctr_addvalue(regvals, "Counters", REG_MULTI_SZ, buffer,
+ buffer_size);
+
+ if(buffer_size > 0) {
+ SAFE_FREE(buffer);
+ }
+
+ buffer_size = reg_perfcount_get_counter_help(base_index, &buffer);
+ regval_ctr_addvalue(regvals, "Help", REG_MULTI_SZ, buffer, buffer_size);
+ if(buffer_size > 0) {
+ SAFE_FREE(buffer);
+ }
+
+ return regval_ctr_numvals( regvals );
+}
+
+static int hkpt_params_fetch_subkeys(const char *key,
+ REGSUBKEY_CTR *subkey_ctr)
+{
+ return regdb_ops.fetch_subkeys(key, subkey_ctr);
+}
+
+REGISTRY_OPS hkpt_params_reg_ops = {
+ .fetch_values = hkpt_params_fetch_values,
+ .fetch_subkeys = hkpt_params_fetch_subkeys,
+};
diff --git a/source3/registry/reg_backend_netlogon_params.c b/source3/registry/reg_backend_netlogon_params.c
new file mode 100644
index 0000000000..71f88144c8
--- /dev/null
+++ b/source3/registry/reg_backend_netlogon_params.c
@@ -0,0 +1,57 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Virtual Windows Registry Layer
+ * Copyright (C) Gerald Carter 2002-2005
+ * Copyright (C) Michael Adam 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/>.
+ */
+
+/*
+ * Netlogon parameters registry backend.
+ *
+ * This replaces the former dynamic netlogon parameters overlay.
+ */
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_REGISTRY
+
+extern REGISTRY_OPS regdb_ops;
+
+static int netlogon_params_fetch_values(const char *key, REGVAL_CTR *regvals)
+{
+ uint32 dwValue;
+
+ if (!pdb_get_account_policy(AP_REFUSE_MACHINE_PW_CHANGE, &dwValue)) {
+ dwValue = 0;
+ }
+
+ regval_ctr_addvalue(regvals, "RefusePasswordChange", REG_DWORD,
+ (char*)&dwValue, sizeof(dwValue));
+
+ return regval_ctr_numvals(regvals);
+}
+
+static int netlogon_params_fetch_subkeys(const char *key,
+ REGSUBKEY_CTR *subkey_ctr)
+{
+ return regdb_ops.fetch_subkeys(key, subkey_ctr);
+}
+
+REGISTRY_OPS netlogon_params_reg_ops = {
+ .fetch_values = netlogon_params_fetch_values,
+ .fetch_subkeys = netlogon_params_fetch_subkeys,
+};
diff --git a/source3/registry/reg_backend_perflib.c b/source3/registry/reg_backend_perflib.c
new file mode 100644
index 0000000000..999bca2682
--- /dev/null
+++ b/source3/registry/reg_backend_perflib.c
@@ -0,0 +1,106 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Virtual Windows Registry Layer
+ * Copyright (C) Gerald Carter 2002-2005
+ * Copyright (C) Michael Adam 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/>.
+ */
+
+/*
+ * perflib registry backend.
+ *
+ * This is a virtual overlay, dynamically presenting perflib values.
+ */
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_REGISTRY
+
+extern REGISTRY_OPS regdb_ops;
+
+#define KEY_PERFLIB_NORM "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB"
+#define KEY_PERFLIB_009_NORM "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB/009"
+
+static int perflib_params( REGVAL_CTR *regvals )
+{
+ int base_index = -1;
+ int last_counter = -1;
+ int last_help = -1;
+ int version = 0x00010001;
+
+ base_index = reg_perfcount_get_base_index();
+ regval_ctr_addvalue(regvals, "Base Index", REG_DWORD, (char *)&base_index, sizeof(base_index));
+ last_counter = reg_perfcount_get_last_counter(base_index);
+ regval_ctr_addvalue(regvals, "Last Counter", REG_DWORD, (char *)&last_counter, sizeof(last_counter));
+ last_help = reg_perfcount_get_last_help(last_counter);
+ regval_ctr_addvalue(regvals, "Last Help", REG_DWORD, (char *)&last_help, sizeof(last_help));
+ regval_ctr_addvalue(regvals, "Version", REG_DWORD, (char *)&version, sizeof(version));
+
+ return regval_ctr_numvals( regvals );
+}
+
+static int perflib_009_params( REGVAL_CTR *regvals )
+{
+ int base_index;
+ int buffer_size;
+ char *buffer = NULL;
+
+ base_index = reg_perfcount_get_base_index();
+ buffer_size = reg_perfcount_get_counter_names(base_index, &buffer);
+ regval_ctr_addvalue(regvals, "Counter", REG_MULTI_SZ, buffer, buffer_size);
+ if(buffer_size > 0)
+ SAFE_FREE(buffer);
+ buffer_size = reg_perfcount_get_counter_help(base_index, &buffer);
+ regval_ctr_addvalue(regvals, "Help", REG_MULTI_SZ, buffer, buffer_size);
+ if(buffer_size > 0)
+ SAFE_FREE(buffer);
+
+ return regval_ctr_numvals( regvals );
+}
+
+static int perflib_fetch_values(const char *key, REGVAL_CTR *regvals)
+{
+ char *path = NULL;
+ TALLOC_CTX *ctx = talloc_tos();
+
+ path = talloc_strdup(ctx, key);
+ if (path == NULL) {
+ return -1;
+ }
+ path = normalize_reg_path(ctx, path);
+ if (path == NULL) {
+ return -1;
+ }
+
+ if (strncmp(path, KEY_PERFLIB_NORM, strlen(path)) == 0) {
+ return perflib_params(regvals);
+ } else if (strncmp(path, KEY_PERFLIB_009_NORM, strlen(path)) == 0) {
+ return perflib_009_params(regvals);
+ } else {
+ return 0;
+ }
+}
+
+static int perflib_fetch_subkeys(const char *key,
+ REGSUBKEY_CTR *subkey_ctr)
+{
+ return regdb_ops.fetch_subkeys(key, subkey_ctr);
+}
+
+REGISTRY_OPS perflib_reg_ops = {
+ .fetch_values = perflib_fetch_values,
+ .fetch_subkeys = perflib_fetch_subkeys,
+};
diff --git a/source3/registry/reg_printing.c b/source3/registry/reg_backend_printing.c
index 2ca74f7c16..a4da103d40 100644
--- a/source3/registry/reg_printing.c
+++ b/source3/registry/reg_backend_printing.c
@@ -1262,9 +1262,8 @@ static bool regprint_store_reg_values( const char *key, REGVAL_CTR *values )
*/
REGISTRY_OPS printing_ops = {
- regprint_fetch_reg_keys,
- regprint_fetch_reg_values,
- regprint_store_reg_keys,
- regprint_store_reg_values,
- NULL, NULL, NULL
+ .fetch_subkeys = regprint_fetch_reg_keys,
+ .fetch_values = regprint_fetch_reg_values,
+ .store_subkeys = regprint_store_reg_keys,
+ .store_values = regprint_store_reg_values,
};
diff --git a/source3/registry/reg_backend_prod_options.c b/source3/registry/reg_backend_prod_options.c
new file mode 100644
index 0000000000..7ac5c5b4b9
--- /dev/null
+++ b/source3/registry/reg_backend_prod_options.c
@@ -0,0 +1,70 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Virtual Windows Registry Layer
+ * Copyright (C) Gerald Carter 2002-2005
+ * Copyright (C) Michael Adam 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/>.
+ */
+
+/*
+ * Product options registry backend.
+ *
+ * This replaces the former dynamic product options overlay.
+ */
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_REGISTRY
+
+extern REGISTRY_OPS regdb_ops;
+
+static int prod_options_fetch_values(const char *key, REGVAL_CTR *regvals)
+{
+ const char *value_ascii = "";
+ fstring value;
+ int value_length;
+
+ switch (lp_server_role()) {
+ case ROLE_DOMAIN_PDC:
+ case ROLE_DOMAIN_BDC:
+ value_ascii = "LanmanNT";
+ break;
+ case ROLE_STANDALONE:
+ value_ascii = "ServerNT";
+ break;
+ case ROLE_DOMAIN_MEMBER:
+ value_ascii = "WinNT";
+ break;
+ }
+
+ value_length = push_ucs2(value, value, value_ascii, sizeof(value),
+ STR_TERMINATE|STR_NOALIGN );
+ regval_ctr_addvalue(regvals, "ProductType", REG_SZ, value,
+ value_length);
+
+ return regval_ctr_numvals( regvals );
+}
+
+static int prod_options_fetch_subkeys(const char *key,
+ REGSUBKEY_CTR *subkey_ctr)
+{
+ return regdb_ops.fetch_subkeys(key, subkey_ctr);
+}
+
+REGISTRY_OPS prod_options_reg_ops = {
+ .fetch_values = prod_options_fetch_values,
+ .fetch_subkeys = prod_options_fetch_subkeys,
+};
diff --git a/source3/registry/reg_shares.c b/source3/registry/reg_backend_shares.c
index 178f23e21c..ee9e5dc5a1 100644
--- a/source3/registry/reg_shares.c
+++ b/source3/registry/reg_backend_shares.c
@@ -155,11 +155,10 @@ static bool shares_store_value( const char *key, REGVAL_CTR *val )
*/
REGISTRY_OPS shares_reg_ops = {
- shares_subkey_info,
- shares_value_info,
- shares_store_subkey,
- shares_store_value,
- NULL, NULL, NULL
+ .fetch_subkeys = shares_subkey_info,
+ .fetch_values = shares_value_info,
+ .store_subkeys = shares_store_subkey,
+ .store_values = shares_store_value,
};
diff --git a/source3/registry/reg_smbconf.c b/source3/registry/reg_backend_smbconf.c
index 116cde936e..a6e478200f 100644
--- a/source3/registry/reg_smbconf.c
+++ b/source3/registry/reg_backend_smbconf.c
@@ -265,11 +265,11 @@ static WERROR smbconf_set_secdesc(const char *key,
*/
REGISTRY_OPS smbconf_reg_ops = {
- smbconf_fetch_keys,
- smbconf_fetch_values,
- smbconf_store_keys,
- smbconf_store_values,
- smbconf_reg_access_check,
- smbconf_get_secdesc,
- smbconf_set_secdesc
+ .fetch_subkeys = smbconf_fetch_keys,
+ .fetch_values = smbconf_fetch_values,
+ .store_subkeys = smbconf_store_keys,
+ .store_values = smbconf_store_values,
+ .reg_access_check = smbconf_reg_access_check,
+ .get_secdesc = smbconf_get_secdesc,
+ .set_secdesc = smbconf_set_secdesc,
};
diff --git a/source3/registry/reg_backend_tcpip_params.c b/source3/registry/reg_backend_tcpip_params.c
new file mode 100644
index 0000000000..db7df5dd8f
--- /dev/null
+++ b/source3/registry/reg_backend_tcpip_params.c
@@ -0,0 +1,67 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Virtual Windows Registry Layer
+ * Copyright (C) Gerald Carter 2002-2005
+ * Copyright (C) Michael Adam 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/>.
+ */
+
+/*
+ * TCP/IP parameters registry backend.
+ *
+ * This replaces the former dynamic tcpip parameters overlay.
+ */
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_REGISTRY
+
+extern REGISTRY_OPS regdb_ops;
+
+static int tcpip_params_fetch_values(const char *key, REGVAL_CTR *regvals)
+{
+ fstring value;
+ int value_length;
+ char *hname;
+ char *mydomainname = NULL;
+
+ hname = myhostname();
+ value_length = push_ucs2(value, value, hname, sizeof(value),
+ STR_TERMINATE|STR_NOALIGN);
+ regval_ctr_addvalue(regvals, "Hostname",REG_SZ, value, value_length);
+
+ mydomainname = get_mydnsdomname(talloc_tos());
+ if (!mydomainname) {
+ return -1;
+ }
+
+ value_length = push_ucs2(value, value, mydomainname, sizeof(value),
+ STR_TERMINATE|STR_NOALIGN);
+ regval_ctr_addvalue(regvals, "Domain", REG_SZ, value, value_length);
+
+ return regval_ctr_numvals(regvals);
+}
+
+static int tcpip_params_fetch_subkeys(const char *key,
+ REGSUBKEY_CTR *subkey_ctr)
+{
+ return regdb_ops.fetch_subkeys(key, subkey_ctr);
+}
+
+REGISTRY_OPS tcpip_params_reg_ops = {
+ .fetch_values = tcpip_params_fetch_values,
+ .fetch_subkeys = tcpip_params_fetch_subkeys,
+};
diff --git a/source3/registry/reg_cachehook.c b/source3/registry/reg_cachehook.c
index 289d4e50ce..f9851c7810 100644
--- a/source3/registry/reg_cachehook.c
+++ b/source3/registry/reg_cachehook.c
@@ -25,19 +25,26 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_REGISTRY
-static SORTED_TREE *cache_tree;
+static SORTED_TREE *cache_tree = NULL;
extern REGISTRY_OPS regdb_ops; /* these are the default */
static REGISTRY_HOOK default_hook = { KEY_TREE_ROOT, &regdb_ops };
/**********************************************************************
- Initialize the cache tree
+ Initialize the cache tree if it has not been initialized yet.
*********************************************************************/
bool reghook_cache_init( void )
{
- cache_tree = pathtree_init( &default_hook, NULL );
+ if (cache_tree == NULL) {
+ cache_tree = pathtree_init(&default_hook, NULL);
+ if (cache_tree !=0) {
+ DEBUG(10, ("reghook_cache_init: new tree with default "
+ "ops %p for key [%s]\n", (void *)&regdb_ops,
+ KEY_TREE_ROOT));
+ }
+ }
- return ( cache_tree == NULL );
+ return (cache_tree != NULL);
}
/**********************************************************************
@@ -54,7 +61,7 @@ bool reghook_cache_add( REGISTRY_HOOK *hook )
return false;
}
- key = talloc_asprintf(ctx, "//%s", hook->keyname);
+ key = talloc_asprintf(ctx, "\\%s", hook->keyname);
if (!key) {
return false;
}
@@ -63,7 +70,8 @@ bool reghook_cache_add( REGISTRY_HOOK *hook )
return false;
}
- DEBUG(10,("reghook_cache_add: Adding key [%s]\n", key));
+ DEBUG(10, ("reghook_cache_add: Adding ops %p for key [%s]\n",
+ (void *)hook->ops, key));
return pathtree_add( cache_tree, key, hook );
}
@@ -100,6 +108,9 @@ REGISTRY_HOOK* reghook_cache_find( const char *keyname )
DEBUG(10,("reghook_cache_find: Searching for keyname [%s]\n", key));
hook = (REGISTRY_HOOK *)pathtree_find( cache_tree, key ) ;
+
+ DEBUG(10, ("reghook_cache_find: found ops %p for key [%s]\n",
+ hook ? (void *)hook->ops : 0, key));
SAFE_FREE( key );
diff --git a/source3/registry/reg_frontend_hilvl.c b/source3/registry/reg_dispatcher.c
index a4b78b24c0..e6e7613457 100644
--- a/source3/registry/reg_frontend_hilvl.c
+++ b/source3/registry/reg_dispatcher.c
@@ -1,25 +1,25 @@
-/*
+/*
* Unix SMB/CIFS implementation.
* Virtual Windows Registry Layer
* Copyright (C) Gerald Carter 2002-2005
- * Copyright (C) Michael Adam 2006
+ * Copyright (C) Michael Adam 2006-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/>.
*/
-/*
- * Implementation of registry frontend view functions.
+/*
+ * Implementation of registry frontend view functions.
* Functions moved from reg_frontend.c to minimize linker deps.
*/
@@ -44,12 +44,12 @@ static SEC_DESC* construct_registry_sd( TALLOC_CTX *ctx )
size_t sd_size;
/* basic access for Everyone */
-
+
init_sec_access(&mask, REG_KEY_READ );
init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
-
+
/* Full Access 'BUILTIN\Administrators' */
-
+
init_sec_access(&mask, REG_KEY_ALL );
init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
@@ -58,9 +58,8 @@ static SEC_DESC* construct_registry_sd( TALLOC_CTX *ctx )
init_sec_access(&mask, REG_KEY_ALL );
init_sec_ace(&ace[i++], &global_sid_System, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
-
/* create the security descriptor */
-
+
if ( !(acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) )
return NULL;
@@ -73,29 +72,25 @@ static SEC_DESC* construct_registry_sd( TALLOC_CTX *ctx )
/***********************************************************************
High level wrapper function for storing registry subkeys
***********************************************************************/
-
+
bool store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys )
{
if ( key->hook && key->hook->ops && key->hook->ops->store_subkeys )
return key->hook->ops->store_subkeys( key->name, subkeys );
-
- return False;
+ return false;
}
/***********************************************************************
High level wrapper function for storing registry values
***********************************************************************/
-
+
bool store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
{
- if ( check_dynamic_reg_values( key ) )
- return False;
-
if ( key->hook && key->hook->ops && key->hook->ops->store_values )
return key->hook->ops->store_values( key->name, val );
- return False;
+ return false;
}
/***********************************************************************
@@ -106,7 +101,7 @@ bool store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr )
{
int result = -1;
-
+
if ( key->hook && key->hook->ops && key->hook->ops->fetch_subkeys )
result = key->hook->ops->fetch_subkeys( key->name, subkey_ctr );
@@ -120,23 +115,18 @@ int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr )
int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
{
int result = -1;
-
+
+ DEBUG(10, ("fetch_reg_values called for key '%s' (ops %p)\n", key->name,
+ (key->hook && key->hook->ops) ? (void *)key->hook->ops : NULL));
+
if ( key->hook && key->hook->ops && key->hook->ops->fetch_values )
result = key->hook->ops->fetch_values( key->name, val );
-
- /* if the backend lookup returned no data, try the dynamic overlay */
-
- if ( result == 0 ) {
- result = fetch_dynamic_reg_values( key, val );
- return ( result != -1 ) ? result : 0;
- }
-
return result;
}
/***********************************************************************
- High level access check for passing the required access mask to the
+ High level access check for passing the required access mask to the
underlying registry backend
***********************************************************************/
@@ -161,21 +151,21 @@ bool regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted,
*/
if (!(mem_ctx = talloc_init("regkey_access_check"))) {
- return False;
+ return false;
}
err = regkey_get_secdesc(mem_ctx, key, &sec_desc);
if (!W_ERROR_IS_OK(err)) {
TALLOC_FREE(mem_ctx);
- return False;
+ return false;
}
se_map_generic( &requested, &reg_generic_map );
if (!se_access_check(sec_desc, token, requested, granted, &status)) {
TALLOC_FREE(mem_ctx);
- return False;
+ return false;
}
TALLOC_FREE(mem_ctx);
@@ -214,3 +204,32 @@ WERROR regkey_set_secdesc(REGISTRY_KEY *key,
return WERR_ACCESS_DENIED;
}
+
+/**
+ * Check whether the in-memory version of the subkyes of a
+ * registry key needs update from disk.
+ */
+bool reg_subkeys_need_update(REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys)
+{
+ if (key->hook && key->hook->ops && key->hook->ops->subkeys_need_update)
+ {
+ return key->hook->ops->subkeys_need_update(subkeys);
+ }
+
+ return false;
+}
+
+/**
+ * Check whether the in-memory version of the values of a
+ * registry key needs update from disk.
+ */
+bool reg_values_need_update(REGISTRY_KEY *key, REGVAL_CTR *values)
+{
+ if (key->hook && key->hook->ops && key->hook->ops->values_need_update)
+ {
+ return key->hook->ops->values_need_update(values);
+ }
+
+ return false;
+}
+
diff --git a/source3/registry/reg_dynamic.c b/source3/registry/reg_dynamic.c
deleted file mode 100644
index e70bd178f9..0000000000
--- a/source3/registry/reg_dynamic.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * Virtual Windows Registry Layer
- * Copyright (C) Gerald Carter 2002-2005
- *
- * 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/>.
- */
-
-/* Implementation of registry frontend view functions. */
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_REGISTRY
-
-struct reg_dyn_values {
- const char *path;
- int (*fetch_values) ( REGVAL_CTR *val );
-};
-
-/***********************************************************************
-***********************************************************************/
-
-static int netlogon_params( REGVAL_CTR *regvals )
-{
- uint32 dwValue;
-
- if ( !pdb_get_account_policy(AP_REFUSE_MACHINE_PW_CHANGE, &dwValue) )
- dwValue = 0;
-
- regval_ctr_addvalue( regvals, "RefusePasswordChange", REG_DWORD,
- (char*)&dwValue, sizeof(dwValue) );
-
- return regval_ctr_numvals( regvals );
-}
-
-/***********************************************************************
-***********************************************************************/
-
-static int prod_options( REGVAL_CTR *regvals )
-{
- const char *value_ascii = "";
- fstring value;
- int value_length;
-
- switch (lp_server_role()) {
- case ROLE_DOMAIN_PDC:
- case ROLE_DOMAIN_BDC:
- value_ascii = "LanmanNT";
- break;
- case ROLE_STANDALONE:
- value_ascii = "ServerNT";
- break;
- case ROLE_DOMAIN_MEMBER:
- value_ascii = "WinNT";
- break;
- }
-
- value_length = push_ucs2( value, value, value_ascii, sizeof(value),
- STR_TERMINATE|STR_NOALIGN );
- regval_ctr_addvalue( regvals, "ProductType", REG_SZ, value,
- value_length );
-
- return regval_ctr_numvals( regvals );
-}
-
-/***********************************************************************
-***********************************************************************/
-
-static int tcpip_params( REGVAL_CTR *regvals )
-{
- fstring value;
- int value_length;
- char *hname;
- char *mydomainname = NULL;
-
- hname = myhostname();
- value_length = push_ucs2( value, value, hname, sizeof(value), STR_TERMINATE|STR_NOALIGN);
- regval_ctr_addvalue( regvals, "Hostname",REG_SZ, value, value_length );
-
- mydomainname = get_mydnsdomname(talloc_tos());
- if (!mydomainname) {
- return -1;
- }
-
- value_length = push_ucs2( value, value, mydomainname, sizeof(value), STR_TERMINATE|STR_NOALIGN);
- regval_ctr_addvalue( regvals, "Domain", REG_SZ, value, value_length );
-
- return regval_ctr_numvals( regvals );
-}
-
-/***********************************************************************
-***********************************************************************/
-
-static int perflib_params( REGVAL_CTR *regvals )
-{
- int base_index = -1;
- int last_counter = -1;
- int last_help = -1;
- int version = 0x00010001;
-
- base_index = reg_perfcount_get_base_index();
- regval_ctr_addvalue(regvals, "Base Index", REG_DWORD, (char *)&base_index, sizeof(base_index));
- last_counter = reg_perfcount_get_last_counter(base_index);
- regval_ctr_addvalue(regvals, "Last Counter", REG_DWORD, (char *)&last_counter, sizeof(last_counter));
- last_help = reg_perfcount_get_last_help(last_counter);
- regval_ctr_addvalue(regvals, "Last Help", REG_DWORD, (char *)&last_help, sizeof(last_help));
- regval_ctr_addvalue(regvals, "Version", REG_DWORD, (char *)&version, sizeof(version));
-
- return regval_ctr_numvals( regvals );
-}
-
-/***********************************************************************
-***********************************************************************/
-
-static int perflib_009_params( REGVAL_CTR *regvals )
-{
- int base_index;
- int buffer_size;
- char *buffer = NULL;
-
- base_index = reg_perfcount_get_base_index();
- buffer_size = reg_perfcount_get_counter_names(base_index, &buffer);
- regval_ctr_addvalue(regvals, "Counter", REG_MULTI_SZ, buffer, buffer_size);
- if(buffer_size > 0)
- SAFE_FREE(buffer);
- buffer_size = reg_perfcount_get_counter_help(base_index, &buffer);
- regval_ctr_addvalue(regvals, "Help", REG_MULTI_SZ, buffer, buffer_size);
- if(buffer_size > 0)
- SAFE_FREE(buffer);
-
- return regval_ctr_numvals( regvals );
-}
-
-/***********************************************************************
-***********************************************************************/
-
-static int hkpt_params( REGVAL_CTR *regvals )
-{
- uint32 base_index;
- uint32 buffer_size;
- char *buffer = NULL;
-
- /* This is ALMOST the same as perflib_009_params, but HKPT has
- a "Counters" entry instead of a "Counter" key. <Grrrr> */
-
- base_index = reg_perfcount_get_base_index();
- buffer_size = reg_perfcount_get_counter_names(base_index, &buffer);
- regval_ctr_addvalue(regvals, "Counters", REG_MULTI_SZ, buffer, buffer_size);
-
- if(buffer_size > 0)
- SAFE_FREE(buffer);
-
- buffer_size = reg_perfcount_get_counter_help(base_index, &buffer);
- regval_ctr_addvalue(regvals, "Help", REG_MULTI_SZ, buffer, buffer_size);
- if(buffer_size > 0)
- SAFE_FREE(buffer);
-
- return regval_ctr_numvals( regvals );
-}
-
-/***********************************************************************
-***********************************************************************/
-
-static int current_version( REGVAL_CTR *values )
-{
- const char *sysroot_string = "c:\\Windows";
- fstring sysversion;
- fstring value;
- uint32 value_length;
-
- value_length = push_ucs2( value, value, sysroot_string, sizeof(value),
- STR_TERMINATE|STR_NOALIGN );
- regval_ctr_addvalue( values, "SystemRoot", REG_SZ, value, value_length );
-
- fstr_sprintf( sysversion, "%d.%d", lp_major_announce_version(), lp_minor_announce_version() );
- value_length = push_ucs2( value, value, sysversion, sizeof(value),
- STR_TERMINATE|STR_NOALIGN );
- regval_ctr_addvalue( values, "CurrentVersion", REG_SZ, value, value_length );
-
-
- return regval_ctr_numvals( values );
-}
-
-
-/***********************************************************************
- Structure holding the registry paths and pointers to the value
- enumeration functions
-***********************************************************************/
-
-static struct reg_dyn_values dynamic_values[] = {
- { "HKLM/SYSTEM/CURRENTCONTROLSET/SERVICES/NETLOGON/PARAMETERS", &netlogon_params },
- { "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRODUCTOPTIONS", &prod_options },
- { "HKLM/SYSTEM/CURRENTCONTROLSET/SERVICES/TCPIP/PARAMETERS", &tcpip_params },
- { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB", &perflib_params },
- { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB/009", &perflib_009_params },
- { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION", &current_version },
- { "HKPT", &hkpt_params },
- { NULL, NULL }
-};
-
-/***********************************************************************
-***********************************************************************/
-
-int fetch_dynamic_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
-{
- int i;
- char *path = NULL;
- TALLOC_CTX *ctx = talloc_tos();
-
- path = talloc_strdup(ctx, key->name);
- if (!path) {
- return -1;
- }
- path = normalize_reg_path(ctx, path);
- if (!path) {
- return -1;
- }
-
- for ( i=0; dynamic_values[i].path; i++ ) {
- if ( strcmp( path, dynamic_values[i].path ) == 0 )
- return dynamic_values[i].fetch_values( val );
- }
-
- return -1;
-}
-
-/***********************************************************************
-***********************************************************************/
-
-bool check_dynamic_reg_values( REGISTRY_KEY *key )
-{
- int i;
- char *path = NULL;
- TALLOC_CTX *ctx = talloc_tos();
-
- path = talloc_strdup(ctx, key->name);
- if (!path) {
- return false;
- }
- path = normalize_reg_path(ctx, path);
- if (!path) {
- return false;
- }
-
- for ( i=0; dynamic_values[i].path; i++ ) {
- /* can't write to dynamic keys */
- if ( strcmp( path, dynamic_values[i].path ) == 0 )
- return true;
- }
-
- return false;
-}
diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c
deleted file mode 100644
index 40d9192b08..0000000000
--- a/source3/registry/reg_frontend.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- * Virtual Windows Registry Layer
- * Copyright (C) Gerald Carter 2002-2005
- *
- * 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/>.
- */
-
-/* Implementation of registry frontend view functions. */
-
-#include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_REGISTRY
-
-extern REGISTRY_OPS printing_ops;
-extern REGISTRY_OPS eventlog_ops;
-extern REGISTRY_OPS shares_reg_ops;
-extern REGISTRY_OPS smbconf_reg_ops;
-extern REGISTRY_OPS regdb_ops; /* these are the default */
-
-/* array of REGISTRY_HOOK's which are read into a tree for easy access */
-/* #define REG_TDB_ONLY 1 */
-
-REGISTRY_HOOK reg_hooks[] = {
-#ifndef REG_TDB_ONLY
- { KEY_PRINTING, &printing_ops },
- { KEY_PRINTING_2K, &printing_ops },
- { KEY_PRINTING_PORTS, &printing_ops },
- { KEY_SHARES, &shares_reg_ops },
- { KEY_SMBCONF, &smbconf_reg_ops },
-#endif
- { NULL, NULL }
-};
-
-/***********************************************************************
- Open the registry database and initialize the REGISTRY_HOOK cache
- ***********************************************************************/
-
-bool init_registry( void )
-{
- int i;
- bool ret = false;
- TALLOC_CTX *frame = talloc_stackframe();
-
-
- if ( !regdb_init() ) {
- DEBUG(0,("init_registry: failed to initialize the registry tdb!\n"));
- goto fail;
- }
-
- /* build the cache tree of registry hooks */
-
- reghook_cache_init();
-
- for ( i=0; reg_hooks[i].keyname; i++ ) {
- if ( !reghook_cache_add(&reg_hooks[i]) )
- goto fail;
- }
-
- if ( DEBUGLEVEL >= 20 )
- reghook_dump_cache(20);
-
- /* add any keys for other services */
-
- svcctl_init_keys();
- eventlog_init_keys();
- perfcount_init_keys();
-
- /* close and let each smbd open up as necessary */
-
- regdb_close();
-
- ret = true;
- fail:
- TALLOC_FREE(frame);
- return ret;
-}
-
-WERROR regkey_open_internal( TALLOC_CTX *ctx, REGISTRY_KEY **regkey,
- const char *path,
- const struct nt_user_token *token,
- uint32 access_desired )
-{
- struct registry_key *key;
- WERROR err;
-
- err = reg_open_path(NULL, path, access_desired, token, &key);
- if (!W_ERROR_IS_OK(err)) {
- return err;
- }
-
- *regkey = talloc_move(ctx, &key->key);
- TALLOC_FREE(key);
- return WERR_OK;
-}
-
-/*
- * Utility function to create a registry key without opening the hive
- * before. Assumes the hive already exists.
- */
-
-WERROR reg_create_path(TALLOC_CTX *mem_ctx, const char *orig_path,
- uint32 desired_access,
- const struct nt_user_token *token,
- enum winreg_CreateAction *paction,
- struct registry_key **pkey)
-{
- struct registry_key *hive;
- char *path, *p;
- WERROR err;
-
- if (!(path = SMB_STRDUP(orig_path))) {
- return WERR_NOMEM;
- }
-
- p = strchr(path, '\\');
-
- if ((p == NULL) || (p[1] == '\0')) {
- /*
- * No key behind the hive, just return the hive
- */
-
- err = reg_openhive(mem_ctx, path, desired_access, token,
- &hive);
- if (!W_ERROR_IS_OK(err)) {
- SAFE_FREE(path);
- return err;
- }
- SAFE_FREE(path);
- *pkey = hive;
- *paction = REG_OPENED_EXISTING_KEY;
- return WERR_OK;
- }
-
- *p = '\0';
-
- err = reg_openhive(mem_ctx, path,
- (strchr(p+1, '\\') != NULL) ?
- SEC_RIGHTS_ENUM_SUBKEYS : SEC_RIGHTS_CREATE_SUBKEY,
- token, &hive);
- if (!W_ERROR_IS_OK(err)) {
- SAFE_FREE(path);
- return err;
- }
-
- err = reg_createkey(mem_ctx, hive, p+1, desired_access, pkey, paction);
- SAFE_FREE(path);
- TALLOC_FREE(hive);
- return err;
-}
-
-/*
- * Utility function to create a registry key without opening the hive
- * before. Will not delete a hive.
- */
-
-WERROR reg_delete_path(const struct nt_user_token *token,
- const char *orig_path)
-{
- struct registry_key *hive;
- char *path, *p;
- WERROR err;
-
- if (!(path = SMB_STRDUP(orig_path))) {
- return WERR_NOMEM;
- }
-
- p = strchr(path, '\\');
-
- if ((p == NULL) || (p[1] == '\0')) {
- SAFE_FREE(path);
- return WERR_INVALID_PARAM;
- }
-
- *p = '\0';
-
- err = reg_openhive(NULL, path,
- (strchr(p+1, '\\') != NULL) ?
- SEC_RIGHTS_ENUM_SUBKEYS : SEC_RIGHTS_CREATE_SUBKEY,
- token, &hive);
- if (!W_ERROR_IS_OK(err)) {
- SAFE_FREE(path);
- return err;
- }
-
- err = reg_deletekey(hive, p+1);
- SAFE_FREE(path);
- TALLOC_FREE(hive);
- return err;
-}
diff --git a/source3/registry/reg_init_full.c b/source3/registry/reg_init_full.c
new file mode 100644
index 0000000000..b6a644bb11
--- /dev/null
+++ b/source3/registry/reg_init_full.c
@@ -0,0 +1,103 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Virtual Windows Registry Layer
+ * Copyright (C) Gerald Carter 2002-2005
+ * Copyright (C) Michael Adam 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/>.
+ */
+
+/* Initialize the registry with all available backends. */
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_REGISTRY
+
+extern REGISTRY_OPS printing_ops;
+extern REGISTRY_OPS eventlog_ops;
+extern REGISTRY_OPS shares_reg_ops;
+extern REGISTRY_OPS smbconf_reg_ops;
+extern REGISTRY_OPS netlogon_params_reg_ops;
+extern REGISTRY_OPS prod_options_reg_ops;
+extern REGISTRY_OPS tcpip_params_reg_ops;
+extern REGISTRY_OPS hkpt_params_reg_ops;
+extern REGISTRY_OPS current_version_reg_ops;
+extern REGISTRY_OPS perflib_reg_ops;
+extern REGISTRY_OPS regdb_ops; /* these are the default */
+
+/* array of REGISTRY_HOOK's which are read into a tree for easy access */
+/* #define REG_TDB_ONLY 1 */
+
+REGISTRY_HOOK reg_hooks[] = {
+#ifndef REG_TDB_ONLY
+ { KEY_PRINTING, &printing_ops },
+ { KEY_PRINTING_2K, &printing_ops },
+ { KEY_PRINTING_PORTS, &printing_ops },
+ { KEY_SHARES, &shares_reg_ops },
+ { KEY_SMBCONF, &smbconf_reg_ops },
+ { KEY_NETLOGON_PARAMS, &netlogon_params_reg_ops },
+ { KEY_PROD_OPTIONS, &prod_options_reg_ops },
+ { KEY_TCPIP_PARAMS, &tcpip_params_reg_ops },
+ { KEY_HKPT, &hkpt_params_reg_ops },
+ { KEY_CURRENT_VERSION, &current_version_reg_ops },
+ { KEY_PERFLIB, &perflib_reg_ops },
+#endif
+ { NULL, NULL }
+};
+
+/***********************************************************************
+ Open the registry database and initialize the REGISTRY_HOOK cache
+ with all available backens.
+ ***********************************************************************/
+
+bool init_registry( void )
+{
+ int i;
+ bool ret = false;
+ TALLOC_CTX *frame = talloc_stackframe();
+
+
+ if ( !regdb_init() ) {
+ DEBUG(0,("init_registry: failed to initialize the registry tdb!\n"));
+ goto fail;
+ }
+
+ /* build the cache tree of registry hooks */
+
+ reghook_cache_init();
+
+ for ( i=0; reg_hooks[i].keyname; i++ ) {
+ if ( !reghook_cache_add(&reg_hooks[i]) )
+ goto fail;
+ }
+
+ if ( DEBUGLEVEL >= 20 )
+ reghook_dump_cache(20);
+
+ /* add any keys for other services */
+
+ svcctl_init_keys();
+ eventlog_init_keys();
+ perfcount_init_keys();
+
+ /* close and let each smbd open up as necessary */
+
+ regdb_close();
+
+ ret = true;
+ fail:
+ TALLOC_FREE(frame);
+ return ret;
+}
diff --git a/source3/registry/reg_init_smbconf.c b/source3/registry/reg_init_smbconf.c
new file mode 100644
index 0000000000..6452b0b15b
--- /dev/null
+++ b/source3/registry/reg_init_smbconf.c
@@ -0,0 +1,97 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Registry helper routines
+ * Copyright (C) Michael Adam 2007
+ *
+ * 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"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_REGISTRY
+
+extern REGISTRY_OPS smbconf_reg_ops;
+
+/*
+ * create a fake token just with enough rights to
+ * locally access the registry:
+ *
+ * - builtin administrators sid
+ * - disk operators privilege
+ */
+NTSTATUS registry_create_admin_token(TALLOC_CTX *mem_ctx,
+ NT_USER_TOKEN **ptoken)
+{
+ NTSTATUS status;
+ NT_USER_TOKEN *token = NULL;
+
+ if (ptoken == NULL) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ token = TALLOC_ZERO_P(mem_ctx, NT_USER_TOKEN);
+ if (token == NULL) {
+ DEBUG(1, ("talloc failed\n"));
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+ token->privileges = se_disk_operators;
+ status = add_sid_to_array(token, &global_sid_Builtin_Administrators,
+ &token->user_sids, &token->num_sids);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("Error adding builtin administrators sid "
+ "to fake token.\n"));
+ goto done;
+ }
+
+ *ptoken = token;
+
+done:
+ return status;
+}
+
+/*
+ * init the smbconf portion of the registry.
+ * for use in places where not the whole registry is needed,
+ * e.g. utils/net_conf.c and loadparm.c
+ */
+bool registry_init_regdb(void)
+{
+ bool ret = false;
+ int saved_errno = 0;
+ static REGISTRY_HOOK smbconf_reg_hook = {KEY_SMBCONF, &smbconf_reg_ops};
+
+ DEBUG(10, ("registry_init_regdb called\n"));
+
+ if (!regdb_init()) {
+ saved_errno = errno;
+ DEBUG(1, ("Can't open the registry"));
+ if (saved_errno) {
+ DEBUGADD(1, (": %s", strerror(saved_errno)));
+ }
+ DEBUGADD(1, (".\n"));
+ goto done;
+ }
+ reghook_cache_init();
+ if (!reghook_cache_add(&smbconf_reg_hook)) {
+ DEBUG(1, ("Error adding smbconf reghooks to reghook cache.\n"));
+ goto done;
+ }
+
+ ret = true;
+
+done:
+ return ret;
+}
diff --git a/source3/registry/reg_util_legacy.c b/source3/registry/reg_util_legacy.c
new file mode 100644
index 0000000000..3e68025ae9
--- /dev/null
+++ b/source3/registry/reg_util_legacy.c
@@ -0,0 +1,47 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Virtual Windows Registry Layer
+ * Copyright (C) Gerald Carter 2002-2005
+ *
+ * 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/>.
+ */
+
+/* Implementation of registry frontend view functions. */
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_REGISTRY
+
+/**
+ * legacy open key function that should be replaced by uses of
+ * reg_open_path
+ */
+WERROR regkey_open_internal( TALLOC_CTX *ctx, REGISTRY_KEY **regkey,
+ const char *path,
+ const struct nt_user_token *token,
+ uint32 access_desired )
+{
+ struct registry_key *key;
+ WERROR err;
+
+ err = reg_open_path(NULL, path, access_desired, token, &key);
+ if (!W_ERROR_IS_OK(err)) {
+ return err;
+ }
+
+ *regkey = talloc_move(ctx, &key->key);
+ TALLOC_FREE(key);
+ return WERR_OK;
+}
diff --git a/source3/registry/regfio.c b/source3/registry/regfio.c
index 22700e6481..3740ff0ee4 100644
--- a/source3/registry/regfio.c
+++ b/source3/registry/regfio.c
@@ -1234,7 +1234,7 @@ static void regfio_mem_free( REGF_FILE *file )
/* cleanup for a file opened for write */
- if ( file->open_flags & (O_WRONLY|O_RDWR) ) {
+ if ((file->fd != -1) && (file->open_flags & (O_WRONLY|O_RDWR))) {
prs_struct ps;
REGF_SK_REC *sk;
@@ -1554,7 +1554,7 @@ static uint32 sk_record_data_size( SEC_DESC * sd )
/* the record size is sizeof(hdr) + name + static members + data_size_field */
- size = sizeof(uint32)*5 + sec_desc_size( sd ) + sizeof(uint32);
+ size = sizeof(uint32)*5 + ndr_size_security_descriptor(sd, 0) + sizeof(uint32);
/* multiple of 8 */
size_mod8 = size & 0xfffffff8;
@@ -1784,7 +1784,8 @@ static int hashrec_cmp( REGF_HASH_REC *h1, REGF_HASH_REC *h2 )
nk->sec_desc->ref_count = 0;
/* size value must be self-inclusive */
- nk->sec_desc->size = sec_desc_size(sec_desc) + sizeof(uint32);
+ nk->sec_desc->size = ndr_size_security_descriptor(sec_desc, 0)
+ + sizeof(uint32);
DLIST_ADD_END( file->sec_desc_list, nk->sec_desc, REGF_SK_REC *);