Fix segfault in svcctl_get_secdesc(): prevent premature TALLOC_FREE.
authorMichael Adam <obnox@samba.org>
Mon, 18 Feb 2008 16:38:19 +0000 (17:38 +0100)
committerMichael Adam <obnox@samba.org>
Mon, 18 Feb 2008 16:41:19 +0000 (17:41 +0100)
This crash was triggered by (e.g.) net rpc service status.
This patch prevents premature freeing of memory and creates a
common exit point to the function.

Michael
(This used to be commit f1fb9fd6f14fc53629871cbe4b8558ad5acc14f0)

source3/services/services_db.c

index 89095c628d5275b4c52710dda4a557258160d869..ae83e726977292bfdc871e74e50568a00e75d163 100644 (file)
@@ -520,29 +520,21 @@ SEC_DESC *svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN *
        if ( !W_ERROR_IS_OK(wresult) ) {
                DEBUG(0,("svcctl_get_secdesc: key lookup failed! [%s] (%s)\n",
                        path, dos_errstr(wresult)));
-               SAFE_FREE(path);
-               return NULL;
+               goto done;
        }
-       SAFE_FREE(path);
 
        if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) {
                DEBUG(0,("svcctl_get_secdesc: talloc() failed!\n"));
-               TALLOC_FREE( key );
-               return NULL;
+               goto done;
        }
 
        if (fetch_reg_values( key, values ) == -1) {
                DEBUG(0, ("Error getting registry values\n"));
-               TALLOC_FREE(key);
-               return NULL;
+               goto done;
        }
 
-       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 );
+               goto fallback_to_default_sd;
        }
 
        /* stream the service security descriptor */
@@ -550,10 +542,18 @@ SEC_DESC *svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN *
        status = unmarshall_sec_desc(ctx, regval_data_p(val),
                                     regval_size(val), &ret_sd);
 
-       if (!NT_STATUS_IS_OK(status)) {
-               return construct_service_sd( ctx );
+       if (NT_STATUS_IS_OK(status)) {
+               goto done;
        }
 
+fallback_to_default_sd:
+       DEBUG(6, ("svcctl_get_secdesc: constructing default secdesc for "
+                 "service [%s]\n", name));
+       ret_sd = construct_service_sd(ctx);
+
+done:
+       SAFE_FREE(path);
+       TALLOC_FREE(key);
        return ret_sd;
 }