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