From 6e1d36f8c613cc95c37993b10e2a0389a3878d9a Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 16 Jan 2008 23:18:07 +0100 Subject: Reformatting: Strip trailing white spaces from reg_frontent_hilvl.c. Michael (This used to be commit 36085d9004592e48b66b681f85346db15e6d9b3a) --- source3/registry/reg_frontend_hilvl.c | 40 +++++++++++++++++------------------ 1 file changed, 19 insertions(+), 21 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_frontend_hilvl.c b/source3/registry/reg_frontend_hilvl.c index 73fcf87e17..08d094cf83 100644 --- a/source3/registry/reg_frontend_hilvl.c +++ b/source3/registry/reg_frontend_hilvl.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 . */ -/* - * 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,20 +72,19 @@ 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 ) ) @@ -106,7 +104,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 +118,23 @@ int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr ) 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 + High level access check for passing the required access mask to the underlying registry backend ***********************************************************************/ -- cgit From 8c2d440c1ffc8f2b5baf0c2519e7f26e4bfa4aeb Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 16 Jan 2008 23:19:38 +0100 Subject: Use the proper boolean constants in reg_frontend_hilvl.c Michael (This used to be commit 5c0a1d5d45948fdc483d6f9de31cea39e12722c6) --- source3/registry/reg_frontend_hilvl.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_frontend_hilvl.c b/source3/registry/reg_frontend_hilvl.c index 08d094cf83..cd02eeef74 100644 --- a/source3/registry/reg_frontend_hilvl.c +++ b/source3/registry/reg_frontend_hilvl.c @@ -78,7 +78,7 @@ 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; } /*********************************************************************** @@ -88,12 +88,12 @@ bool store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys ) bool store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ) { if ( check_dynamic_reg_values( key ) ) - return False; + 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; } /*********************************************************************** @@ -159,21 +159,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, ®_generic_map ); if (!se_access_check(sec_desc, token, requested, granted, &status)) { TALLOC_FREE(mem_ctx); - return False; + return false; } TALLOC_FREE(mem_ctx); -- cgit From 1a15320dcdf72884a4250d535e46315bcf1aa9ee Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 17 Jan 2008 00:16:58 +0100 Subject: Make utility function reg_deletekey_recursive_internal() static. Michael (This used to be commit 3e661273229bcf021276cc0b71350acf8d8fed7c) --- source3/registry/reg_api.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index d1657c8cf6..cef14e2ca1 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -715,10 +715,10 @@ WERROR reg_open_path(TALLOC_CTX *mem_ctx, const char *orig_path, * 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; -- cgit From b6eaf05479fb757da5e8a717c02a6f6c44c42ab5 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 17 Jan 2008 00:57:53 +0100 Subject: Add some sectioning comments to reg_api.c Michael (This used to be commit d3c9c273740b42e5da101f53d4df3aee70cdacf7) --- source3/registry/reg_api.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'source3/registry') diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index cef14e2ca1..744e5eb6e3 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -24,6 +24,11 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_REGISTRY + +/********************************************************************** + * Helper functions + **********************************************************************/ + static WERROR fill_value_cache(struct registry_key *key) { if (key->values != NULL) { @@ -186,6 +191,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) @@ -627,6 +637,11 @@ WERROR reg_deletevalue(struct registry_key *key, const char *name) return WERR_OK; } + +/********************************************************************** + * Higher level utility functions + **********************************************************************/ + WERROR reg_deleteallvalues(struct registry_key *key) { WERROR err; -- cgit From 99b195a6aa39bdf3f327fe1c7b1295032c3c3caa Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 17 Jan 2008 10:19:12 +0100 Subject: Move reg_create_path() and reg_delete_path() to reg_api.c Michael (This used to be commit 4d82cc586c089a16d1d2db214f5e198062890b58) --- source3/registry/reg_api.c | 95 +++++++++++++++++++++++++++++++++++++++++ source3/registry/reg_frontend.c | 95 ----------------------------------------- 2 files changed, 95 insertions(+), 95 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index 744e5eb6e3..83c5f1a634 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -794,3 +794,98 @@ WERROR reg_deletesubkeys_recursive(TALLOC_CTX *ctx, { return reg_deletekey_recursive_internal(ctx, parent, path, false); } + +/* + * 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_frontend.c b/source3/registry/reg_frontend.c index 40d9192b08..9e84d3a8c4 100644 --- a/source3/registry/reg_frontend.c +++ b/source3/registry/reg_frontend.c @@ -105,98 +105,3 @@ WERROR regkey_open_internal( TALLOC_CTX *ctx, REGISTRY_KEY **regkey, 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; -} -- cgit From fcb47f5ea91d497a3921cf5617e30da50638deab Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 17 Jan 2008 10:30:56 +0100 Subject: Comment out unused reg_create_path() and reg_delete_path(). These functions are unused. Comment them out for now. Michael (This used to be commit 0cb8399d7c6f228b38c918f8c6c77fd31c346f89) --- source3/registry/reg_api.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index 83c5f1a634..ee138b284d 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -795,7 +795,10 @@ WERROR reg_deletesubkeys_recursive(TALLOC_CTX *ctx, 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. */ @@ -889,3 +892,4 @@ WERROR reg_delete_path(const struct nt_user_token *token, TALLOC_FREE(hive); return err; } +#endif /* #if 0 */ -- cgit From da4ecfc0faed73599412b10d081c86fb748ec0d4 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 17 Jan 2008 11:02:15 +0100 Subject: Add reg_api functions reg_getkeysecurity() and reg_setkeysecurity(). These are wrappers around the lower level functions regkey_get_secdesc() and regkey_set_secdesc(). Next step towards hiding reg_frontend from the surface. Michael (This used to be commit 7251a24b489a008243091279d96157cacec35b62) --- source3/registry/reg_api.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/registry') diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index ee138b284d..4ba5073cb0 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -637,6 +637,17 @@ 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); +} /********************************************************************** * Higher level utility functions -- cgit From 138f7ec45165cd842112627c52891e973a3ff21e Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 17 Jan 2008 11:07:28 +0100 Subject: Add a comment header comparing winreg.idl and reg_api.c. Michael (This used to be commit 15163926a8ae1116a0f0986f35fc16bcf9ce6ce2) --- source3/registry/reg_api.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'source3/registry') diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index 4ba5073cb0..085f52b33d 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -19,6 +19,48 @@ /* 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 + * 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 -- cgit From 7f8e4bc68ea727ab999c3f60927adbc8acc5a651 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 17 Jan 2008 11:09:08 +0100 Subject: Add my (C) to reg_api.c - Michael (This used to be commit 81d6a1fbed5e685376637af8e8bcd70ab2701aa0) --- source3/registry/reg_api.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/registry') diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index 085f52b33d..a4c88e2e88 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -2,6 +2,7 @@ * 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 -- cgit From 32a8e740785147256c008730a69ae6d60a294884 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 17 Jan 2008 11:22:01 +0100 Subject: Add a reg_getversion() function to reg_api and use it in srv_winreg_nt.c. Michael (This used to be commit 903223b160eef6ba6ff19a8bfef19e5fe7008631) --- source3/registry/reg_api.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index a4c88e2e88..18435ff033 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -50,7 +50,7 @@ * 0x17 winreg_UnLoadKey * 0x18 winreg_InitiateSystemShutdown * 0x19 winreg_AbortSystemShutdown - * 0x1a winreg_GetVersion + * 0x1a winreg_GetVersion reg_getversion * 0x1b winreg_OpenHKCC * 0x1c winreg_OpenHKDD * 0x1d winreg_QueryMultipleValues @@ -692,6 +692,16 @@ WERROR reg_setkeysecurity(struct registry_key *key, 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 **********************************************************************/ -- cgit From 1ea809383ef310f442bae7b5d4591f9aa655ad60 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 18 Jan 2008 08:15:27 +0100 Subject: Fix typo in debug message. Michael (This used to be commit d7a8d7ffbd724a59aa3fc4bdeca6be5d5a0e7258) --- source3/registry/reg_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index 18435ff033..788af28d5d 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -183,7 +183,7 @@ 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; -- cgit From 60fbc7e4f03bff29ad548c1e8640e6fde23ace2a Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 18 Jan 2008 09:40:42 +0100 Subject: Add a registry backend netlogon_params that replaces the former dynamic overlay. This is the first step in replacing the dynamic overlays by proper backends implementing REGISTRY_OPS. Michael (This used to be commit e8a0524961d81fa83e0316905dc9d215e4aa7656) --- source3/registry/reg_backend_netlogon_params.c | 58 ++++++++++++++++++++++++++ source3/registry/reg_dynamic.c | 4 ++ source3/registry/reg_frontend.c | 2 + 3 files changed, 64 insertions(+) create mode 100644 source3/registry/reg_backend_netlogon_params.c (limited to 'source3/registry') diff --git a/source3/registry/reg_backend_netlogon_params.c b/source3/registry/reg_backend_netlogon_params.c new file mode 100644 index 0000000000..b70e1bdf50 --- /dev/null +++ b/source3/registry/reg_backend_netlogon_params.c @@ -0,0 +1,58 @@ +/* + * 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 . + */ + +/* + * Netlogon parameters registry backend. + * + * This replaces the former dynamic netlogon parameters overlay. + */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_REGISTRY + + +static int netlogon_params_fetch_reg_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 ); +} + + +REGISTRY_OPS netlogon_params_reg_ops = { + NULL, + netlogon_params_fetch_reg_values, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; diff --git a/source3/registry/reg_dynamic.c b/source3/registry/reg_dynamic.c index e70bd178f9..07c9673c28 100644 --- a/source3/registry/reg_dynamic.c +++ b/source3/registry/reg_dynamic.c @@ -29,6 +29,7 @@ struct reg_dyn_values { int (*fetch_values) ( REGVAL_CTR *val ); }; +#if 0 /*********************************************************************** ***********************************************************************/ @@ -44,6 +45,7 @@ static int netlogon_params( REGVAL_CTR *regvals ) return regval_ctr_numvals( regvals ); } +#endif /*********************************************************************** ***********************************************************************/ @@ -200,7 +202,9 @@ static int current_version( REGVAL_CTR *values ) ***********************************************************************/ static struct reg_dyn_values dynamic_values[] = { +#if 0 { "HKLM/SYSTEM/CURRENTCONTROLSET/SERVICES/NETLOGON/PARAMETERS", &netlogon_params }, +#endif { "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRODUCTOPTIONS", &prod_options }, { "HKLM/SYSTEM/CURRENTCONTROLSET/SERVICES/TCPIP/PARAMETERS", &tcpip_params }, { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB", &perflib_params }, diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c index 9e84d3a8c4..6674b0ba20 100644 --- a/source3/registry/reg_frontend.c +++ b/source3/registry/reg_frontend.c @@ -28,6 +28,7 @@ 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 regdb_ops; /* these are the default */ /* array of REGISTRY_HOOK's which are read into a tree for easy access */ @@ -40,6 +41,7 @@ REGISTRY_HOOK reg_hooks[] = { { KEY_PRINTING_PORTS, &printing_ops }, { KEY_SHARES, &shares_reg_ops }, { KEY_SMBCONF, &smbconf_reg_ops }, + { KEY_NETLOGON_PARAMS, &netlogon_params_reg_ops }, #endif { NULL, NULL } }; -- cgit From 27d9ac321961891b0580a9f67366ef6b603de418 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 18 Jan 2008 12:07:02 +0100 Subject: Use C99 structure initializers for netlogon_params_reg_ops. Michael (This used to be commit f3901f179b770ffadb3e5a82ac5a2da00d83f40a) --- source3/registry/reg_backend_netlogon_params.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_backend_netlogon_params.c b/source3/registry/reg_backend_netlogon_params.c index b70e1bdf50..507d2c5df8 100644 --- a/source3/registry/reg_backend_netlogon_params.c +++ b/source3/registry/reg_backend_netlogon_params.c @@ -46,13 +46,5 @@ static int netlogon_params_fetch_reg_values(const char *key, REGISTRY_OPS netlogon_params_reg_ops = { - NULL, - netlogon_params_fetch_reg_values, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL + .fetch_values = netlogon_params_fetch_reg_values, }; -- cgit From 29af710d6acc4fe7e02313b7c878dc7301feeaea Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 19 Jan 2008 23:01:58 +0100 Subject: Use c99 struct initializers for REGISTRY_OPS in reg_smbconf.c. Michael (This used to be commit 96d116b003c1187869cbdbc21274a0b5cb1bf7d6) --- source3/registry/reg_smbconf.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_smbconf.c b/source3/registry/reg_smbconf.c index 8dfb745a7e..a6e478200f 100644 --- a/source3/registry/reg_smbconf.c +++ b/source3/registry/reg_smbconf.c @@ -265,13 +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, - NULL, - NULL + .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, }; -- cgit From 15015b74906fd4ce6bab5c500946ca0aa7da0fa8 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 19 Jan 2008 23:06:12 +0100 Subject: Use c99 struct initializers for REGISTRY_OPS in reg_printing.c Michael (This used to be commit a89bee4139666ba163385c9e7d15fbc5d623ed6f) --- source3/registry/reg_printing.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_printing.c b/source3/registry/reg_printing.c index 5be0796002..a4da103d40 100644 --- a/source3/registry/reg_printing.c +++ b/source3/registry/reg_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, 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, }; -- cgit From cb1e0de56f180fa6da82908a73610daecd19b9d7 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 19 Jan 2008 23:09:38 +0100 Subject: Use c99 struct initializers for REGISTRY_OPS in reg_shares.c Michael (This used to be commit 2c4dfd7aaa3c3b384b547451f914a86f59157928) --- source3/registry/reg_shares.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_shares.c b/source3/registry/reg_shares.c index 4ac6e1d151..ee9e5dc5a1 100644 --- a/source3/registry/reg_shares.c +++ b/source3/registry/reg_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, NULL, NULL + .fetch_subkeys = shares_subkey_info, + .fetch_values = shares_value_info, + .store_subkeys = shares_store_subkey, + .store_values = shares_store_value, }; -- cgit From 139340f570f006032aba2d5d98e13731e373bdfe Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 18 Jan 2008 12:13:37 +0100 Subject: Volker is right: why keep commented out migrated dynamic reg overlays around?... Michael (This used to be commit a73b8d16aa0f7a3bb7417e9839e04380e6a68629) --- source3/registry/reg_dynamic.c | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_dynamic.c b/source3/registry/reg_dynamic.c index 07c9673c28..037bdab0cc 100644 --- a/source3/registry/reg_dynamic.c +++ b/source3/registry/reg_dynamic.c @@ -29,24 +29,6 @@ struct reg_dyn_values { int (*fetch_values) ( REGVAL_CTR *val ); }; -#if 0 -/*********************************************************************** -***********************************************************************/ - -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 ); -} -#endif - /*********************************************************************** ***********************************************************************/ @@ -202,9 +184,6 @@ static int current_version( REGVAL_CTR *values ) ***********************************************************************/ static struct reg_dyn_values dynamic_values[] = { -#if 0 - { "HKLM/SYSTEM/CURRENTCONTROLSET/SERVICES/NETLOGON/PARAMETERS", &netlogon_params }, -#endif { "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRODUCTOPTIONS", &prod_options }, { "HKLM/SYSTEM/CURRENTCONTROLSET/SERVICES/TCPIP/PARAMETERS", &tcpip_params }, { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB", &perflib_params }, -- cgit From 563c4ef74082b0d06d0511fef700980d92f04d08 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 18 Jan 2008 16:13:01 +0100 Subject: Use constant KEY_NETLOGON_PARAMS instead of literal key. Michael (This used to be commit daf37c954572bbf652506daae9ff0c9c365b2a9e) --- source3/registry/reg_db.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_db.c b/source3/registry/reg_db.c index c4bfc2b6c9..1b95c2558c 100644 --- a/source3/registry/reg_db.c +++ b/source3/registry/reg_db.c @@ -50,7 +50,7 @@ static const char *builtin_registry_paths[] = { "HKLM\\SYSTEM\\CurrentControlSet\\Control\\ProductOptions", "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration", "HKLM\\SYSTEM\\CurrentControlSet\\Services\\TcpIp\\Parameters", - "HKLM\\SYSTEM\\CurrentControlSet\\Services\\Netlogon\\Parameters", + KEY_NETLOGON_PARAMS, "HKU", "HKCR", "HKPD", -- cgit From 1b2dd2dcc8a78c3b6d4ba9fe229dd6f286947b32 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 18 Jan 2008 17:51:57 +0100 Subject: Fix registering Registry backends in reghook_cache_add(). This was broken in 331c0d6216e1a1607a49ed7eb4078e10138ec16a (pstring removal). Michael (This used to be commit 7d1e986f3a5ab316a8501ddaca1ba1f0867b4531) --- source3/registry/reg_cachehook.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_cachehook.c b/source3/registry/reg_cachehook.c index 74670aac30..22352c6112 100644 --- a/source3/registry/reg_cachehook.c +++ b/source3/registry/reg_cachehook.c @@ -56,7 +56,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; } -- cgit From c8a0b2a3a2c82312076341fb2fe53e0abed0a6fb Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 19 Jan 2008 22:39:33 +0100 Subject: In reg_backend_netlogon_params, delegate fetch_subkeys() to regdb. In order to be able to open the netlogon_params key (the new backend replacing the former dynamic overlay), certain methods need to be provided. Delegate these to the regdb backend (like e.g. the smbconf backend does). Michael (This used to be commit 9261b2c4bf48e133eecda9ec0095bd8edf20326c) --- source3/registry/reg_backend_netlogon_params.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/registry') diff --git a/source3/registry/reg_backend_netlogon_params.c b/source3/registry/reg_backend_netlogon_params.c index 507d2c5df8..ff5a33e6e4 100644 --- a/source3/registry/reg_backend_netlogon_params.c +++ b/source3/registry/reg_backend_netlogon_params.c @@ -29,6 +29,7 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_REGISTRY +extern REGISTRY_OPS regdb_ops; static int netlogon_params_fetch_reg_values(const char *key, REGVAL_CTR *regvals) @@ -44,7 +45,13 @@ static int netlogon_params_fetch_reg_values(const char *key, 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_reg_values, + .fetch_subkeys = netlogon_params_fetch_subkeys, }; -- cgit From 2e47997e6e433f915bcba6cd891857c15ea95a12 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 19 Jan 2008 22:42:30 +0100 Subject: Rename netlogon_params_fetch_reg_values() to netlogon_params_fetch_values(). Michael (This used to be commit 54e7c8098565495a833500d4b2a8d5240ed55c82) --- source3/registry/reg_backend_netlogon_params.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_backend_netlogon_params.c b/source3/registry/reg_backend_netlogon_params.c index ff5a33e6e4..d63cd6b31b 100644 --- a/source3/registry/reg_backend_netlogon_params.c +++ b/source3/registry/reg_backend_netlogon_params.c @@ -31,8 +31,7 @@ extern REGISTRY_OPS regdb_ops; -static int netlogon_params_fetch_reg_values(const char *key, - REGVAL_CTR *regvals) +static int netlogon_params_fetch_values(const char *key, REGVAL_CTR *regvals) { uint32 dwValue; @@ -52,6 +51,6 @@ static int netlogon_params_fetch_subkeys(const char *key, } REGISTRY_OPS netlogon_params_reg_ops = { - .fetch_values = netlogon_params_fetch_reg_values, + .fetch_values = netlogon_params_fetch_values, .fetch_subkeys = netlogon_params_fetch_subkeys, }; -- cgit From d48c5f15993c90635f4bb46f87245d9c244d7ddf Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 20 Jan 2008 01:30:38 +0100 Subject: Some reformatting in netlogon_params_fetch_values(). Michael (This used to be commit 24f13fb72e4cbaba48235fa840b2a93bf1c5d9c3) --- source3/registry/reg_backend_netlogon_params.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_backend_netlogon_params.c b/source3/registry/reg_backend_netlogon_params.c index d63cd6b31b..71f88144c8 100644 --- a/source3/registry/reg_backend_netlogon_params.c +++ b/source3/registry/reg_backend_netlogon_params.c @@ -34,14 +34,15 @@ 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) ) + + if (!pdb_get_account_policy(AP_REFUSE_MACHINE_PW_CHANGE, &dwValue)) { dwValue = 0; - - regval_ctr_addvalue( regvals, "RefusePasswordChange", REG_DWORD, - (char*)&dwValue, sizeof(dwValue) ); + } + + regval_ctr_addvalue(regvals, "RefusePasswordChange", REG_DWORD, + (char*)&dwValue, sizeof(dwValue)); - return regval_ctr_numvals( regvals ); + return regval_ctr_numvals(regvals); } static int netlogon_params_fetch_subkeys(const char *key, -- cgit From 663815ec2bbb4b2566a6d72f6680b39953640bb1 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 18 Jan 2008 16:15:43 +0100 Subject: Add a registry backend prod_options that replaces the former dynamic overlay. Michael (This used to be commit d9b89e9d30702f64805b3a3a3612066b19c051d1) --- source3/registry/reg_backend_prod_options.c | 70 +++++++++++++++++++++++++++++ source3/registry/reg_db.c | 2 +- source3/registry/reg_dynamic.c | 31 ------------- source3/registry/reg_frontend.c | 2 + 4 files changed, 73 insertions(+), 32 deletions(-) create mode 100644 source3/registry/reg_backend_prod_options.c (limited to 'source3/registry') diff --git a/source3/registry/reg_backend_prod_options.c b/source3/registry/reg_backend_prod_options.c new file mode 100644 index 0000000000..7be97bee06 --- /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 . + */ + +/* + * 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_db.c b/source3/registry/reg_db.c index 1b95c2558c..f70e44fd51 100644 --- a/source3/registry/reg_db.c +++ b/source3/registry/reg_db.c @@ -47,7 +47,7 @@ static const char *builtin_registry_paths[] = { "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib", "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\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", KEY_NETLOGON_PARAMS, diff --git a/source3/registry/reg_dynamic.c b/source3/registry/reg_dynamic.c index 037bdab0cc..2735e2a27a 100644 --- a/source3/registry/reg_dynamic.c +++ b/source3/registry/reg_dynamic.c @@ -32,36 +32,6 @@ struct reg_dyn_values { /*********************************************************************** ***********************************************************************/ -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; @@ -184,7 +154,6 @@ static int current_version( REGVAL_CTR *values ) ***********************************************************************/ static struct reg_dyn_values dynamic_values[] = { - { "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 }, diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c index 6674b0ba20..32ec7f9a87 100644 --- a/source3/registry/reg_frontend.c +++ b/source3/registry/reg_frontend.c @@ -29,6 +29,7 @@ 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 regdb_ops; /* these are the default */ /* array of REGISTRY_HOOK's which are read into a tree for easy access */ @@ -42,6 +43,7 @@ REGISTRY_HOOK reg_hooks[] = { { KEY_SHARES, &shares_reg_ops }, { KEY_SMBCONF, &smbconf_reg_ops }, { KEY_NETLOGON_PARAMS, &netlogon_params_reg_ops }, + { KEY_PROD_OPTIONS, &prod_options_reg_ops }, #endif { NULL, NULL } }; -- cgit From f383b853f58d54352332a60e6f0842dfd41f5ff0 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 20 Jan 2008 01:25:08 +0100 Subject: Some reformatting in prod_options_fetch_values(). Michael (This used to be commit 347b9886547516bc2a43190ae7faaf349d2c9d04) --- source3/registry/reg_backend_prod_options.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_backend_prod_options.c b/source3/registry/reg_backend_prod_options.c index 7be97bee06..7ac5c5b4b9 100644 --- a/source3/registry/reg_backend_prod_options.c +++ b/source3/registry/reg_backend_prod_options.c @@ -33,10 +33,10 @@ 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; - + const char *value_ascii = ""; + fstring value; + int value_length; + switch (lp_server_role()) { case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: @@ -49,12 +49,12 @@ static int prod_options_fetch_values(const char *key, REGVAL_CTR *regvals) 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 ); - + + 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 ); } -- cgit From c5a5b404b43817525590aa924f1762824f49d156 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 19 Jan 2008 23:46:13 +0100 Subject: Add a registry backend tcpip_params that replaces the former dynamic overlay. Michael (This used to be commit a8a743b693a162954948ca2438ce4b842c5cba30) --- source3/registry/reg_backend_tcpip_params.c | 65 +++++++++++++++++++++++++++++ source3/registry/reg_db.c | 2 +- source3/registry/reg_dynamic.c | 26 ------------ source3/registry/reg_frontend.c | 2 + 4 files changed, 68 insertions(+), 27 deletions(-) create mode 100644 source3/registry/reg_backend_tcpip_params.c (limited to 'source3/registry') diff --git a/source3/registry/reg_backend_tcpip_params.c b/source3/registry/reg_backend_tcpip_params.c new file mode 100644 index 0000000000..1714bdb439 --- /dev/null +++ b/source3/registry/reg_backend_tcpip_params.c @@ -0,0 +1,65 @@ +/* + * 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 . + */ + +/* + * 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_db.c b/source3/registry/reg_db.c index f70e44fd51..ce88c56c61 100644 --- a/source3/registry/reg_db.c +++ b/source3/registry/reg_db.c @@ -49,7 +49,7 @@ static const char *builtin_registry_paths[] = { "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors", KEY_PROD_OPTIONS, "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration", - "HKLM\\SYSTEM\\CurrentControlSet\\Services\\TcpIp\\Parameters", + KEY_TCPIP_PARAMS, KEY_NETLOGON_PARAMS, "HKU", "HKCR", diff --git a/source3/registry/reg_dynamic.c b/source3/registry/reg_dynamic.c index 2735e2a27a..9d20b8935c 100644 --- a/source3/registry/reg_dynamic.c +++ b/source3/registry/reg_dynamic.c @@ -32,31 +32,6 @@ struct reg_dyn_values { /*********************************************************************** ***********************************************************************/ -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; @@ -154,7 +129,6 @@ static int current_version( REGVAL_CTR *values ) ***********************************************************************/ static struct reg_dyn_values dynamic_values[] = { - { "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", ¤t_version }, diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c index 32ec7f9a87..6ecc8011e4 100644 --- a/source3/registry/reg_frontend.c +++ b/source3/registry/reg_frontend.c @@ -30,6 +30,7 @@ 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 regdb_ops; /* these are the default */ /* array of REGISTRY_HOOK's which are read into a tree for easy access */ @@ -44,6 +45,7 @@ REGISTRY_HOOK reg_hooks[] = { { 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 }, #endif { NULL, NULL } }; -- cgit From b4e3c752722f6e7d143caa810ce0f8eb9c8d12c9 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 20 Jan 2008 01:21:45 +0100 Subject: Some reformatting in tcpip_params_fetch_values(). Michael (This used to be commit 5b3813b233dc2a60e6d5a9942b4044219d800415) --- source3/registry/reg_backend_tcpip_params.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_backend_tcpip_params.c b/source3/registry/reg_backend_tcpip_params.c index 1714bdb439..db7df5dd8f 100644 --- a/source3/registry/reg_backend_tcpip_params.c +++ b/source3/registry/reg_backend_tcpip_params.c @@ -33,24 +33,26 @@ extern REGISTRY_OPS regdb_ops; static int tcpip_params_fetch_values(const char *key, REGVAL_CTR *regvals) { - fstring value; - int value_length; - char *hname; + 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 ); + 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 ); + 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 ); + return regval_ctr_numvals(regvals); } static int tcpip_params_fetch_subkeys(const char *key, -- cgit From 949a88ee2f1163605a73a28920190c11c25e4609 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 20 Jan 2008 01:00:14 +0100 Subject: Add a registry backend hkpt_params that replaces the former dynamic overlay. Michael (This used to be commit 8e8bb6ba120adf9942f612b7fd89bdbced6c1285) --- source3/registry/reg_backend_hkpt_params.c | 67 ++++++++++++++++++++++++++++++ source3/registry/reg_dynamic.c | 29 ------------- source3/registry/reg_frontend.c | 2 + 3 files changed, 69 insertions(+), 29 deletions(-) create mode 100644 source3/registry/reg_backend_hkpt_params.c (limited to 'source3/registry') diff --git a/source3/registry/reg_backend_hkpt_params.c b/source3/registry/reg_backend_hkpt_params.c new file mode 100644 index 0000000000..0b962e10bd --- /dev/null +++ b/source3/registry/reg_backend_hkpt_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 . + */ + +/* + * 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. */ + + 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_dynamic.c b/source3/registry/reg_dynamic.c index 9d20b8935c..c342cd07e4 100644 --- a/source3/registry/reg_dynamic.c +++ b/source3/registry/reg_dynamic.c @@ -75,33 +75,6 @@ static int perflib_009_params( REGVAL_CTR *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. */ - - 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"; @@ -122,7 +95,6 @@ static int current_version( REGVAL_CTR *values ) return regval_ctr_numvals( values ); } - /*********************************************************************** Structure holding the registry paths and pointers to the value enumeration functions @@ -132,7 +104,6 @@ static struct reg_dyn_values dynamic_values[] = { { "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", ¤t_version }, - { "HKPT", &hkpt_params }, { NULL, NULL } }; diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c index 6ecc8011e4..9539c2ba2f 100644 --- a/source3/registry/reg_frontend.c +++ b/source3/registry/reg_frontend.c @@ -31,6 +31,7 @@ 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 regdb_ops; /* these are the default */ /* array of REGISTRY_HOOK's which are read into a tree for easy access */ @@ -46,6 +47,7 @@ REGISTRY_HOOK reg_hooks[] = { { 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 }, #endif { NULL, NULL } }; -- cgit From 8eed06fb8cc6db37d15ddc0f64744a536588ba29 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 20 Jan 2008 01:15:31 +0100 Subject: Some reformatting in hkpt_params_fetch_values(). Michael (This used to be commit f245c4e094ad56080847e286c76976f29c95a221) --- source3/registry/reg_backend_hkpt_params.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_backend_hkpt_params.c b/source3/registry/reg_backend_hkpt_params.c index 0b962e10bd..2ed5e78e1c 100644 --- a/source3/registry/reg_backend_hkpt_params.c +++ b/source3/registry/reg_backend_hkpt_params.c @@ -39,19 +39,22 @@ static int hkpt_params_fetch_values(const char *key, REGVAL_CTR *regvals) /* This is ALMOST the same as perflib_009_params, but HKPT has a "Counters" entry instead of a "Counter" key. */ - + 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) + 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) + if(buffer_size > 0) { SAFE_FREE(buffer); - + } + return regval_ctr_numvals( regvals ); } -- cgit From 25c21fb562c6bb9c61a9e2e58d585619f18d3c84 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 20 Jan 2008 01:09:52 +0100 Subject: Use some consts instead of literal strings for registry keys. Michael (This used to be commit 80024f4e1c6594c3038e86a765f763d24fd96b59) --- source3/registry/reg_db.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_db.c b/source3/registry/reg_db.c index ce88c56c61..fad6c8acd1 100644 --- a/source3/registry/reg_db.c +++ b/source3/registry/reg_db.c @@ -51,10 +51,10 @@ static const char *builtin_registry_paths[] = { "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration", KEY_TCPIP_PARAMS, KEY_NETLOGON_PARAMS, - "HKU", - "HKCR", - "HKPD", - "HKPT", + KEY_HKU, + KEY_HKCR, + KEY_HKPD, + KEY_HKPT, NULL }; struct builtin_regkey_value { -- cgit From 2925d8357319c9872d570fe045c883a25891b59e Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 20 Jan 2008 03:24:13 +0100 Subject: Add a registry backend current_version that replaces the former dynamic overlay. Make sure to only respond to the exact current version key since subkeys are registered by other backends (printing and - soon - perflib). Michael (This used to be commit 2c650bf63ccd9dc5dddbf4700831489544ded055) --- source3/registry/reg_backend_current_version.c | 80 ++++++++++++++++++++++++++ source3/registry/reg_dynamic.c | 24 -------- source3/registry/reg_frontend.c | 2 + 3 files changed, 82 insertions(+), 24 deletions(-) create mode 100644 source3/registry/reg_backend_current_version.c (limited to 'source3/registry') diff --git a/source3/registry/reg_backend_current_version.c b/source3/registry/reg_backend_current_version.c new file mode 100644 index 0000000000..51b081721c --- /dev/null +++ b/source3/registry/reg_backend_current_version.c @@ -0,0 +1,80 @@ +/* + * 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 . + */ + +/* + * 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_dynamic.c b/source3/registry/reg_dynamic.c index c342cd07e4..ca87cc60f5 100644 --- a/source3/registry/reg_dynamic.c +++ b/source3/registry/reg_dynamic.c @@ -72,29 +72,6 @@ static int perflib_009_params( REGVAL_CTR *regvals ) 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 @@ -103,7 +80,6 @@ static int current_version( REGVAL_CTR *values ) static struct reg_dyn_values dynamic_values[] = { { "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", ¤t_version }, { NULL, NULL } }; diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c index 9539c2ba2f..d489050904 100644 --- a/source3/registry/reg_frontend.c +++ b/source3/registry/reg_frontend.c @@ -32,6 +32,7 @@ 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 regdb_ops; /* these are the default */ /* array of REGISTRY_HOOK's which are read into a tree for easy access */ @@ -48,6 +49,7 @@ REGISTRY_HOOK reg_hooks[] = { { KEY_PROD_OPTIONS, &prod_options_reg_ops }, { KEY_TCPIP_PARAMS, &tcpip_params_reg_ops }, { KEY_HKPT, &hkpt_params_reg_ops }, + { KEY_CURRENT_VERSION, ¤t_version_reg_ops }, #endif { NULL, NULL } }; -- cgit From c4b65647ca551eeb87ec31579eda9ebf79fdceed Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 20 Jan 2008 03:25:54 +0100 Subject: Some reformatting of current_version_fetch_values(). Michael (This used to be commit d2e3814db8a4a5f0fc097e9f56753888470ef213) --- source3/registry/reg_backend_current_version.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_backend_current_version.c b/source3/registry/reg_backend_current_version.c index 51b081721c..a9d281c522 100644 --- a/source3/registry/reg_backend_current_version.c +++ b/source3/registry/reg_backend_current_version.c @@ -55,17 +55,18 @@ static int current_version_fetch_values(const char *key, REGVAL_CTR *values) 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 ); + 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, -- cgit From c16b74cc861c031fda34ea131dadc9d4e175a8ed Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 20 Jan 2008 03:39:27 +0100 Subject: Add a registry backend perflib that replaces the former dynamic overlay. Michael (This used to be commit c3fba415951329ee90c7250b4e8d539f91b227f6) --- source3/registry/reg_backend_perflib.c | 106 +++++++++++++++++++++++++++++++++ source3/registry/reg_db.c | 4 +- source3/registry/reg_dynamic.c | 45 -------------- source3/registry/reg_frontend.c | 2 + 4 files changed, 110 insertions(+), 47 deletions(-) create mode 100644 source3/registry/reg_backend_perflib.c (limited to 'source3/registry') 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 . + */ + +/* + * 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_db.c b/source3/registry/reg_db.c index fad6c8acd1..e162fb587f 100644 --- a/source3/registry/reg_db.c +++ b/source3/registry/reg_db.c @@ -44,8 +44,8 @@ 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", KEY_PROD_OPTIONS, "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration", diff --git a/source3/registry/reg_dynamic.c b/source3/registry/reg_dynamic.c index ca87cc60f5..97cb462615 100644 --- a/source3/registry/reg_dynamic.c +++ b/source3/registry/reg_dynamic.c @@ -29,57 +29,12 @@ struct reg_dyn_values { int (*fetch_values) ( REGVAL_CTR *val ); }; -/*********************************************************************** -***********************************************************************/ - -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 ); -} - /*********************************************************************** Structure holding the registry paths and pointers to the value enumeration functions ***********************************************************************/ static struct reg_dyn_values dynamic_values[] = { - { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB", &perflib_params }, - { "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PERFLIB/009", &perflib_009_params }, { NULL, NULL } }; diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c index d489050904..9a35eb2263 100644 --- a/source3/registry/reg_frontend.c +++ b/source3/registry/reg_frontend.c @@ -33,6 +33,7 @@ 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 */ @@ -50,6 +51,7 @@ REGISTRY_HOOK reg_hooks[] = { { KEY_TCPIP_PARAMS, &tcpip_params_reg_ops }, { KEY_HKPT, &hkpt_params_reg_ops }, { KEY_CURRENT_VERSION, ¤t_version_reg_ops }, + { KEY_PERFLIB, &perflib_reg_ops }, #endif { NULL, NULL } }; -- cgit From e45dacce898021bbce0ba5b2c18dc8e103931e51 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 20 Jan 2008 03:45:40 +0100 Subject: Remove the dynamic registry overlay. It is unnecessary now the dynamic functions have been made registry backends of their own. Michael (This used to be commit e327953bd6b11aeb6f2ae48b49550a942eae8e88) --- source3/registry/reg_dynamic.c | 92 ----------------------------------- source3/registry/reg_frontend_hilvl.c | 11 ----- 2 files changed, 103 deletions(-) delete mode 100644 source3/registry/reg_dynamic.c (limited to 'source3/registry') diff --git a/source3/registry/reg_dynamic.c b/source3/registry/reg_dynamic.c deleted file mode 100644 index 97cb462615..0000000000 --- a/source3/registry/reg_dynamic.c +++ /dev/null @@ -1,92 +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 . - */ - -/* 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 ); -}; - -/*********************************************************************** - Structure holding the registry paths and pointers to the value - enumeration functions -***********************************************************************/ - -static struct reg_dyn_values dynamic_values[] = { - { 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_hilvl.c b/source3/registry/reg_frontend_hilvl.c index cd02eeef74..6819d06704 100644 --- a/source3/registry/reg_frontend_hilvl.c +++ b/source3/registry/reg_frontend_hilvl.c @@ -87,9 +87,6 @@ bool store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys ) 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 ); @@ -122,14 +119,6 @@ int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ) 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; } -- cgit From 7745674f0cbf5be272ad20fdd1e5edd45165e849 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 18 Jan 2008 16:08:52 +0100 Subject: Add some debugging output to reg_cachehook.c Michael (This used to be commit 2a278928805f4497e8afa28bdca433cbedc4a8d7) --- source3/registry/reg_cachehook.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_cachehook.c b/source3/registry/reg_cachehook.c index 22352c6112..f9851c7810 100644 --- a/source3/registry/reg_cachehook.c +++ b/source3/registry/reg_cachehook.c @@ -37,6 +37,11 @@ bool reghook_cache_init( void ) { 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 *)®db_ops, + KEY_TREE_ROOT)); + } } return (cache_tree != NULL); @@ -65,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 ); } @@ -102,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 ); -- cgit From 6c5a831e96982ce0954c09de126205e334ff3a31 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 18 Jan 2008 17:57:32 +0100 Subject: Add a debug message to fetch_reg_values(). Michael (This used to be commit 239aa59cc1b78f7fb82aa66418cdf92517ebc123) --- source3/registry/reg_frontend_hilvl.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/registry') diff --git a/source3/registry/reg_frontend_hilvl.c b/source3/registry/reg_frontend_hilvl.c index 6819d06704..e6e7613457 100644 --- a/source3/registry/reg_frontend_hilvl.c +++ b/source3/registry/reg_frontend_hilvl.c @@ -116,6 +116,9 @@ 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 ); -- cgit From 33f3eeaa00974860dfc45962d5fd34cf05396c76 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jan 2008 17:35:25 +0100 Subject: Fix some "set but never used" warnings (This used to be commit 4a6dadc5178f4861e9c032321939db3b639734b5) --- source3/registry/reg_api.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index 788af28d5d..9c4009368d 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -453,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; @@ -517,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; -- cgit From 1e68e24c8ef105ebef249d770aa7e39db0abfa30 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 20 Jan 2008 23:59:06 +0100 Subject: Rename reg_printing.c to reg_backend_printing.c Start making naming of source files more systematic to facilitate understanding of the structures. Michael (This used to be commit b3c2fb17a4226559788a47fee968ef19b7fbb6b2) --- source3/registry/reg_backend_printing.c | 1269 +++++++++++++++++++++++++++++++ source3/registry/reg_printing.c | 1269 ------------------------------- 2 files changed, 1269 insertions(+), 1269 deletions(-) create mode 100644 source3/registry/reg_backend_printing.c delete mode 100644 source3/registry/reg_printing.c (limited to 'source3/registry') diff --git a/source3/registry/reg_backend_printing.c b/source3/registry/reg_backend_printing.c new file mode 100644 index 0000000000..a4da103d40 --- /dev/null +++ b/source3/registry/reg_backend_printing.c @@ -0,0 +1,1269 @@ +/* + * 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 . + */ + +/* Implementation of registry virtual views for printing information */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_REGISTRY + +/* registrt paths used in the print_registry[] */ + +#define KEY_MONITORS "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/MONITORS" +#define KEY_FORMS "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/FORMS" +#define KEY_CONTROL_PRINTERS "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/PRINTERS" +#define KEY_ENVIRONMENTS "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/ENVIRONMENTS" +#define KEY_CONTROL_PRINT "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT" +#define KEY_WINNT_PRINTERS "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT/PRINTERS" +#define KEY_WINNT_PRINT "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT" +#define KEY_PORTS "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PORTS" + +/* callback table for various registry paths below the ones we service in this module */ + +struct reg_dyn_tree { + /* full key path in normalized form */ + const char *path; + + /* callbscks for fetch/store operations */ + int ( *fetch_subkeys) ( const char *path, REGSUBKEY_CTR *subkeys ); + bool (*store_subkeys) ( const char *path, REGSUBKEY_CTR *subkeys ); + int (*fetch_values) ( const char *path, REGVAL_CTR *values ); + bool (*store_values) ( const char *path, REGVAL_CTR *values ); +}; + +/********************************************************************* + ********************************************************************* + ** Utility Functions + ********************************************************************* + *********************************************************************/ + +/*********************************************************************** + simple function to prune a pathname down to the basename of a file + **********************************************************************/ + +static const char *dos_basename(const char *path) +{ + const char *p; + + if (!(p = strrchr( path, '\\'))) { + p = path; + } else { + p++; + } + + return p; +} + +/********************************************************************* + ********************************************************************* + ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/FORMS" + ********************************************************************* + *********************************************************************/ + +static int key_forms_fetch_keys(const char *key, REGSUBKEY_CTR *subkeys) +{ + char *p = reg_remaining_path(talloc_tos(), key + strlen(KEY_FORMS)); + + /* no keys below Forms */ + + if (p) { + return -1; + } + + return 0; +} + +/********************************************************************** + *********************************************************************/ + +static int key_forms_fetch_values( const char *key, REGVAL_CTR *values ) +{ + uint32 data[8]; + int i, num_values, form_index = 1; + nt_forms_struct *forms_list = NULL; + nt_forms_struct *form; + + DEBUG(10,("print_values_forms: key=>[%s]\n", key ? key : "NULL" )); + + num_values = get_ntforms( &forms_list ); + + DEBUG(10,("hive_forms_fetch_values: [%d] user defined forms returned\n", + num_values)); + + /* handle user defined forms */ + + for ( i=0; iwidth; + data[1] = form->length; + data[2] = form->left; + data[3] = form->top; + data[4] = form->right; + data[5] = form->bottom; + data[6] = form_index++; + data[7] = form->flag; + + regval_ctr_addvalue( values, form->name, REG_BINARY, (char*)data, sizeof(data) ); + } + + SAFE_FREE( forms_list ); + forms_list = NULL; + + /* handle built-on forms */ + + num_values = get_builtin_ntforms( &forms_list ); + + DEBUG(10,("print_subpath_values_forms: [%d] built-in forms returned\n", + num_values)); + + for ( i=0; iwidth; + data[1] = form->length; + data[2] = form->left; + data[3] = form->top; + data[4] = form->right; + data[5] = form->bottom; + data[6] = form_index++; + data[7] = form->flag; + + regval_ctr_addvalue(values, form->name, REG_BINARY, (char*)data, sizeof(data) ); + } + + SAFE_FREE(forms_list); + + return regval_ctr_numvals(values); +} + +/********************************************************************* + ********************************************************************* + ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/PRINTERS" + ** "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT/PRINTERS" + ********************************************************************* + *********************************************************************/ + +/********************************************************************* + strip off prefix for printers key. DOes return a pointer to static + memory. + *********************************************************************/ + +static char *strip_printers_prefix(const char *key) +{ + char *subkeypath = NULL; + char *path = NULL; + TALLOC_CTX *ctx = talloc_tos(); + + path = talloc_strdup(ctx, key); + if (!path) { + return NULL; + } + path = normalize_reg_path(ctx, path); + if (!path) { + return NULL; + } + + /* normalizing the path does not change length, just key delimiters and case */ + + if (strncmp(path, KEY_WINNT_PRINTERS, strlen(KEY_WINNT_PRINTERS)) == 0) { + subkeypath = reg_remaining_path(ctx, key + strlen(KEY_WINNT_PRINTERS)); + } else { + subkeypath = reg_remaining_path(ctx, key + strlen(KEY_CONTROL_PRINTERS)); + } + + TALLOC_FREE(path); + return subkeypath; +} + +/********************************************************************* + *********************************************************************/ + +static int key_printers_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys ) +{ + int n_services = lp_numservices(); + int snum; + fstring sname; + int i; + int num_subkeys = 0; + char *printers_key; + char *printername, *printerdatakey; + NT_PRINTER_INFO_LEVEL *printer = NULL; + fstring *subkey_names = NULL; + + DEBUG(10,("key_printers_fetch_keys: key=>[%s]\n", key ? key : "NULL" )); + + printers_key = strip_printers_prefix( key ); + + if ( !printers_key ) { + /* enumerate all printers */ + + for (snum=0; snum=n_services + || !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) ) + { + return -1; + } + + num_subkeys = get_printer_subkeys( printer->info_2->data, printerdatakey?printerdatakey:"", &subkey_names ); + + for ( i=0; iinfo_2->data, "", &existing_subkeys ); + + for ( i=0; iinfo_2->data, existing_subkeys[i] ); + } + } + + num_subkeys = regsubkey_ctr_numkeys( subkeys ); + for ( i=0; iinfo_2->data, subkeyname) == -1 ) { + DEBUG(5,("key_printers_store_keys: adding key %s\n", + existing_subkeys[i])); + if ( add_new_printer_key( printer->info_2->data, subkeyname ) == -1 ) { + SAFE_FREE( existing_subkeys ); + return False; + } + } + } + + /* write back to disk */ + + mod_a_printer( printer, 2 ); + + /* cleanup */ + + if ( printer ) + free_a_printer( &printer, 2 ); + + SAFE_FREE( existing_subkeys ); + + return True; +} + +/********************************************************************** + *********************************************************************/ + +static void fill_in_printer_values( NT_PRINTER_INFO_LEVEL_2 *info2, REGVAL_CTR *values ) +{ + DEVICEMODE *devmode; + prs_struct prs; + uint32 offset; + UNISTR2 data; + char *p; + uint32 printer_status = PRINTER_STATUS_OK; + + regval_ctr_addvalue( values, "Attributes", REG_DWORD, (char*)&info2->attributes, sizeof(info2->attributes) ); + regval_ctr_addvalue( values, "Priority", REG_DWORD, (char*)&info2->priority, sizeof(info2->attributes) ); + regval_ctr_addvalue( values, "ChangeID", REG_DWORD, (char*)&info2->changeid, sizeof(info2->changeid) ); + regval_ctr_addvalue( values, "Default Priority", REG_DWORD, (char*)&info2->default_priority, sizeof(info2->default_priority) ); + + /* lie and say everything is ok since we don't want to call print_queue_length() to get the real status */ + regval_ctr_addvalue( values, "Status", REG_DWORD, (char*)&printer_status, sizeof(info2->status) ); + + regval_ctr_addvalue( values, "StartTime", REG_DWORD, (char*)&info2->starttime, sizeof(info2->starttime) ); + regval_ctr_addvalue( values, "UntilTime", REG_DWORD, (char*)&info2->untiltime, sizeof(info2->untiltime) ); + + /* strip the \\server\ from this string */ + if ( !(p = strrchr( info2->printername, '\\' ) ) ) + p = info2->printername; + else + p++; + init_unistr2( &data, p, UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + + init_unistr2( &data, info2->location, UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Location", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + + init_unistr2( &data, info2->comment, UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Description", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + + init_unistr2( &data, info2->parameters, UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Parameters", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + + init_unistr2( &data, info2->portname, UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Port", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + + init_unistr2( &data, info2->sharename, UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Share Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + + init_unistr2( &data, info2->drivername, UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Printer Driver", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + + init_unistr2( &data, info2->sepfile, UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Separator File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + + init_unistr2( &data, "WinPrint", UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Print Processor", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + + init_unistr2( &data, "RAW", UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Datatype", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + + + /* use a prs_struct for converting the devmode and security + descriptor to REG_BINARY */ + + prs_init( &prs, RPC_MAX_PDU_FRAG_LEN, values, MARSHALL); + + /* stream the device mode */ + + if ( (devmode = construct_dev_mode( info2->sharename )) != NULL ) { + if ( spoolss_io_devmode( "devmode", &prs, 0, devmode ) ) { + offset = prs_offset( &prs ); + regval_ctr_addvalue( values, "Default Devmode", REG_BINARY, prs_data_p(&prs), offset ); + } + } + + prs_mem_clear( &prs ); + prs_set_offset( &prs, 0 ); + + /* stream the printer security descriptor */ + + if ( info2->secdesc_buf && + info2->secdesc_buf->sd && + info2->secdesc_buf->sd_size ) + { + if ( sec_io_desc("sec_desc", &info2->secdesc_buf->sd, &prs, 0 ) ) { + offset = prs_offset( &prs ); + regval_ctr_addvalue( values, "Security", REG_BINARY, prs_data_p(&prs), offset ); + } + } + + prs_mem_free( &prs ); + + return; +} + +/********************************************************************** + *********************************************************************/ + +static int key_printers_fetch_values( const char *key, REGVAL_CTR *values ) +{ + int num_values; + char *printers_key; + char *printername, *printerdatakey; + NT_PRINTER_INFO_LEVEL *printer = NULL; + NT_PRINTER_DATA *p_data; + int i, key_index; + + printers_key = strip_printers_prefix( key ); + + /* top level key values stored in the registry has no values */ + + if ( !printers_key ) { + /* normalize to the 'HKLM\SOFTWARE\...\Print\Printers' key */ + return regdb_fetch_values( KEY_WINNT_PRINTERS, values ); + } + + /* lookup the printer object */ + + if (!reg_split_path( printers_key, &printername, &printerdatakey )) { + return -1; + } + + if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) ) + goto done; + + if ( !printerdatakey ) { + fill_in_printer_values( printer->info_2, values ); + goto done; + } + + /* iterate over all printer data keys and fill the regval container */ + + p_data = printer->info_2->data; + if ( (key_index = lookup_printerkey( p_data, printerdatakey )) == -1 ) { + /* failure....should never happen if the client has a valid open handle first */ + DEBUG(10,("key_printers_fetch_values: Unknown keyname [%s]\n", printerdatakey)); + if ( printer ) + free_a_printer( &printer, 2 ); + return -1; + } + + num_values = regval_ctr_numvals( p_data->keys[key_index].values ); + for ( i=0; ikeys[key_index].values, i) ); + + +done: + if ( printer ) + free_a_printer( &printer, 2 ); + + return regval_ctr_numvals( values ); +} + +/********************************************************************** + *********************************************************************/ + +#define REG_IDX_ATTRIBUTES 1 +#define REG_IDX_PRIORITY 2 +#define REG_IDX_DEFAULT_PRIORITY 3 +#define REG_IDX_CHANGEID 4 +#define REG_IDX_STATUS 5 +#define REG_IDX_STARTTIME 6 +#define REG_IDX_NAME 7 +#define REG_IDX_LOCATION 8 +#define REG_IDX_DESCRIPTION 9 +#define REG_IDX_PARAMETERS 10 +#define REG_IDX_PORT 12 +#define REG_IDX_SHARENAME 13 +#define REG_IDX_DRIVER 14 +#define REG_IDX_SEP_FILE 15 +#define REG_IDX_PRINTPROC 16 +#define REG_IDX_DATATYPE 17 +#define REG_IDX_DEVMODE 18 +#define REG_IDX_SECDESC 19 +#define REG_IDX_UNTILTIME 20 + +struct { + const char *name; + int index; +} printer_values_map[] = { + { "Attributes", REG_IDX_ATTRIBUTES }, + { "Priority", REG_IDX_PRIORITY }, + { "Default Priority", REG_IDX_DEFAULT_PRIORITY }, + { "ChangeID", REG_IDX_CHANGEID }, + { "Status", REG_IDX_STATUS }, + { "StartTime", REG_IDX_STARTTIME }, + { "UntilTime", REG_IDX_UNTILTIME }, + { "Name", REG_IDX_NAME }, + { "Location", REG_IDX_LOCATION }, + { "Description", REG_IDX_DESCRIPTION }, + { "Parameters", REG_IDX_PARAMETERS }, + { "Port", REG_IDX_PORT }, + { "Share Name", REG_IDX_SHARENAME }, + { "Printer Driver", REG_IDX_DRIVER }, + { "Separator File", REG_IDX_SEP_FILE }, + { "Print Processor", REG_IDX_PRINTPROC }, + { "Datatype", REG_IDX_DATATYPE }, + { "Default Devmode", REG_IDX_DEVMODE }, + { "Security", REG_IDX_SECDESC }, + { NULL, -1 } +}; + + +static int find_valuename_index( const char *valuename ) +{ + int i; + + for ( i=0; printer_values_map[i].name; i++ ) { + if ( strequal( valuename, printer_values_map[i].name ) ) + return printer_values_map[i].index; + } + + return -1; +} + +/********************************************************************** + *********************************************************************/ + +static void convert_values_to_printer_info_2( NT_PRINTER_INFO_LEVEL_2 *printer2, REGVAL_CTR *values ) +{ + int num_values = regval_ctr_numvals( values ); + uint32 value_index; + REGISTRY_VALUE *val; + int i; + + for ( i=0; iattributes = (uint32)(*regval_data_p(val)); + break; + case REG_IDX_PRIORITY: + printer2->priority = (uint32)(*regval_data_p(val)); + break; + case REG_IDX_DEFAULT_PRIORITY: + printer2->default_priority = (uint32)(*regval_data_p(val)); + break; + case REG_IDX_CHANGEID: + printer2->changeid = (uint32)(*regval_data_p(val)); + break; + case REG_IDX_STARTTIME: + printer2->starttime = (uint32)(*regval_data_p(val)); + break; + case REG_IDX_UNTILTIME: + printer2->untiltime = (uint32)(*regval_data_p(val)); + break; + case REG_IDX_NAME: + rpcstr_pull( printer2->printername, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); + break; + case REG_IDX_LOCATION: + rpcstr_pull( printer2->location, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); + break; + case REG_IDX_DESCRIPTION: + rpcstr_pull( printer2->comment, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); + break; + case REG_IDX_PARAMETERS: + rpcstr_pull( printer2->parameters, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); + break; + case REG_IDX_PORT: + rpcstr_pull( printer2->portname, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); + break; + case REG_IDX_SHARENAME: + rpcstr_pull( printer2->sharename, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); + break; + case REG_IDX_DRIVER: + rpcstr_pull( printer2->drivername, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); + break; + case REG_IDX_SEP_FILE: + rpcstr_pull( printer2->sepfile, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); + break; + case REG_IDX_PRINTPROC: + rpcstr_pull( printer2->printprocessor, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); + break; + case REG_IDX_DATATYPE: + rpcstr_pull( printer2->datatype, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); + break; + case REG_IDX_DEVMODE: + break; + case REG_IDX_SECDESC: + break; + default: + /* unsupported value...throw away */ + DEBUG(8,("convert_values_to_printer_info_2: Unsupported registry value [%s]\n", + regval_name( val ) )); + } + } + + return; +} + +/********************************************************************** + *********************************************************************/ + +static bool key_printers_store_values( const char *key, REGVAL_CTR *values ) +{ + char *printers_key; + char *printername, *keyname; + NT_PRINTER_INFO_LEVEL *printer = NULL; + WERROR result; + + printers_key = strip_printers_prefix( key ); + + /* values in the top level key get stored in the registry */ + + if ( !printers_key ) { + /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */ + return regdb_store_values( KEY_WINNT_PRINTERS, values ); + } + + if (!reg_split_path( printers_key, &printername, &keyname )) { + return False; + } + + if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, printername) ) ) + return False; + + /* deal with setting values directly under the printername */ + + if ( !keyname ) { + convert_values_to_printer_info_2( printer->info_2, values ); + } + else { + int num_values = regval_ctr_numvals( values ); + int i; + REGISTRY_VALUE *val; + + delete_printer_key( printer->info_2->data, keyname ); + + /* deal with any subkeys */ + for ( i=0; i[%s]\n", key ? key : "NULL" )); + + keystr = reg_remaining_path(ctx, key + strlen(KEY_ENVIRONMENTS) ); + + /* list all possible architectures */ + + if ( !keystr ) { + for ( num_subkeys=0; environments[num_subkeys]; num_subkeys++ ) + regsubkey_ctr_addkey( subkeys, environments[num_subkeys] ); + + return num_subkeys; + } + + /* we are dealing with a subkey of "Environments */ + key2 = talloc_strdup(ctx, keystr); + if (!key2) { + return -1; + } + keystr = key2; + if (!reg_split_path(keystr, &base, &subkeypath )) { + return -1; + } + + /* sanity check */ + + for ( env_index=0; environments[env_index]; env_index++ ) { + if ( strequal( environments[env_index], base ) ) + break; + } + if ( !environments[env_index] ) + return -1; + + /* ...\Print\Environements\...\ */ + + if ( !subkeypath ) { + regsubkey_ctr_addkey( subkeys, "Drivers" ); + regsubkey_ctr_addkey( subkeys, "Print Processors" ); + + return 2; + } + + /* more of the key path to process */ + + keystr = subkeypath; + if (!reg_split_path( keystr, &base, &subkeypath )) { + return -1; + } + + /* ...\Print\Environements\...\Drivers\ */ + + if ( !subkeypath ) { + if ( strequal(base, "Drivers") ) { + switch ( env_index ) { + case 0: /* Win9x */ + regsubkey_ctr_addkey( subkeys, "Version-0" ); + break; + default: /* Windows NT based systems */ + regsubkey_ctr_addkey( subkeys, "Version-2" ); + regsubkey_ctr_addkey( subkeys, "Version-3" ); + break; + } + + return regsubkey_ctr_numkeys( subkeys ); + } else if ( strequal(base, "Print Processors") ) { + if ( env_index == 1 || env_index == 5 || env_index == 6 ) + + + return regsubkey_ctr_numkeys( subkeys ); + } else + return -1; /* bad path */ + } + + /* we finally get to enumerate the drivers */ + + /* only one possible subkey below PrintProc key */ + + if ( strequal(base, "Print Processors") ) { + keystr = subkeypath; + if (!reg_split_path( keystr, &base, &subkeypath )) { + return -1; + } + + /* no subkeys below this point */ + + if ( subkeypath ) + return -1; + + /* only allow one keyname here -- 'winprint' */ + + return strequal( base, "winprint" ) ? 0 : -1; + } + + /* only dealing with drivers from here on out */ + + keystr = subkeypath; + if (!reg_split_path( keystr, &base, &subkeypath )) { + return -1; + } + + version = atoi(&base[strlen(base)-1]); + + switch (env_index) { + case 0: + if ( version != 0 ) + return -1; + break; + default: + if ( version != 2 && version != 3 ) + return -1; + break; + } + + + if ( !subkeypath ) { + num_drivers = get_ntdrivers( &drivers, environments[env_index], version ); + for ( i=0; idriverpath ); + init_unistr2( &data, filename, UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Driver", REG_SZ, (char*)data.buffer, + data.uni_str_len*sizeof(uint16) ); + + filename = dos_basename( info3->configfile ); + init_unistr2( &data, filename, UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Configuration File", REG_SZ, (char*)data.buffer, + data.uni_str_len*sizeof(uint16) ); + + filename = dos_basename( info3->datafile ); + init_unistr2( &data, filename, UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Data File", REG_SZ, (char*)data.buffer, + data.uni_str_len*sizeof(uint16) ); + + filename = dos_basename( info3->helpfile ); + init_unistr2( &data, filename, UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Help File", REG_SZ, (char*)data.buffer, + data.uni_str_len*sizeof(uint16) ); + + init_unistr2( &data, info3->defaultdatatype, UNI_STR_TERMINATE); + regval_ctr_addvalue( values, "Data Type", REG_SZ, (char*)data.buffer, + data.uni_str_len*sizeof(uint16) ); + + regval_ctr_addvalue( values, "Version", REG_DWORD, (char*)&info3->cversion, + sizeof(info3->cversion) ); + + if ( info3->dependentfiles ) { + /* place the list of dependent files in a single + character buffer, separating each file name by + a NULL */ + + for ( i=0; strcmp(info3->dependentfiles[i], ""); i++ ) { + /* strip the path to only the file's base name */ + + filename = dos_basename( info3->dependentfiles[i] ); + + length = strlen(filename); + + buffer = (char *)SMB_REALLOC( buffer, buffer_size + (length + 1)*sizeof(uint16) ); + if ( !buffer ) { + break; + } + + init_unistr2( &data, filename, UNI_STR_TERMINATE); + memcpy( buffer+buffer_size, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); + + buffer_size += (length + 1)*sizeof(uint16); + } + + /* terminated by double NULL. Add the final one here */ + + buffer = (char *)SMB_REALLOC( buffer, buffer_size + 2 ); + if ( !buffer ) { + buffer_size = 0; + } else { + buffer[buffer_size++] = '\0'; + buffer[buffer_size++] = '\0'; + } + } + + regval_ctr_addvalue( values, "Dependent Files", REG_MULTI_SZ, buffer, buffer_size ); + + SAFE_FREE( buffer ); + + return; +} + +/********************************************************************** + *********************************************************************/ + +static int driver_arch_fetch_values( char *key, REGVAL_CTR *values ) +{ + char *keystr, *base, *subkeypath; + fstring arch_environment; + fstring driver; + int version; + NT_PRINTER_DRIVER_INFO_LEVEL driver_ctr; + WERROR w_result; + + if (!reg_split_path( key, &base, &subkeypath )) { + return -1; + } + + /* no values in 'Environments\Drivers\Windows NT x86' */ + + if ( !subkeypath ) + return 0; + + /* We have the Architecture string and some subkey name: + Currently we only support + * Drivers + * Print Processors + Anything else is an error. + */ + + fstrcpy( arch_environment, base ); + + keystr = subkeypath; + if (!reg_split_path( keystr, &base, &subkeypath )) { + return -1; + } + + if ( strequal(base, "Print Processors") ) + return 0; + + /* only Drivers key can be left */ + + if ( !strequal(base, "Drivers") ) + return -1; + + if ( !subkeypath ) + return 0; + + /* We know that we have Architechure\Drivers with some subkey name + The subkey name has to be Version-XX */ + + keystr = subkeypath; + if (!reg_split_path( keystr, &base, &subkeypath )) { + return -1; + } + + if ( !subkeypath ) + return 0; + + version = atoi(&base[strlen(base)-1]); + + /* BEGIN PRINTER DRIVER NAME BLOCK */ + + keystr = subkeypath; + if (!reg_split_path( keystr, &base, &subkeypath )) { + return -1; + } + + /* don't go any deeper for now */ + + fstrcpy( driver, base ); + + w_result = get_a_printer_driver( &driver_ctr, 3, driver, arch_environment, version ); + + if ( !W_ERROR_IS_OK(w_result) ) + return -1; + + fill_in_driver_values( driver_ctr.info_3, values ); + + free_a_printer_driver( driver_ctr, 3 ); + + /* END PRINTER DRIVER NAME BLOCK */ + + + DEBUG(8,("key_driver_fetch_values: Exit\n")); + + return regval_ctr_numvals( values ); +} + +/********************************************************************** + *********************************************************************/ + +static int key_driver_fetch_values( const char *key, REGVAL_CTR *values ) +{ + char *keystr = NULL; + char *subkey = NULL; + TALLOC_CTX *ctx = talloc_tos(); + + DEBUG(8,("key_driver_fetch_values: Enter key => [%s]\n", key ? key : "NULL")); + + /* no values in the Environments key */ + + if (!(keystr = reg_remaining_path(ctx, key + strlen(KEY_ENVIRONMENTS)))) + return 0; + + subkey = talloc_strdup(ctx, keystr); + if (!subkey) { + return 0; + } + + /* pass off to handle subkeys */ + + return driver_arch_fetch_values( subkey, values ); +} + +/********************************************************************* + ********************************************************************* + ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT" + ********************************************************************* + *********************************************************************/ + +static int key_print_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys ) +{ + int key_len = strlen(key); + + /* no keys below 'Print' handled here */ + + if ( (key_len != strlen(KEY_CONTROL_PRINT)) && (key_len != strlen(KEY_WINNT_PRINT)) ) + return -1; + + regsubkey_ctr_addkey( subkeys, "Environments" ); + regsubkey_ctr_addkey( subkeys, "Monitors" ); + regsubkey_ctr_addkey( subkeys, "Forms" ); + regsubkey_ctr_addkey( subkeys, "Printers" ); + + return regsubkey_ctr_numkeys( subkeys ); +} + +/********************************************************************** + ********************************************************************* + ** Structure to hold dispatch table of ops for various printer keys. + ** Make sure to always store deeper keys along the same path first so + ** we ge a more specific match. + ********************************************************************* + *********************************************************************/ + +static struct reg_dyn_tree print_registry[] = { +/* just pass the monitor onto the registry tdb */ +{ KEY_MONITORS, + ®db_fetch_keys, + ®db_store_keys, + ®db_fetch_values, + ®db_store_values }, +{ KEY_FORMS, + &key_forms_fetch_keys, + NULL, + &key_forms_fetch_values, + NULL }, +{ KEY_CONTROL_PRINTERS, + &key_printers_fetch_keys, + &key_printers_store_keys, + &key_printers_fetch_values, + &key_printers_store_values }, +{ KEY_ENVIRONMENTS, + &key_driver_fetch_keys, + NULL, + &key_driver_fetch_values, + NULL }, +{ KEY_CONTROL_PRINT, + &key_print_fetch_keys, + NULL, + NULL, + NULL }, +{ KEY_WINNT_PRINTERS, + &key_printers_fetch_keys, + &key_printers_store_keys, + &key_printers_fetch_values, + &key_printers_store_values }, +{ KEY_PORTS, + ®db_fetch_keys, + ®db_store_keys, + ®db_fetch_values, + ®db_store_values }, + +{ NULL, NULL, NULL, NULL, NULL } +}; + + +/********************************************************************** + ********************************************************************* + ** Main reg_printing interface functions + ********************************************************************* + *********************************************************************/ + +/*********************************************************************** + Lookup a key in the print_registry table, returning its index. + -1 on failure + **********************************************************************/ + +static int match_registry_path(const char *key) +{ + int i; + char *path = NULL; + TALLOC_CTX *ctx = talloc_tos(); + + if ( !key ) + return -1; + + path = talloc_strdup(ctx, key); + if (!path) { + return -1; + } + path = normalize_reg_path(ctx, path); + if (!path) { + return -1; + } + + for ( i=0; print_registry[i].path; i++ ) { + if (strncmp( path, print_registry[i].path, strlen(print_registry[i].path) ) == 0 ) + return i; + } + + return -1; +} + +/*********************************************************************** + **********************************************************************/ + +static int regprint_fetch_reg_keys( const char *key, REGSUBKEY_CTR *subkeys ) +{ + int i = match_registry_path( key ); + + if ( i == -1 ) + return -1; + + if ( !print_registry[i].fetch_subkeys ) + return -1; + + return print_registry[i].fetch_subkeys( key, subkeys ); +} + +/********************************************************************** + *********************************************************************/ + +static bool regprint_store_reg_keys( const char *key, REGSUBKEY_CTR *subkeys ) +{ + int i = match_registry_path( key ); + + if ( i == -1 ) + return False; + + if ( !print_registry[i].store_subkeys ) + return False; + + return print_registry[i].store_subkeys( key, subkeys ); +} + +/********************************************************************** + *********************************************************************/ + +static int regprint_fetch_reg_values( const char *key, REGVAL_CTR *values ) +{ + int i = match_registry_path( key ); + + if ( i == -1 ) + return -1; + + /* return 0 values by default since we know the key had + to exist because the client opened a handle */ + + if ( !print_registry[i].fetch_values ) + return 0; + + return print_registry[i].fetch_values( key, values ); +} + +/********************************************************************** + *********************************************************************/ + +static bool regprint_store_reg_values( const char *key, REGVAL_CTR *values ) +{ + int i = match_registry_path( key ); + + if ( i == -1 ) + return False; + + if ( !print_registry[i].store_values ) + return False; + + return print_registry[i].store_values( key, values ); +} + +/* + * Table of function pointers for accessing printing data + */ + +REGISTRY_OPS printing_ops = { + .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_printing.c b/source3/registry/reg_printing.c deleted file mode 100644 index a4da103d40..0000000000 --- a/source3/registry/reg_printing.c +++ /dev/null @@ -1,1269 +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 . - */ - -/* Implementation of registry virtual views for printing information */ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_REGISTRY - -/* registrt paths used in the print_registry[] */ - -#define KEY_MONITORS "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/MONITORS" -#define KEY_FORMS "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/FORMS" -#define KEY_CONTROL_PRINTERS "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/PRINTERS" -#define KEY_ENVIRONMENTS "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/ENVIRONMENTS" -#define KEY_CONTROL_PRINT "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT" -#define KEY_WINNT_PRINTERS "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT/PRINTERS" -#define KEY_WINNT_PRINT "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT" -#define KEY_PORTS "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PORTS" - -/* callback table for various registry paths below the ones we service in this module */ - -struct reg_dyn_tree { - /* full key path in normalized form */ - const char *path; - - /* callbscks for fetch/store operations */ - int ( *fetch_subkeys) ( const char *path, REGSUBKEY_CTR *subkeys ); - bool (*store_subkeys) ( const char *path, REGSUBKEY_CTR *subkeys ); - int (*fetch_values) ( const char *path, REGVAL_CTR *values ); - bool (*store_values) ( const char *path, REGVAL_CTR *values ); -}; - -/********************************************************************* - ********************************************************************* - ** Utility Functions - ********************************************************************* - *********************************************************************/ - -/*********************************************************************** - simple function to prune a pathname down to the basename of a file - **********************************************************************/ - -static const char *dos_basename(const char *path) -{ - const char *p; - - if (!(p = strrchr( path, '\\'))) { - p = path; - } else { - p++; - } - - return p; -} - -/********************************************************************* - ********************************************************************* - ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/FORMS" - ********************************************************************* - *********************************************************************/ - -static int key_forms_fetch_keys(const char *key, REGSUBKEY_CTR *subkeys) -{ - char *p = reg_remaining_path(talloc_tos(), key + strlen(KEY_FORMS)); - - /* no keys below Forms */ - - if (p) { - return -1; - } - - return 0; -} - -/********************************************************************** - *********************************************************************/ - -static int key_forms_fetch_values( const char *key, REGVAL_CTR *values ) -{ - uint32 data[8]; - int i, num_values, form_index = 1; - nt_forms_struct *forms_list = NULL; - nt_forms_struct *form; - - DEBUG(10,("print_values_forms: key=>[%s]\n", key ? key : "NULL" )); - - num_values = get_ntforms( &forms_list ); - - DEBUG(10,("hive_forms_fetch_values: [%d] user defined forms returned\n", - num_values)); - - /* handle user defined forms */ - - for ( i=0; iwidth; - data[1] = form->length; - data[2] = form->left; - data[3] = form->top; - data[4] = form->right; - data[5] = form->bottom; - data[6] = form_index++; - data[7] = form->flag; - - regval_ctr_addvalue( values, form->name, REG_BINARY, (char*)data, sizeof(data) ); - } - - SAFE_FREE( forms_list ); - forms_list = NULL; - - /* handle built-on forms */ - - num_values = get_builtin_ntforms( &forms_list ); - - DEBUG(10,("print_subpath_values_forms: [%d] built-in forms returned\n", - num_values)); - - for ( i=0; iwidth; - data[1] = form->length; - data[2] = form->left; - data[3] = form->top; - data[4] = form->right; - data[5] = form->bottom; - data[6] = form_index++; - data[7] = form->flag; - - regval_ctr_addvalue(values, form->name, REG_BINARY, (char*)data, sizeof(data) ); - } - - SAFE_FREE(forms_list); - - return regval_ctr_numvals(values); -} - -/********************************************************************* - ********************************************************************* - ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/PRINTERS" - ** "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT/PRINTERS" - ********************************************************************* - *********************************************************************/ - -/********************************************************************* - strip off prefix for printers key. DOes return a pointer to static - memory. - *********************************************************************/ - -static char *strip_printers_prefix(const char *key) -{ - char *subkeypath = NULL; - char *path = NULL; - TALLOC_CTX *ctx = talloc_tos(); - - path = talloc_strdup(ctx, key); - if (!path) { - return NULL; - } - path = normalize_reg_path(ctx, path); - if (!path) { - return NULL; - } - - /* normalizing the path does not change length, just key delimiters and case */ - - if (strncmp(path, KEY_WINNT_PRINTERS, strlen(KEY_WINNT_PRINTERS)) == 0) { - subkeypath = reg_remaining_path(ctx, key + strlen(KEY_WINNT_PRINTERS)); - } else { - subkeypath = reg_remaining_path(ctx, key + strlen(KEY_CONTROL_PRINTERS)); - } - - TALLOC_FREE(path); - return subkeypath; -} - -/********************************************************************* - *********************************************************************/ - -static int key_printers_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys ) -{ - int n_services = lp_numservices(); - int snum; - fstring sname; - int i; - int num_subkeys = 0; - char *printers_key; - char *printername, *printerdatakey; - NT_PRINTER_INFO_LEVEL *printer = NULL; - fstring *subkey_names = NULL; - - DEBUG(10,("key_printers_fetch_keys: key=>[%s]\n", key ? key : "NULL" )); - - printers_key = strip_printers_prefix( key ); - - if ( !printers_key ) { - /* enumerate all printers */ - - for (snum=0; snum=n_services - || !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) ) - { - return -1; - } - - num_subkeys = get_printer_subkeys( printer->info_2->data, printerdatakey?printerdatakey:"", &subkey_names ); - - for ( i=0; iinfo_2->data, "", &existing_subkeys ); - - for ( i=0; iinfo_2->data, existing_subkeys[i] ); - } - } - - num_subkeys = regsubkey_ctr_numkeys( subkeys ); - for ( i=0; iinfo_2->data, subkeyname) == -1 ) { - DEBUG(5,("key_printers_store_keys: adding key %s\n", - existing_subkeys[i])); - if ( add_new_printer_key( printer->info_2->data, subkeyname ) == -1 ) { - SAFE_FREE( existing_subkeys ); - return False; - } - } - } - - /* write back to disk */ - - mod_a_printer( printer, 2 ); - - /* cleanup */ - - if ( printer ) - free_a_printer( &printer, 2 ); - - SAFE_FREE( existing_subkeys ); - - return True; -} - -/********************************************************************** - *********************************************************************/ - -static void fill_in_printer_values( NT_PRINTER_INFO_LEVEL_2 *info2, REGVAL_CTR *values ) -{ - DEVICEMODE *devmode; - prs_struct prs; - uint32 offset; - UNISTR2 data; - char *p; - uint32 printer_status = PRINTER_STATUS_OK; - - regval_ctr_addvalue( values, "Attributes", REG_DWORD, (char*)&info2->attributes, sizeof(info2->attributes) ); - regval_ctr_addvalue( values, "Priority", REG_DWORD, (char*)&info2->priority, sizeof(info2->attributes) ); - regval_ctr_addvalue( values, "ChangeID", REG_DWORD, (char*)&info2->changeid, sizeof(info2->changeid) ); - regval_ctr_addvalue( values, "Default Priority", REG_DWORD, (char*)&info2->default_priority, sizeof(info2->default_priority) ); - - /* lie and say everything is ok since we don't want to call print_queue_length() to get the real status */ - regval_ctr_addvalue( values, "Status", REG_DWORD, (char*)&printer_status, sizeof(info2->status) ); - - regval_ctr_addvalue( values, "StartTime", REG_DWORD, (char*)&info2->starttime, sizeof(info2->starttime) ); - regval_ctr_addvalue( values, "UntilTime", REG_DWORD, (char*)&info2->untiltime, sizeof(info2->untiltime) ); - - /* strip the \\server\ from this string */ - if ( !(p = strrchr( info2->printername, '\\' ) ) ) - p = info2->printername; - else - p++; - init_unistr2( &data, p, UNI_STR_TERMINATE); - regval_ctr_addvalue( values, "Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - init_unistr2( &data, info2->location, UNI_STR_TERMINATE); - regval_ctr_addvalue( values, "Location", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - init_unistr2( &data, info2->comment, UNI_STR_TERMINATE); - regval_ctr_addvalue( values, "Description", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - init_unistr2( &data, info2->parameters, UNI_STR_TERMINATE); - regval_ctr_addvalue( values, "Parameters", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - init_unistr2( &data, info2->portname, UNI_STR_TERMINATE); - regval_ctr_addvalue( values, "Port", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - init_unistr2( &data, info2->sharename, UNI_STR_TERMINATE); - regval_ctr_addvalue( values, "Share Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - init_unistr2( &data, info2->drivername, UNI_STR_TERMINATE); - regval_ctr_addvalue( values, "Printer Driver", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - init_unistr2( &data, info2->sepfile, UNI_STR_TERMINATE); - regval_ctr_addvalue( values, "Separator File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - init_unistr2( &data, "WinPrint", UNI_STR_TERMINATE); - regval_ctr_addvalue( values, "Print Processor", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - init_unistr2( &data, "RAW", UNI_STR_TERMINATE); - regval_ctr_addvalue( values, "Datatype", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - - /* use a prs_struct for converting the devmode and security - descriptor to REG_BINARY */ - - prs_init( &prs, RPC_MAX_PDU_FRAG_LEN, values, MARSHALL); - - /* stream the device mode */ - - if ( (devmode = construct_dev_mode( info2->sharename )) != NULL ) { - if ( spoolss_io_devmode( "devmode", &prs, 0, devmode ) ) { - offset = prs_offset( &prs ); - regval_ctr_addvalue( values, "Default Devmode", REG_BINARY, prs_data_p(&prs), offset ); - } - } - - prs_mem_clear( &prs ); - prs_set_offset( &prs, 0 ); - - /* stream the printer security descriptor */ - - if ( info2->secdesc_buf && - info2->secdesc_buf->sd && - info2->secdesc_buf->sd_size ) - { - if ( sec_io_desc("sec_desc", &info2->secdesc_buf->sd, &prs, 0 ) ) { - offset = prs_offset( &prs ); - regval_ctr_addvalue( values, "Security", REG_BINARY, prs_data_p(&prs), offset ); - } - } - - prs_mem_free( &prs ); - - return; -} - -/********************************************************************** - *********************************************************************/ - -static int key_printers_fetch_values( const char *key, REGVAL_CTR *values ) -{ - int num_values; - char *printers_key; - char *printername, *printerdatakey; - NT_PRINTER_INFO_LEVEL *printer = NULL; - NT_PRINTER_DATA *p_data; - int i, key_index; - - printers_key = strip_printers_prefix( key ); - - /* top level key values stored in the registry has no values */ - - if ( !printers_key ) { - /* normalize to the 'HKLM\SOFTWARE\...\Print\Printers' key */ - return regdb_fetch_values( KEY_WINNT_PRINTERS, values ); - } - - /* lookup the printer object */ - - if (!reg_split_path( printers_key, &printername, &printerdatakey )) { - return -1; - } - - if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) ) - goto done; - - if ( !printerdatakey ) { - fill_in_printer_values( printer->info_2, values ); - goto done; - } - - /* iterate over all printer data keys and fill the regval container */ - - p_data = printer->info_2->data; - if ( (key_index = lookup_printerkey( p_data, printerdatakey )) == -1 ) { - /* failure....should never happen if the client has a valid open handle first */ - DEBUG(10,("key_printers_fetch_values: Unknown keyname [%s]\n", printerdatakey)); - if ( printer ) - free_a_printer( &printer, 2 ); - return -1; - } - - num_values = regval_ctr_numvals( p_data->keys[key_index].values ); - for ( i=0; ikeys[key_index].values, i) ); - - -done: - if ( printer ) - free_a_printer( &printer, 2 ); - - return regval_ctr_numvals( values ); -} - -/********************************************************************** - *********************************************************************/ - -#define REG_IDX_ATTRIBUTES 1 -#define REG_IDX_PRIORITY 2 -#define REG_IDX_DEFAULT_PRIORITY 3 -#define REG_IDX_CHANGEID 4 -#define REG_IDX_STATUS 5 -#define REG_IDX_STARTTIME 6 -#define REG_IDX_NAME 7 -#define REG_IDX_LOCATION 8 -#define REG_IDX_DESCRIPTION 9 -#define REG_IDX_PARAMETERS 10 -#define REG_IDX_PORT 12 -#define REG_IDX_SHARENAME 13 -#define REG_IDX_DRIVER 14 -#define REG_IDX_SEP_FILE 15 -#define REG_IDX_PRINTPROC 16 -#define REG_IDX_DATATYPE 17 -#define REG_IDX_DEVMODE 18 -#define REG_IDX_SECDESC 19 -#define REG_IDX_UNTILTIME 20 - -struct { - const char *name; - int index; -} printer_values_map[] = { - { "Attributes", REG_IDX_ATTRIBUTES }, - { "Priority", REG_IDX_PRIORITY }, - { "Default Priority", REG_IDX_DEFAULT_PRIORITY }, - { "ChangeID", REG_IDX_CHANGEID }, - { "Status", REG_IDX_STATUS }, - { "StartTime", REG_IDX_STARTTIME }, - { "UntilTime", REG_IDX_UNTILTIME }, - { "Name", REG_IDX_NAME }, - { "Location", REG_IDX_LOCATION }, - { "Description", REG_IDX_DESCRIPTION }, - { "Parameters", REG_IDX_PARAMETERS }, - { "Port", REG_IDX_PORT }, - { "Share Name", REG_IDX_SHARENAME }, - { "Printer Driver", REG_IDX_DRIVER }, - { "Separator File", REG_IDX_SEP_FILE }, - { "Print Processor", REG_IDX_PRINTPROC }, - { "Datatype", REG_IDX_DATATYPE }, - { "Default Devmode", REG_IDX_DEVMODE }, - { "Security", REG_IDX_SECDESC }, - { NULL, -1 } -}; - - -static int find_valuename_index( const char *valuename ) -{ - int i; - - for ( i=0; printer_values_map[i].name; i++ ) { - if ( strequal( valuename, printer_values_map[i].name ) ) - return printer_values_map[i].index; - } - - return -1; -} - -/********************************************************************** - *********************************************************************/ - -static void convert_values_to_printer_info_2( NT_PRINTER_INFO_LEVEL_2 *printer2, REGVAL_CTR *values ) -{ - int num_values = regval_ctr_numvals( values ); - uint32 value_index; - REGISTRY_VALUE *val; - int i; - - for ( i=0; iattributes = (uint32)(*regval_data_p(val)); - break; - case REG_IDX_PRIORITY: - printer2->priority = (uint32)(*regval_data_p(val)); - break; - case REG_IDX_DEFAULT_PRIORITY: - printer2->default_priority = (uint32)(*regval_data_p(val)); - break; - case REG_IDX_CHANGEID: - printer2->changeid = (uint32)(*regval_data_p(val)); - break; - case REG_IDX_STARTTIME: - printer2->starttime = (uint32)(*regval_data_p(val)); - break; - case REG_IDX_UNTILTIME: - printer2->untiltime = (uint32)(*regval_data_p(val)); - break; - case REG_IDX_NAME: - rpcstr_pull( printer2->printername, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); - break; - case REG_IDX_LOCATION: - rpcstr_pull( printer2->location, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); - break; - case REG_IDX_DESCRIPTION: - rpcstr_pull( printer2->comment, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); - break; - case REG_IDX_PARAMETERS: - rpcstr_pull( printer2->parameters, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); - break; - case REG_IDX_PORT: - rpcstr_pull( printer2->portname, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); - break; - case REG_IDX_SHARENAME: - rpcstr_pull( printer2->sharename, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); - break; - case REG_IDX_DRIVER: - rpcstr_pull( printer2->drivername, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); - break; - case REG_IDX_SEP_FILE: - rpcstr_pull( printer2->sepfile, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); - break; - case REG_IDX_PRINTPROC: - rpcstr_pull( printer2->printprocessor, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); - break; - case REG_IDX_DATATYPE: - rpcstr_pull( printer2->datatype, regval_data_p(val), sizeof(fstring), regval_size(val), 0 ); - break; - case REG_IDX_DEVMODE: - break; - case REG_IDX_SECDESC: - break; - default: - /* unsupported value...throw away */ - DEBUG(8,("convert_values_to_printer_info_2: Unsupported registry value [%s]\n", - regval_name( val ) )); - } - } - - return; -} - -/********************************************************************** - *********************************************************************/ - -static bool key_printers_store_values( const char *key, REGVAL_CTR *values ) -{ - char *printers_key; - char *printername, *keyname; - NT_PRINTER_INFO_LEVEL *printer = NULL; - WERROR result; - - printers_key = strip_printers_prefix( key ); - - /* values in the top level key get stored in the registry */ - - if ( !printers_key ) { - /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */ - return regdb_store_values( KEY_WINNT_PRINTERS, values ); - } - - if (!reg_split_path( printers_key, &printername, &keyname )) { - return False; - } - - if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, printername) ) ) - return False; - - /* deal with setting values directly under the printername */ - - if ( !keyname ) { - convert_values_to_printer_info_2( printer->info_2, values ); - } - else { - int num_values = regval_ctr_numvals( values ); - int i; - REGISTRY_VALUE *val; - - delete_printer_key( printer->info_2->data, keyname ); - - /* deal with any subkeys */ - for ( i=0; i[%s]\n", key ? key : "NULL" )); - - keystr = reg_remaining_path(ctx, key + strlen(KEY_ENVIRONMENTS) ); - - /* list all possible architectures */ - - if ( !keystr ) { - for ( num_subkeys=0; environments[num_subkeys]; num_subkeys++ ) - regsubkey_ctr_addkey( subkeys, environments[num_subkeys] ); - - return num_subkeys; - } - - /* we are dealing with a subkey of "Environments */ - key2 = talloc_strdup(ctx, keystr); - if (!key2) { - return -1; - } - keystr = key2; - if (!reg_split_path(keystr, &base, &subkeypath )) { - return -1; - } - - /* sanity check */ - - for ( env_index=0; environments[env_index]; env_index++ ) { - if ( strequal( environments[env_index], base ) ) - break; - } - if ( !environments[env_index] ) - return -1; - - /* ...\Print\Environements\...\ */ - - if ( !subkeypath ) { - regsubkey_ctr_addkey( subkeys, "Drivers" ); - regsubkey_ctr_addkey( subkeys, "Print Processors" ); - - return 2; - } - - /* more of the key path to process */ - - keystr = subkeypath; - if (!reg_split_path( keystr, &base, &subkeypath )) { - return -1; - } - - /* ...\Print\Environements\...\Drivers\ */ - - if ( !subkeypath ) { - if ( strequal(base, "Drivers") ) { - switch ( env_index ) { - case 0: /* Win9x */ - regsubkey_ctr_addkey( subkeys, "Version-0" ); - break; - default: /* Windows NT based systems */ - regsubkey_ctr_addkey( subkeys, "Version-2" ); - regsubkey_ctr_addkey( subkeys, "Version-3" ); - break; - } - - return regsubkey_ctr_numkeys( subkeys ); - } else if ( strequal(base, "Print Processors") ) { - if ( env_index == 1 || env_index == 5 || env_index == 6 ) - - - return regsubkey_ctr_numkeys( subkeys ); - } else - return -1; /* bad path */ - } - - /* we finally get to enumerate the drivers */ - - /* only one possible subkey below PrintProc key */ - - if ( strequal(base, "Print Processors") ) { - keystr = subkeypath; - if (!reg_split_path( keystr, &base, &subkeypath )) { - return -1; - } - - /* no subkeys below this point */ - - if ( subkeypath ) - return -1; - - /* only allow one keyname here -- 'winprint' */ - - return strequal( base, "winprint" ) ? 0 : -1; - } - - /* only dealing with drivers from here on out */ - - keystr = subkeypath; - if (!reg_split_path( keystr, &base, &subkeypath )) { - return -1; - } - - version = atoi(&base[strlen(base)-1]); - - switch (env_index) { - case 0: - if ( version != 0 ) - return -1; - break; - default: - if ( version != 2 && version != 3 ) - return -1; - break; - } - - - if ( !subkeypath ) { - num_drivers = get_ntdrivers( &drivers, environments[env_index], version ); - for ( i=0; idriverpath ); - init_unistr2( &data, filename, UNI_STR_TERMINATE); - regval_ctr_addvalue( values, "Driver", REG_SZ, (char*)data.buffer, - data.uni_str_len*sizeof(uint16) ); - - filename = dos_basename( info3->configfile ); - init_unistr2( &data, filename, UNI_STR_TERMINATE); - regval_ctr_addvalue( values, "Configuration File", REG_SZ, (char*)data.buffer, - data.uni_str_len*sizeof(uint16) ); - - filename = dos_basename( info3->datafile ); - init_unistr2( &data, filename, UNI_STR_TERMINATE); - regval_ctr_addvalue( values, "Data File", REG_SZ, (char*)data.buffer, - data.uni_str_len*sizeof(uint16) ); - - filename = dos_basename( info3->helpfile ); - init_unistr2( &data, filename, UNI_STR_TERMINATE); - regval_ctr_addvalue( values, "Help File", REG_SZ, (char*)data.buffer, - data.uni_str_len*sizeof(uint16) ); - - init_unistr2( &data, info3->defaultdatatype, UNI_STR_TERMINATE); - regval_ctr_addvalue( values, "Data Type", REG_SZ, (char*)data.buffer, - data.uni_str_len*sizeof(uint16) ); - - regval_ctr_addvalue( values, "Version", REG_DWORD, (char*)&info3->cversion, - sizeof(info3->cversion) ); - - if ( info3->dependentfiles ) { - /* place the list of dependent files in a single - character buffer, separating each file name by - a NULL */ - - for ( i=0; strcmp(info3->dependentfiles[i], ""); i++ ) { - /* strip the path to only the file's base name */ - - filename = dos_basename( info3->dependentfiles[i] ); - - length = strlen(filename); - - buffer = (char *)SMB_REALLOC( buffer, buffer_size + (length + 1)*sizeof(uint16) ); - if ( !buffer ) { - break; - } - - init_unistr2( &data, filename, UNI_STR_TERMINATE); - memcpy( buffer+buffer_size, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); - - buffer_size += (length + 1)*sizeof(uint16); - } - - /* terminated by double NULL. Add the final one here */ - - buffer = (char *)SMB_REALLOC( buffer, buffer_size + 2 ); - if ( !buffer ) { - buffer_size = 0; - } else { - buffer[buffer_size++] = '\0'; - buffer[buffer_size++] = '\0'; - } - } - - regval_ctr_addvalue( values, "Dependent Files", REG_MULTI_SZ, buffer, buffer_size ); - - SAFE_FREE( buffer ); - - return; -} - -/********************************************************************** - *********************************************************************/ - -static int driver_arch_fetch_values( char *key, REGVAL_CTR *values ) -{ - char *keystr, *base, *subkeypath; - fstring arch_environment; - fstring driver; - int version; - NT_PRINTER_DRIVER_INFO_LEVEL driver_ctr; - WERROR w_result; - - if (!reg_split_path( key, &base, &subkeypath )) { - return -1; - } - - /* no values in 'Environments\Drivers\Windows NT x86' */ - - if ( !subkeypath ) - return 0; - - /* We have the Architecture string and some subkey name: - Currently we only support - * Drivers - * Print Processors - Anything else is an error. - */ - - fstrcpy( arch_environment, base ); - - keystr = subkeypath; - if (!reg_split_path( keystr, &base, &subkeypath )) { - return -1; - } - - if ( strequal(base, "Print Processors") ) - return 0; - - /* only Drivers key can be left */ - - if ( !strequal(base, "Drivers") ) - return -1; - - if ( !subkeypath ) - return 0; - - /* We know that we have Architechure\Drivers with some subkey name - The subkey name has to be Version-XX */ - - keystr = subkeypath; - if (!reg_split_path( keystr, &base, &subkeypath )) { - return -1; - } - - if ( !subkeypath ) - return 0; - - version = atoi(&base[strlen(base)-1]); - - /* BEGIN PRINTER DRIVER NAME BLOCK */ - - keystr = subkeypath; - if (!reg_split_path( keystr, &base, &subkeypath )) { - return -1; - } - - /* don't go any deeper for now */ - - fstrcpy( driver, base ); - - w_result = get_a_printer_driver( &driver_ctr, 3, driver, arch_environment, version ); - - if ( !W_ERROR_IS_OK(w_result) ) - return -1; - - fill_in_driver_values( driver_ctr.info_3, values ); - - free_a_printer_driver( driver_ctr, 3 ); - - /* END PRINTER DRIVER NAME BLOCK */ - - - DEBUG(8,("key_driver_fetch_values: Exit\n")); - - return regval_ctr_numvals( values ); -} - -/********************************************************************** - *********************************************************************/ - -static int key_driver_fetch_values( const char *key, REGVAL_CTR *values ) -{ - char *keystr = NULL; - char *subkey = NULL; - TALLOC_CTX *ctx = talloc_tos(); - - DEBUG(8,("key_driver_fetch_values: Enter key => [%s]\n", key ? key : "NULL")); - - /* no values in the Environments key */ - - if (!(keystr = reg_remaining_path(ctx, key + strlen(KEY_ENVIRONMENTS)))) - return 0; - - subkey = talloc_strdup(ctx, keystr); - if (!subkey) { - return 0; - } - - /* pass off to handle subkeys */ - - return driver_arch_fetch_values( subkey, values ); -} - -/********************************************************************* - ********************************************************************* - ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT" - ********************************************************************* - *********************************************************************/ - -static int key_print_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys ) -{ - int key_len = strlen(key); - - /* no keys below 'Print' handled here */ - - if ( (key_len != strlen(KEY_CONTROL_PRINT)) && (key_len != strlen(KEY_WINNT_PRINT)) ) - return -1; - - regsubkey_ctr_addkey( subkeys, "Environments" ); - regsubkey_ctr_addkey( subkeys, "Monitors" ); - regsubkey_ctr_addkey( subkeys, "Forms" ); - regsubkey_ctr_addkey( subkeys, "Printers" ); - - return regsubkey_ctr_numkeys( subkeys ); -} - -/********************************************************************** - ********************************************************************* - ** Structure to hold dispatch table of ops for various printer keys. - ** Make sure to always store deeper keys along the same path first so - ** we ge a more specific match. - ********************************************************************* - *********************************************************************/ - -static struct reg_dyn_tree print_registry[] = { -/* just pass the monitor onto the registry tdb */ -{ KEY_MONITORS, - ®db_fetch_keys, - ®db_store_keys, - ®db_fetch_values, - ®db_store_values }, -{ KEY_FORMS, - &key_forms_fetch_keys, - NULL, - &key_forms_fetch_values, - NULL }, -{ KEY_CONTROL_PRINTERS, - &key_printers_fetch_keys, - &key_printers_store_keys, - &key_printers_fetch_values, - &key_printers_store_values }, -{ KEY_ENVIRONMENTS, - &key_driver_fetch_keys, - NULL, - &key_driver_fetch_values, - NULL }, -{ KEY_CONTROL_PRINT, - &key_print_fetch_keys, - NULL, - NULL, - NULL }, -{ KEY_WINNT_PRINTERS, - &key_printers_fetch_keys, - &key_printers_store_keys, - &key_printers_fetch_values, - &key_printers_store_values }, -{ KEY_PORTS, - ®db_fetch_keys, - ®db_store_keys, - ®db_fetch_values, - ®db_store_values }, - -{ NULL, NULL, NULL, NULL, NULL } -}; - - -/********************************************************************** - ********************************************************************* - ** Main reg_printing interface functions - ********************************************************************* - *********************************************************************/ - -/*********************************************************************** - Lookup a key in the print_registry table, returning its index. - -1 on failure - **********************************************************************/ - -static int match_registry_path(const char *key) -{ - int i; - char *path = NULL; - TALLOC_CTX *ctx = talloc_tos(); - - if ( !key ) - return -1; - - path = talloc_strdup(ctx, key); - if (!path) { - return -1; - } - path = normalize_reg_path(ctx, path); - if (!path) { - return -1; - } - - for ( i=0; print_registry[i].path; i++ ) { - if (strncmp( path, print_registry[i].path, strlen(print_registry[i].path) ) == 0 ) - return i; - } - - return -1; -} - -/*********************************************************************** - **********************************************************************/ - -static int regprint_fetch_reg_keys( const char *key, REGSUBKEY_CTR *subkeys ) -{ - int i = match_registry_path( key ); - - if ( i == -1 ) - return -1; - - if ( !print_registry[i].fetch_subkeys ) - return -1; - - return print_registry[i].fetch_subkeys( key, subkeys ); -} - -/********************************************************************** - *********************************************************************/ - -static bool regprint_store_reg_keys( const char *key, REGSUBKEY_CTR *subkeys ) -{ - int i = match_registry_path( key ); - - if ( i == -1 ) - return False; - - if ( !print_registry[i].store_subkeys ) - return False; - - return print_registry[i].store_subkeys( key, subkeys ); -} - -/********************************************************************** - *********************************************************************/ - -static int regprint_fetch_reg_values( const char *key, REGVAL_CTR *values ) -{ - int i = match_registry_path( key ); - - if ( i == -1 ) - return -1; - - /* return 0 values by default since we know the key had - to exist because the client opened a handle */ - - if ( !print_registry[i].fetch_values ) - return 0; - - return print_registry[i].fetch_values( key, values ); -} - -/********************************************************************** - *********************************************************************/ - -static bool regprint_store_reg_values( const char *key, REGVAL_CTR *values ) -{ - int i = match_registry_path( key ); - - if ( i == -1 ) - return False; - - if ( !print_registry[i].store_values ) - return False; - - return print_registry[i].store_values( key, values ); -} - -/* - * Table of function pointers for accessing printing data - */ - -REGISTRY_OPS printing_ops = { - .fetch_subkeys = regprint_fetch_reg_keys, - .fetch_values = regprint_fetch_reg_values, - .store_subkeys = regprint_store_reg_keys, - .store_values = regprint_store_reg_values, -}; -- cgit From 4ccee0dc0cd6cacc6e1ed57eb2a7e3993ec81748 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 21 Jan 2008 00:07:41 +0100 Subject: Rename reg_smbconf.c to reg_backend_smbconf.c Michael (This used to be commit b85e5ee45075211dd3ab85ac79c2d856187d5e3e) --- source3/registry/reg_backend_smbconf.c | 275 +++++++++++++++++++++++++++++++++ source3/registry/reg_smbconf.c | 275 --------------------------------- 2 files changed, 275 insertions(+), 275 deletions(-) create mode 100644 source3/registry/reg_backend_smbconf.c delete mode 100644 source3/registry/reg_smbconf.c (limited to 'source3/registry') diff --git a/source3/registry/reg_backend_smbconf.c b/source3/registry/reg_backend_smbconf.c new file mode 100644 index 0000000000..a6e478200f --- /dev/null +++ b/source3/registry/reg_backend_smbconf.c @@ -0,0 +1,275 @@ +/* + * Unix SMB/CIFS implementation. + * Virtual Windows Registry Layer + * Copyright (C) Volker Lendecke 2006 + * 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 . + */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_REGISTRY + +extern REGISTRY_OPS regdb_ops; /* these are the default */ + +static int smbconf_fetch_keys( const char *key, REGSUBKEY_CTR *subkey_ctr ) +{ + return regdb_ops.fetch_subkeys(key, subkey_ctr); +} + +static bool smbconf_store_keys( const char *key, REGSUBKEY_CTR *subkeys ) +{ + return regdb_ops.store_subkeys(key, subkeys); +} + +static int smbconf_fetch_values( const char *key, REGVAL_CTR *val ) +{ + return regdb_ops.fetch_values(key, val); +} + +static WERROR regval_hilvl_to_lolvl(TALLOC_CTX *mem_ctx, const char *valname, + struct registry_value *src, + REGISTRY_VALUE **dst) +{ + WERROR err; + DATA_BLOB value_data; + REGISTRY_VALUE *newval = NULL; + + if (dst == NULL) { + return WERR_INVALID_PARAM; + } + + err = registry_push_value(mem_ctx, src, &value_data); + if (!W_ERROR_IS_OK(err)) { + DEBUG(10, ("error calling registry_push_value.\n")); + return err; + } + + newval = regval_compose(mem_ctx, valname, src->type, + (char *)value_data.data, value_data.length); + if (newval == NULL) { + DEBUG(10, ("error composing registry value. (no memory?)\n")); + return WERR_NOMEM; + } + + *dst = newval; + return WERR_OK; +} + +static WERROR regval_lolvl_to_hilvl(TALLOC_CTX *mem_ctx, REGISTRY_VALUE *src, + struct registry_value **dst) +{ + if (dst == NULL) { + return WERR_INVALID_PARAM; + } + + return registry_pull_value(mem_ctx, dst, regval_type(src), + regval_data_p(src), regval_size(src), + regval_size(src)); +} + +/* + * Utility function used by smbconf_store_values to canonicalize + * a registry value. + * registry_pull_value / registry_push_value are used for (un)marshalling. + */ +static REGISTRY_VALUE *smbconf_canonicalize_regval(TALLOC_CTX *mem_ctx, + REGISTRY_VALUE *theval) +{ + char *valstr; + size_t len; + const char *canon_valname; + const char *canon_valstr; + bool inverse; + struct registry_value *value; + WERROR err; + TALLOC_CTX *tmp_ctx; + REGISTRY_VALUE *newval = NULL; + + if (!lp_parameter_is_valid(regval_name(theval)) || + lp_parameter_is_canonical(regval_name(theval))) + { + return theval; + } + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + DEBUG(1, ("out of memory...\n")); + goto done; + } + + err = regval_lolvl_to_hilvl(tmp_ctx, theval, &value); + if (!W_ERROR_IS_OK(err)) { + goto done; + } + + /* we need the value-string zero-terminated */ + valstr = value->v.sz.str; + len = value->v.sz.len; + if (valstr[len - 1] != '\0') { + DEBUG(10, ("string is not '\\0'-terminated. adding '\\0'.\n")); + valstr = TALLOC_REALLOC_ARRAY(tmp_ctx, valstr, char, len + 1); + if (valstr == NULL) { + DEBUG(1, ("out of memory\n")); + goto done; + } + valstr[len] = '\0'; + } + + if (!lp_canonicalize_parameter(regval_name(theval), &canon_valname, + &inverse)) + { + DEBUG(5, ("Error: lp_canonicalize_parameter failed after " + "lp_parameter_is_valid. This should not happen!\n")); + goto done; + } + DEBUG(10, ("old value name: '%s', canonical value name: '%s'\n", + regval_name(theval), canon_valname)); + if (inverse && lp_string_is_valid_boolean(valstr)) { + lp_invert_boolean(valstr, &canon_valstr); + } else { + canon_valstr = valstr; + } + + ZERO_STRUCTP(value); + value->type = REG_SZ; + value->v.sz.str = CONST_DISCARD(char *, canon_valstr); + value->v.sz.len = strlen(canon_valstr) + 1; + + err = regval_hilvl_to_lolvl(mem_ctx, canon_valname, value, &newval); + if (!W_ERROR_IS_OK(err)) { + DEBUG(10, ("error calling regval_hilvl_to_lolvl.\n")); + goto done; + } + +done: + TALLOC_FREE(tmp_ctx); + return newval; +} + +static bool smbconf_store_values( const char *key, REGVAL_CTR *val ) +{ + int i; + int num_values = regval_ctr_numvals(val); + REGVAL_CTR *new_val_ctr; + + /* + * we build a second regval container and copy over the values, + * possibly changing names to the canonical name, because when + * canonicalizing parameter names and replacing the original parameter + * (with reval_ctr_deletevalue and regval_ctr_addvalue) in the original + * container, the order would change and that is not so good in the + * "for" loop... :-o + */ + new_val_ctr = TALLOC_ZERO_P(val, REGVAL_CTR); + if (new_val_ctr == NULL) { + DEBUG(1, ("out of memory\n")); + return False; + } + + for (i=0; i < num_values; i++) { + REGISTRY_VALUE *theval = regval_ctr_specific_value(val, i); + const char *valname = regval_name(theval); + int res; + + DEBUG(10, ("inspecting value '%s'\n", valname)); + + /* unfortunately, we can not reject names that are not + * valid parameter names here, since e.g. regedit first + * creates values as "New Value #1" and so on and then + * drops into rename. */ + + if (regval_type(theval) != REG_SZ) { + DEBUG(1, ("smbconf_store_values: only registry value " + "type REG_SZ currently allowed under key " + "smbconf\n")); + return False; + } + + if (registry_smbconf_valname_forbidden(valname)) { + DEBUG(1, ("smbconf_store_values: value '%s' forbidden " + "in registry.\n", valname)); + return False; + } + + if (lp_parameter_is_valid(valname) && + !lp_parameter_is_canonical(valname)) + { + DEBUG(5, ("valid parameter '%s' given but it is a " + "synonym. going to canonicalize it.\n", + valname)); + theval = smbconf_canonicalize_regval(val, theval); + if (theval == NULL) { + DEBUG(10, ("error canonicalizing registry " + "value\n")); + return False; + } + } else { + DEBUG(10, ("%s parameter found, " + "copying it to new container...\n", + (lp_parameter_is_valid(valname)? + "valid":"unknown"))); + } + res = regval_ctr_copyvalue(new_val_ctr, theval); + if (res == 0) { + DEBUG(10, ("error calling regval_ctr_copyvalue. " + "(no memory?)\n")); + return False; + } + DEBUG(10, ("parameter copied. container now has %d values.\n", + res)); + } + return regdb_ops.store_values(key, new_val_ctr); +} + +static bool smbconf_reg_access_check(const char *keyname, uint32 requested, + uint32 *granted, + const struct nt_user_token *token) +{ + if (!(user_has_privileges(token, &se_disk_operators))) { + return False; + } + + *granted = REG_KEY_ALL; + return True; +} + +static WERROR smbconf_get_secdesc(TALLOC_CTX *mem_ctx, const char *key, + struct security_descriptor **psecdesc) +{ + return regdb_ops.get_secdesc(mem_ctx, key, psecdesc); +} + +static WERROR smbconf_set_secdesc(const char *key, + struct security_descriptor *secdesc) +{ + return regdb_ops.set_secdesc(key, secdesc); +} + + +/* + * Table of function pointers for accessing smb.conf data + */ + +REGISTRY_OPS smbconf_reg_ops = { + .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_smbconf.c b/source3/registry/reg_smbconf.c deleted file mode 100644 index a6e478200f..0000000000 --- a/source3/registry/reg_smbconf.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * Virtual Windows Registry Layer - * Copyright (C) Volker Lendecke 2006 - * 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 . - */ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_REGISTRY - -extern REGISTRY_OPS regdb_ops; /* these are the default */ - -static int smbconf_fetch_keys( const char *key, REGSUBKEY_CTR *subkey_ctr ) -{ - return regdb_ops.fetch_subkeys(key, subkey_ctr); -} - -static bool smbconf_store_keys( const char *key, REGSUBKEY_CTR *subkeys ) -{ - return regdb_ops.store_subkeys(key, subkeys); -} - -static int smbconf_fetch_values( const char *key, REGVAL_CTR *val ) -{ - return regdb_ops.fetch_values(key, val); -} - -static WERROR regval_hilvl_to_lolvl(TALLOC_CTX *mem_ctx, const char *valname, - struct registry_value *src, - REGISTRY_VALUE **dst) -{ - WERROR err; - DATA_BLOB value_data; - REGISTRY_VALUE *newval = NULL; - - if (dst == NULL) { - return WERR_INVALID_PARAM; - } - - err = registry_push_value(mem_ctx, src, &value_data); - if (!W_ERROR_IS_OK(err)) { - DEBUG(10, ("error calling registry_push_value.\n")); - return err; - } - - newval = regval_compose(mem_ctx, valname, src->type, - (char *)value_data.data, value_data.length); - if (newval == NULL) { - DEBUG(10, ("error composing registry value. (no memory?)\n")); - return WERR_NOMEM; - } - - *dst = newval; - return WERR_OK; -} - -static WERROR regval_lolvl_to_hilvl(TALLOC_CTX *mem_ctx, REGISTRY_VALUE *src, - struct registry_value **dst) -{ - if (dst == NULL) { - return WERR_INVALID_PARAM; - } - - return registry_pull_value(mem_ctx, dst, regval_type(src), - regval_data_p(src), regval_size(src), - regval_size(src)); -} - -/* - * Utility function used by smbconf_store_values to canonicalize - * a registry value. - * registry_pull_value / registry_push_value are used for (un)marshalling. - */ -static REGISTRY_VALUE *smbconf_canonicalize_regval(TALLOC_CTX *mem_ctx, - REGISTRY_VALUE *theval) -{ - char *valstr; - size_t len; - const char *canon_valname; - const char *canon_valstr; - bool inverse; - struct registry_value *value; - WERROR err; - TALLOC_CTX *tmp_ctx; - REGISTRY_VALUE *newval = NULL; - - if (!lp_parameter_is_valid(regval_name(theval)) || - lp_parameter_is_canonical(regval_name(theval))) - { - return theval; - } - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - DEBUG(1, ("out of memory...\n")); - goto done; - } - - err = regval_lolvl_to_hilvl(tmp_ctx, theval, &value); - if (!W_ERROR_IS_OK(err)) { - goto done; - } - - /* we need the value-string zero-terminated */ - valstr = value->v.sz.str; - len = value->v.sz.len; - if (valstr[len - 1] != '\0') { - DEBUG(10, ("string is not '\\0'-terminated. adding '\\0'.\n")); - valstr = TALLOC_REALLOC_ARRAY(tmp_ctx, valstr, char, len + 1); - if (valstr == NULL) { - DEBUG(1, ("out of memory\n")); - goto done; - } - valstr[len] = '\0'; - } - - if (!lp_canonicalize_parameter(regval_name(theval), &canon_valname, - &inverse)) - { - DEBUG(5, ("Error: lp_canonicalize_parameter failed after " - "lp_parameter_is_valid. This should not happen!\n")); - goto done; - } - DEBUG(10, ("old value name: '%s', canonical value name: '%s'\n", - regval_name(theval), canon_valname)); - if (inverse && lp_string_is_valid_boolean(valstr)) { - lp_invert_boolean(valstr, &canon_valstr); - } else { - canon_valstr = valstr; - } - - ZERO_STRUCTP(value); - value->type = REG_SZ; - value->v.sz.str = CONST_DISCARD(char *, canon_valstr); - value->v.sz.len = strlen(canon_valstr) + 1; - - err = regval_hilvl_to_lolvl(mem_ctx, canon_valname, value, &newval); - if (!W_ERROR_IS_OK(err)) { - DEBUG(10, ("error calling regval_hilvl_to_lolvl.\n")); - goto done; - } - -done: - TALLOC_FREE(tmp_ctx); - return newval; -} - -static bool smbconf_store_values( const char *key, REGVAL_CTR *val ) -{ - int i; - int num_values = regval_ctr_numvals(val); - REGVAL_CTR *new_val_ctr; - - /* - * we build a second regval container and copy over the values, - * possibly changing names to the canonical name, because when - * canonicalizing parameter names and replacing the original parameter - * (with reval_ctr_deletevalue and regval_ctr_addvalue) in the original - * container, the order would change and that is not so good in the - * "for" loop... :-o - */ - new_val_ctr = TALLOC_ZERO_P(val, REGVAL_CTR); - if (new_val_ctr == NULL) { - DEBUG(1, ("out of memory\n")); - return False; - } - - for (i=0; i < num_values; i++) { - REGISTRY_VALUE *theval = regval_ctr_specific_value(val, i); - const char *valname = regval_name(theval); - int res; - - DEBUG(10, ("inspecting value '%s'\n", valname)); - - /* unfortunately, we can not reject names that are not - * valid parameter names here, since e.g. regedit first - * creates values as "New Value #1" and so on and then - * drops into rename. */ - - if (regval_type(theval) != REG_SZ) { - DEBUG(1, ("smbconf_store_values: only registry value " - "type REG_SZ currently allowed under key " - "smbconf\n")); - return False; - } - - if (registry_smbconf_valname_forbidden(valname)) { - DEBUG(1, ("smbconf_store_values: value '%s' forbidden " - "in registry.\n", valname)); - return False; - } - - if (lp_parameter_is_valid(valname) && - !lp_parameter_is_canonical(valname)) - { - DEBUG(5, ("valid parameter '%s' given but it is a " - "synonym. going to canonicalize it.\n", - valname)); - theval = smbconf_canonicalize_regval(val, theval); - if (theval == NULL) { - DEBUG(10, ("error canonicalizing registry " - "value\n")); - return False; - } - } else { - DEBUG(10, ("%s parameter found, " - "copying it to new container...\n", - (lp_parameter_is_valid(valname)? - "valid":"unknown"))); - } - res = regval_ctr_copyvalue(new_val_ctr, theval); - if (res == 0) { - DEBUG(10, ("error calling regval_ctr_copyvalue. " - "(no memory?)\n")); - return False; - } - DEBUG(10, ("parameter copied. container now has %d values.\n", - res)); - } - return regdb_ops.store_values(key, new_val_ctr); -} - -static bool smbconf_reg_access_check(const char *keyname, uint32 requested, - uint32 *granted, - const struct nt_user_token *token) -{ - if (!(user_has_privileges(token, &se_disk_operators))) { - return False; - } - - *granted = REG_KEY_ALL; - return True; -} - -static WERROR smbconf_get_secdesc(TALLOC_CTX *mem_ctx, const char *key, - struct security_descriptor **psecdesc) -{ - return regdb_ops.get_secdesc(mem_ctx, key, psecdesc); -} - -static WERROR smbconf_set_secdesc(const char *key, - struct security_descriptor *secdesc) -{ - return regdb_ops.set_secdesc(key, secdesc); -} - - -/* - * Table of function pointers for accessing smb.conf data - */ - -REGISTRY_OPS smbconf_reg_ops = { - .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, -}; -- cgit From e7520f3ad8af65cd6c59030724c5354423b9937f Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 21 Jan 2008 00:14:10 +0100 Subject: Rename reg_shares.c to reg_backend_shares.c Michael (This used to be commit aaf33ae5b8bfaefd2342c9ce6363577ce7c0c4f1) --- source3/registry/reg_backend_shares.c | 164 ++++++++++++++++++++++++++++++++++ source3/registry/reg_shares.c | 164 ---------------------------------- 2 files changed, 164 insertions(+), 164 deletions(-) create mode 100644 source3/registry/reg_backend_shares.c delete mode 100644 source3/registry/reg_shares.c (limited to 'source3/registry') diff --git a/source3/registry/reg_backend_shares.c b/source3/registry/reg_backend_shares.c new file mode 100644 index 0000000000..ee9e5dc5a1 --- /dev/null +++ b/source3/registry/reg_backend_shares.c @@ -0,0 +1,164 @@ +/* + * Unix SMB/CIFS implementation. + * Virtual Windows Registry Layer + * Copyright (C) Gerald Carter 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 . + */ + +/* Implementation of registry virtual views for printing information */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_REGISTRY + +/********************************************************************** + It is safe to assume that every registry path passed into on of + the exported functions here begins with KEY_PRINTING else + these functions would have never been called. This is a small utility + function to strip the beginning of the path and make a copy that the + caller can modify. Note that the caller is responsible for releasing + the memory allocated here. + **********************************************************************/ + +static char* trim_reg_path( const char *path ) +{ + const char *p; + uint16 key_len = strlen(KEY_SHARES); + + /* + * sanity check...this really should never be True. + * It is only here to prevent us from accessing outside + * the path buffer in the extreme case. + */ + + if ( strlen(path) < key_len ) { + DEBUG(0,("trim_reg_path: Registry path too short! [%s]\n", path)); + return NULL; + } + + + p = path + strlen( KEY_SHARES ); + + if ( *p == '\\' ) + p++; + + if ( *p ) + return SMB_STRDUP(p); + else + return NULL; +} + +/********************************************************************** + Enumerate registry subkey names given a registry path. + Caller is responsible for freeing memory to **subkeys + *********************************************************************/ + +static int shares_subkey_info( const char *key, REGSUBKEY_CTR *subkey_ctr ) +{ + char *path; + bool top_level = False; + int num_subkeys = 0; + + DEBUG(10,("printing_subkey_info: key=>[%s]\n", key)); + + path = trim_reg_path( key ); + + /* check to see if we are dealing with the top level key */ + + if ( !path ) + top_level = True; + + if ( top_level ) { + num_subkeys = 1; + regsubkey_ctr_addkey( subkey_ctr, "Security" ); + } +#if 0 + else + num_subkeys = handle_share_subpath( path, subkey_ctr, NULL ); +#endif + + SAFE_FREE( path ); + + return num_subkeys; +} + +/********************************************************************** + Enumerate registry values given a registry path. + Caller is responsible for freeing memory + *********************************************************************/ + +static int shares_value_info( const char *key, REGVAL_CTR *val ) +{ + char *path; + bool top_level = False; + int num_values = 0; + + DEBUG(10,("printing_value_info: key=>[%s]\n", key)); + + path = trim_reg_path( key ); + + /* check to see if we are dealing with the top level key */ + + if ( !path ) + top_level = True; + + /* fill in values from the getprinterdata_printer_server() */ + if ( top_level ) + num_values = 0; +#if 0 + else + num_values = handle_printing_subpath( path, NULL, val ); +#endif + + SAFE_FREE(path); + + return num_values; +} + +/********************************************************************** + Stub function which always returns failure since we don't want + people storing printing information directly via regostry calls + (for now at least) + *********************************************************************/ + +static bool shares_store_subkey( const char *key, REGSUBKEY_CTR *subkeys ) +{ + return False; +} + +/********************************************************************** + Stub function which always returns failure since we don't want + people storing printing information directly via regostry calls + (for now at least) + *********************************************************************/ + +static bool shares_store_value( const char *key, REGVAL_CTR *val ) +{ + return False; +} + +/* + * Table of function pointers for accessing printing data + */ + +REGISTRY_OPS shares_reg_ops = { + .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_shares.c b/source3/registry/reg_shares.c deleted file mode 100644 index ee9e5dc5a1..0000000000 --- a/source3/registry/reg_shares.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * Virtual Windows Registry Layer - * Copyright (C) Gerald Carter 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 . - */ - -/* Implementation of registry virtual views for printing information */ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_REGISTRY - -/********************************************************************** - It is safe to assume that every registry path passed into on of - the exported functions here begins with KEY_PRINTING else - these functions would have never been called. This is a small utility - function to strip the beginning of the path and make a copy that the - caller can modify. Note that the caller is responsible for releasing - the memory allocated here. - **********************************************************************/ - -static char* trim_reg_path( const char *path ) -{ - const char *p; - uint16 key_len = strlen(KEY_SHARES); - - /* - * sanity check...this really should never be True. - * It is only here to prevent us from accessing outside - * the path buffer in the extreme case. - */ - - if ( strlen(path) < key_len ) { - DEBUG(0,("trim_reg_path: Registry path too short! [%s]\n", path)); - return NULL; - } - - - p = path + strlen( KEY_SHARES ); - - if ( *p == '\\' ) - p++; - - if ( *p ) - return SMB_STRDUP(p); - else - return NULL; -} - -/********************************************************************** - Enumerate registry subkey names given a registry path. - Caller is responsible for freeing memory to **subkeys - *********************************************************************/ - -static int shares_subkey_info( const char *key, REGSUBKEY_CTR *subkey_ctr ) -{ - char *path; - bool top_level = False; - int num_subkeys = 0; - - DEBUG(10,("printing_subkey_info: key=>[%s]\n", key)); - - path = trim_reg_path( key ); - - /* check to see if we are dealing with the top level key */ - - if ( !path ) - top_level = True; - - if ( top_level ) { - num_subkeys = 1; - regsubkey_ctr_addkey( subkey_ctr, "Security" ); - } -#if 0 - else - num_subkeys = handle_share_subpath( path, subkey_ctr, NULL ); -#endif - - SAFE_FREE( path ); - - return num_subkeys; -} - -/********************************************************************** - Enumerate registry values given a registry path. - Caller is responsible for freeing memory - *********************************************************************/ - -static int shares_value_info( const char *key, REGVAL_CTR *val ) -{ - char *path; - bool top_level = False; - int num_values = 0; - - DEBUG(10,("printing_value_info: key=>[%s]\n", key)); - - path = trim_reg_path( key ); - - /* check to see if we are dealing with the top level key */ - - if ( !path ) - top_level = True; - - /* fill in values from the getprinterdata_printer_server() */ - if ( top_level ) - num_values = 0; -#if 0 - else - num_values = handle_printing_subpath( path, NULL, val ); -#endif - - SAFE_FREE(path); - - return num_values; -} - -/********************************************************************** - Stub function which always returns failure since we don't want - people storing printing information directly via regostry calls - (for now at least) - *********************************************************************/ - -static bool shares_store_subkey( const char *key, REGSUBKEY_CTR *subkeys ) -{ - return False; -} - -/********************************************************************** - Stub function which always returns failure since we don't want - people storing printing information directly via regostry calls - (for now at least) - *********************************************************************/ - -static bool shares_store_value( const char *key, REGVAL_CTR *val ) -{ - return False; -} - -/* - * Table of function pointers for accessing printing data - */ - -REGISTRY_OPS shares_reg_ops = { - .fetch_subkeys = shares_subkey_info, - .fetch_values = shares_value_info, - .store_subkeys = shares_store_subkey, - .store_values = shares_store_value, -}; - - -- cgit From b5666ceefbeae35dfb390c0be6a6dc5caa1f0406 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 21 Jan 2008 00:16:40 +0100 Subject: Rename reg_db.c to reg_backend_db.c Michael (This used to be commit c3f695d3b14ee06fc5d517ca094236e885f9e707) --- source3/registry/reg_backend_db.c | 949 ++++++++++++++++++++++++++++++++++++++ source3/registry/reg_db.c | 949 -------------------------------------- 2 files changed, 949 insertions(+), 949 deletions(-) create mode 100644 source3/registry/reg_backend_db.c delete mode 100644 source3/registry/reg_db.c (limited to 'source3/registry') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c new file mode 100644 index 0000000000..e162fb587f --- /dev/null +++ b/source3/registry/reg_backend_db.c @@ -0,0 +1,949 @@ +/* + * 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 . + */ + +/* Implementation of internal registry database functions. */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_REGISTRY + +static struct tdb_wrap *tdb_reg = NULL; +static int tdb_refcount; + +/* List the deepest path into the registry. All part components will be created.*/ + +/* If you want to have a part of the path controlled by the tdb and part by + a virtual registry db (e.g. printing), then you have to list the deepest path. + For example,"HKLM/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Print" + allows the reg_db backend to handle everything up to + "HKLM/SOFTWARE/Microsoft/Windows NT/CurrentVersion" and then we'll hook + the reg_printing backend onto the last component of the path (see + KEY_PRINTING_2K in include/rpc_reg.h) --jerry */ + +static const char *builtin_registry_paths[] = { + KEY_PRINTING_2K, + KEY_PRINTING_PORTS, + KEY_PRINTING, + KEY_SHARES, + KEY_EVENTLOG, + KEY_SMBCONF, + KEY_PERFLIB, + KEY_PERFLIB_009, + "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors", + KEY_PROD_OPTIONS, + "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration", + KEY_TCPIP_PARAMS, + KEY_NETLOGON_PARAMS, + KEY_HKU, + KEY_HKCR, + KEY_HKPD, + KEY_HKPT, + NULL }; + +struct builtin_regkey_value { + const char *path; + const char *valuename; + uint32 type; + union { + const char *string; + uint32 dw_value; + } data; +}; + +static struct builtin_regkey_value builtin_registry_values[] = { + { KEY_PRINTING_PORTS, + SAMBA_PRINTER_PORT_NAME, REG_SZ, { "" } }, + { KEY_PRINTING_2K, + "DefaultSpoolDirectory", REG_SZ, { "C:\\Windows\\System32\\Spool\\Printers" } }, + { KEY_EVENTLOG, + "DisplayName", REG_SZ, { "Event Log" } }, + { KEY_EVENTLOG, + "ErrorControl", REG_DWORD, { (char*)0x00000001 } }, + { NULL, NULL, 0, { NULL } } +}; + +/*********************************************************************** + Open the registry data in the tdb + ***********************************************************************/ + +static bool init_registry_data( void ) +{ + char *path = NULL; + char *base = NULL; + char *remaining = NULL; + TALLOC_CTX *frame = NULL; + char *keyname; + char *subkeyname; + REGSUBKEY_CTR *subkeys; + REGVAL_CTR *values; + int i; + const char *p, *p2; + UNISTR2 data; + + /* + * There are potentially quite a few store operations which are all + * indiviually wrapped in tdb transactions. Wrapping them in a single + * transaction gives just a single transaction_commit() to actually do + * its fsync()s. See tdb/common/transaction.c for info about nested + * transaction behaviour. + */ + + if ( tdb_transaction_start( tdb_reg->tdb ) == -1 ) { + DEBUG(0, ("init_registry_data: tdb_transaction_start " + "failed\n")); + return false; + } + + /* loop over all of the predefined paths and add each component */ + + for ( i=0; builtin_registry_paths[i] != NULL; i++ ) { + + frame = talloc_stackframe(); + + DEBUG(6,("init_registry_data: Adding [%s]\n", builtin_registry_paths[i])); + + path = talloc_strdup(talloc_tos(), builtin_registry_paths[i]); + base = talloc_strdup(talloc_tos(), ""); + if (!path || !base) { + goto fail; + } + p = path; + + while (next_token_talloc(talloc_tos(), &p, &keyname, "\\")) { + + /* build up the registry path from the components */ + + if (*base) { + base = talloc_asprintf(talloc_tos(), "%s\\", base); + if (!base) { + goto fail; + } + } + base = talloc_asprintf_append(base, "%s", keyname); + if (!base) { + goto fail; + } + + /* get the immediate subkeyname (if we have one ) */ + + subkeyname = talloc_strdup(talloc_tos(), ""); + if (!subkeyname) { + goto fail; + } + if (*p) { + remaining = talloc_strdup(talloc_tos(), p); + if (!remaining) { + goto fail; + } + p2 = remaining; + + if (!next_token_talloc(talloc_tos(), &p2, + &subkeyname, "\\")) { + subkeyname = talloc_strdup(talloc_tos(),p2); + if (!subkeyname) { + goto fail; + } + } + } + + DEBUG(10,("init_registry_data: Storing key [%s] with subkey [%s]\n", + base, *subkeyname ? subkeyname : "NULL")); + + /* we don't really care if the lookup succeeds or not since + we are about to update the record. We just want any + subkeys already present */ + + if ( !(subkeys = TALLOC_ZERO_P(talloc_tos(), REGSUBKEY_CTR )) ) { + DEBUG(0,("talloc() failure!\n")); + goto fail; + } + + regdb_fetch_keys(base, subkeys); + if (*subkeyname) { + regsubkey_ctr_addkey( subkeys, subkeyname); + } + if (!regdb_store_keys( base, subkeys)) { + goto fail; + } + } + + TALLOC_FREE(frame); + } + + /* loop over all of the predefined values and add each component */ + + for (i=0; builtin_registry_values[i].path != NULL; i++) { + + if (!(values = TALLOC_ZERO_P(talloc_tos(), REGVAL_CTR))) { + goto fail; + } + + regdb_fetch_values( builtin_registry_values[i].path, values); + + /* preserve existing values across restarts. Only add new ones */ + + if (!regval_ctr_key_exists(values, builtin_registry_values[i].valuename)) { + switch(builtin_registry_values[i].type) { + case REG_DWORD: + regval_ctr_addvalue( values, + builtin_registry_values[i].valuename, + REG_DWORD, + (char*)&builtin_registry_values[i].data.dw_value, + sizeof(uint32) ); + break; + + case REG_SZ: + init_unistr2( &data, builtin_registry_values[i].data.string, UNI_STR_TERMINATE); + regval_ctr_addvalue( values, + builtin_registry_values[i].valuename, + REG_SZ, + (char*)data.buffer, + data.uni_str_len*sizeof(uint16) ); + break; + + default: + DEBUG(0,("init_registry_data: invalid value type in builtin_registry_values [%d]\n", + builtin_registry_values[i].type)); + } + regdb_store_values( builtin_registry_values[i].path, values ); + } + TALLOC_FREE( values ); + } + + TALLOC_FREE(frame); + + if (tdb_transaction_commit( tdb_reg->tdb ) == -1) { + DEBUG(0, ("init_registry_data: Could not commit " + "transaction\n")); + return false; + } + + return true; + + fail: + + TALLOC_FREE(frame); + + if (tdb_transaction_cancel( tdb_reg->tdb ) == -1) { + smb_panic("init_registry_data: tdb_transaction_cancel " + "failed\n"); + } + + return false; +} + +/*********************************************************************** + Open the registry database + ***********************************************************************/ + +bool regdb_init( void ) +{ + const char *vstring = "INFO/version"; + uint32 vers_id; + + if ( tdb_reg ) + return true; + + if ( !(tdb_reg = tdb_wrap_open(NULL, state_path("registry.tdb"), 0, REG_TDB_FLAGS, O_RDWR, 0600)) ) + { + tdb_reg = tdb_wrap_open(NULL, state_path("registry.tdb"), 0, REG_TDB_FLAGS, O_RDWR|O_CREAT, 0600); + if ( !tdb_reg ) { + DEBUG(0,("regdb_init: Failed to open registry %s (%s)\n", + state_path("registry.tdb"), strerror(errno) )); + return false; + } + + DEBUG(10,("regdb_init: Successfully created registry tdb\n")); + } + + tdb_refcount = 1; + + vers_id = tdb_fetch_int32(tdb_reg->tdb, vstring); + + if ( vers_id != REGVER_V1 ) { + /* any upgrade code here if needed */ + DEBUG(10, ("regdb_init: got INFO/version = %d != %d\n", + vers_id, REGVER_V1)); + } + + /* always setup the necessary keys and values */ + + if ( !init_registry_data() ) { + DEBUG(0,("regdb_init: Failed to initialize data in registry!\n")); + return false; + } + + return true; +} + +/*********************************************************************** + Open the registry. Must already have been initialized by regdb_init() + ***********************************************************************/ + +WERROR regdb_open( void ) +{ + WERROR result = WERR_OK; + + if ( tdb_reg ) { + DEBUG(10,("regdb_open: incrementing refcount (%d)\n", tdb_refcount)); + tdb_refcount++; + return WERR_OK; + } + + become_root(); + + tdb_reg = tdb_wrap_open(NULL, state_path("registry.tdb"), 0, REG_TDB_FLAGS, O_RDWR, 0600); + if ( !tdb_reg ) { + result = ntstatus_to_werror( map_nt_error_from_unix( errno ) ); + DEBUG(0,("regdb_open: Failed to open %s! (%s)\n", + state_path("registry.tdb"), strerror(errno) )); + } + + unbecome_root(); + + tdb_refcount = 1; + DEBUG(10,("regdb_open: refcount reset (%d)\n", tdb_refcount)); + + return result; +} + +/*********************************************************************** + ***********************************************************************/ + +int regdb_close( void ) +{ + if (tdb_refcount == 0) { + return 0; + } + + tdb_refcount--; + + DEBUG(10,("regdb_close: decrementing refcount (%d)\n", tdb_refcount)); + + if ( tdb_refcount > 0 ) + return 0; + + SMB_ASSERT( tdb_refcount >= 0 ); + + TALLOC_FREE(tdb_reg); + return 0; +} + +/*********************************************************************** + return the tdb sequence number of the registry tdb. + this is an indicator for the content of the registry + having changed. it will change upon regdb_init, too, though. + ***********************************************************************/ +int regdb_get_seqnum(void) +{ + return tdb_get_seqnum(tdb_reg->tdb); +} + +/*********************************************************************** + Add subkey strings to the registry tdb under a defined key + fmt is the same format as tdb_pack except this function only supports + fstrings + ***********************************************************************/ + +static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr) +{ + TDB_DATA dbuf; + uint8 *buffer = NULL; + int i = 0; + uint32 len, buflen; + bool ret = true; + uint32 num_subkeys = regsubkey_ctr_numkeys(ctr); + char *keyname = NULL; + TALLOC_CTX *ctx = talloc_tos(); + + if (!key) { + return false; + } + + keyname = talloc_strdup(ctx, key); + if (!keyname) { + return false; + } + keyname = normalize_reg_path(ctx, keyname); + + /* allocate some initial memory */ + + if (!(buffer = (uint8 *)SMB_MALLOC(1024))) { + return false; + } + buflen = 1024; + len = 0; + + /* store the number of subkeys */ + + len += tdb_pack(buffer+len, buflen-len, "d", num_subkeys ); + + /* pack all the strings */ + + for (i=0; i buflen ) { + /* 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; + goto done; + } + buflen = len*2; + + len = tdb_pack( buffer+len, buflen-len, "f", regsubkey_ctr_specific_key(ctr, i) ); + } + } + + /* finally write out the data */ + + dbuf.dptr = buffer; + dbuf.dsize = len; + if ( tdb_store_bystring( tdb_reg->tdb, keyname, dbuf, TDB_REPLACE ) == -1) { + ret = false; + goto done; + } + +done: + SAFE_FREE( buffer ); + return ret; +} + +/*********************************************************************** + Store the new subkey record and create any child key records that + do not currently exist + ***********************************************************************/ + +bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr) +{ + int num_subkeys, i; + char *path = NULL; + REGSUBKEY_CTR *subkeys = NULL, *old_subkeys = NULL; + char *oldkeyname = NULL; + TALLOC_CTX *ctx = talloc_tos(); + + /* + * fetch a list of the old subkeys so we can determine if anything has + * changed + */ + + if (!(old_subkeys = TALLOC_ZERO_P(ctr, REGSUBKEY_CTR))) { + DEBUG(0,("regdb_store_keys: talloc() failure!\n")); + return false; + } + + regdb_fetch_keys(key, old_subkeys); + + if (ctr->num_subkeys == old_subkeys->num_subkeys) { + + for (i = 0; inum_subkeys; i++) { + if (strcmp(ctr->subkeys[i], + old_subkeys->subkeys[i]) != 0) { + break; + } + } + if (i == ctr->num_subkeys) { + /* + * Nothing changed, no point to even start a tdb + * transaction + */ + TALLOC_FREE(old_subkeys); + return true; + } + } + + if (tdb_transaction_start( tdb_reg->tdb ) == -1) { + DEBUG(0, ("regdb_store_keys: tdb_transaction_start failed\n")); + return false; + } + + /* + * Re-fetch the old keys inside the transaction + */ + + TALLOC_FREE(old_subkeys); + + if (!(old_subkeys = TALLOC_ZERO_P(ctr, REGSUBKEY_CTR))) { + DEBUG(0,("regdb_store_keys: talloc() failure!\n")); + goto fail; + } + + regdb_fetch_keys(key, old_subkeys); + + /* store the subkey list for the parent */ + + if (!regdb_store_keys_internal(key, ctr) ) { + DEBUG(0,("regdb_store_keys: Failed to store new subkey list " + "for parent [%s]\n", key)); + goto fail; + } + + /* now delete removed keys */ + + num_subkeys = regsubkey_ctr_numkeys(old_subkeys); + for (i=0; itdb, path) == -1) { + DEBUG(1, ("Deleting %s failed\n", path)); + goto fail; + } + + TALLOC_FREE(path); + path = talloc_asprintf(ctx, "%s/%s/%s", + REG_VALUE_PREFIX, + key, + oldkeyname ); + if (!path) { + goto fail; + } + path = normalize_reg_path(ctx, path); + if (!path) { + goto fail; + } + + /* + * Ignore errors here, we might have no values around + */ + tdb_delete_bystring( tdb_reg->tdb, path ); + TALLOC_FREE(path); + } + + TALLOC_FREE(old_subkeys); + + /* now create records for any subkeys that don't already exist */ + + num_subkeys = regsubkey_ctr_numkeys(ctr); + for (i=0; itdb ) == -1) { + DEBUG(0, ("regdb_store_keys: Could not commit transaction\n")); + return false; + } + + return true; + + fail: + TALLOC_FREE(old_subkeys); + TALLOC_FREE(subkeys); + + if (tdb_transaction_cancel(tdb_reg->tdb) == -1) { + smb_panic("regdb_store_keys: tdb_transaction_cancel failed\n"); + } + + return false; +} + + +/*********************************************************************** + Retrieve an array of strings containing subkeys. Memory should be + released by the caller. + ***********************************************************************/ + +int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr) +{ + char *path = NULL; + uint32 num_items; + TDB_DATA dbuf; + uint8 *buf; + uint32 buflen, len; + int i; + fstring subkeyname; + int ret = -1; + TALLOC_CTX *frame = talloc_stackframe(); + + DEBUG(11,("regdb_fetch_keys: Enter key => [%s]\n", key ? key : "NULL")); + + path = talloc_strdup(talloc_tos(), key); + if (!path) { + goto fail; + } + + /* convert to key format */ + path = talloc_string_sub(talloc_tos(), path, "\\", "/"); + if (!path) { + goto fail; + } + 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; + + if ( !buf ) { + DEBUG(5,("regdb_fetch_keys: tdb lookup failed to locate key [%s]\n", key)); + goto fail; + } + + len = tdb_unpack( buf, buflen, "d", &num_items); + + for (i=0; itdb, 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 */ + return 0; + } + + regdb_unpack_values(values, data.dptr, data.dsize); + + SAFE_FREE(data.dptr); + return regval_ctr_numvals(values); +} + +bool regdb_store_values( const char *key, REGVAL_CTR *values ) +{ + TDB_DATA old_data, data; + char *keystr = NULL; + TALLOC_CTX *ctx = talloc_tos(); + int len, ret; + + DEBUG(10,("regdb_store_values: Looking for value of key [%s] \n", key)); + + ZERO_STRUCT(data); + + len = regdb_pack_values(values, data.dptr, data.dsize); + if (len <= 0) { + DEBUG(0,("regdb_store_values: unable to pack values. len <= 0\n")); + return false; + } + + data.dptr = SMB_MALLOC_ARRAY( uint8, len ); + data.dsize = len; + + len = regdb_pack_values(values, data.dptr, data.dsize); + + SMB_ASSERT( len == data.dsize ); + + keystr = talloc_asprintf(ctx, "%s/%s", REG_VALUE_PREFIX, key ); + if (!keystr) { + SAFE_FREE(data.dptr); + return false; + } + keystr = normalize_reg_path(ctx, keystr); + if (!keystr) { + SAFE_FREE(data.dptr); + return false; + } + + old_data = tdb_fetch_bystring(tdb_reg->tdb, keystr); + + if ((old_data.dptr != NULL) + && (old_data.dsize == data.dsize) + && (memcmp(old_data.dptr, data.dptr, data.dsize) == 0)) { + SAFE_FREE(old_data.dptr); + SAFE_FREE(data.dptr); + return true; + } + + ret = tdb_trans_store_bystring(tdb_reg->tdb, keystr, data, TDB_REPLACE); + + SAFE_FREE( old_data.dptr ); + SAFE_FREE( data.dptr ); + + return ret != -1 ; +} + +static WERROR regdb_get_secdesc(TALLOC_CTX *mem_ctx, const char *key, + struct security_descriptor **psecdesc) +{ + char *tdbkey; + TDB_DATA data; + NTSTATUS status; + + DEBUG(10, ("regdb_get_secdesc: Getting secdesc of key [%s]\n", key)); + + if (asprintf(&tdbkey, "%s/%s", REG_SECDESC_PREFIX, key) == -1) { + return WERR_NOMEM; + } + normalize_dbkey(tdbkey); + + data = tdb_fetch_bystring(tdb_reg->tdb, tdbkey); + SAFE_FREE(tdbkey); + + if (data.dptr == NULL) { + return WERR_BADFILE; + } + + status = unmarshall_sec_desc(mem_ctx, (uint8 *)data.dptr, data.dsize, + psecdesc); + + SAFE_FREE(data.dptr); + + if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MEMORY)) { + return WERR_NOMEM; + } + + if (!NT_STATUS_IS_OK(status)) { + return WERR_REG_CORRUPT; + } + + return WERR_OK; +} + +static WERROR regdb_set_secdesc(const char *key, + struct security_descriptor *secdesc) +{ + prs_struct ps; + TALLOC_CTX *mem_ctx; + char *tdbkey; + WERROR err = WERR_NOMEM; + TDB_DATA tdbdata; + + if (!(mem_ctx = talloc_init("regdb_set_secdesc"))) { + return WERR_NOMEM; + } + + ZERO_STRUCT(ps); + + if (!(tdbkey = talloc_asprintf(mem_ctx, "%s/%s", REG_SECDESC_PREFIX, + key))) { + goto done; + } + normalize_dbkey(tdbkey); + + if (secdesc == NULL) { + /* assuming a delete */ + int tdb_ret; + + tdb_ret = tdb_trans_delete(tdb_reg->tdb, + string_term_tdb_data(tdbkey)); + if (tdb_ret == -1) { + err = ntstatus_to_werror(map_nt_error_from_unix(errno)); + } else { + err = WERR_OK; + } + + goto done; + } + + err = ntstatus_to_werror(marshall_sec_desc(mem_ctx, secdesc, + &tdbdata.dptr, + &tdbdata.dsize)); + if (!W_ERROR_IS_OK(err)) { + goto done; + } + + if (tdb_trans_store_bystring(tdb_reg->tdb, tdbkey, tdbdata, 0) == -1) { + err = ntstatus_to_werror(map_nt_error_from_unix(errno)); + goto done; + } + + done: + prs_mem_free(&ps); + TALLOC_FREE(mem_ctx); + 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 + */ + +REGISTRY_OPS regdb_ops = { + regdb_fetch_keys, + regdb_fetch_values, + regdb_store_keys, + regdb_store_values, + NULL, + regdb_get_secdesc, + regdb_set_secdesc, + regdb_subkeys_need_update, + regdb_values_need_update +}; diff --git a/source3/registry/reg_db.c b/source3/registry/reg_db.c deleted file mode 100644 index e162fb587f..0000000000 --- a/source3/registry/reg_db.c +++ /dev/null @@ -1,949 +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 . - */ - -/* Implementation of internal registry database functions. */ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_REGISTRY - -static struct tdb_wrap *tdb_reg = NULL; -static int tdb_refcount; - -/* List the deepest path into the registry. All part components will be created.*/ - -/* If you want to have a part of the path controlled by the tdb and part by - a virtual registry db (e.g. printing), then you have to list the deepest path. - For example,"HKLM/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Print" - allows the reg_db backend to handle everything up to - "HKLM/SOFTWARE/Microsoft/Windows NT/CurrentVersion" and then we'll hook - the reg_printing backend onto the last component of the path (see - KEY_PRINTING_2K in include/rpc_reg.h) --jerry */ - -static const char *builtin_registry_paths[] = { - KEY_PRINTING_2K, - KEY_PRINTING_PORTS, - KEY_PRINTING, - KEY_SHARES, - KEY_EVENTLOG, - KEY_SMBCONF, - KEY_PERFLIB, - KEY_PERFLIB_009, - "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors", - KEY_PROD_OPTIONS, - "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration", - KEY_TCPIP_PARAMS, - KEY_NETLOGON_PARAMS, - KEY_HKU, - KEY_HKCR, - KEY_HKPD, - KEY_HKPT, - NULL }; - -struct builtin_regkey_value { - const char *path; - const char *valuename; - uint32 type; - union { - const char *string; - uint32 dw_value; - } data; -}; - -static struct builtin_regkey_value builtin_registry_values[] = { - { KEY_PRINTING_PORTS, - SAMBA_PRINTER_PORT_NAME, REG_SZ, { "" } }, - { KEY_PRINTING_2K, - "DefaultSpoolDirectory", REG_SZ, { "C:\\Windows\\System32\\Spool\\Printers" } }, - { KEY_EVENTLOG, - "DisplayName", REG_SZ, { "Event Log" } }, - { KEY_EVENTLOG, - "ErrorControl", REG_DWORD, { (char*)0x00000001 } }, - { NULL, NULL, 0, { NULL } } -}; - -/*********************************************************************** - Open the registry data in the tdb - ***********************************************************************/ - -static bool init_registry_data( void ) -{ - char *path = NULL; - char *base = NULL; - char *remaining = NULL; - TALLOC_CTX *frame = NULL; - char *keyname; - char *subkeyname; - REGSUBKEY_CTR *subkeys; - REGVAL_CTR *values; - int i; - const char *p, *p2; - UNISTR2 data; - - /* - * There are potentially quite a few store operations which are all - * indiviually wrapped in tdb transactions. Wrapping them in a single - * transaction gives just a single transaction_commit() to actually do - * its fsync()s. See tdb/common/transaction.c for info about nested - * transaction behaviour. - */ - - if ( tdb_transaction_start( tdb_reg->tdb ) == -1 ) { - DEBUG(0, ("init_registry_data: tdb_transaction_start " - "failed\n")); - return false; - } - - /* loop over all of the predefined paths and add each component */ - - for ( i=0; builtin_registry_paths[i] != NULL; i++ ) { - - frame = talloc_stackframe(); - - DEBUG(6,("init_registry_data: Adding [%s]\n", builtin_registry_paths[i])); - - path = talloc_strdup(talloc_tos(), builtin_registry_paths[i]); - base = talloc_strdup(talloc_tos(), ""); - if (!path || !base) { - goto fail; - } - p = path; - - while (next_token_talloc(talloc_tos(), &p, &keyname, "\\")) { - - /* build up the registry path from the components */ - - if (*base) { - base = talloc_asprintf(talloc_tos(), "%s\\", base); - if (!base) { - goto fail; - } - } - base = talloc_asprintf_append(base, "%s", keyname); - if (!base) { - goto fail; - } - - /* get the immediate subkeyname (if we have one ) */ - - subkeyname = talloc_strdup(talloc_tos(), ""); - if (!subkeyname) { - goto fail; - } - if (*p) { - remaining = talloc_strdup(talloc_tos(), p); - if (!remaining) { - goto fail; - } - p2 = remaining; - - if (!next_token_talloc(talloc_tos(), &p2, - &subkeyname, "\\")) { - subkeyname = talloc_strdup(talloc_tos(),p2); - if (!subkeyname) { - goto fail; - } - } - } - - DEBUG(10,("init_registry_data: Storing key [%s] with subkey [%s]\n", - base, *subkeyname ? subkeyname : "NULL")); - - /* we don't really care if the lookup succeeds or not since - we are about to update the record. We just want any - subkeys already present */ - - if ( !(subkeys = TALLOC_ZERO_P(talloc_tos(), REGSUBKEY_CTR )) ) { - DEBUG(0,("talloc() failure!\n")); - goto fail; - } - - regdb_fetch_keys(base, subkeys); - if (*subkeyname) { - regsubkey_ctr_addkey( subkeys, subkeyname); - } - if (!regdb_store_keys( base, subkeys)) { - goto fail; - } - } - - TALLOC_FREE(frame); - } - - /* loop over all of the predefined values and add each component */ - - for (i=0; builtin_registry_values[i].path != NULL; i++) { - - if (!(values = TALLOC_ZERO_P(talloc_tos(), REGVAL_CTR))) { - goto fail; - } - - regdb_fetch_values( builtin_registry_values[i].path, values); - - /* preserve existing values across restarts. Only add new ones */ - - if (!regval_ctr_key_exists(values, builtin_registry_values[i].valuename)) { - switch(builtin_registry_values[i].type) { - case REG_DWORD: - regval_ctr_addvalue( values, - builtin_registry_values[i].valuename, - REG_DWORD, - (char*)&builtin_registry_values[i].data.dw_value, - sizeof(uint32) ); - break; - - case REG_SZ: - init_unistr2( &data, builtin_registry_values[i].data.string, UNI_STR_TERMINATE); - regval_ctr_addvalue( values, - builtin_registry_values[i].valuename, - REG_SZ, - (char*)data.buffer, - data.uni_str_len*sizeof(uint16) ); - break; - - default: - DEBUG(0,("init_registry_data: invalid value type in builtin_registry_values [%d]\n", - builtin_registry_values[i].type)); - } - regdb_store_values( builtin_registry_values[i].path, values ); - } - TALLOC_FREE( values ); - } - - TALLOC_FREE(frame); - - if (tdb_transaction_commit( tdb_reg->tdb ) == -1) { - DEBUG(0, ("init_registry_data: Could not commit " - "transaction\n")); - return false; - } - - return true; - - fail: - - TALLOC_FREE(frame); - - if (tdb_transaction_cancel( tdb_reg->tdb ) == -1) { - smb_panic("init_registry_data: tdb_transaction_cancel " - "failed\n"); - } - - return false; -} - -/*********************************************************************** - Open the registry database - ***********************************************************************/ - -bool regdb_init( void ) -{ - const char *vstring = "INFO/version"; - uint32 vers_id; - - if ( tdb_reg ) - return true; - - if ( !(tdb_reg = tdb_wrap_open(NULL, state_path("registry.tdb"), 0, REG_TDB_FLAGS, O_RDWR, 0600)) ) - { - tdb_reg = tdb_wrap_open(NULL, state_path("registry.tdb"), 0, REG_TDB_FLAGS, O_RDWR|O_CREAT, 0600); - if ( !tdb_reg ) { - DEBUG(0,("regdb_init: Failed to open registry %s (%s)\n", - state_path("registry.tdb"), strerror(errno) )); - return false; - } - - DEBUG(10,("regdb_init: Successfully created registry tdb\n")); - } - - tdb_refcount = 1; - - vers_id = tdb_fetch_int32(tdb_reg->tdb, vstring); - - if ( vers_id != REGVER_V1 ) { - /* any upgrade code here if needed */ - DEBUG(10, ("regdb_init: got INFO/version = %d != %d\n", - vers_id, REGVER_V1)); - } - - /* always setup the necessary keys and values */ - - if ( !init_registry_data() ) { - DEBUG(0,("regdb_init: Failed to initialize data in registry!\n")); - return false; - } - - return true; -} - -/*********************************************************************** - Open the registry. Must already have been initialized by regdb_init() - ***********************************************************************/ - -WERROR regdb_open( void ) -{ - WERROR result = WERR_OK; - - if ( tdb_reg ) { - DEBUG(10,("regdb_open: incrementing refcount (%d)\n", tdb_refcount)); - tdb_refcount++; - return WERR_OK; - } - - become_root(); - - tdb_reg = tdb_wrap_open(NULL, state_path("registry.tdb"), 0, REG_TDB_FLAGS, O_RDWR, 0600); - if ( !tdb_reg ) { - result = ntstatus_to_werror( map_nt_error_from_unix( errno ) ); - DEBUG(0,("regdb_open: Failed to open %s! (%s)\n", - state_path("registry.tdb"), strerror(errno) )); - } - - unbecome_root(); - - tdb_refcount = 1; - DEBUG(10,("regdb_open: refcount reset (%d)\n", tdb_refcount)); - - return result; -} - -/*********************************************************************** - ***********************************************************************/ - -int regdb_close( void ) -{ - if (tdb_refcount == 0) { - return 0; - } - - tdb_refcount--; - - DEBUG(10,("regdb_close: decrementing refcount (%d)\n", tdb_refcount)); - - if ( tdb_refcount > 0 ) - return 0; - - SMB_ASSERT( tdb_refcount >= 0 ); - - TALLOC_FREE(tdb_reg); - return 0; -} - -/*********************************************************************** - return the tdb sequence number of the registry tdb. - this is an indicator for the content of the registry - having changed. it will change upon regdb_init, too, though. - ***********************************************************************/ -int regdb_get_seqnum(void) -{ - return tdb_get_seqnum(tdb_reg->tdb); -} - -/*********************************************************************** - Add subkey strings to the registry tdb under a defined key - fmt is the same format as tdb_pack except this function only supports - fstrings - ***********************************************************************/ - -static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr) -{ - TDB_DATA dbuf; - uint8 *buffer = NULL; - int i = 0; - uint32 len, buflen; - bool ret = true; - uint32 num_subkeys = regsubkey_ctr_numkeys(ctr); - char *keyname = NULL; - TALLOC_CTX *ctx = talloc_tos(); - - if (!key) { - return false; - } - - keyname = talloc_strdup(ctx, key); - if (!keyname) { - return false; - } - keyname = normalize_reg_path(ctx, keyname); - - /* allocate some initial memory */ - - if (!(buffer = (uint8 *)SMB_MALLOC(1024))) { - return false; - } - buflen = 1024; - len = 0; - - /* store the number of subkeys */ - - len += tdb_pack(buffer+len, buflen-len, "d", num_subkeys ); - - /* pack all the strings */ - - for (i=0; i buflen ) { - /* 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; - goto done; - } - buflen = len*2; - - len = tdb_pack( buffer+len, buflen-len, "f", regsubkey_ctr_specific_key(ctr, i) ); - } - } - - /* finally write out the data */ - - dbuf.dptr = buffer; - dbuf.dsize = len; - if ( tdb_store_bystring( tdb_reg->tdb, keyname, dbuf, TDB_REPLACE ) == -1) { - ret = false; - goto done; - } - -done: - SAFE_FREE( buffer ); - return ret; -} - -/*********************************************************************** - Store the new subkey record and create any child key records that - do not currently exist - ***********************************************************************/ - -bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr) -{ - int num_subkeys, i; - char *path = NULL; - REGSUBKEY_CTR *subkeys = NULL, *old_subkeys = NULL; - char *oldkeyname = NULL; - TALLOC_CTX *ctx = talloc_tos(); - - /* - * fetch a list of the old subkeys so we can determine if anything has - * changed - */ - - if (!(old_subkeys = TALLOC_ZERO_P(ctr, REGSUBKEY_CTR))) { - DEBUG(0,("regdb_store_keys: talloc() failure!\n")); - return false; - } - - regdb_fetch_keys(key, old_subkeys); - - if (ctr->num_subkeys == old_subkeys->num_subkeys) { - - for (i = 0; inum_subkeys; i++) { - if (strcmp(ctr->subkeys[i], - old_subkeys->subkeys[i]) != 0) { - break; - } - } - if (i == ctr->num_subkeys) { - /* - * Nothing changed, no point to even start a tdb - * transaction - */ - TALLOC_FREE(old_subkeys); - return true; - } - } - - if (tdb_transaction_start( tdb_reg->tdb ) == -1) { - DEBUG(0, ("regdb_store_keys: tdb_transaction_start failed\n")); - return false; - } - - /* - * Re-fetch the old keys inside the transaction - */ - - TALLOC_FREE(old_subkeys); - - if (!(old_subkeys = TALLOC_ZERO_P(ctr, REGSUBKEY_CTR))) { - DEBUG(0,("regdb_store_keys: talloc() failure!\n")); - goto fail; - } - - regdb_fetch_keys(key, old_subkeys); - - /* store the subkey list for the parent */ - - if (!regdb_store_keys_internal(key, ctr) ) { - DEBUG(0,("regdb_store_keys: Failed to store new subkey list " - "for parent [%s]\n", key)); - goto fail; - } - - /* now delete removed keys */ - - num_subkeys = regsubkey_ctr_numkeys(old_subkeys); - for (i=0; itdb, path) == -1) { - DEBUG(1, ("Deleting %s failed\n", path)); - goto fail; - } - - TALLOC_FREE(path); - path = talloc_asprintf(ctx, "%s/%s/%s", - REG_VALUE_PREFIX, - key, - oldkeyname ); - if (!path) { - goto fail; - } - path = normalize_reg_path(ctx, path); - if (!path) { - goto fail; - } - - /* - * Ignore errors here, we might have no values around - */ - tdb_delete_bystring( tdb_reg->tdb, path ); - TALLOC_FREE(path); - } - - TALLOC_FREE(old_subkeys); - - /* now create records for any subkeys that don't already exist */ - - num_subkeys = regsubkey_ctr_numkeys(ctr); - for (i=0; itdb ) == -1) { - DEBUG(0, ("regdb_store_keys: Could not commit transaction\n")); - return false; - } - - return true; - - fail: - TALLOC_FREE(old_subkeys); - TALLOC_FREE(subkeys); - - if (tdb_transaction_cancel(tdb_reg->tdb) == -1) { - smb_panic("regdb_store_keys: tdb_transaction_cancel failed\n"); - } - - return false; -} - - -/*********************************************************************** - Retrieve an array of strings containing subkeys. Memory should be - released by the caller. - ***********************************************************************/ - -int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr) -{ - char *path = NULL; - uint32 num_items; - TDB_DATA dbuf; - uint8 *buf; - uint32 buflen, len; - int i; - fstring subkeyname; - int ret = -1; - TALLOC_CTX *frame = talloc_stackframe(); - - DEBUG(11,("regdb_fetch_keys: Enter key => [%s]\n", key ? key : "NULL")); - - path = talloc_strdup(talloc_tos(), key); - if (!path) { - goto fail; - } - - /* convert to key format */ - path = talloc_string_sub(talloc_tos(), path, "\\", "/"); - if (!path) { - goto fail; - } - 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; - - if ( !buf ) { - DEBUG(5,("regdb_fetch_keys: tdb lookup failed to locate key [%s]\n", key)); - goto fail; - } - - len = tdb_unpack( buf, buflen, "d", &num_items); - - for (i=0; itdb, 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 */ - return 0; - } - - regdb_unpack_values(values, data.dptr, data.dsize); - - SAFE_FREE(data.dptr); - return regval_ctr_numvals(values); -} - -bool regdb_store_values( const char *key, REGVAL_CTR *values ) -{ - TDB_DATA old_data, data; - char *keystr = NULL; - TALLOC_CTX *ctx = talloc_tos(); - int len, ret; - - DEBUG(10,("regdb_store_values: Looking for value of key [%s] \n", key)); - - ZERO_STRUCT(data); - - len = regdb_pack_values(values, data.dptr, data.dsize); - if (len <= 0) { - DEBUG(0,("regdb_store_values: unable to pack values. len <= 0\n")); - return false; - } - - data.dptr = SMB_MALLOC_ARRAY( uint8, len ); - data.dsize = len; - - len = regdb_pack_values(values, data.dptr, data.dsize); - - SMB_ASSERT( len == data.dsize ); - - keystr = talloc_asprintf(ctx, "%s/%s", REG_VALUE_PREFIX, key ); - if (!keystr) { - SAFE_FREE(data.dptr); - return false; - } - keystr = normalize_reg_path(ctx, keystr); - if (!keystr) { - SAFE_FREE(data.dptr); - return false; - } - - old_data = tdb_fetch_bystring(tdb_reg->tdb, keystr); - - if ((old_data.dptr != NULL) - && (old_data.dsize == data.dsize) - && (memcmp(old_data.dptr, data.dptr, data.dsize) == 0)) { - SAFE_FREE(old_data.dptr); - SAFE_FREE(data.dptr); - return true; - } - - ret = tdb_trans_store_bystring(tdb_reg->tdb, keystr, data, TDB_REPLACE); - - SAFE_FREE( old_data.dptr ); - SAFE_FREE( data.dptr ); - - return ret != -1 ; -} - -static WERROR regdb_get_secdesc(TALLOC_CTX *mem_ctx, const char *key, - struct security_descriptor **psecdesc) -{ - char *tdbkey; - TDB_DATA data; - NTSTATUS status; - - DEBUG(10, ("regdb_get_secdesc: Getting secdesc of key [%s]\n", key)); - - if (asprintf(&tdbkey, "%s/%s", REG_SECDESC_PREFIX, key) == -1) { - return WERR_NOMEM; - } - normalize_dbkey(tdbkey); - - data = tdb_fetch_bystring(tdb_reg->tdb, tdbkey); - SAFE_FREE(tdbkey); - - if (data.dptr == NULL) { - return WERR_BADFILE; - } - - status = unmarshall_sec_desc(mem_ctx, (uint8 *)data.dptr, data.dsize, - psecdesc); - - SAFE_FREE(data.dptr); - - if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MEMORY)) { - return WERR_NOMEM; - } - - if (!NT_STATUS_IS_OK(status)) { - return WERR_REG_CORRUPT; - } - - return WERR_OK; -} - -static WERROR regdb_set_secdesc(const char *key, - struct security_descriptor *secdesc) -{ - prs_struct ps; - TALLOC_CTX *mem_ctx; - char *tdbkey; - WERROR err = WERR_NOMEM; - TDB_DATA tdbdata; - - if (!(mem_ctx = talloc_init("regdb_set_secdesc"))) { - return WERR_NOMEM; - } - - ZERO_STRUCT(ps); - - if (!(tdbkey = talloc_asprintf(mem_ctx, "%s/%s", REG_SECDESC_PREFIX, - key))) { - goto done; - } - normalize_dbkey(tdbkey); - - if (secdesc == NULL) { - /* assuming a delete */ - int tdb_ret; - - tdb_ret = tdb_trans_delete(tdb_reg->tdb, - string_term_tdb_data(tdbkey)); - if (tdb_ret == -1) { - err = ntstatus_to_werror(map_nt_error_from_unix(errno)); - } else { - err = WERR_OK; - } - - goto done; - } - - err = ntstatus_to_werror(marshall_sec_desc(mem_ctx, secdesc, - &tdbdata.dptr, - &tdbdata.dsize)); - if (!W_ERROR_IS_OK(err)) { - goto done; - } - - if (tdb_trans_store_bystring(tdb_reg->tdb, tdbkey, tdbdata, 0) == -1) { - err = ntstatus_to_werror(map_nt_error_from_unix(errno)); - goto done; - } - - done: - prs_mem_free(&ps); - TALLOC_FREE(mem_ctx); - 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 - */ - -REGISTRY_OPS regdb_ops = { - regdb_fetch_keys, - regdb_fetch_values, - regdb_store_keys, - regdb_store_values, - NULL, - regdb_get_secdesc, - regdb_set_secdesc, - regdb_subkeys_need_update, - regdb_values_need_update -}; -- cgit From 99186bf72642ad81505cb9588a444da4e89b3be2 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 21 Jan 2008 00:28:39 +0100 Subject: Extract regkey_open_internal() from reg_frontend.c to new reg_util_legacy.c reg_openpath should be used instead of this function (along with the reg_api interface). Last callers of this function are in services_db.c Michael (This used to be commit 0005b88d74fca1ea1410c9911d504b0a636a0472) --- source3/registry/reg_frontend.c | 18 --------------- source3/registry/reg_util_legacy.c | 47 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 18 deletions(-) create mode 100644 source3/registry/reg_util_legacy.c (limited to 'source3/registry') diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c index 9a35eb2263..fa210b4c05 100644 --- a/source3/registry/reg_frontend.c +++ b/source3/registry/reg_frontend.c @@ -99,21 +99,3 @@ bool init_registry( void ) 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; -} 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 . + */ + +/* 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; +} -- cgit From 42641d6321ca88efa07137af5ed17c3a17e9dcbf Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 21 Jan 2008 00:32:01 +0100 Subject: Extend/fix comments. Michael (This used to be commit 4952417fca89f5d797c861cde9fe74050ae02e2f) --- source3/registry/reg_frontend.c | 101 -------------------------------------- source3/registry/reg_init_full.c | 103 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 101 deletions(-) delete mode 100644 source3/registry/reg_frontend.c create mode 100644 source3/registry/reg_init_full.c (limited to 'source3/registry') diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c deleted file mode 100644 index fa210b4c05..0000000000 --- a/source3/registry/reg_frontend.c +++ /dev/null @@ -1,101 +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 . - */ - -/* 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 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, ¤t_version_reg_ops }, - { KEY_PERFLIB, &perflib_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(®_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_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 . + */ + +/* 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, ¤t_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(®_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; +} -- cgit From 1b4dfc2e7d7841ee0dba95062d5369d37dd85700 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 21 Jan 2008 00:34:06 +0100 Subject: Move reg_frontend_hilvl.c to reg_dispatcher.c This is actually the dispatcher to the registered registry backends. Michael (This used to be commit 39d65d11f8eff0aff998d5bfed8480b0f00655bd) --- source3/registry/reg_dispatcher.c | 235 ++++++++++++++++++++++++++++++++++ source3/registry/reg_frontend_hilvl.c | 235 ---------------------------------- 2 files changed, 235 insertions(+), 235 deletions(-) create mode 100644 source3/registry/reg_dispatcher.c delete mode 100644 source3/registry/reg_frontend_hilvl.c (limited to 'source3/registry') diff --git a/source3/registry/reg_dispatcher.c b/source3/registry/reg_dispatcher.c new file mode 100644 index 0000000000..e6e7613457 --- /dev/null +++ b/source3/registry/reg_dispatcher.c @@ -0,0 +1,235 @@ +/* + * Unix SMB/CIFS implementation. + * Virtual Windows Registry Layer + * Copyright (C) Gerald Carter 2002-2005 + * 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 . + */ + +/* + * Implementation of registry frontend view functions. + * Functions moved from reg_frontend.c to minimize linker deps. + */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_REGISTRY + +static const 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[3]; + 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); + + /* Full Access 'NT Authority\System' */ + + 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; + + 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 ( 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; + + 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 ); + + 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, ®_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); +} + +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) +{ + if (key->hook && key->hook->ops && key->hook->ops->set_secdesc) { + return key->hook->ops->set_secdesc(key->name, psecdesc); + } + + 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_frontend_hilvl.c b/source3/registry/reg_frontend_hilvl.c deleted file mode 100644 index e6e7613457..0000000000 --- a/source3/registry/reg_frontend_hilvl.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * Virtual Windows Registry Layer - * Copyright (C) Gerald Carter 2002-2005 - * 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 . - */ - -/* - * Implementation of registry frontend view functions. - * Functions moved from reg_frontend.c to minimize linker deps. - */ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_REGISTRY - -static const 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[3]; - 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); - - /* Full Access 'NT Authority\System' */ - - 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; - - 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 ( 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; - - 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 ); - - 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, ®_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); -} - -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) -{ - if (key->hook && key->hook->ops && key->hook->ops->set_secdesc) { - return key->hook->ops->set_secdesc(key->name, psecdesc); - } - - 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; -} - -- cgit From 99dfd664881f92dd1972f872c7471c5665869b86 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 21 Jan 2008 00:40:10 +0100 Subject: Rename lib/util_reg_smbconf.c to registry/reg_init_smbconf.c This actually is a counterpart to reg_init_full, in that is does open and initialize the registry too, but only registeres the backends necessary to access the SMBCONF key. Michael (This used to be commit 01bda3ab359fb3868c1dc849044f613bf2bc563e) --- source3/registry/reg_init_smbconf.c | 97 +++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 source3/registry/reg_init_smbconf.c (limited to 'source3/registry') 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 . + */ + +#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; +} -- cgit From 6d387037b1969391b71ea56717e21a11ef05323e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Jan 2008 11:13:19 +0100 Subject: Fix Coverity IDs 451, 452 (This used to be commit d28a537277bedb65d1c2a01c971a3a22b1aa6624) --- source3/registry/regfio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/registry') diff --git a/source3/registry/regfio.c b/source3/registry/regfio.c index 92077aa847..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; -- cgit From 9af84dd382aad55fcdfa803238d8edd57636f2aa Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 15 Feb 2008 13:57:31 +0100 Subject: Rename registry_init_regdb() to registry_init_smbconf(). That's what it actually is. Michael (This used to be commit 9d3c27f55726dbdce41fcf71c8bc1a7829340268) --- source3/registry/reg_init_smbconf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_init_smbconf.c b/source3/registry/reg_init_smbconf.c index 6452b0b15b..b7e6add112 100644 --- a/source3/registry/reg_init_smbconf.c +++ b/source3/registry/reg_init_smbconf.c @@ -67,13 +67,13 @@ done: * 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 registry_init_smbconf(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")); + DEBUG(10, ("registry_init_smbconf called\n")); if (!regdb_init()) { saved_errno = errno; -- cgit From 8fffca2e9505e08a6e9b89d88dcb43dc6fa69eb6 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 15 Feb 2008 14:23:31 +0100 Subject: Adapt a comment to current circumstances. Michael (This used to be commit 84ec89ab9f7837e8a9830a0236fddc2d00d1c0d6) --- source3/registry/reg_api.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index 9c4009368d..1358fcbde6 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -726,9 +726,7 @@ WERROR reg_deleteallvalues(struct registry_key *key) } /* - * Utility function to open a complete registry path including the hive - * prefix. This should become the replacement function for - * regkey_open_internal. + * Utility function to open a complete registry path including the hive prefix. */ WERROR reg_open_path(TALLOC_CTX *mem_ctx, const char *orig_path, -- cgit From c720a0e228bd157b8c743f8b98cc63817650d364 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 15 Feb 2008 15:14:20 +0100 Subject: Move implementation of _winreg_SaveKey() from srv_winreg_nt.c to reg_api.c This gives a new function reg_savekey() and hides a piece of the backend code from srv_winreg_nt.c. One step towards using reg_api throughout samba code. Michael (This used to be commit bf6340d00dd631fdc909c20632250977a3a112c4) --- source3/registry/reg_api.c | 168 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 167 insertions(+), 1 deletion(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index 1358fcbde6..fd3e08cacd 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -44,7 +44,7 @@ * 0x11 winreg_QueryValue reg_queryvalue * 0x12 winreg_ReplaceKey * 0x13 winreg_RestoreKey - * 0x14 winreg_SaveKey + * 0x14 winreg_SaveKey reg_savekey * 0x15 winreg_SetKeySecurity reg_setkeysecurity * 0x16 winreg_SetValue reg_setvalue * 0x17 winreg_UnLoadKey @@ -63,6 +63,7 @@ */ #include "includes.h" +#include "regfio.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_REGISTRY @@ -696,6 +697,171 @@ WERROR reg_getversion(uint32_t *version) return WERR_OK; } +/******************************************************************** +********************************************************************/ + +static WERROR reg_write_tree( REGF_FILE *regfile, const char *keypath, + REGF_NK_REC *parent, SEC_DESC *sec_desc ) +{ + REGF_NK_REC *key; + REGVAL_CTR *values; + REGSUBKEY_CTR *subkeys; + int i, num_subkeys; + char *key_tmp = NULL; + char *keyname, *parentpath; + char *subkeypath = NULL; + char *subkeyname; + REGISTRY_KEY registry_key; + WERROR result = WERR_OK; + + 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 object here to enumerate subkeys and values */ + + ZERO_STRUCT( registry_key ); + + if ( (registry_key.name = talloc_strdup(regfile->mem_ctx, keypath)) == NULL ) + return WERR_NOMEM; + + if ( (registry_key.hook = reghook_cache_find( registry_key.name )) == NULL ) + return WERR_BADFILE; + + /* lookup the values and subkeys */ + + if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) ) + return WERR_NOMEM; + + if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) + return WERR_NOMEM; + + fetch_reg_keys( ®istry_key, subkeys ); + fetch_reg_values( ®istry_key, values ); + + /* write out this key */ + + if ( !(key = regfio_write_key( regfile, keyname, values, subkeys, sec_desc, parent )) ) { + result = WERR_CAN_NOT_COMPLETE; + goto done; + } + + /* write each one of the subkeys out */ + + num_subkeys = regsubkey_ctr_numkeys( subkeys ); + for ( i=0; imem_ctx, + "%s\\%s", keypath, subkeyname); + if (!subkeypath) { + result = WERR_NOMEM; + goto done; + } + result = reg_write_tree( regfile, subkeypath, key, sec_desc ); + 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 const struct generic_mapping reg_generic_map = + { REG_KEY_READ, REG_KEY_WRITE, REG_KEY_EXECUTE, REG_KEY_ALL }; + +static WERROR make_default_reg_sd( TALLOC_CTX *ctx, SEC_DESC **psd ) +{ + DOM_SID adm_sid, owner_sid; + SEC_ACE ace[2]; /* at most 2 entries */ + SEC_ACCESS mask; + SEC_ACL *psa = NULL; + size_t sd_size; + + /* set the owner to BUILTIN\Administrator */ + + sid_copy(&owner_sid, &global_sid_Builtin); + sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN ); + + + /* basic access for Everyone */ + + init_sec_access(&mask, reg_generic_map.generic_execute | reg_generic_map.generic_read ); + init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); + + /* add Full Access 'BUILTIN\Administrators' */ + + init_sec_access(&mask, reg_generic_map.generic_all); + sid_copy(&adm_sid, &global_sid_Builtin); + sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS); + init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); + + /* create the security descriptor */ + + if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 2, ace)) == NULL) + return WERR_NOMEM; + + if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1, + SEC_DESC_SELF_RELATIVE, &owner_sid, NULL, + NULL, psa, &sd_size)) == NULL) + return WERR_NOMEM; + + return WERR_OK; +} + +static WERROR backup_registry_key ( REGISTRY_KEY *krecord, const char *fname ) +{ + REGF_FILE *regfile; + WERROR result; + SEC_DESC *sd = NULL; + + /* open the registry file....fail if the file already exists */ + + if ( !(regfile = regfio_open( fname, (O_RDWR|O_CREAT|O_EXCL), (S_IREAD|S_IWRITE) )) ) { + DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n", + fname, strerror(errno) )); + return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) ); + } + + if ( !W_ERROR_IS_OK(result = make_default_reg_sd( regfile->mem_ctx, &sd )) ) { + regfio_close( regfile ); + return result; + } + + /* write the registry tree to the file */ + + result = reg_write_tree( regfile, krecord->name, NULL, sd ); + + /* 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 **********************************************************************/ -- cgit From 355faf2e3d0aa83401c63e70a5aff9c9f5466195 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 15 Feb 2008 15:31:31 +0100 Subject: Move the implementation of _winreg_RestoreKey to reg_api.c This removes the internals of reg_api from srv_winreg_nt.c entirely, only reg_api is used there, now. This enlarges the dependencies of reg_api somewhat now since it adds regfio. But this can be separated out later. The current goal is to achieve a complete use of reg_api. Michael (This used to be commit 2222acbac955cd6d5bd48d1ce5cf4b4c7c067093) --- source3/registry/reg_api.c | 126 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 1 deletion(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index fd3e08cacd..6be60f04ec 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -43,7 +43,7 @@ * 0x10 winreg_QueryInfoKey reg_queryinfokey * 0x11 winreg_QueryValue reg_queryvalue * 0x12 winreg_ReplaceKey - * 0x13 winreg_RestoreKey + * 0x13 winreg_RestoreKey reg_restorekey * 0x14 winreg_SaveKey reg_savekey * 0x15 winreg_SetKeySecurity reg_setkeysecurity * 0x16 winreg_SetValue reg_setvalue @@ -697,6 +697,130 @@ 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; + REGISTRY_KEY registry_key; + REGVAL_CTR *values; + REGSUBKEY_CTR *subkeys; + int i; + char *path = NULL; + WERROR result = WERR_OK; + + /* initialize the REGISTRY_KEY structure */ + + if ( !(registry_key.hook = reghook_cache_find(topkeypath)) ) { + DEBUG(0,("reg_load_tree: Failed to assigned a REGISTRY_HOOK 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 */ + + if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) ) + return WERR_NOMEM; + + if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) + return WERR_NOMEM; + + /* copy values into the REGVAL_CTR */ + + for ( i=0; inum_values; i++ ) { + regval_ctr_addvalue( values, key->values[i].valuename, key->values[i].type, + (char*)key->values[i].data, (key->values[i].data_size & ~VK_DATA_IN_OFFSET) ); + } + + /* copy subkeys into the REGSUBKEY_CTR */ + + key->subkey_index = 0; + while ( (subkey = regfio_fetch_subkey( regfile, key )) ) { + regsubkey_ctr_addkey( subkeys, subkey->keyname ); + } + + /* write this key and values out */ + + if ( !store_reg_values( ®istry_key, values ) + || !store_reg_keys( ®istry_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) { + return WERR_NOMEM; + } + result = reg_load_tree( regfile, path, subkey ); + if ( !W_ERROR_IS_OK(result) ) + break; + } + + return result; +} + +/******************************************************************* + ********************************************************************/ + +static WERROR restore_registry_key ( REGISTRY_KEY *krecord, const char *fname ) +{ + REGF_FILE *regfile; + REGF_NK_REC *rootkey; + WERROR result; + + /* open the registry file....fail if the file already exists */ + + if ( !(regfile = regfio_open( fname, (O_RDONLY), 0 )) ) { + 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); +} + /******************************************************************** ********************************************************************/ -- cgit From abdedc7940b187789ffc583dabc778f824039095 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 15 Feb 2008 17:25:16 +0100 Subject: Reformat copied reg_savekey/reg_restorekey code. Sticking to coding rules. Michael (This used to be commit 2c54ef2d07ab440f1c163b666caedcb9c061543b) --- source3/registry/reg_api.c | 205 ++++++++++++++++++++++++++------------------- 1 file changed, 119 insertions(+), 86 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index 6be60f04ec..aba5735a0c 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -702,8 +702,8 @@ WERROR reg_getversion(uint32_t *version) loaded into (including the name of the key) ********************************************************************/ -static WERROR reg_load_tree( REGF_FILE *regfile, const char *topkeypath, - REGF_NK_REC *key ) +static WERROR reg_load_tree(REGF_FILE *regfile, const char *topkeypath, + REGF_NK_REC *key) { REGF_NK_REC *subkey; REGISTRY_KEY registry_key; @@ -715,68 +715,77 @@ static WERROR reg_load_tree( REGF_FILE *regfile, const char *topkeypath, /* initialize the REGISTRY_KEY structure */ - if ( !(registry_key.hook = reghook_cache_find(topkeypath)) ) { - DEBUG(0,("reg_load_tree: Failed to assigned a REGISTRY_HOOK to [%s]\n", - topkeypath )); + registry_key.hook = reghook_cache_find(topkeypath); + if (!registry_key.hook) { + DEBUG(0, ("reg_load_tree: Failed to assigned a REGISTRY_HOOK " + "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")); + 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 */ - if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) ) + subkeys = TALLOC_ZERO_P(regfile->mem_ctx, REGSUBKEY_CTR); + if (subkeys == NULL) { return WERR_NOMEM; + } - if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) + values = TALLOC_ZERO_P(subkeys, REGVAL_CTR); + if (values == NULL) { return WERR_NOMEM; + } /* copy values into the REGVAL_CTR */ - for ( i=0; inum_values; i++ ) { - regval_ctr_addvalue( values, key->values[i].valuename, key->values[i].type, - (char*)key->values[i].data, (key->values[i].data_size & ~VK_DATA_IN_OFFSET) ); + for (i=0; inum_values; i++) { + regval_ctr_addvalue(values, key->values[i].valuename, + key->values[i].type, + (char*)key->values[i].data, + (key->values[i].data_size & ~VK_DATA_IN_OFFSET)); } /* copy subkeys into the REGSUBKEY_CTR */ key->subkey_index = 0; - while ( (subkey = regfio_fetch_subkey( regfile, key )) ) { - regsubkey_ctr_addkey( subkeys, subkey->keyname ); + while ((subkey = regfio_fetch_subkey( regfile, key ))) { + regsubkey_ctr_addkey(subkeys, subkey->keyname); } /* write this key and values out */ - if ( !store_reg_values( ®istry_key, values ) - || !store_reg_keys( ®istry_key, subkeys ) ) + if (!store_reg_values(®istry_key, values) + || !store_reg_keys(®istry_key, subkeys)) { DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath)); result = WERR_REG_IO_FAILURE; } - TALLOC_FREE( subkeys ); + TALLOC_FREE(subkeys); - if ( !W_ERROR_IS_OK(result) ) + 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 )) ) { + while ((subkey = regfio_fetch_subkey(regfile, key))) { path = talloc_asprintf(regfile->mem_ctx, - "%s\\%s", - topkeypath, - subkey->keyname); - if (!path) { + "%s\\%s", + topkeypath, + subkey->keyname); + if (path == NULL) { return WERR_NOMEM; } - result = reg_load_tree( regfile, path, subkey ); - if ( !W_ERROR_IS_OK(result) ) + result = reg_load_tree(regfile, path, subkey); + if (!W_ERROR_IS_OK(result)) { break; + } } return result; @@ -785,33 +794,34 @@ static WERROR reg_load_tree( REGF_FILE *regfile, const char *topkeypath, /******************************************************************* ********************************************************************/ -static WERROR restore_registry_key ( REGISTRY_KEY *krecord, const char *fname ) +static WERROR restore_registry_key(REGISTRY_KEY *krecord, const char *fname) { REGF_FILE *regfile; REGF_NK_REC *rootkey; WERROR result; - + /* open the registry file....fail if the file already exists */ - - if ( !(regfile = regfio_open( fname, (O_RDONLY), 0 )) ) { - DEBUG(0,("restore_registry_key: failed to open \"%s\" (%s)\n", - fname, strerror(errno) )); - return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) ); - } - + + 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 ); + + if (!(rootkey = regfio_rootkey(regfile))) { + regfio_close(regfile); return WERR_REG_FILE_INVALID; } - result = reg_load_tree( regfile, krecord->name, rootkey ); + result = reg_load_tree(regfile, krecord->name, rootkey); /* cleanup */ - regfio_close( regfile ); + regfio_close(regfile); return result; } @@ -824,8 +834,8 @@ WERROR reg_restorekey(struct registry_key *key, const char *fname) /******************************************************************** ********************************************************************/ -static WERROR reg_write_tree( REGF_FILE *regfile, const char *keypath, - REGF_NK_REC *parent, SEC_DESC *sec_desc ) +static WERROR reg_write_tree(REGF_FILE *regfile, const char *keypath, + REGF_NK_REC *parent, SEC_DESC *sec_desc) { REGF_NK_REC *key; REGVAL_CTR *values; @@ -838,11 +848,13 @@ static WERROR reg_write_tree( REGF_FILE *regfile, const char *keypath, REGISTRY_KEY registry_key; WERROR result = WERR_OK; - if (!regfile) + if (!regfile) { return WERR_GENERAL_FAILURE; + } - if (!keypath) + if (!keypath) { return WERR_OBJECT_PATH_INVALID; + } /* split up the registry key path */ @@ -850,61 +862,73 @@ static WERROR reg_write_tree( REGF_FILE *regfile, const char *keypath, if (!key_tmp) { return WERR_NOMEM; } - if (!reg_split_key( key_tmp, &parentpath, &keyname ) ) + if (!reg_split_key(key_tmp, &parentpath, &keyname)) { return WERR_OBJECT_PATH_INVALID; + } - if ( !keyname ) + if (!keyname) { keyname = parentpath; + } /* we need a REGISTRY_KEY object here to enumerate subkeys and values */ - ZERO_STRUCT( registry_key ); + ZERO_STRUCT(registry_key); - if ( (registry_key.name = talloc_strdup(regfile->mem_ctx, keypath)) == NULL ) + registry_key.name = talloc_strdup(regfile->mem_ctx, keypath); + if (registry_key.name == NULL) { return WERR_NOMEM; + } - if ( (registry_key.hook = reghook_cache_find( registry_key.name )) == NULL ) + registry_key.hook = reghook_cache_find(registry_key.name); + if (registry_key.hook == NULL) { return WERR_BADFILE; + } /* lookup the values and subkeys */ - if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) ) + subkeys = TALLOC_ZERO_P(regfile->mem_ctx, REGSUBKEY_CTR); + if (subkeys == NULL) { return WERR_NOMEM; + } - if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) + values = TALLOC_ZERO_P(subkeys, REGVAL_CTR); + if (values == NULL) { return WERR_NOMEM; + } - fetch_reg_keys( ®istry_key, subkeys ); - fetch_reg_values( ®istry_key, values ); + fetch_reg_keys(®istry_key, subkeys); + fetch_reg_values(®istry_key, values); /* write out this key */ - if ( !(key = regfio_write_key( regfile, keyname, values, subkeys, sec_desc, parent )) ) { + 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; imem_ctx, - "%s\\%s", keypath, subkeyname); - if (!subkeypath) { + num_subkeys = regsubkey_ctr_numkeys(subkeys); + for (i=0; imem_ctx, "%s\\%s", + keypath, subkeyname); + if (subkeypath == NULL) { result = WERR_NOMEM; goto done; } - result = reg_write_tree( regfile, subkeypath, key, sec_desc ); - if ( !W_ERROR_IS_OK(result) ) + result = reg_write_tree(regfile, subkeypath, key, sec_desc); + if (!W_ERROR_IS_OK(result)) goto done; } - DEBUG(6,("reg_write_tree: wrote key [%s]\n", keypath )); + DEBUG(6, ("reg_write_tree: wrote key [%s]\n", keypath)); done: - TALLOC_FREE( subkeys ); - TALLOC_FREE( registry_key.name ); + TALLOC_FREE(subkeys); + TALLOC_FREE(registry_key.name); return result; } @@ -912,7 +936,7 @@ done: static const struct generic_mapping reg_generic_map = { REG_KEY_READ, REG_KEY_WRITE, REG_KEY_EXECUTE, REG_KEY_ALL }; -static WERROR make_default_reg_sd( TALLOC_CTX *ctx, SEC_DESC **psd ) +static WERROR make_default_reg_sd(TALLOC_CTX *ctx, SEC_DESC **psd) { DOM_SID adm_sid, owner_sid; SEC_ACE ace[2]; /* at most 2 entries */ @@ -928,8 +952,10 @@ static WERROR make_default_reg_sd( TALLOC_CTX *ctx, SEC_DESC **psd ) /* basic access for Everyone */ - init_sec_access(&mask, reg_generic_map.generic_execute | reg_generic_map.generic_read ); - init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); + init_sec_access(&mask, reg_generic_map.generic_execute + | reg_generic_map.generic_read); + init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, + mask, 0); /* add Full Access 'BUILTIN\Administrators' */ @@ -938,45 +964,52 @@ static WERROR make_default_reg_sd( TALLOC_CTX *ctx, SEC_DESC **psd ) sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS); init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - /* create the security descriptor */ + /* create the security descriptor */ - if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 2, ace)) == NULL) - return WERR_NOMEM; + psa = make_sec_acl(ctx, NT4_ACL_REVISION, 2, ace); + if (psa == NULL) { + return WERR_NOMEM; + } - if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1, - SEC_DESC_SELF_RELATIVE, &owner_sid, NULL, - NULL, psa, &sd_size)) == NULL) - return WERR_NOMEM; + *psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1, + SEC_DESC_SELF_RELATIVE, &owner_sid, NULL, + NULL, psa, &sd_size); + if (*psd == NULL) { + return WERR_NOMEM; + } return WERR_OK; } -static WERROR backup_registry_key ( REGISTRY_KEY *krecord, const char *fname ) +static WERROR backup_registry_key(REGISTRY_KEY *krecord, const char *fname) { REGF_FILE *regfile; WERROR result; SEC_DESC *sd = NULL; - + /* open the registry file....fail if the file already exists */ - if ( !(regfile = regfio_open( fname, (O_RDWR|O_CREAT|O_EXCL), (S_IREAD|S_IWRITE) )) ) { - DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n", - fname, strerror(errno) )); - return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) ); - } + 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)); + } - if ( !W_ERROR_IS_OK(result = make_default_reg_sd( regfile->mem_ctx, &sd )) ) { - regfio_close( regfile ); + result = make_default_reg_sd(regfile->mem_ctx, &sd); + if (!W_ERROR_IS_OK(result)) { + regfio_close(regfile); return result; } /* write the registry tree to the file */ - result = reg_write_tree( regfile, krecord->name, NULL, sd ); + result = reg_write_tree(regfile, krecord->name, NULL, sd); /* cleanup */ - regfio_close( regfile ); + regfio_close(regfile); return result; } -- cgit From d38e756feb33718ff252d65fccdf8e4c7fe8ab4a Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 18 Feb 2008 15:51:56 +0100 Subject: Use BUILTIN\administrators as owner of the default registry key security descriptor. Michael (This used to be commit 52e98157650d8dbc9b3ebb55f995ca543839543b) --- source3/registry/reg_dispatcher.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_dispatcher.c b/source3/registry/reg_dispatcher.c index e6e7613457..93b36f9289 100644 --- a/source3/registry/reg_dispatcher.c +++ b/source3/registry/reg_dispatcher.c @@ -63,7 +63,7 @@ static SEC_DESC* construct_registry_sd( TALLOC_CTX *ctx ) 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)) ) + if ( !(sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, &global_sid_Builtin_Administrators, NULL, NULL, acl, &sd_size)) ) return NULL; return sd; -- cgit From e16f039f26c88b8c602dc0d5e8a836688f7464d2 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 18 Feb 2008 14:44:51 +0100 Subject: Reformat construct_registry_sd() slightly (stick to coding rules). Michael (This used to be commit d87fb13959f84dfbbd3e1cc875f78d6e8ad44130) --- source3/registry/reg_dispatcher.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_dispatcher.c b/source3/registry/reg_dispatcher.c index 93b36f9289..f3fe5de98c 100644 --- a/source3/registry/reg_dispatcher.c +++ b/source3/registry/reg_dispatcher.c @@ -34,7 +34,7 @@ static const struct generic_mapping reg_generic_map = /******************************************************************** ********************************************************************/ -static SEC_DESC* construct_registry_sd( TALLOC_CTX *ctx ) +static SEC_DESC* construct_registry_sd(TALLOC_CTX *ctx) { SEC_ACE ace[3]; SEC_ACCESS mask; @@ -45,26 +45,35 @@ static SEC_DESC* construct_registry_sd( TALLOC_CTX *ctx ) /* 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); + 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); + init_sec_access(&mask, REG_KEY_ALL); + init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, + SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); /* Full Access 'NT Authority\System' */ init_sec_access(&mask, REG_KEY_ALL ); - init_sec_ace(&ace[i++], &global_sid_System, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); + 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)) ) + acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace); + if (acl == NULL) { return NULL; + } - if ( !(sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, &global_sid_Builtin_Administrators, NULL, NULL, acl, &sd_size)) ) + sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, + &global_sid_Builtin_Administrators, NULL, NULL, acl, + &sd_size); + if (sd == NULL) { return NULL; + } return sd; } -- cgit From 59e7ee6d7db618432ab22e023ddc1cf03bb34da8 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 18 Feb 2008 14:55:48 +0100 Subject: Change construct_registry_sd() to return WERROR instead of the SEC_DESC *. Michael (This used to be commit 91dbe79df2636959381825af6ab8a66abd7f97a1) --- source3/registry/reg_dispatcher.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_dispatcher.c b/source3/registry/reg_dispatcher.c index f3fe5de98c..778a844883 100644 --- a/source3/registry/reg_dispatcher.c +++ b/source3/registry/reg_dispatcher.c @@ -34,7 +34,7 @@ static const struct generic_mapping reg_generic_map = /******************************************************************** ********************************************************************/ -static SEC_DESC* construct_registry_sd(TALLOC_CTX *ctx) +static WERROR construct_registry_sd(TALLOC_CTX *ctx, SEC_DESC **psd) { SEC_ACE ace[3]; SEC_ACCESS mask; @@ -65,17 +65,18 @@ static SEC_DESC* construct_registry_sd(TALLOC_CTX *ctx) acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace); if (acl == NULL) { - return NULL; + return WERR_NOMEM; } sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, &global_sid_Builtin_Administrators, NULL, NULL, acl, &sd_size); if (sd == NULL) { - return NULL; + return WERR_NOMEM; } - return sd; + *psd = sd; + return WERR_OK; } /*********************************************************************** @@ -185,19 +186,19 @@ WERROR regkey_get_secdesc(TALLOC_CTX *mem_ctx, REGISTRY_KEY *key, struct security_descriptor **psecdesc) { struct security_descriptor *secdesc; + WERROR werr; 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)) { + werr = key->hook->ops->get_secdesc(mem_ctx, key->name, + psecdesc); + if (W_ERROR_IS_OK(werr)) { return WERR_OK; } } - if (!(secdesc = construct_registry_sd(mem_ctx))) { - return WERR_NOMEM; + werr = construct_registry_sd(mem_ctx, &secdesc); + if (!W_ERROR_IS_OK(werr)) { + return werr; } *psecdesc = secdesc; -- cgit From f3694d50a37c60897849a49946128228a259207e Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 18 Feb 2008 16:03:16 +0100 Subject: Add NT Authority\System as group sid to default registry key security descriptor. Michael (This used to be commit 9f0448ca323a6645ad662c97d92a7e30320e0c11) --- source3/registry/reg_dispatcher.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_dispatcher.c b/source3/registry/reg_dispatcher.c index 778a844883..cdcd045904 100644 --- a/source3/registry/reg_dispatcher.c +++ b/source3/registry/reg_dispatcher.c @@ -69,7 +69,8 @@ static WERROR construct_registry_sd(TALLOC_CTX *ctx, SEC_DESC **psd) } sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, - &global_sid_Builtin_Administrators, NULL, NULL, acl, + &global_sid_Builtin_Administrators, + &global_sid_System, NULL, acl, &sd_size); if (sd == NULL) { return WERR_NOMEM; -- cgit From 7ba906634bc89a0a9180687402ecb52ccb5f13c4 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 18 Feb 2008 16:33:47 +0100 Subject: Grab secdesc for key from registry for reg_savekey() instead of construction another default secdesc. Michael (This used to be commit 194e00822c349aa0c11641672b35b0e0c021da08) --- source3/registry/reg_api.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index aba5735a0c..25cf101aaf 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -835,7 +835,7 @@ WERROR reg_restorekey(struct registry_key *key, const char *fname) ********************************************************************/ static WERROR reg_write_tree(REGF_FILE *regfile, const char *keypath, - REGF_NK_REC *parent, SEC_DESC *sec_desc) + REGF_NK_REC *parent) { REGF_NK_REC *key; REGVAL_CTR *values; @@ -847,6 +847,7 @@ static WERROR reg_write_tree(REGF_FILE *regfile, const char *keypath, char *subkeyname; REGISTRY_KEY registry_key; WERROR result = WERR_OK; + SEC_DESC *sec_desc = NULL; if (!regfile) { return WERR_GENERAL_FAILURE; @@ -899,6 +900,11 @@ static WERROR reg_write_tree(REGF_FILE *regfile, const char *keypath, fetch_reg_keys(®istry_key, subkeys); fetch_reg_values(®istry_key, values); + result = regkey_get_secdesc(regfile->mem_ctx, ®istry_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, @@ -919,7 +925,7 @@ static WERROR reg_write_tree(REGF_FILE *regfile, const char *keypath, result = WERR_NOMEM; goto done; } - result = reg_write_tree(regfile, subkeypath, key, sec_desc); + result = reg_write_tree(regfile, subkeypath, key); if (!W_ERROR_IS_OK(result)) goto done; } @@ -985,7 +991,6 @@ static WERROR backup_registry_key(REGISTRY_KEY *krecord, const char *fname) { REGF_FILE *regfile; WERROR result; - SEC_DESC *sd = NULL; /* open the registry file....fail if the file already exists */ @@ -997,15 +1002,9 @@ static WERROR backup_registry_key(REGISTRY_KEY *krecord, const char *fname) return ntstatus_to_werror(map_nt_error_from_unix(errno)); } - result = make_default_reg_sd(regfile->mem_ctx, &sd); - if (!W_ERROR_IS_OK(result)) { - regfio_close(regfile); - return result; - } - /* write the registry tree to the file */ - result = reg_write_tree(regfile, krecord->name, NULL, sd); + result = reg_write_tree(regfile, krecord->name, NULL); /* cleanup */ -- cgit From bb0bf5c902c4fbf51efaeab8548fae215caf40e3 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 18 Feb 2008 16:34:39 +0100 Subject: Remove (now) unused function make_default_reg_sd(). Michael (This used to be commit 2c66413de284fb4cb9dc7def0ee4eb07b986c9ca) --- source3/registry/reg_api.c | 48 ---------------------------------------------- 1 file changed, 48 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index 25cf101aaf..e52aaacb4d 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -939,54 +939,6 @@ done: return result; } -static const struct generic_mapping reg_generic_map = - { REG_KEY_READ, REG_KEY_WRITE, REG_KEY_EXECUTE, REG_KEY_ALL }; - -static WERROR make_default_reg_sd(TALLOC_CTX *ctx, SEC_DESC **psd) -{ - DOM_SID adm_sid, owner_sid; - SEC_ACE ace[2]; /* at most 2 entries */ - SEC_ACCESS mask; - SEC_ACL *psa = NULL; - size_t sd_size; - - /* set the owner to BUILTIN\Administrator */ - - sid_copy(&owner_sid, &global_sid_Builtin); - sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN ); - - - /* basic access for Everyone */ - - init_sec_access(&mask, reg_generic_map.generic_execute - | reg_generic_map.generic_read); - init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, - mask, 0); - - /* add Full Access 'BUILTIN\Administrators' */ - - init_sec_access(&mask, reg_generic_map.generic_all); - sid_copy(&adm_sid, &global_sid_Builtin); - sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS); - init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - - /* create the security descriptor */ - - psa = make_sec_acl(ctx, NT4_ACL_REVISION, 2, ace); - if (psa == NULL) { - return WERR_NOMEM; - } - - *psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1, - SEC_DESC_SELF_RELATIVE, &owner_sid, NULL, - NULL, psa, &sd_size); - if (*psd == NULL) { - return WERR_NOMEM; - } - - return WERR_OK; -} - static WERROR backup_registry_key(REGISTRY_KEY *krecord, const char *fname) { REGF_FILE *regfile; -- cgit From 9e9cd40a7d755b19ad70011409d213c9e9013fe6 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 19 Feb 2008 01:04:31 +0100 Subject: Make regdb_init() behave like regdb_open() when registry is already opened. I.e. increment the refcounter. Michael (This used to be commit 951d3fae2cbea09cc4e1806cbf0a94ecdfcee8d5) --- source3/registry/reg_backend_db.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/registry') diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index e162fb587f..52e0fd4289 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -258,8 +258,11 @@ bool regdb_init( void ) const char *vstring = "INFO/version"; uint32 vers_id; - if ( tdb_reg ) + if ( tdb_reg ) { + DEBUG(10,("regdb_init: incrementing refcount (%d)\n", tdb_refcount)); + tdb_refcount++; return true; + } if ( !(tdb_reg = tdb_wrap_open(NULL, state_path("registry.tdb"), 0, REG_TDB_FLAGS, O_RDWR, 0600)) ) { -- cgit From 34eef81d2ab05e576401da1f80a264f1fd193f36 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 18 Feb 2008 20:37:33 +1100 Subject: Fix double free bugs after calling regfio_close() (This used to be commit 737bb950d50ac6c5d4f99279bf535ae3a9963b2f) --- source3/registry/regfio.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/registry') diff --git a/source3/registry/regfio.c b/source3/registry/regfio.c index 3740ff0ee4..1c3aad7a25 100644 --- a/source3/registry/regfio.c +++ b/source3/registry/regfio.c @@ -1171,7 +1171,6 @@ out: if ( !(rb->mem_ctx = talloc_init( "read_regf_block" )) ) { regfio_close( rb ); - SAFE_FREE(rb); return NULL; } @@ -1182,7 +1181,6 @@ out: if ( (rb->fd = open(filename, flags, mode)) == -1 ) { DEBUG(0,("regfio_open: failure to open %s (%s)\n", filename, strerror(errno))); regfio_close( rb ); - SAFE_FREE(rb); return NULL; } @@ -1192,7 +1190,6 @@ out: if ( !init_regf_block( rb ) ) { DEBUG(0,("regfio_open: Failed to read initial REGF block\n")); regfio_close( rb ); - SAFE_FREE(rb); return NULL; } @@ -1205,7 +1202,6 @@ out: if ( !read_regf_block( rb ) ) { DEBUG(0,("regfio_open: Failed to read initial REGF block\n")); regfio_close( rb ); - SAFE_FREE(rb); return NULL; } -- cgit