summaryrefslogtreecommitdiff
path: root/source3/registry
diff options
context:
space:
mode:
authorVolker Lendecke <vlendec@samba.org>2007-04-09 10:38:55 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:19:16 -0500
commita40df6f92d42676a9184fb2c20a11d5662ca5b3a (patch)
tree98091de9917888e317ae98b4d14e5e27d699be96 /source3/registry
parent4838055e5f300ec5c9e09ac5ebb9d661fa9a7cd1 (diff)
downloadsamba-a40df6f92d42676a9184fb2c20a11d5662ca5b3a.tar.gz
samba-a40df6f92d42676a9184fb2c20a11d5662ca5b3a.tar.bz2
samba-a40df6f92d42676a9184fb2c20a11d5662ca5b3a.zip
r22135: Check in most of Michael Adam's net conf utility. A good share of this patch
is moving functions around to fix some linker dependencies for the registry. Michael, I've renamed your auth_utils2.c to token_utils.c. Thanks! Volker (This used to be commit 9de16f25c1c3e0b203da47391772ef2e2fe291ac)
Diffstat (limited to 'source3/registry')
-rw-r--r--source3/registry/reg_api.c60
-rw-r--r--source3/registry/reg_frontend.c346
-rw-r--r--source3/registry/reg_frontend_hilvl.c315
3 files changed, 375 insertions, 346 deletions
diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c
index 7d8cd993a3..9057932538 100644
--- a/source3/registry/reg_api.c
+++ b/source3/registry/reg_api.c
@@ -496,3 +496,63 @@ WERROR reg_deletevalue(struct registry_key *key, const char *name)
return WERR_OK;
}
+
+/*
+ * Utility function to open a complete registry path including the hive
+ * prefix. This should become the replacement function for
+ * regkey_open_internal.
+ */
+
+WERROR reg_open_path(TALLOC_CTX *mem_ctx, const char *orig_path,
+ uint32 desired_access, const struct nt_user_token *token,
+ struct registry_key **pkey)
+{
+ struct registry_key *hive, *key;
+ 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;
+ return WERR_OK;
+ }
+
+ *p = '\0';
+
+ err = reg_openhive(mem_ctx, path, SEC_RIGHTS_ENUM_SUBKEYS, token,
+ &hive);
+ if (!W_ERROR_IS_OK(err)) {
+ SAFE_FREE(path);
+ return err;
+ }
+
+ err = reg_openkey(mem_ctx, hive, p+1, desired_access, &key);
+
+ TALLOC_FREE(hive);
+ SAFE_FREE(path);
+
+ if (!W_ERROR_IS_OK(err)) {
+ return err;
+ }
+
+ *pkey = key;
+ return WERR_OK;
+}
+
+/* END */
diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c
index 2ec532dcdc..dd904f1863 100644
--- a/source3/registry/reg_frontend.c
+++ b/source3/registry/reg_frontend.c
@@ -45,45 +45,6 @@ REGISTRY_HOOK reg_hooks[] = {
{ NULL, NULL }
};
-
-static struct generic_mapping reg_generic_map =
- { REG_KEY_READ, REG_KEY_WRITE, REG_KEY_EXECUTE, REG_KEY_ALL };
-
-/********************************************************************
-********************************************************************/
-
-static SEC_DESC* construct_registry_sd( TALLOC_CTX *ctx )
-{
- SEC_ACE ace[2];
- SEC_ACCESS mask;
- size_t i = 0;
- SEC_DESC *sd;
- SEC_ACL *acl;
- 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);
-
-
- /* create the security descriptor */
-
- if ( !(acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) )
- return NULL;
-
- if ( !(sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, acl, &sd_size)) )
- return NULL;
-
- return sd;
-}
-
-
/***********************************************************************
Open the registry database and initialize the REGISTRY_HOOK cache
***********************************************************************/
@@ -123,231 +84,6 @@ BOOL init_registry( void )
return True;
}
-/***********************************************************************
- 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;
-
-}
-
-/***********************************************************************
- 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;
-}
-
-
-/***********************************************************************
- High level wrapper function for enumerating registry subkeys
- Initialize the TALLOC_CTX if necessary
- ***********************************************************************/
-
-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 );
-
- return result;
-}
-
-/***********************************************************************
- High level wrapper function for enumerating registry values
- ***********************************************************************/
-
-int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
-{
- int result = -1;
-
- 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
- underlying registry backend
- ***********************************************************************/
-
-BOOL regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted,
- const struct nt_user_token *token )
-{
- SEC_DESC *sec_desc;
- NTSTATUS status;
- WERROR err;
- TALLOC_CTX *mem_ctx;
-
- /* use the default security check if the backend has not defined its
- * own */
-
- if (key->hook && key->hook->ops && key->hook->ops->reg_access_check) {
- return key->hook->ops->reg_access_check( key->name, requested,
- granted, token );
- }
-
- /*
- * The secdesc routines can't yet cope with a NULL talloc ctx sanely.
- */
-
- if (!(mem_ctx = talloc_init("regkey_access_check"))) {
- return False;
- }
-
- err = regkey_get_secdesc(mem_ctx, key, &sec_desc);
-
- if (!W_ERROR_IS_OK(err)) {
- TALLOC_FREE(mem_ctx);
- 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;
- }
-
- TALLOC_FREE(mem_ctx);
- return NT_STATUS_IS_OK(status);
-}
-
-/***********************************************************************
-***********************************************************************/
-
-static int regkey_destructor(REGISTRY_KEY *key)
-{
- return regdb_close();
-}
-
-WERROR regkey_open_onelevel( TALLOC_CTX *mem_ctx, struct registry_key *parent,
- const char *name,
- const struct nt_user_token *token,
- uint32 access_desired,
- struct registry_key **pregkey)
-{
- WERROR result = WERR_OK;
- struct registry_key *regkey;
- REGISTRY_KEY *key;
- REGSUBKEY_CTR *subkeys = NULL;
-
- DEBUG(7,("regkey_open_onelevel: name = [%s]\n", name));
-
- SMB_ASSERT(strchr(name, '\\') == NULL);
-
- if (!(regkey = TALLOC_ZERO_P(mem_ctx, struct registry_key)) ||
- !(regkey->token = dup_nt_token(regkey, token)) ||
- !(regkey->key = TALLOC_ZERO_P(regkey, REGISTRY_KEY))) {
- result = WERR_NOMEM;
- goto done;
- }
-
- if ( !(W_ERROR_IS_OK(result = regdb_open())) ) {
- goto done;
- }
-
- key = regkey->key;
- talloc_set_destructor(key, regkey_destructor);
-
- /* initialization */
-
- key->type = REG_KEY_GENERIC;
-
- if (name[0] == '\0') {
- /*
- * Open a copy of the parent key
- */
- if (!parent) {
- result = WERR_BADFILE;
- goto done;
- }
- key->name = talloc_strdup(key, parent->key->name);
- }
- else {
- /*
- * Normal subkey open
- */
- key->name = talloc_asprintf(key, "%s%s%s",
- parent ? parent->key->name : "",
- parent ? "\\": "",
- name);
- }
-
- if (key->name == NULL) {
- result = WERR_NOMEM;
- goto done;
- }
-
- /* Tag this as a Performance Counter Key */
-
- if( StrnCaseCmp(key->name, KEY_HKPD, strlen(KEY_HKPD)) == 0 )
- key->type = REG_KEY_HKPD;
-
- /* 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 "
- "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 */
-
- if ( !(subkeys = TALLOC_ZERO_P( key, REGSUBKEY_CTR )) ) {
- result = WERR_NOMEM;
- goto done;
- }
-
- if ( fetch_reg_keys( key, subkeys ) == -1 ) {
- result = WERR_BADFILE;
- goto done;
- }
-
- TALLOC_FREE( subkeys );
-
- if ( !regkey_access_check( key, access_desired, &key->access_granted,
- token ) ) {
- result = WERR_ACCESS_DENIED;
- goto done;
- }
-
- *pregkey = regkey;
- result = WERR_OK;
-
-done:
- if ( !W_ERROR_IS_OK(result) ) {
- TALLOC_FREE(regkey);
- }
-
- return result;
-}
-
WERROR regkey_open_internal( TALLOC_CTX *ctx, REGISTRY_KEY **regkey,
const char *path,
const struct nt_user_token *token,
@@ -366,29 +102,6 @@ WERROR regkey_open_internal( TALLOC_CTX *ctx, REGISTRY_KEY **regkey,
return WERR_OK;
}
-WERROR regkey_get_secdesc(TALLOC_CTX *mem_ctx, REGISTRY_KEY *key,
- struct security_descriptor **psecdesc)
-{
- struct security_descriptor *secdesc;
-
- if (key->hook && key->hook->ops && key->hook->ops->get_secdesc) {
- WERROR err;
-
- err = key->hook->ops->get_secdesc(mem_ctx, key->name,
- psecdesc);
- if (W_ERROR_IS_OK(err)) {
- return WERR_OK;
- }
- }
-
- if (!(secdesc = construct_registry_sd(mem_ctx))) {
- return WERR_NOMEM;
- }
-
- *psecdesc = secdesc;
- return WERR_OK;
-}
-
WERROR regkey_set_secdesc(REGISTRY_KEY *key,
struct security_descriptor *psecdesc)
{
@@ -399,65 +112,6 @@ WERROR regkey_set_secdesc(REGISTRY_KEY *key,
return WERR_ACCESS_DENIED;
}
-
-/*
- * Utility function to open a complete registry path including the hive
- * prefix. This should become the replacement function for
- * regkey_open_internal.
- */
-
-WERROR reg_open_path(TALLOC_CTX *mem_ctx, const char *orig_path,
- uint32 desired_access, const struct nt_user_token *token,
- struct registry_key **pkey)
-{
- struct registry_key *hive, *key;
- 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;
- return WERR_OK;
- }
-
- *p = '\0';
-
- err = reg_openhive(mem_ctx, path, SEC_RIGHTS_ENUM_SUBKEYS, token,
- &hive);
- if (!W_ERROR_IS_OK(err)) {
- SAFE_FREE(path);
- return err;
- }
-
- err = reg_openkey(mem_ctx, hive, p+1, desired_access, &key);
-
- TALLOC_FREE(hive);
- SAFE_FREE(path);
-
- if (!W_ERROR_IS_OK(err)) {
- return err;
- }
-
- *pkey = key;
- return WERR_OK;
-}
-
/*
* Utility function to create a registry key without opening the hive
* before. Assumes the hive already exists.
diff --git a/source3/registry/reg_frontend_hilvl.c b/source3/registry/reg_frontend_hilvl.c
new file mode 100644
index 0000000000..72441535b5
--- /dev/null
+++ b/source3/registry/reg_frontend_hilvl.c
@@ -0,0 +1,315 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Virtual Windows Registry Layer
+ * Copyright (C) Gerald Carter 2002-2005
+ * Copyright (C) Michael Adam 2006
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Implementation of registry frontend view functions.
+ * Functions moved from reg_frontend.c to minimize linker deps.
+ */
+
+#include "includes.h"
+
+
+static struct generic_mapping reg_generic_map =
+ { REG_KEY_READ, REG_KEY_WRITE, REG_KEY_EXECUTE, REG_KEY_ALL };
+
+/********************************************************************
+********************************************************************/
+
+static SEC_DESC* construct_registry_sd( TALLOC_CTX *ctx )
+{
+ SEC_ACE ace[2];
+ SEC_ACCESS mask;
+ size_t i = 0;
+ SEC_DESC *sd;
+ SEC_ACL *acl;
+ 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);
+
+
+ /* create the security descriptor */
+
+ if ( !(acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) )
+ return NULL;
+
+ if ( !(sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, acl, &sd_size)) )
+ return NULL;
+
+ return sd;
+}
+
+/***********************************************************************
+ 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;
+
+}
+
+/***********************************************************************
+ 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;
+}
+
+/***********************************************************************
+ High level wrapper function for enumerating registry subkeys
+ Initialize the TALLOC_CTX if necessary
+ ***********************************************************************/
+
+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 );
+
+ return result;
+}
+
+/***********************************************************************
+ High level wrapper function for enumerating registry values
+ ***********************************************************************/
+
+int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val )
+{
+ int result = -1;
+
+ 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
+ underlying registry backend
+ ***********************************************************************/
+
+BOOL regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted,
+ const struct nt_user_token *token )
+{
+ SEC_DESC *sec_desc;
+ NTSTATUS status;
+ WERROR err;
+ TALLOC_CTX *mem_ctx;
+
+ /* use the default security check if the backend has not defined its
+ * own */
+
+ if (key->hook && key->hook->ops && key->hook->ops->reg_access_check) {
+ return key->hook->ops->reg_access_check( key->name, requested,
+ granted, token );
+ }
+
+ /*
+ * The secdesc routines can't yet cope with a NULL talloc ctx sanely.
+ */
+
+ if (!(mem_ctx = talloc_init("regkey_access_check"))) {
+ return False;
+ }
+
+ err = regkey_get_secdesc(mem_ctx, key, &sec_desc);
+
+ if (!W_ERROR_IS_OK(err)) {
+ TALLOC_FREE(mem_ctx);
+ 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;
+ }
+
+ TALLOC_FREE(mem_ctx);
+ return NT_STATUS_IS_OK(status);
+}
+
+/***********************************************************************
+***********************************************************************/
+
+static int regkey_destructor(REGISTRY_KEY *key)
+{
+ return regdb_close();
+}
+
+WERROR regkey_open_onelevel( TALLOC_CTX *mem_ctx, struct registry_key *parent,
+ const char *name,
+ const struct nt_user_token *token,
+ uint32 access_desired,
+ struct registry_key **pregkey)
+{
+ WERROR result = WERR_OK;
+ struct registry_key *regkey;
+ REGISTRY_KEY *key;
+ REGSUBKEY_CTR *subkeys = NULL;
+
+ DEBUG(7,("regkey_open_onelevel: name = [%s]\n", name));
+
+ SMB_ASSERT(strchr(name, '\\') == NULL);
+
+ if (!(regkey = TALLOC_ZERO_P(mem_ctx, struct registry_key)) ||
+ !(regkey->token = dup_nt_token(regkey, token)) ||
+ !(regkey->key = TALLOC_ZERO_P(regkey, REGISTRY_KEY))) {
+ result = WERR_NOMEM;
+ goto done;
+ }
+
+ if ( !(W_ERROR_IS_OK(result = regdb_open())) ) {
+ goto done;
+ }
+
+ key = regkey->key;
+ talloc_set_destructor(key, regkey_destructor);
+
+ /* initialization */
+
+ key->type = REG_KEY_GENERIC;
+
+ if (name[0] == '\0') {
+ /*
+ * Open a copy of the parent key
+ */
+ if (!parent) {
+ result = WERR_BADFILE;
+ goto done;
+ }
+ key->name = talloc_strdup(key, parent->key->name);
+ }
+ else {
+ /*
+ * Normal subkey open
+ */
+ key->name = talloc_asprintf(key, "%s%s%s",
+ parent ? parent->key->name : "",
+ parent ? "\\": "",
+ name);
+ }
+
+ if (key->name == NULL) {
+ result = WERR_NOMEM;
+ goto done;
+ }
+
+ /* Tag this as a Performance Counter Key */
+
+ if( StrnCaseCmp(key->name, KEY_HKPD, strlen(KEY_HKPD)) == 0 )
+ key->type = REG_KEY_HKPD;
+
+ /* 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 "
+ "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 */
+
+ if ( !(subkeys = TALLOC_ZERO_P( key, REGSUBKEY_CTR )) ) {
+ result = WERR_NOMEM;
+ goto done;
+ }
+
+ if ( fetch_reg_keys( key, subkeys ) == -1 ) {
+ result = WERR_BADFILE;
+ goto done;
+ }
+
+ TALLOC_FREE( subkeys );
+
+ if ( !regkey_access_check( key, access_desired, &key->access_granted,
+ token ) ) {
+ result = WERR_ACCESS_DENIED;
+ goto done;
+ }
+
+ *pregkey = regkey;
+ result = WERR_OK;
+
+done:
+ if ( !W_ERROR_IS_OK(result) ) {
+ TALLOC_FREE(regkey);
+ }
+
+ return result;
+}
+
+WERROR regkey_get_secdesc(TALLOC_CTX *mem_ctx, REGISTRY_KEY *key,
+ struct security_descriptor **psecdesc)
+{
+ struct security_descriptor *secdesc;
+
+ if (key->hook && key->hook->ops && key->hook->ops->get_secdesc) {
+ WERROR err;
+
+ err = key->hook->ops->get_secdesc(mem_ctx, key->name,
+ psecdesc);
+ if (W_ERROR_IS_OK(err)) {
+ return WERR_OK;
+ }
+ }
+
+ if (!(secdesc = construct_registry_sd(mem_ctx))) {
+ return WERR_NOMEM;
+ }
+
+ *psecdesc = secdesc;
+ return WERR_OK;
+}
+
+
+/* END */