From d412289ae6a7cc112449b51f2b8570e285ea7980 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Fri, 19 Oct 2012 11:31:08 +0200
Subject: [PATCH 1/4] do not leak memory on failure in *_process_init()

---
 src/responder/autofs/autofssrv.c        | 13 +++++++++----
 src/responder/common/responder_common.c | 24 ++++++++++++++----------
 src/responder/nss/nsssrv.c              | 19 ++++++++++++-------
 src/responder/pac/pacsrv.c              | 17 +++++++++++------
 src/responder/pam/pamsrv.c              |  2 +-
 src/responder/ssh/sshsrv.c              | 12 ++++++++----
 src/responder/sudo/sudosrv.c            | 10 +++++++---
 7 files changed, 62 insertions(+), 35 deletions(-)

diff --git a/src/responder/autofs/autofssrv.c b/src/responder/autofs/autofssrv.c
index dcb188fd41e786c8f765832908a13f7df7e097c9..9b0708629d31d917f2e12872114a072dabdff394 100644
--- a/src/responder/autofs/autofssrv.c
+++ b/src/responder/autofs/autofssrv.c
@@ -122,7 +122,7 @@ autofs_process_init(TALLOC_CTX *mem_ctx,
     ret = autofs_get_config(autofs_ctx, cdb);
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE, ("Cannot read autofs configuration\n"));
-        return ret;
+        goto fail;
     }
 
     autofs_cmds = get_autofs_cmds();
@@ -137,7 +137,7 @@ autofs_process_init(TALLOC_CTX *mem_ctx,
                            &autofs_dp_interface,
                            &autofs_ctx->rctx);
     if (ret != EOK) {
-        return ret;
+        goto fail;
     }
     autofs_ctx->rctx->pvt_ctx = autofs_ctx;
 
@@ -149,7 +149,7 @@ autofs_process_init(TALLOC_CTX *mem_ctx,
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE,
               ("Failed to set up automatic reconnection\n"));
-        return ret;
+        goto fail;
     }
 
     for (iter = autofs_ctx->rctx->be_conns; iter; iter = iter->next) {
@@ -162,11 +162,16 @@ autofs_process_init(TALLOC_CTX *mem_ctx,
     if (hret != HASH_SUCCESS) {
         DEBUG(SSSDBG_CRIT_FAILURE,
               ("Unable to initialize automount maps hash table\n"));
-        return EIO;
+        ret = EIO;
+        goto fail;
     }
 
     DEBUG(SSSDBG_TRACE_FUNC, ("autofs Initialization complete\n"));
     return EOK;
+
+fail:
+    talloc_free(autofs_ctx);
+    return ret;
 }
 
 int main(int argc, const char *argv[])
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index d9f73fe2698cd7eacfb1a589c159e5cb037dab64..dfc2f0fe3d5ed3abb5d8a0c434f3a741dd627417 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -769,7 +769,7 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
         DEBUG(SSSDBG_OP_FAILURE,
               ("Cannot get the client idle timeout [%d]: %s\n",
                ret, strerror(ret)));
-        return ret;
+        goto fail;
     }
 
     /* Ensure that the client timeout is at least ten seconds */
@@ -784,7 +784,7 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
         DEBUG(SSSDBG_OP_FAILURE,
               ("Cannnot get the default domain timeout [%d]: %s\n",
                ret, strerror(ret)));
-        return ret;
+        goto fail;
     }
 
     if (rctx->domains_timeout < 0) {
@@ -795,7 +795,7 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
     ret = confdb_get_domains(rctx->cdb, &rctx->domains);
     if (ret != EOK) {
         DEBUG(0, ("fatal error setting up domain map\n"));
-        return ret;
+        goto fail;
     }
 
     ret = confdb_get_string(rctx->cdb, rctx, CONFDB_MONITOR_CONF_ENTRY,
@@ -805,7 +805,7 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
         DEBUG(SSSDBG_OP_FAILURE,
               ("Cannnot get the default domain [%d]: %s\n",
                ret, strerror(ret)));
-        return ret;
+        goto fail;
     }
 
     ret = sss_monitor_init(rctx, rctx->ev, monitor_intf,
@@ -813,7 +813,7 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
                            &rctx->mon_conn);
     if (ret != EOK) {
         DEBUG(0, ("fatal error setting up message bus\n"));
-        return ret;
+        goto fail;
     }
 
     for (dom = rctx->domains; dom; dom = dom->next) {
@@ -822,7 +822,7 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
             DEBUG(SSSDBG_FATAL_FAILURE,
                   ("fatal error initializing regex data for domain: %s\n",
                    dom->name));
-            return ret;
+            goto fail;
         }
 
         /* skip local domain, it doesn't have a backend */
@@ -833,21 +833,21 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
         ret = sss_dp_init(rctx, dp_intf, cli_name, dom);
         if (ret != EOK) {
             DEBUG(0, ("fatal error setting up backend connector\n"));
-            return ret;
+            goto fail;
         }
     }
 
     ret = sysdb_init(rctx, cdb, NULL, false, &rctx->db_list);
     if (ret != EOK) {
         DEBUG(0, ("fatal error initializing resp_ctx\n"));
-        return ret;
+        goto fail;
     }
 
     /* after all initializations we are ready to listen on our socket */
     ret = set_unix_socket(rctx);
     if (ret != EOK) {
         DEBUG(0, ("fatal error initializing socket\n"));
-        return ret;
+        goto fail;
     }
 
     /* Create DP request table */
