Resolve circular header dependencies.
authorJennifer Richards <jennifer@painless-security.com>
Mon, 23 May 2016 21:54:03 +0000 (17:54 -0400)
committerJennifer Richards <jennifer@painless-security.com>
Mon, 23 May 2016 22:11:43 +0000 (18:11 -0400)
The use of TR_INSTANCE throughout various modules created a situation
where circular header file inclusion was occurring. Resolve this by
moving responsibility for picking out appropriate members from the
active configuration to the caller and passing only the directly
data into various functions. Also cleaned up some allocation code
to better make use of talloc.

common/tr_comm.c
common/tr_config.c
common/tr_idp.c
common/tr_rp.c
include/tr.h
include/tr_comm.h
include/tr_config.h
include/tr_idp.h
include/tr_rp.h
tr/tr_main.c

index 08d6638..a471cf4 100644 (file)
  *
  */
 
+#include <tr.h>
+#include <tr_rp.h>
 #include <trust_router/tr_name.h>
 #include <tr_config.h>
-#include <tr.h>
 #include <tr_comm.h>
-#include <tr_rp.h>
 #include <tr_debug.h>
 
 TR_IDP_REALM *tr_find_comm_idp (TR_COMM *comm, TR_NAME *idp_realm)
@@ -75,13 +75,13 @@ TR_RP_REALM *tr_find_comm_rp (TR_COMM *comm, TR_NAME *rp_realm)
   return NULL;
 }
 
