From 01a1e5cdb0339a7cb3a85280b118985562bb2d7f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 7 Oct 2005 12:14:25 +0000 Subject: r10819: merging a couple of fixes from trunk * only keep the registry,tdb file open when we have an open key handle * tpot's setup.py fix * removing files that no longer exist in trunk and copying some that were missing in 3.0 (This used to be commit 6c6bf6ca5fd430a7a20bf20ed08050328660e570) --- source3/include/rpc_buffer.h | 35 --------- source3/include/rpc_creds.h | 96 ------------------------- source3/include/rpc_parse.h | 30 -------- source3/modules/developer.c | 132 ++++++++++++++++++++++++++++++++++ source3/python/setup.py | 31 ++++---- source3/registry/reg_db.c | 62 +++++++++++++++- source3/registry/reg_frontend.c | 26 ++++++- source3/rpc_server/srv_eventlog_lib.c | 3 +- source3/rpc_server/srv_eventlog_nt.c | 2 +- source3/rpc_server/srv_reg_nt.c | 5 +- source3/services/services_db.c | 34 +++++---- 11 files changed, 257 insertions(+), 199 deletions(-) delete mode 100644 source3/include/rpc_buffer.h delete mode 100644 source3/include/rpc_creds.h delete mode 100644 source3/include/rpc_parse.h create mode 100644 source3/modules/developer.c (limited to 'source3') diff --git a/source3/include/rpc_buffer.h b/source3/include/rpc_buffer.h deleted file mode 100644 index da2be8a4df..0000000000 --- a/source3/include/rpc_buffer.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Unix SMB/Netbios implementation. - - Copyright (C) Andrew Tridgell 1992-2000, - Copyright (C) Luke Kenneth Casson Leighton 1996-2000, - Copyright (C) Jean Francois Micouleau 1998-2000. - Copyright (C) Gerald Carter 2001-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 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef _RPC_BUFFER_H /* _RPC_SPOOLSS_H */ -#define _RPC_BUFFER_H - -typedef struct { - uint32 size; - prs_struct prs; - uint32 struct_start; - uint32 string_at_end; -} RPC_BUFFER; - - -#endif /* _RPC_BUFFER_H */ diff --git a/source3/include/rpc_creds.h b/source3/include/rpc_creds.h deleted file mode 100644 index 3022b17289..0000000000 --- a/source3/include/rpc_creds.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SMB parameters and setup - Copyright (C) Andrew Tridgell 1992-1999 - Copyright (C) Luke Kenneth Casson Leighton 1996-1999 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - - -#ifndef _RPC_CREDS_H /* _RPC_CREDS_H */ -#define _RPC_CREDS_H - -typedef struct ntuser_creds -{ - fstring user_name; - fstring domain; - struct pwd_info pwd; - - uint32 ntlmssp_flags; - -} CREDS_NT; - -typedef struct unixuser_creds -{ - fstring user_name; - fstring requested_name; - fstring real_name; - BOOL guest; - -} CREDS_UNIX; - -typedef struct unixsec_creds -{ - uint32 uid; - uint32 gid; - int num_grps; - uint32 *grps; - -} CREDS_UNIX_SEC; - -typedef struct ntsec_creds -{ - DOM_SID sid; - uint32 num_grps; - uint32 *grp_rids; - -} CREDS_NT_SEC; - -typedef struct user_creds -{ - BOOL reuse; - - uint32 ptr_ntc; - uint32 ptr_uxc; - uint32 ptr_nts; - uint32 ptr_uxs; - uint32 ptr_ssk; - - CREDS_NT ntc; - CREDS_UNIX uxc; - - CREDS_NT_SEC nts; - CREDS_UNIX_SEC uxs; - - uchar usr_sess_key[16]; - -} CREDS_HYBRID; - -typedef struct cred_command -{ - uint16 version; - uint16 command; - uint32 pid; /* unique process id */ - - fstring name; - - uint32 ptr_creds; - CREDS_HYBRID *cred; - -} CREDS_CMD; - -#endif /* _RPC_CREDS_H */ - diff --git a/source3/include/rpc_parse.h b/source3/include/rpc_parse.h deleted file mode 100644 index 73fbcb2b1b..0000000000 --- a/source3/include/rpc_parse.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SMB parameters and setup - Copyright (C) Andrew Tridgell 1992-2000 - Copyright (C) Luke Kenneth Casson Leighton 1996-2000 - Copyright (C) Elrond 2000 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef _RPC_PARSE_H -#define _RPC_PARSE_H - -/* different dce/rpc pipes */ -#include "rpc_reg.h" -#include "rpc_brs.h" - -#endif /* _RPC_PARSE_H */ diff --git a/source3/modules/developer.c b/source3/modules/developer.c new file mode 100644 index 0000000000..7ffc3ff50d --- /dev/null +++ b/source3/modules/developer.c @@ -0,0 +1,132 @@ +/* + Unix SMB/CIFS implementation. + Samba module with developer tools + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Jelmer Vernooij 2002 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +static struct { + char from; + char *to; + int len; +} weird_table[] = { + {'q', "^q^", 3}, + {'Q', "^Q^", 3}, + {0, NULL} +}; + +static size_t weird_pull(void *cd, char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft) +{ + while (*inbytesleft >= 1 && *outbytesleft >= 2) { + int i; + int done = 0; + for (i=0;weird_table[i].from;i++) { + if (strncmp((*inbuf), + weird_table[i].to, + weird_table[i].len) == 0) { + if (*inbytesleft < weird_table[i].len) { + DEBUG(0,("ERROR: truncated weird string\n")); + /* smb_panic("weird_pull"); */ + + } else { + (*outbuf)[0] = weird_table[i].from; + (*outbuf)[1] = 0; + (*inbytesleft) -= weird_table[i].len; + (*outbytesleft) -= 2; + (*inbuf) += weird_table[i].len; + (*outbuf) += 2; + done = 1; + break; + } + } + } + if (done) continue; + (*outbuf)[0] = (*inbuf)[0]; + (*outbuf)[1] = 0; + (*inbytesleft) -= 1; + (*outbytesleft) -= 2; + (*inbuf) += 1; + (*outbuf) += 2; + } + + if (*inbytesleft > 0) { + errno = E2BIG; + return -1; + } + + return 0; +} + +static size_t weird_push(void *cd, char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft) +{ + int ir_count=0; + + while (*inbytesleft >= 2 && *outbytesleft >= 1) { + int i; + int done=0; + for (i=0;weird_table[i].from;i++) { + if ((*inbuf)[0] == weird_table[i].from && + (*inbuf)[1] == 0) { + if (*outbytesleft < weird_table[i].len) { + DEBUG(0,("No room for weird character\n")); + /* smb_panic("weird_push"); */ + } else { + memcpy(*outbuf, weird_table[i].to, + weird_table[i].len); + (*inbytesleft) -= 2; + (*outbytesleft) -= weird_table[i].len; + (*inbuf) += 2; + (*outbuf) += weird_table[i].len; + done = 1; + break; + } + } + } + if (done) continue; + + (*outbuf)[0] = (*inbuf)[0]; + if ((*inbuf)[1]) ir_count++; + (*inbytesleft) -= 2; + (*outbytesleft) -= 1; + (*inbuf) += 2; + (*outbuf) += 1; + } + + if (*inbytesleft == 1) { + errno = EINVAL; + return -1; + } + + if (*inbytesleft > 1) { + errno = E2BIG; + return -1; + } + + return ir_count; +} + +struct charset_functions weird_functions = {"WEIRD", weird_pull, weird_push}; + +int charset_weird_init(void) +{ + smb_register_charset(&weird_functions); + return True; +} diff --git a/source3/python/setup.py b/source3/python/setup.py index a8b2c2c26d..18f1f2648a 100755 --- a/source3/python/setup.py +++ b/source3/python/setup.py @@ -52,21 +52,28 @@ obj_list = string.split(samba_objs) libraries = [] library_dirs = [] +next_is_path = 0 +next_is_flag = 0 + for lib in string.split(samba_libs): - if lib[0:2] == "-l": - libraries.append(lib[2:]) - continue - if lib[0:8] == "-pthread": + if next_is_path != 0: + library_dirs.append(lib); + next_is_path = 0; + elif next_is_flag != 0: + next_is_flag = 0; + elif lib == "-Wl,-rpath": + next_is_path = 1; + elif lib[0:2] in ("-l","-pthread"): libraries.append(lib[2:]) - continue - if lib[0:2] == "-L": + elif lib[0:2] == "-L": library_dirs.append(lib[2:]) - continue - if lib[0:2] == "-W": - # Skip linker flags - continue - print "Unknown entry '%s' in $LIBS variable passed to setup.py" % lib - sys.exit(1) + elif lib[0:2] in ("-W","-s"): + pass # Skip linker flags + elif lib[0:2] == "-z": + next_is_flag = 1 # Skip linker flags + else: + print "Unknown entry '%s' in $LIBS variable passed to setup.py" % lib + sys.exit(1) flags_list = string.split(samba_cflags) diff --git a/source3/registry/reg_db.c b/source3/registry/reg_db.c index ab8fc14d90..ddc08cf2ce 100644 --- a/source3/registry/reg_db.c +++ b/source3/registry/reg_db.c @@ -26,6 +26,7 @@ #define DBGC_CLASS DBGC_RPC_SRV static TDB_CONTEXT *tdb_reg; +static int tdb_refcount; #define VALUE_PREFIX "SAMBA_REGVAL" @@ -196,7 +197,7 @@ static BOOL init_registry_data( void ) Open the registry database ***********************************************************************/ -BOOL init_registry_db( void ) +BOOL regdb_init( void ) { const char *vstring = "INFO/version"; uint32 vers_id; @@ -208,13 +209,15 @@ BOOL init_registry_db( void ) { tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); if ( !tdb_reg ) { - DEBUG(0,("init_registry: Failed to open registry %s (%s)\n", + DEBUG(0,("regdb_init: Failed to open registry %s (%s)\n", lock_path("registry.tdb"), strerror(errno) )); return False; } - DEBUG(10,("init_registry: Successfully created registry tdb\n")); + DEBUG(10,("regdb_init: Successfully created registry tdb\n")); } + + tdb_refcount = 1; vers_id = tdb_fetch_int32(tdb_reg, vstring); @@ -233,6 +236,59 @@ BOOL init_registry_db( void ) 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_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, 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", + lock_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 ) +{ + int ret; + + tdb_refcount--; + + DEBUG(10,("regdb_close: decrementing refcount (%d)\n", tdb_refcount)); + + if ( tdb_refcount > 0 ) + return 0; + + SMB_ASSERT( tdb_refcount >= 0 ); + + ret = tdb_close( tdb_reg ); + tdb_reg = NULL; + + return ret; +} + /*********************************************************************** Add subkey strings to the registry tdb under a defined key fmt is the same format as tdb_pack except this function only supports diff --git a/source3/registry/reg_frontend.c b/source3/registry/reg_frontend.c index f5284e9e88..b0e713a882 100644 --- a/source3/registry/reg_frontend.c +++ b/source3/registry/reg_frontend.c @@ -110,7 +110,7 @@ BOOL init_registry( void ) int i; - if ( !init_registry_db() ) { + if ( !regdb_init() ) { DEBUG(0,("init_registry: failed to initialize the registry tdb!\n")); return False; } @@ -132,6 +132,10 @@ BOOL init_registry( void ) svcctl_init_keys(); eventlog_init_keys(); + /* close and let each smbd open up as necessary */ + + regdb_close(); + return True; } @@ -348,10 +352,15 @@ WERROR regkey_open_internal( REGISTRY_KEY **regkey, const char *path, REGSUBKEY_CTR *subkeys = NULL; uint32 access_granted; + if ( !(W_ERROR_IS_OK(result = regdb_open()) ) ) + return result; + DEBUG(7,("regkey_open_internal: name = [%s]\n", path)); - if ( !(*regkey = TALLOC_ZERO_P(NULL, REGISTRY_KEY)) ) + if ( !(*regkey = TALLOC_ZERO_P(NULL, REGISTRY_KEY)) ) { + regdb_close(); return WERR_NOMEM; + } keyinfo = *regkey; @@ -399,8 +408,19 @@ WERROR regkey_open_internal( REGISTRY_KEY **regkey, const char *path, done: if ( !W_ERROR_IS_OK(result) ) { - TALLOC_FREE( *regkey ); + regkey_close_internal( *regkey ); } return result; } + +/******************************************************************* +*******************************************************************/ + +WERROR regkey_close_internal( REGISTRY_KEY *key ) +{ + TALLOC_FREE( key ); + regdb_close(); + + return WERR_OK; +} diff --git a/source3/rpc_server/srv_eventlog_lib.c b/source3/rpc_server/srv_eventlog_lib.c index 8c7ce4a648..3b7a32dac2 100644 --- a/source3/rpc_server/srv_eventlog_lib.c +++ b/source3/rpc_server/srv_eventlog_lib.c @@ -304,8 +304,7 @@ TDB_CONTEXT *open_eventlog_tdb( char *tdbfilename ) TDB_CONTEXT *the_tdb; the_tdb = - tdb_open_log( tdbfilename, 0, TDB_DEFAULT, O_RDWR | O_CREAT, - 0664 ); + tdb_open_log( tdbfilename, 0, TDB_DEFAULT, O_RDONLY,0664 ); if ( the_tdb == NULL ) { return init_eventlog_tdb( tdbfilename ); } diff --git a/source3/rpc_server/srv_eventlog_nt.c b/source3/rpc_server/srv_eventlog_nt.c index 6067c94fe8..d3b350f233 100644 --- a/source3/rpc_server/srv_eventlog_nt.c +++ b/source3/rpc_server/srv_eventlog_nt.c @@ -400,7 +400,7 @@ static BOOL sync_eventlog_params( const char *elogname ) if ( ( val = regval_ctr_getvalue( values, "MaxSize" ) ) != NULL ) uiMaxSize = IVAL( regval_data_p( val ), 0 ); - TALLOC_FREE( keyinfo ); + regkey_close_internal( keyinfo ); tdb_store_int32( the_tdb, VN_maxsize, uiMaxSize ); tdb_store_int32( the_tdb, VN_retention, uiRetention ); diff --git a/source3/rpc_server/srv_reg_nt.c b/source3/rpc_server/srv_reg_nt.c index 0ba3e04b99..47c8746b12 100644 --- a/source3/rpc_server/srv_reg_nt.c +++ b/source3/rpc_server/srv_reg_nt.c @@ -43,7 +43,7 @@ static struct generic_mapping reg_generic_map = static void free_regkey_info(void *ptr) { - TALLOC_FREE( ptr ); + regkey_close_internal( (REGISTRY_KEY*)ptr ); } /****************************************************************** @@ -99,10 +99,9 @@ static WERROR open_registry_key( pipes_struct *p, POLICY_HND *hnd, if ( !create_policy_hnd( p, hnd, free_regkey_info, *keyinfo ) ) { result = WERR_BADFILE; - TALLOC_FREE( *keyinfo ); + regkey_close_internal( *keyinfo ); } - return result; } diff --git a/source3/services/services_db.c b/source3/services/services_db.c index 7c75d41352..e1b2f88865 100644 --- a/source3/services/services_db.c +++ b/source3/services/services_db.c @@ -325,6 +325,7 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, if ( !(svc_subkeys = TALLOC_ZERO_P( key_service, REGSUBKEY_CTR )) ) { DEBUG(0,("add_new_svc_name: talloc() failed!\n")); + regkey_close_internal( key_service ); return; } @@ -336,6 +337,7 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, if ( !(values = TALLOC_ZERO_P( key_service, REGVAL_CTR )) ) { DEBUG(0,("add_new_svc_name: talloc() failed!\n")); + regkey_close_internal( key_service ); return; } @@ -344,7 +346,7 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, /* cleanup the service key*/ - TALLOC_FREE( key_service ); + regkey_close_internal( key_service ); /* now add the security descriptor */ @@ -354,17 +356,19 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("add_new_svc_name: key lookup failed! [%s] (%s)\n", path, dos_errstr(wresult))); + regkey_close_internal( key_secdesc ); return; } if ( !(values = TALLOC_ZERO_P( key_secdesc, REGVAL_CTR )) ) { DEBUG(0,("add_new_svc_name: talloc() failed!\n")); + regkey_close_internal( key_secdesc ); return; } if ( !(sd = construct_service_sd(key_secdesc)) ) { DEBUG(0,("add_new_svc_name: Failed to create default sec_desc!\n")); - TALLOC_FREE( key_secdesc ); + regkey_close_internal( key_secdesc ); return; } @@ -381,7 +385,7 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, /* finally cleanup the Security key */ prs_mem_free( &ps ); - TALLOC_FREE( key_secdesc ); + regkey_close_internal( key_secdesc ); return; } @@ -413,6 +417,7 @@ void svcctl_init_keys( void ) if ( !(subkeys = TALLOC_ZERO_P( key, REGSUBKEY_CTR )) ) { DEBUG(0,("init_services_keys: talloc() failed!\n")); + regkey_close_internal( key ); return; } @@ -436,7 +441,7 @@ void svcctl_init_keys( void ) new_services = True; } - TALLOC_FREE( key ); + regkey_close_internal( key ); /* initialize the control hooks */ @@ -474,7 +479,7 @@ SEC_DESC* svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN * if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) { DEBUG(0,("add_new_svc_name: talloc() failed!\n")); - TALLOC_FREE( key ); + regkey_close_internal( key ); return NULL; } @@ -483,7 +488,7 @@ SEC_DESC* svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN * if ( !(val = regval_ctr_getvalue( values, "Security" )) ) { DEBUG(6,("svcctl_get_secdesc: constructing default secdesc for service [%s]\n", name)); - TALLOC_FREE( key ); + regkey_close_internal( key ); return construct_service_sd( ctx ); } @@ -494,7 +499,7 @@ SEC_DESC* svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN * prs_give_memory( &ps, regval_data_p(val), regval_size(val), False ); if ( !sec_io_desc("sec_desc", &sd, &ps, 0 ) ) { - TALLOC_FREE( key ); + regkey_close_internal( key ); return construct_service_sd( ctx ); } @@ -503,7 +508,7 @@ SEC_DESC* svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN * /* finally cleanup the Security key */ prs_mem_free( &ps ); - TALLOC_FREE( key ); + regkey_close_internal( key ); return ret_sd; } @@ -532,7 +537,7 @@ char* svcctl_lookup_dispname( const char *name, NT_USER_TOKEN *token ) if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) { DEBUG(0,("svcctl_lookup_dispname: talloc() failed!\n")); - TALLOC_FREE( key ); + regkey_close_internal( key ); goto fail; } @@ -543,12 +548,13 @@ char* svcctl_lookup_dispname( const char *name, NT_USER_TOKEN *token ) rpcstr_pull( display_name, regval_data_p(val), sizeof(display_name), regval_size(val), 0 ); - TALLOC_FREE( key ); + regkey_close_internal( key ); return display_name; fail: /* default to returning the service name */ + regkey_close_internal( key ); fstrcpy( display_name, name ); return display_name; } @@ -577,7 +583,7 @@ char* svcctl_lookup_description( const char *name, NT_USER_TOKEN *token ) if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) { DEBUG(0,("svcctl_lookup_dispname: talloc() failed!\n")); - TALLOC_FREE( key ); + regkey_close_internal( key ); return NULL; } @@ -588,7 +594,7 @@ char* svcctl_lookup_description( const char *name, NT_USER_TOKEN *token ) else rpcstr_pull( description, regval_data_p(val), sizeof(description), regval_size(val), 0 ); - TALLOC_FREE( key ); + regkey_close_internal( key ); return description; } @@ -616,13 +622,13 @@ REGVAL_CTR* svcctl_fetch_regvalues( const char *name, NT_USER_TOKEN *token ) if ( !(values = TALLOC_ZERO_P( NULL, REGVAL_CTR )) ) { DEBUG(0,("svcctl_fetch_regvalues: talloc() failed!\n")); - TALLOC_FREE( key ); + regkey_close_internal( key ); return NULL; } fetch_reg_values( key, values ); - TALLOC_FREE( key ); + regkey_close_internal( key ); return values; } -- cgit