@@ -855,13 +855,17 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE,
               ("Could not create hash table for the request queue\n"));
-        return ret;
+        goto fail;
     }
 
     DEBUG(SSSDBG_TRACE_FUNC, ("Responder Initialization complete\n"));
 
     *responder_ctx = rctx;
     return EOK;
+
+fail:
+    talloc_free(rctx);
+    return ret;
 }
 
 int sss_dp_get_domain_conn(struct resp_ctx *rctx, const char *domain,
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index 1156c45f41cc09bbbb6cc1a8ce7fb165f4a1a110..764737db023cbdf9d52781342785091d0e9d4e16 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -343,7 +343,7 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
     ret = sss_ncache_init(nctx, &nctx->ncache);
     if (ret != EOK) {
         DEBUG(0, ("fatal error initializing negative cache\n"));
-        return ret;
+        goto fail;
     }
 
     nss_cmds = get_nss_cmds();
@@ -358,14 +358,14 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
                            "NSS", &nss_dp_interface,
                            &nctx->rctx);
     if (ret != EOK) {
-        return ret;
+        goto fail;
     }
     nctx->rctx->pvt_ctx = nctx;
 
     ret = nss_get_config(nctx, cdb);
     if (ret != EOK) {
         DEBUG(0, ("fatal error getting nss config\n"));
-        return ret;
+        goto fail;
     }
 
     /* Enable automatic reconnection to the Data Provider */
@@ -375,7 +375,7 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
                          3, &max_retries);
     if (ret != EOK) {
         DEBUG(0, ("Failed to set up automatic reconnection\n"));
-        return ret;
+        goto fail;
     }
 
     for (iter = nctx->rctx->be_conns; iter; iter = iter->next) {
@@ -387,7 +387,8 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
     hret = sss_hash_create(nctx, 10, &nctx->netgroups);
     if (hret != HASH_SUCCESS) {
         DEBUG(0,("Unable to initialize netgroup hash table\n"));
-        return EIO;
+        ret = EIO;
+        goto fail;
     }
 
     /* create mmap caches */
@@ -407,7 +408,7 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
                          300, &memcache_timeout);
     if (ret != EOK) {
         DEBUG(0, ("Failed to set up automatic reconnection\n"));
-        return ret;
+        goto fail;
     }
 
     /* TODO: read cache sizes from configuration */
@@ -434,13 +435,17 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE,
               ("Failed to set up file descriptor limit\n"));
-        return ret;
+        goto fail;
     }
     responder_set_fd_limit(fd_limit);
 
     DEBUG(SSSDBG_TRACE_FUNC, ("NSS Initialization complete\n"));
 
     return EOK;
+
+fail:
+    talloc_free(nctx);
+    return ret;
 }
 
 int main(int argc, const char *argv[])
diff --git a/src/responder/pac/pacsrv.c b/src/responder/pac/pacsrv.c
index 348fc6f47863ebeed2b06d8b4a3016926d794ebd..c6cac0942a266447ce46e974abc7c382941bce69 100644
--- a/src/responder/pac/pacsrv.c
+++ b/src/responder/pac/pacsrv.c
@@ -145,7 +145,7 @@ int pac_process_init(TALLOC_CTX *mem_ctx,
                            "PAC", &pac_dp_interface,
                            &pac_ctx->rctx);
     if (ret != EOK) {
-        return ret;
+        goto fail;
     }
     pac_ctx->rctx->pvt_ctx = pac_ctx;
 
@@ -155,7 +155,7 @@ int pac_process_init(TALLOC_CTX *mem_ctx,
                             DEFAULT_ALLOWED_UIDS, &uid_str);
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE, ("Failed to get allowed UIDs.\n"));
-        return ret;
+        goto fail;
     }
 
     ret = csv_string_to_uid_array(pac_ctx->rctx, uid_str, true,
@@ -163,7 +163,7 @@ int pac_process_init(TALLOC_CTX *mem_ctx,
                                   &pac_ctx->rctx->allowed_uids);
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE, ("Failed to set allowed UIDs.\n"));
-        return ret;
+        goto fail;
     }
 
     /* Enable automatic reconnection to the Data Provider */
