summaryrefslogtreecommitdiff
path: root/source3/services/services_db.c
diff options
context:
space:
mode:
authorJames Peach <jpeach@samba.org>2007-11-21 18:31:35 -0800
committerJames Peach <jpeach@samba.org>2007-11-21 18:31:35 -0800
commit64b54e534008a1ac36b9ba21726ca0954fe00d63 (patch)
tree5a5e0f42c70d4afa14ba689bf4f97af321432510 /source3/services/services_db.c
parentfebaaae2021c2993d265cc48cf9fbef05cb4ed1b (diff)
parent7ef6c19074495110d5c0b698b05c4ee52a0744d6 (diff)
downloadsamba-64b54e534008a1ac36b9ba21726ca0954fe00d63.tar.gz
samba-64b54e534008a1ac36b9ba21726ca0954fe00d63.tar.bz2
samba-64b54e534008a1ac36b9ba21726ca0954fe00d63.zip
Merge ssh://git.samba.org/data/git/samba into v3-2-test
(This used to be commit 660ea443364e949ed06c28b00f0e1c3757f0da27)
Diffstat (limited to 'source3/services/services_db.c')
-rw-r--r--source3/services/services_db.c302
1 files changed, 175 insertions, 127 deletions
diff --git a/source3/services/services_db.c b/source3/services/services_db.c
index ccb69d76e4..07f7aa6002 100644
--- a/source3/services/services_db.c
+++ b/source3/services/services_db.c
@@ -33,7 +33,7 @@ struct service_display_info {
const char *description;
};
-struct service_display_info builtin_svcs[] = {
+struct service_display_info builtin_svcs[] = {
{ "Spooler", "smbd", "Print Spooler", "Internal service for spooling files to print devices" },
{ "NETLOGON", "smbd", "Net Logon", "File service providing access to policy and profile data (not remotely manageable)" },
{ "RemoteRegistry", "smbd", "Remote Registry Service", "Internal service providing remote access to "
@@ -43,7 +43,7 @@ struct service_display_info builtin_svcs[] = {
{ NULL, NULL, NULL, NULL }
};
-struct service_display_info common_unix_svcs[] = {
+struct service_display_info common_unix_svcs[] = {
{ "cups", NULL, "Common Unix Printing System","Provides unified printing support for all operating systems" },
{ "postfix", NULL, "Internet Mail Service", "Provides support for sending and receiving electonic mail" },
{ "sendmail", NULL, "Internet Mail Service", "Provides support for sending and receiving electonic mail" },
@@ -88,27 +88,27 @@ struct service_display_info common_unix_svcs[] = {
static SEC_DESC* construct_service_sd( TALLOC_CTX *ctx )
{
- SEC_ACE ace[4];
+ SEC_ACE ace[4];
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, SERVICE_READ_ACCESS );
init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
-
+
init_sec_access(&mask,SERVICE_EXECUTE_ACCESS );
init_sec_ace(&ace[i++], &global_sid_Builtin_Power_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
-
+
init_sec_access(&mask,SERVICE_ALL_ACCESS );
init_sec_ace(&ace[i++], &global_sid_Builtin_Server_Operators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
-
+
/* create the security descriptor */
-
+
if ( !(acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) )
return NULL;
@@ -127,52 +127,58 @@ static char *get_common_service_dispname( const char *servicename )
{
static fstring dispname;
int i;
-
+
for ( i=0; common_unix_svcs[i].servicename; i++ ) {
- if ( strequal( servicename, common_unix_svcs[i].servicename ) ) {
- fstr_sprintf( dispname, "%s (%s)",
+ if (strequal(servicename, common_unix_svcs[i].servicename)) {
+ fstr_sprintf( dispname, "%s (%s)",
common_unix_svcs[i].dispname,
common_unix_svcs[i].servicename );
-
+
return dispname;
}
- }
-
+ }
+
fstrcpy( dispname, servicename );
-
+
return dispname;
}
/********************************************************************
********************************************************************/
-static char* cleanup_string( const char *string )
+static char *cleanup_string( const char *string )
{
- pstring clean;
+ char *clean = NULL;
char *begin, *end;
+ TALLOC_CTX *ctx = talloc_tos();
- pstrcpy( clean, string );
+ clean = talloc_strdup(ctx, string);
+ if (!clean) {
+ return NULL;
+ }
begin = clean;
-
+
/* trim any beginning whilespace */
-
- while ( isspace(*begin) )
+
+ while (isspace(*begin)) {
begin++;
+ }
- if ( *begin == '\0' )
+ if (*begin == '\0') {
return NULL;
-
+ }
+
/* trim any trailing whitespace or carriage returns.
Start at the end and move backwards */
-
+
end = begin + strlen(begin) - 1;
-
+
while ( isspace(*end) || *end=='\n' || *end=='\r' ) {
*end = '\0';
end--;
}
- return talloc_strdup(talloc_tos(), begin);
+ return begin;
}
/********************************************************************
@@ -181,50 +187,57 @@ static char* cleanup_string( const char *string )
static bool read_init_file( const char *servicename, struct rcinit_file_information **service_info )
{
struct rcinit_file_information *info;
- pstring filepath, str;
+ char *filepath = NULL;
+ char str[1024];
XFILE *f;
char *p;
-
+
if ( !(info = TALLOC_ZERO_P( NULL, struct rcinit_file_information ) ) )
return False;
-
+
/* attempt the file open */
-
- pstr_sprintf( filepath, "%s/%s/%s", dyn_LIBDIR, SVCCTL_SCRIPT_DIR, servicename );
- if ( !(f = x_fopen( filepath, O_RDONLY, 0 )) ) {
+
+ filepath = talloc_asprintf(info, "%s/%s/%s", dyn_LIBDIR,
+ SVCCTL_SCRIPT_DIR, servicename);
+ if (!filepath) {
+ TALLOC_FREE(info);
+ return false;
+ }
+ if (!(f = x_fopen( filepath, O_RDONLY, 0 ))) {
DEBUG(0,("read_init_file: failed to open [%s]\n", filepath));
TALLOC_FREE(info);
- return False;
+ return false;
}
-
+
while ( (x_fgets( str, sizeof(str)-1, f )) != NULL ) {
- /* ignore everything that is not a full line
+ /* ignore everything that is not a full line
comment starting with a '#' */
-
+
if ( str[0] != '#' )
continue;
-
+
/* Look for a line like '^#.*Description:' */
-
+
if ( (p = strstr( str, "Description:" )) != NULL ) {
char *desc;
p += strlen( "Description:" ) + 1;
- if ( !p )
+ if ( !p )
break;
-
+
if ( (desc = cleanup_string(p)) != NULL )
info->description = talloc_strdup( info, desc );
}
}
-
+
x_fclose( f );
-
+
if ( !info->description )
info->description = talloc_strdup( info, "External Unix Service" );
-
+
*service_info = info;
-
+ TALLOC_FREE(filepath);
+
return True;
}
@@ -237,50 +250,62 @@ static void fill_service_values( const char *name, REGVAL_CTR *values )
{
UNISTR2 data, dname, ipath, description;
uint32 dword;
- pstring pstr;
int i;
-
+
/* These values are hardcoded in all QueryServiceConfig() replies.
I'm just storing them here for cosmetic purposes */
-
+
dword = SVCCTL_AUTO_START;
regval_ctr_addvalue( values, "Start", REG_DWORD, (char*)&dword, sizeof(uint32));
-
+
dword = SVCCTL_WIN32_OWN_PROC;
regval_ctr_addvalue( values, "Type", REG_DWORD, (char*)&dword, sizeof(uint32));
dword = SVCCTL_SVC_ERROR_NORMAL;
regval_ctr_addvalue( values, "ErrorControl", REG_DWORD, (char*)&dword, sizeof(uint32));
-
+
/* everything runs as LocalSystem */
-
+
init_unistr2( &data, "LocalSystem", UNI_STR_TERMINATE );
regval_ctr_addvalue( values, "ObjectName", REG_SZ, (char*)data.buffer, data.uni_str_len*2);
-
+
/* special considerations for internal services and the DisplayName value */
-
+
for ( i=0; builtin_svcs[i].servicename; i++ ) {
if ( strequal( name, builtin_svcs[i].servicename ) ) {
- pstr_sprintf( pstr, "%s/%s/%s",dyn_LIBDIR, SVCCTL_SCRIPT_DIR, builtin_svcs[i].daemon );
- init_unistr2( &ipath, pstr, UNI_STR_TERMINATE );
+ char *pstr = NULL;
+ if (asprintf(&pstr, "%s/%s/%s",
+ dyn_LIBDIR, SVCCTL_SCRIPT_DIR,
+ builtin_svcs[i].daemon) > 0) {
+ init_unistr2( &ipath, pstr, UNI_STR_TERMINATE );
+ SAFE_FREE(pstr);
+ } else {
+ init_unistr2( &ipath, "", UNI_STR_TERMINATE );
+ }
init_unistr2( &description, builtin_svcs[i].description, UNI_STR_TERMINATE );
init_unistr2( &dname, builtin_svcs[i].dispname, UNI_STR_TERMINATE );
break;
}
- }
-
+ }
+
/* default to an external service if we haven't found a match */
-
+
if ( builtin_svcs[i].servicename == NULL ) {
+ char *pstr = NULL;
struct rcinit_file_information *init_info = NULL;
- pstr_sprintf( pstr, "%s/%s/%s",dyn_LIBDIR, SVCCTL_SCRIPT_DIR, name );
- init_unistr2( &ipath, pstr, UNI_STR_TERMINATE );
-
+ if (asprintf(&pstr, "%s/%s/%s",dyn_LIBDIR,
+ SVCCTL_SCRIPT_DIR, name) > 0) {
+ init_unistr2( &ipath, pstr, UNI_STR_TERMINATE );
+ SAFE_FREE(pstr);
+ } else {
+ init_unistr2( &ipath, "", UNI_STR_TERMINATE );
+ }
+
/* lookup common unix display names */
init_unistr2( &dname, get_common_service_dispname( name ), UNI_STR_TERMINATE );
- /* get info from init file itself */
+ /* get info from init file itself */
if ( read_init_file( name, &init_info ) ) {
init_unistr2( &description, init_info->description, UNI_STR_TERMINATE );
TALLOC_FREE( init_info );
@@ -289,25 +314,25 @@ static void fill_service_values( const char *name, REGVAL_CTR *values )
init_unistr2( &description, "External Unix Service", UNI_STR_TERMINATE );
}
}
-
+
/* add the new values */
-
+
regval_ctr_addvalue( values, "DisplayName", REG_SZ, (char*)dname.buffer, dname.uni_str_len*2);
regval_ctr_addvalue( values, "ImagePath", REG_SZ, (char*)ipath.buffer, ipath.uni_str_len*2);
regval_ctr_addvalue( values, "Description", REG_SZ, (char*)description.buffer, description.uni_str_len*2);
-
+
return;
}
/********************************************************************
********************************************************************/
-static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys,
+static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys,
const char *name )
{
REGISTRY_KEY *key_service, *key_secdesc;
WERROR wresult;
- pstring path;
+ char *path = NULL;
REGVAL_CTR *values;
REGSUBKEY_CTR *svc_subkeys;
SEC_DESC *sd;
@@ -321,15 +346,19 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys,
/* open the new service key */
- pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name );
+ if (asprintf(&path, "%s\\%s", KEY_SERVICES, name) < 0) {
+ return;
+ }
wresult = regkey_open_internal( NULL, &key_service, path,
get_root_nt_token(), REG_KEY_ALL );
if ( !W_ERROR_IS_OK(wresult) ) {
- DEBUG(0,("add_new_svc_name: key lookup failed! [%s] (%s)\n",
+ DEBUG(0,("add_new_svc_name: key lookup failed! [%s] (%s)\n",
path, dos_errstr(wresult)));
+ SAFE_FREE(path);
return;
}
-
+ SAFE_FREE(path);
+
/* add the 'Security' key */
if ( !(svc_subkeys = TALLOC_ZERO_P( key_service, REGSUBKEY_CTR )) ) {
@@ -337,13 +366,13 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys,
TALLOC_FREE( key_service );
return;
}
-
+
fetch_reg_keys( key_service, svc_subkeys );
regsubkey_ctr_addkey( svc_subkeys, "Security" );
store_reg_keys( key_service, svc_subkeys );
/* now for the service values */
-
+
if ( !(values = TALLOC_ZERO_P( key_service, REGVAL_CTR )) ) {
DEBUG(0,("add_new_svc_name: talloc() failed!\n"));
TALLOC_FREE( key_service );
@@ -359,15 +388,19 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys,
/* now add the security descriptor */
- pstr_sprintf( path, "%s\\%s\\%s", KEY_SERVICES, name, "Security" );
+ if (asprintf(&path, "%s\\%s\\%s", KEY_SERVICES, name, "Security") < 0) {
+ return;
+ }
wresult = regkey_open_internal( NULL, &key_secdesc, path,
get_root_nt_token(), REG_KEY_ALL );
if ( !W_ERROR_IS_OK(wresult) ) {
- DEBUG(0,("add_new_svc_name: key lookup failed! [%s] (%s)\n",
+ DEBUG(0,("add_new_svc_name: key lookup failed! [%s] (%s)\n",
path, dos_errstr(wresult)));
TALLOC_FREE( key_secdesc );
+ SAFE_FREE(path);
return;
}
+ SAFE_FREE(path);
if ( !(values = TALLOC_ZERO_P( key_secdesc, REGVAL_CTR )) ) {
DEBUG(0,("add_new_svc_name: talloc() failed!\n"));
@@ -389,11 +422,11 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys,
TALLOC_FREE(key_secdesc);
return;
}
-
+
regval_ctr_addvalue(values, "Security", REG_BINARY,
(const char *)sd_blob.data, sd_blob.length);
store_reg_values( key_secdesc, values );
-
+
TALLOC_FREE( key_secdesc );
return;
@@ -409,35 +442,35 @@ void svcctl_init_keys( void )
REGSUBKEY_CTR *subkeys;
REGISTRY_KEY *key = NULL;
WERROR wresult;
-
+
/* bad mojo here if the lookup failed. Should not happen */
-
+
wresult = regkey_open_internal( NULL, &key, KEY_SERVICES,
get_root_nt_token(), REG_KEY_ALL );
if ( !W_ERROR_IS_OK(wresult) ) {
- DEBUG(0,("svcctl_init_keys: key lookup failed! (%s)\n",
+ DEBUG(0,("svcctl_init_keys: key lookup failed! (%s)\n",
dos_errstr(wresult)));
return;
}
-
- /* lookup the available subkeys */
-
+
+ /* lookup the available subkeys */
+
if ( !(subkeys = TALLOC_ZERO_P( key, REGSUBKEY_CTR )) ) {
DEBUG(0,("svcctl_init_keys: talloc() failed!\n"));
TALLOC_FREE( key );
return;
}
-
+
fetch_reg_keys( key, subkeys );
-
+
/* the builting services exist */
-
+
for ( i=0; builtin_svcs[i].servicename; i++ )
add_new_svc_name( key, subkeys, builtin_svcs[i].servicename );
-
+
for ( i=0; service_list && service_list[i]; i++ ) {
-
+
/* only add new services */
if ( regsubkey_ctr_key_exists( subkeys, service_list[i] ) )
continue;
@@ -458,30 +491,34 @@ void svcctl_init_keys( void )
/********************************************************************
This is where we do the dirty work of filling in things like the
- Display name, Description, etc...Always return a default secdesc
+ Display name, Description, etc...Always return a default secdesc
in case of any failure.
********************************************************************/
-SEC_DESC* svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN *token )
+SEC_DESC *svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN *token )
{
REGISTRY_KEY *key;
REGVAL_CTR *values;
REGISTRY_VALUE *val;
SEC_DESC *ret_sd = NULL;
- pstring path;
+ char *path= NULL;
WERROR wresult;
NTSTATUS status;
-
+
/* now add the security descriptor */
- pstr_sprintf( path, "%s\\%s\\%s", KEY_SERVICES, name, "Security" );
+ if (asprintf(&path, "%s\\%s\\%s", KEY_SERVICES, name, "Security") < 0) {
+ return NULL;
+ }
wresult = regkey_open_internal( NULL, &key, path, token,
REG_KEY_ALL );
if ( !W_ERROR_IS_OK(wresult) ) {
- DEBUG(0,("svcctl_get_secdesc: key lookup failed! [%s] (%s)\n",
+ DEBUG(0,("svcctl_get_secdesc: key lookup failed! [%s] (%s)\n",
path, dos_errstr(wresult)));
+ SAFE_FREE(path);
return NULL;
}
+ SAFE_FREE(path);
if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) {
DEBUG(0,("add_new_svc_name: talloc() failed!\n"));
@@ -492,13 +529,12 @@ SEC_DESC* svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN *
fetch_reg_values( key, values );
TALLOC_FREE(key);
-
+
if ( !(val = regval_ctr_getvalue( values, "Security" )) ) {
DEBUG(6,("svcctl_get_secdesc: constructing default secdesc for service [%s]\n",
name));
return construct_service_sd( ctx );
}
-
/* stream the service security descriptor */
@@ -520,40 +556,43 @@ bool svcctl_set_secdesc( TALLOC_CTX *ctx, const char *name, SEC_DESC *sec_desc,
{
REGISTRY_KEY *key;
WERROR wresult;
- pstring path;
+ char *path = NULL;
REGVAL_CTR *values;
prs_struct ps;
bool ret = False;
-
+
/* now add the security descriptor */
- pstr_sprintf( path, "%s\\%s\\%s", KEY_SERVICES, name, "Security" );
+ if (asprintf(&path, "%s\\%s\\%s", KEY_SERVICES, name, "Security") < 0) {
+ return false;
+ }
wresult = regkey_open_internal( NULL, &key, path, token,
REG_KEY_ALL );
if ( !W_ERROR_IS_OK(wresult) ) {
- DEBUG(0,("svcctl_get_secdesc: key lookup failed! [%s] (%s)\n",
+ DEBUG(0,("svcctl_get_secdesc: key lookup failed! [%s] (%s)\n",
path, dos_errstr(wresult)));
+ SAFE_FREE(path);
return False;
}
+ SAFE_FREE(path);
if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) {
DEBUG(0,("add_new_svc_name: talloc() failed!\n"));
TALLOC_FREE( key );
return False;
}
-
+
/* stream the printer security descriptor */
-
prs_init( &ps, RPC_MAX_PDU_FRAG_LEN, key, MARSHALL);
-
+
if ( sec_io_desc("sec_desc", &sec_desc, &ps, 0 ) ) {
uint32 offset = prs_offset( &ps );
regval_ctr_addvalue( values, "Security", REG_BINARY, prs_data_p(&ps), offset );
ret = store_reg_values( key, values );
}
-
+
/* cleanup */
-
+
prs_mem_free( &ps );
TALLOC_FREE( key);
@@ -563,25 +602,29 @@ bool svcctl_set_secdesc( TALLOC_CTX *ctx, const char *name, SEC_DESC *sec_desc,
/********************************************************************
********************************************************************/
-char* svcctl_lookup_dispname( const char *name, NT_USER_TOKEN *token )
+char *svcctl_lookup_dispname( const char *name, NT_USER_TOKEN *token )
{
static fstring display_name;
- REGISTRY_KEY *key;
+ REGISTRY_KEY *key = NULL;
REGVAL_CTR *values;
REGISTRY_VALUE *val;
- pstring path;
+ char *path = NULL;
WERROR wresult;
-
+
/* now add the security descriptor */
- pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name );
+ if (asprintf(&path, "%s\\%s", KEY_SERVICES, name) < 0) {
+ return NULL;
+ }
wresult = regkey_open_internal( NULL, &key, path, token,
REG_KEY_READ );
if ( !W_ERROR_IS_OK(wresult) ) {
DEBUG(0,("svcctl_lookup_dispname: key lookup failed! [%s] (%s)\n",
path, dos_errstr(wresult)));
+ SAFE_FREE(path);
goto fail;
}
+ SAFE_FREE(path);
if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) {
DEBUG(0,("svcctl_lookup_dispname: talloc() failed!\n"));
@@ -590,14 +633,14 @@ char* svcctl_lookup_dispname( const char *name, NT_USER_TOKEN *token )
}
fetch_reg_values( key, values );
-
+
if ( !(val = regval_ctr_getvalue( values, "DisplayName" )) )
goto fail;
rpcstr_pull( display_name, regval_data_p(val), sizeof(display_name), regval_size(val), 0 );
TALLOC_FREE( key );
-
+
return display_name;
fail:
@@ -610,25 +653,29 @@ fail:
/********************************************************************
********************************************************************/
-char* svcctl_lookup_description( const char *name, NT_USER_TOKEN *token )
+char *svcctl_lookup_description( const char *name, NT_USER_TOKEN *token )
{
static fstring description;
- REGISTRY_KEY *key;
+ REGISTRY_KEY *key = NULL;
REGVAL_CTR *values;
REGISTRY_VALUE *val;
- pstring path;
+ char *path = NULL;
WERROR wresult;
-
+
/* now add the security descriptor */
- pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name );
+ if (asprintf(&path, "%s\\%s", KEY_SERVICES, name) < 0) {
+ return NULL;
+ }
wresult = regkey_open_internal( NULL, &key, path, token,
REG_KEY_READ );
if ( !W_ERROR_IS_OK(wresult) ) {
DEBUG(0,("svcctl_lookup_dispname: key lookup failed! [%s] (%s)\n",
path, dos_errstr(wresult)));
+ SAFE_FREE(path);
return NULL;
}
+ SAFE_FREE(path);
if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) {
DEBUG(0,("svcctl_lookup_dispname: talloc() failed!\n"));
@@ -637,14 +684,14 @@ char* svcctl_lookup_description( const char *name, NT_USER_TOKEN *token )
}
fetch_reg_values( key, values );
-
+
if ( !(val = regval_ctr_getvalue( values, "Description" )) )
fstrcpy( description, "Unix Service");
else
rpcstr_pull( description, regval_data_p(val), sizeof(description), regval_size(val), 0 );
TALLOC_FREE( key );
-
+
return description;
}
@@ -652,34 +699,35 @@ char* svcctl_lookup_description( const char *name, NT_USER_TOKEN *token )
/********************************************************************
********************************************************************/
-REGVAL_CTR* svcctl_fetch_regvalues( const char *name, NT_USER_TOKEN *token )
+REGVAL_CTR *svcctl_fetch_regvalues( const char *name, NT_USER_TOKEN *token )
{
- REGISTRY_KEY *key;
+ REGISTRY_KEY *key = NULL;
REGVAL_CTR *values;
- pstring path;
+ char *path = NULL;
WERROR wresult;
-
+
/* now add the security descriptor */
- pstr_sprintf( path, "%s\\%s", KEY_SERVICES, name );
+ if (asprintf(&path, "%s\\%s", KEY_SERVICES, name) < 0) {
+ return NULL;
+ }
wresult = regkey_open_internal( NULL, &key, path, token,
REG_KEY_READ );
if ( !W_ERROR_IS_OK(wresult) ) {
- DEBUG(0,("svcctl_fetch_regvalues: key lookup failed! [%s] (%s)\n",
+ DEBUG(0,("svcctl_fetch_regvalues: key lookup failed! [%s] (%s)\n",
path, dos_errstr(wresult)));
+ SAFE_FREE(path);
return NULL;
}
+ SAFE_FREE(path);
if ( !(values = TALLOC_ZERO_P( NULL, REGVAL_CTR )) ) {
DEBUG(0,("svcctl_fetch_regvalues: talloc() failed!\n"));
TALLOC_FREE( key );
return NULL;
}
-
fetch_reg_values( key, values );
TALLOC_FREE( key );
-
return values;
}
-