-TR_COMM *tr_comm_lookup(TR_INSTANCE *tr, TR_NAME *comm
+TR_COMM *tr_comm_lookup(TR_COMM *comms, TR_NAME *comm_name
 {
   TR_COMM *cfg_comm = NULL;
 
-  for (cfg_comm = tr->active_cfg->comms; NULL != cfg_comm; cfg_comm = cfg_comm->next) {
-    if ((cfg_comm->id->len == comm->len) &&
-       (!strncmp(cfg_comm->id->buf, comm->buf, comm->len)))
+  for (cfg_comm = comms; NULL != cfg_comm; cfg_comm = cfg_comm->next) {
+    if ((cfg_comm->id->len == comm_name->len) &&
+       (!strncmp(cfg_comm->id->buf, comm_name->buf, comm_name->len)))
       return cfg_comm;
   }
   return NULL;
index b71a405..0e41c99 100644 (file)
@@ -49,23 +49,30 @@ void tr_print_config (FILE *stream, TR_CFG *cfg) {
   return;
 }
 
+TR_CFG *tr_cfg_new(TALLOC_CTX *mem_ctx)
+{
+  return talloc_zero(mem_ctx, TR_CFG);
+}
+
 void tr_cfg_free (TR_CFG *cfg) {
   talloc_free(cfg);
   return;
 }
 
-TR_CFG_RC tr_apply_new_config (TR_INSTANCE *tr) {
-  if (!tr)
+TR_CFG_RC tr_apply_new_config (TR_CFG **active_cfg,
+                               TR_CFG **new_cfg)
+{
+  if ((active_cfg==NULL) || (new_cfg==NULL))
     return TR_CFG_BAD_PARAMS;
 
-  if (tr->active_cfg)
-    tr_cfg_free(tr->active_cfg);
+  if (*active_cfg != NULL)
+    tr_cfg_free(*active_cfg);
 
-  tr->active_cfg = tr->new_cfg;
-  tr->new_cfg=NULL; /* only keep a single handle on the new configuration */
+  *active_cfg = *new_cfg;
+  *new_cfg=NULL; /* only keep a single handle on the new configuration */
 
-  tr_log_threshold(tr->active_cfg->internal->log_threshold);
-  tr_console_threshold(tr->active_cfg->internal->console_threshold);
+  tr_log_threshold((*active_cfg)->internal->log_threshold);
+  tr_console_threshold((*active_cfg)->internal->console_threshold);
 
   return TR_CFG_SUCCESS;
 }
@@ -83,10 +90,8 @@ static TR_CFG_RC tr_cfg_parse_internal (TR_CFG *trc, json_t *jcfg) {
     return TR_CFG_BAD_PARAMS;
 
   if (NULL == trc->internal) {
-    if (NULL == (trc->internal = talloc(trc, TR_CFG_INTERNAL)))
+    if (NULL == (trc->internal = talloc_zero(trc, TR_CFG_INTERNAL)))
       return TR_CFG_NOMEM;
-
-    memset(trc->internal, 0, sizeof(TR_CFG_INTERNAL));
   }
 
   if (NULL != (jint = json_object_get(jcfg, "tr_internal"))) {
@@ -172,14 +177,12 @@ static TR_CONSTRAINT *tr_cfg_parse_one_constraint (TR_CFG *trc, char *ctype, jso
     return NULL;
   }
 
-  if (NULL == (cons = talloc(trc, TR_CONSTRAINT))) {
+  if (NULL == (cons = talloc_zero(trc, TR_CONSTRAINT))) {
     tr_debug("tr_cfg_parse_one_constraint: Out of memory (cons).");
     *rc = TR_CFG_NOMEM;
     return NULL;
   }
 
-  memset(cons, 0, sizeof(TR_CONSTRAINT));
-
   if (NULL == (cons->type = tr_new_name(ctype))) {
     tr_debug("tr_cfg_parse_one_constraint: Out of memory (type).");
     *rc = TR_CFG_NOMEM;
@@ -226,14 +229,12 @@ static TR_FILTER *tr_cfg_parse_one_filter (TR_CFG *trc, json_t *jfilt, TR_CFG_RC
     return NULL;
   }
 
-  if (NULL == (filt = talloc(trc, TR_FILTER))) {
+  if (NULL == (filt = talloc_zero(trc, TR_FILTER))) {
     tr_debug("tr_cfg_parse_one_filter: Out of memory.");
     *rc = TR_CFG_NOMEM;
     return NULL;
   }
 
-  memset(filt, 0, sizeof(TR_FILTER));
-
   if (!strcmp(json_string_value(jftype), "rp_permitted")) {
     filt->type = TR_FILTER_TYPE_RP_PERMITTED;
   }
@@ -271,15 +272,13 @@ static TR_FILTER *tr_cfg_parse_one_filter (TR_CFG *trc, json_t *jfilt, TR_CFG_RC
       return NULL;
     }
 
-    if (NULL == (filt->lines[i] = talloc(trc, TR_FLINE))) {
+    if (NULL == (filt->lines[i] = talloc_zero(trc, TR_FLINE))) {
       tr_debug("tr_cfg_parse_one_filter: Out of memory (fline).");
       *rc = TR_CFG_NOMEM;
       tr_filter_free(filt);
       return NULL;
     }
 
-    memset(filt->lines[i], 0, sizeof(TR_FLINE));
-
     if (!strcmp(json_string_value(jfaction), "accept")) {
        filt->lines[i]->action = TR_FILTER_ACTION_ACCEPT;
     }
@@ -330,15 +329,13 @@ static TR_FILTER *tr_cfg_parse_one_filter (TR_CFG *trc, json_t *jfilt, TR_CFG_RC
        return NULL;
       }
 
-      if (NULL == (filt->lines[i]->specs[j] = talloc(trc, TR_FSPEC))) {
+      if (NULL == (filt->lines[i]->specs[j] = talloc_zero(trc, TR_FSPEC))) {
        tr_debug("tr_cfg_parse_one_filter: Out of memory.");
        *rc = TR_CFG_NOMEM;
        tr_filter_free(filt);
        return NULL;
       }
 
-      memset(filt->lines[i]->specs[j], 0, sizeof(TR_FSPEC));
-    
       if ((NULL == (filt->lines[i]->specs[j]->field = tr_new_name((char *)json_string_value(jffield)))) ||
          (NULL == (filt->lines[i]->specs[j]->match = tr_new_name((char *)json_string_value(jfmatch))))) {
        tr_debug("tr_cfg_parse_one_filter: Out of memory.");
@@ -396,13 +393,11 @@ static TR_RP_CLIENT *tr_cfg_parse_one_rp_client (TR_CFG *trc, json_t *jrp, TR_CF
     return NULL;
   }
 
-  if (NULL == (rp = talloc(trc, TR_RP_CLIENT))) {
+  if (NULL == (rp = talloc_zero(trc, TR_RP_CLIENT))) {
     tr_debug("tr_cfg_parse_one_rp_realm: Out of memory.");
     *rc = TR_CFG_NOMEM;
     return NULL;
   }
-  
-  memset(rp, 0, sizeof(TR_RP_CLIENT));
 
   /* TBD -- support more than one filter entry per RP Client? */
   if (NULL == (rp->filter = tr_cfg_parse_one_filter(trc, jfilt, rc))) {
@@ -460,14 +455,12 @@ static TR_AAA_SERVER *tr_cfg_parse_one_aaa_server (TR_CFG *trc, json_t *jaddr, T
     return NULL;
   }
 
-  if (NULL == (aaa = talloc(trc, TR_AAA_SERVER))) {
+  if (NULL == (aaa = talloc_zero(trc, TR_AAA_SERVER))) {
     tr_debug("tr_cfg_parse_one_aaa_server: Out of memory.");
     *rc = TR_CFG_NOMEM;
     return NULL;
   }
 
-  memset(aaa, 0, sizeof(TR_AAA_SERVER));
-
   aaa->hostname = tr_new_name((char *)(json_string_value(jaddr)));
 
   return aaa;
@@ -504,14 +497,12 @@ static TR_APC *tr_cfg_parse_apcs (TR_CFG *trc, json_t *japcs, TR_CFG_RC *rc)
     return NULL;
   }
 
-  if (NULL == (apc = talloc(trc, TR_APC))) {
+  if (NULL == (apc = talloc_zero(trc, TR_APC))) {
     tr_debug("tr_cfg_parse_apcs: Out of memory.");
     *rc = TR_CFG_NOMEM;
     return NULL;
   }
 
-  memset(apc, 0, sizeof(TR_APC));
-
   /* TBD, deal with more than one APC.  In the meantime, though...                */
   /* Only parse the first APC, because we only know how to deal with one, anyway. */
   if (0 == json_array_size(japcs))
@@ -540,14 +531,12 @@ static TR_IDP_REALM *tr_cfg_parse_one_idp_realm (TR_CFG *trc, json_t *jidp, TR_C
     return NULL;
   }
 
-  if (NULL == (idp = talloc(trc, TR_IDP_REALM))) {
+  if (NULL == (idp = talloc_zero(trc, TR_IDP_REALM))) {
     tr_debug("tr_cfg_parse_one_idp_realm: Out of memory.");
     *rc = TR_CFG_NOMEM;
     return NULL;
   }
 
-  memset(idp, 0, sizeof(TR_IDP_REALM));
-
   if ((NULL == (jrid = json_object_get(jidp, "realm_id"))) ||
       (!json_is_string(jrid)) ||
       (NULL == (jscfg = json_object_get(jidp, "shared_config"))) ||
@@ -692,13 +681,12 @@ static TR_RP_REALM *tr_cfg_parse_comm_rps (TR_CFG *trc, json_t *jrps, TR_CFG_RC
   }
 
   for (i = (json_array_size(jrps)-1); i >= 0; i--) {
-    if (NULL == (temp_rp = talloc(trc, TR_RP_REALM))) {
+    if (NULL == (temp_rp = talloc_zero(trc, TR_RP_REALM))) {
       tr_debug("tr_cfg_parse_comm_rps: Can't allocate memory for RP Realm.");
       if (rc)
        *rc = TR_CFG_NOMEM;
       return NULL;
     }
-    memset (temp_rp, 0, sizeof(TR_RP_REALM));
 
     if (NULL == (temp_rp->realm_name = tr_new_name((char *)json_string_value(json_array_get(jrps, i))))) {
       tr_debug("tr_cfg_parse_comm_rps: No memory for RP Realm Name.");
@@ -873,24 +861,15 @@ static char *join_paths(const char *p1, const char *p2) {
   return talloc_asprintf(NULL, "%s/%s", p1, p2); /* returns NULL on a failure */
 }
 
-/* Reads configuration files in config_dir ("" or "./" will use the current directory) */
-TR_CFG_RC tr_parse_config (TR_INSTANCE *tr, const char *config_dir, int n, struct dirent **cfg_files) {
+/* Reads configuration files in config_dir ("" or "./" will use the current directory). */
+TR_CFG_RC tr_parse_config (TR_CFG *new_cfg, const char *config_dir, int n, struct dirent **cfg_files) {
   json_t *jcfg;
   json_error_t rc;
   char *file_with_path;
 
-  if ((!tr) || (!cfg_files) || (n<=0))
+  if ((!new_cfg) || (!cfg_files) || (n<=0))
     return TR_CFG_BAD_PARAMS;
 
-  /* If there is a partial/abandoned config lying around, free it */
-  if (tr->new_cfg) 
-    tr_cfg_free(tr->new_cfg);
-  
-  if (NULL == (tr->new_cfg = talloc(NULL, TR_CFG)))
-    return TR_CFG_NOMEM;
-
-  memset(tr->new_cfg, 0, sizeof(TR_CFG));
-
   /* Parse configuration information from each config file */
   while (n--) {
     file_with_path=join_paths(config_dir, cfg_files[n]->d_name); /* must free result with talloc_free */
@@ -908,18 +887,17 @@ TR_CFG_RC tr_parse_config (TR_INSTANCE *tr, const char *config_dir, int n, struc
     }
     talloc_free(file_with_path); /* done with filename */
 
-    if ((TR_CFG_SUCCESS != tr_cfg_parse_internal(tr->new_cfg, jcfg)) ||
-        (TR_CFG_SUCCESS != tr_cfg_parse_rp_clients(tr->new_cfg, jcfg)) ||
-        (TR_CFG_SUCCESS != tr_cfg_parse_idp_realms(tr->new_cfg, jcfg)) ||
-        (TR_CFG_SUCCESS != tr_cfg_parse_default_servers(tr->new_cfg, jcfg)) ||
-        (TR_CFG_SUCCESS != tr_cfg_parse_comms(tr->new_cfg, jcfg))) {
-      tr_cfg_free(tr->new_cfg);
+    if ((TR_CFG_SUCCESS != tr_cfg_parse_internal(new_cfg, jcfg)) ||
+        (TR_CFG_SUCCESS != tr_cfg_parse_rp_clients(new_cfg, jcfg)) ||
+        (TR_CFG_SUCCESS != tr_cfg_parse_idp_realms(new_cfg, jcfg)) ||
+        (TR_CFG_SUCCESS != tr_cfg_parse_default_servers(new_cfg, jcfg)) ||
+        (TR_CFG_SUCCESS != tr_cfg_parse_comms(new_cfg, jcfg))) {
       return TR_CFG_ERROR;
     }
   }
 
   /* make sure we got a complete, consistent configuration */
-  if (TR_CFG_SUCCESS != tr_cfg_validate(tr->new_cfg)) {
+  if (TR_CFG_SUCCESS != tr_cfg_validate(new_cfg)) {
     tr_err("tr_parse_config: Error: INVALID CONFIGURATION");
     return TR_CFG_ERROR;
   }
index eb0c6fd..3cba7be 100644 (file)
 
 #include <trust_router/tr_name.h>
 #include <tr_idp.h>
-#include <tr.h>
 #include <tr_config.h>
 
-TR_AAA_SERVER *tr_idp_aaa_server_lookup(TR_INSTANCE *tr, TR_NAME *idp_realm, TR_NAME *comm)
+TR_AAA_SERVER *tr_idp_aaa_server_lookup(TR_IDP_REALM *idp_realms, TR_NAME *idp_realm_name, TR_NAME *comm)
 {
   TR_IDP_REALM *idp = NULL;
 
-  for (idp = tr->active_cfg->idp_realms; idp != NULL; idp = idp->next) {
-    if (!tr_name_cmp(idp_realm, idp->realm_id)) {
+  for (idp = idp_realms; idp != NULL; idp = idp->next) {
+    if (!tr_name_cmp(idp_realm_name, idp->realm_id)) {
       /* TBD -- check that the community is one of the APCs for the IDP */
       break;
     }
@@ -53,10 +52,10 @@ TR_AAA_SERVER *tr_idp_aaa_server_lookup(TR_INSTANCE *tr, TR_NAME *idp_realm, TR_
     return NULL;
 }
 
-TR_AAA_SERVER *tr_default_server_lookup(TR_INSTANCE *tr, TR_NAME *comm)
+TR_AAA_SERVER *tr_default_server_lookup(TR_AAA_SERVER *default_servers, TR_NAME *comm)
 {
-  if ((!tr) || (!(tr->active_cfg)))
+  if (!default_servers)
     return NULL;
 
-  return(tr->active_cfg->default_servers);
+  return(default_servers);
 }
index 7244cbd..b7d3562 100644 (file)
  *
  */
 
+#include <tr.h>
 #include <trust_router/tr_name.h>
-#include <tr_rp.h>
 #include <tr_config.h>
-#include <tr.h>
+#include <tr_rp.h>
 #include <tr_debug.h>
 
-TR_RP_CLIENT *tr_rp_client_lookup(TR_INSTANCE *tr, TR_NAME *gss_name) {
+TR_RP_CLIENT *tr_rp_client_lookup(TR_RP_CLIENT *rp_clients, TR_NAME *gss_name) {
   TR_RP_CLIENT *rp = NULL;
   int i = 0;
 
-  if ((!tr) || (!tr->active_cfg) || (!gss_name)) {
+  if ((!rp_clients) || (!gss_name)) {
     tr_debug("tr_rp_client_lookup: Bad parameters.");
     return NULL;
   }
 
-  for (rp = tr->active_cfg->rp_clients; NULL != rp; rp = rp->next) {
+  for (rp = rp_clients; NULL != rp; rp = rp->next) {
     for (i = 0; ((i < TR_MAX_GSS_NAMES) && (NULL != (rp->gss_names[i]))); i++) {
        if (!tr_name_cmp(gss_name, rp->gss_names[i])) {
        return rp;
index 61adc36..9d75fa5 100644 (file)
@@ -39,6 +39,7 @@
 #include <trust_router/tr_name.h>
 #include <tr_msg.h>
 #include <tr_rp.h>
+#include <tr_config.h>
 
 typedef struct tr_instance {
   struct tr_cfg *new_cfg;      /* unapplied configuration */
index 374227b..46b9f8b 100644 (file)
@@ -55,7 +55,7 @@ typedef struct tr_comm {
   time_t expiration_interval; /*Minutes to key expiration; only valid for an APC*/
 } TR_COMM;
 
-TR_COMM *tr_comm_lookup(TR_INSTANCE *tr, TR_NAME *comm);
+TR_COMM *tr_comm_lookup(TR_COMM *comms, TR_NAME *comm_name);
 TR_RP_REALM *tr_find_comm_rp (TR_COMM *comm, TR_NAME *rp_realm);
 TR_IDP_REALM *tr_find_comm_idp (TR_COMM *comm, TR_NAME *idp_realm);
 
index 28b0c05..ca8b4e4 100644 (file)
@@ -39,6 +39,7 @@
 #include <dirent.h>
 #include <jansson.h>
 #include <syslog.h>
+#include <talloc.h>
 
 #include <tr.h>
 #include <tr_rp.h>
@@ -80,14 +81,14 @@ typedef struct tr_cfg {
 
 int tr_find_config_files (const char *config_dir, struct dirent ***cfg_files);
 void tr_free_config_file_list(int n, struct dirent ***cfg_files);
-TR_CFG_RC tr_parse_config (TR_INSTANCE *tr, const char *config_dir, int n, struct dirent **cfg_files);
-TR_CFG_RC tr_apply_new_config (TR_INSTANCE *tr);
+TR_CFG_RC tr_parse_config (TR_CFG *new_cfg, const char *config_dir, int n, struct dirent **cfg_files);
+TR_CFG_RC tr_apply_new_config (TR_CFG **active_cfg, TR_CFG **new_cfg);
 TR_CFG_RC tr_cfg_validate (TR_CFG *trc);
+TR_CFG *tr_cfg_new(TALLOC_CTX *mem_ctx);
 void tr_cfg_free(TR_CFG *cfg);
 void tr_print_config(FILE *stream, TR_CFG *cfg);
 
 TR_IDP_REALM *tr_cfg_find_idp (TR_CFG *tr_cfg, TR_NAME *idp_id, TR_CFG_RC *rc);
 TR_RP_CLIENT *tr_cfg_find_rp (TR_CFG *tr_cfg, TR_NAME *rp_gss, TR_CFG_RC *rc);
-TR_RP_CLIENT *tr_rp_client_lookup(TR_INSTANCE *tr, TR_NAME *gss_name);
 
 #endif
index 0eba315..25d281d 100644 (file)
@@ -36,7 +36,6 @@
 #define TR_IDP_H
 
 #include <trust_router/tr_name.h>
-#include <tr.h>
 #include <tr_apc.h>
 
 typedef struct tr_aaa_server {
@@ -53,6 +52,6 @@ typedef struct tr_idp_realm {
   TR_APC *apcs;
 } TR_IDP_REALM;
   
-TR_AAA_SERVER *tr_idp_aaa_server_lookup(TR_INSTANCE *tr, TR_NAME *idp_realm, TR_NAME *comm);
-TR_AAA_SERVER *tr_default_server_lookup(TR_INSTANCE *tr, TR_NAME *comm);
+TR_AAA_SERVER *tr_idp_aaa_server_lookup(TR_IDP_REALM *idp_realms, TR_NAME *idp_realm_name, TR_NAME *comm);
+TR_AAA_SERVER *tr_default_server_lookup(TR_AAA_SERVER *default_servers, TR_NAME *comm);
 #endif
index 43a3b58..eec1d55 100644 (file)
@@ -35,7 +35,6 @@
 #ifndef TR_RP_H
 #define TR_RP_H
 
-#include <tr.h>
 #include <tr_filter.h>
 
 #define TR_MAX_GSS_NAMES 5
@@ -53,4 +52,7 @@ typedef struct tr_rp_realm {
   TR_NAME *realm_name;
 } TR_RP_REALM;
 
+/* prototypes */
+TR_RP_CLIENT *tr_rp_client_lookup(TR_RP_CLIENT *rp_clients, TR_NAME *gss_name);
+
 #endif
index dd64abb..e3cb91d 100644 (file)
@@ -165,11 +165,11 @@ static int tr_tids_req_handler (TIDS_INSTANCE *tids,
   }
 
   /* Find the AAA server(s) for this request */
-  if (NULL == (aaa_servers = tr_idp_aaa_server_lookup((TR_INSTANCE *)tids->cookie
+  if (NULL == (aaa_servers = tr_idp_aaa_server_lookup(((TR_INSTANCE *)tids->cookie)->active_cfg->idp_realms
                                                      orig_req->realm, 
                                                      orig_req->comm))) {
       tr_debug("tr_tids_req_handler: No AAA Servers for realm %s, defaulting.", orig_req->realm->buf);
-      if (NULL == (aaa_servers = tr_default_server_lookup ((TR_INSTANCE *)tids->cookie,
+      if (NULL == (aaa_servers = tr_default_server_lookup (((TR_INSTANCE *)tids->cookie)->active_cfg->default_servers,
                                                           orig_req->comm))) {
        tr_notice("tr_tids_req_handler: No default AAA servers, discarded.");
         tids_send_err_response(tids, orig_req, "No path to AAA Server(s) for realm");
@@ -246,7 +246,7 @@ static int tr_tids_gss_handler(gss_name_t client_name, TR_NAME *gss_name,
   }
   
   /* look up the RP client matching the GSS name */
-  if ((NULL == (rp = tr_rp_client_lookup(tr, gss_name)))) {
+  if ((NULL == (rp = tr_rp_client_lookup(tr->active_cfg->rp_clients, gss_name)))) {
     tr_debug("tr_tids_gss_handler: Unknown GSS name %s", gss_name->buf);
     return -1;
   }
@@ -486,16 +486,27 @@ static int tr_read_and_apply_config(TR_CFGWATCH *cfgwatch)
     retval=1; goto cleanup;
   }
 
-  if (TR_CFG_SUCCESS != tr_parse_config(cfgwatch->tr, config_dir, n_files, cfg_files)) {
-    tr_debug("tr_read_and_apply_config: Error decoding configuration information.");
+  /* allocate a new configuration, dumping an old one if needed */
+  if(cfgwatch->tr->new_cfg != NULL)
+    tr_cfg_free(cfgwatch->tr->new_cfg);
+  cfgwatch->tr->new_cfg=tr_cfg_new(tmp_ctx);
+  if (cfgwatch->tr->new_cfg==NULL) {
+    tr_debug("tr_read_and_apply_config: Error allocating new_cfg.");
+    retval=1; goto cleanup;
+  }
+  /* now fill it in */
+  if (TR_CFG_SUCCESS != (rc = tr_parse_config(cfgwatch->tr->new_cfg, config_dir, n_files, cfg_files))) {
+    tr_debug("tr_read_and_apply_config: Error decoding configuration information, rc=%d.", rc);
     retval=1; goto cleanup;
   }
 
   /* apply initial configuration */
-  if (TR_CFG_SUCCESS != (rc = tr_apply_new_config(cfgwatch->tr))) {
+  if (TR_CFG_SUCCESS != (rc = tr_apply_new_config(&cfgwatch->tr->active_cfg,
+                                                 &cfgwatch->tr->new_cfg))) {
     tr_debug("tr_read_and_apply_config: Error applying configuration, rc = %d.", rc);
     retval=1; goto cleanup;
   }
+  talloc_steal(cfgwatch->ctx, cfgwatch->tr->active_cfg); /* hand over ownership */
 
   /* give ownership of the new_fstat_list to caller's context */
   if (cfgwatch->fstat_list != NULL) {
@@ -717,7 +728,7 @@ int main (int argc, char *argv[])
   /* Get a configuration status object */
   cfgwatch=tr_cfgwatch_create(main_ctx);
   if (cfgwatch == NULL) {
-    tr_error("Unable to create configuration watcher object, exiting.");
+    tr_err("Unable to create configuration watcher object, exiting.");
     return 1;
   }