@@ -173,7 +173,7 @@ int pac_process_init(TALLOC_CTX *mem_ctx,
                          3, &max_retries);
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE, ("Failed to set up automatic reconnection\n"));
-        return ret;
+        goto fail;
     }
 
     for (iter = pac_ctx->rctx->be_conns; iter; iter = iter->next) {
@@ -185,7 +185,8 @@ int pac_process_init(TALLOC_CTX *mem_ctx,
                          &pac_ctx->idmap_ctx);
     if (err != IDMAP_SUCCESS) {
         DEBUG(SSSDBG_FATAL_FAILURE, ("sss_idmap_init failed.\n"));
-        return EFAULT;
+        ret = EFAULT;
+        goto fail;
     }
 
     /* Set up file descriptor limits */
@@ -197,13 +198,17 @@ int pac_process_init(TALLOC_CTX *mem_ctx,
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE,
               ("Failed to set up file descriptor limit\n"));
-        return ret;
+        goto fail;
     }
     responder_set_fd_limit(fd_limit);
 
     DEBUG(SSSDBG_TRACE_FUNC, ("PAC Initialization complete\n"));
 
     return EOK;
+
+fail:
+    talloc_free(pac_ctx);
+    return ret;
 }
 
 int main(int argc, const char *argv[])
diff --git a/src/responder/pam/pamsrv.c b/src/responder/pam/pamsrv.c
index c94596c4c9000ec546ab3404fb44312ddd71c606..4a549526edd91c87583756dc030bfd509a1a7a4e 100644
--- a/src/responder/pam/pamsrv.c
+++ b/src/responder/pam/pamsrv.c
@@ -194,7 +194,7 @@ static int pam_process_init(TALLOC_CTX *mem_ctx,
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE,
               ("Failed to set up file descriptor limit\n"));
-        return ret;
+        goto done;
     }
     responder_set_fd_limit(fd_limit);
 
diff --git a/src/responder/ssh/sshsrv.c b/src/responder/ssh/sshsrv.c
index fe01f81f1dbb2a3889d247579cb169327632312e..2cc8a8287bee42deea4da248e0e8033beec1c038 100644
--- a/src/responder/ssh/sshsrv.c
+++ b/src/responder/ssh/sshsrv.c
@@ -108,7 +108,7 @@ int ssh_process_init(TALLOC_CTX *mem_ctx,
                            &ssh_dp_interface,
                            &ssh_ctx->rctx);
     if (ret != EOK) {
-        return ret;
+        goto fail;
     }
     ssh_ctx->rctx->pvt_ctx = ssh_ctx;
 
@@ -120,7 +120,7 @@ int ssh_process_init(TALLOC_CTX *mem_ctx,
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE,
               ("Failed to set up automatic reconnection\n"));
-        return ret;
+        goto fail;
     }
 
     for (iter = ssh_ctx->rctx->be_conns; iter; iter = iter->next) {
@@ -138,7 +138,7 @@ int ssh_process_init(TALLOC_CTX *mem_ctx,
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE, ("Error reading from confdb (%d) [%s]\n",
               ret, strerror(ret)));
-        return ret;
+        goto fail;
     }
 
     /* Get ssh_known_hosts_timeout option */
@@ -149,12 +149,16 @@ int ssh_process_init(TALLOC_CTX *mem_ctx,
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE, ("Error reading from confdb (%d) [%s]\n",
               ret, strerror(ret)));
-        return ret;
+        goto fail;
     }
 
     DEBUG(SSSDBG_TRACE_FUNC, ("SSH Initialization complete\n"));
 
     return EOK;
+
+fail:
+    talloc_free(ssh_ctx);
+    return ret;
 }
 
 int main(int argc, const char *argv[])
diff --git a/src/responder/sudo/sudosrv.c b/src/responder/sudo/sudosrv.c
index b4f8f8879a0c9c4090eb578961574921a2211b37..c6fc2d3db6681f57f4f45b8483e1c0d9249a8041 100644
--- a/src/responder/sudo/sudosrv.c
+++ b/src/responder/sudo/sudosrv.c
@@ -109,7 +109,7 @@ int sudo_process_init(TALLOC_CTX *mem_ctx,
                            &sudo_dp_interface,
                            &sudo_ctx->rctx);
     if (ret != EOK) {
-        return ret;
+        goto fail;
     }
     sudo_ctx->rctx->pvt_ctx = sudo_ctx;
 
@@ -121,7 +121,7 @@ int sudo_process_init(TALLOC_CTX *mem_ctx,
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE,
               ("Failed to set up automatic reconnection\n"));
-        return ret;
+        goto fail;
     }
 
     for (iter = sudo_ctx->rctx->be_conns; iter; iter = iter->next) {
@@ -139,12 +139,16 @@ int sudo_process_init(TALLOC_CTX *mem_ctx,
     if (ret != EOK) {
         DEBUG(SSSDBG_FATAL_FAILURE, ("Error reading from confdb (%d) [%s]\n",
               ret, strerror(ret)));
-        return ret;
+        goto fail;
     }
 
     DEBUG(SSSDBG_TRACE_FUNC, ("SUDO Initialization complete\n"));
 
     return EOK;
+
+fail:
+    talloc_free(sudo_ctx);
+    return ret;
 }
 
 int main(int argc, const char *argv[])
-- 
1.7.11.4

