r10819: merging a couple of fixes from trunk
authorGerald Carter <jerry@samba.org>
Fri, 7 Oct 2005 12:14:25 +0000 (12:14 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:04:54 +0000 (11:04 -0500)
* 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 [deleted file]
source3/include/rpc_creds.h [deleted file]
source3/include/rpc_parse.h [deleted file]
source3/modules/developer.c [new file with mode: 0644]
source3/python/setup.py
source3/registry/reg_db.c
source3/registry/reg_frontend.c
source3/rpc_server/srv_eventlog_lib.c
source3/rpc_server/srv_eventlog_nt.c
source3/rpc_server/srv_reg_nt.c
source3/services/services_db.c

diff --git a/source3/include/rpc_buffer.h b/source3/include/rpc_buffer.h
deleted file mode 100644 (file)
index da2be8a..0000000
+++ /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 (file)
index 3022b17..0000000
+++ /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 (file)
index 73fbcb2..0000000
+++ /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 (file)
index 0000000..7ffc3ff
--- /dev/null
@@ -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;
+}
index a8b2c2c26d60701ba4d36241328246ee764d0d1d..18f1f2648abada28f72d9dd72d4230b53d7e0c75 100755 (executable)
@@ -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)
 
index ab8fc14d909cd04c7787551749980f04881df763..ddc08cf2ce4a0627b1b9f48558a2626e7a5798a8 100644 (file)
@@ -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
index f5284e9e88f2904c6ebffafe68d76239a90f3f72..b0e713a8826cfdd6aefcb7c378269d33a4981e76 100644 (file)
@@ -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;
+}
index 8c7ce4a648554264f82f20df2c061eca71c18b41..3b7a32dac2114e54da3c7e52eb1873f6fecfe8ad 100644 (file)
@@ -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 );
        }
index 6067c94fe89f278fc3eb5087e26213591ef69aa9..d3b350f233c01cbfbe00b8213ca304c439260d80 100644 (file)
@@ -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 );
index 0ba3e04b99f09460642a8fdada6c925e6ab7b530..47c8746b121c79d6ba86373d8975be13845af03c 100644 (file)
@@ -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;
 }
 
index 7c75d41352890288a851f69872b0924da80739ce..e1b2f888651dfc0ead3ca5f2914b287e504237f3 100644 (file)
@@ -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;
 }