Enforce single COI->APC mapping.
[trust_router.git] / tr / tr_tid.c
index 3e1577e..63744ab 100644 (file)
@@ -1,3 +1,37 @@
+/*
+ * Copyright (c) 2016, JANET(UK)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of JANET(UK) nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
 #include <talloc.h>
 
 #include <tid_internal.h>
@@ -81,7 +115,7 @@ static int tr_tids_req_handler (TIDS_INSTANCE *tids,
     goto cleanup;
   }
 
-  if (NULL == (cfg_comm = tr_comm_lookup(cfg_mgr->active->comms, orig_req->comm))) {
+  if (NULL == (cfg_comm = tr_comm_table_find_comm(cfg_mgr->active->ctable, orig_req->comm))) {
     tr_notice("tr_tids_req_hander: Request for unknown comm: %s.", orig_req->comm->buf);
     tids_send_err_response(tids, orig_req, "Unknown community");
     retval=-1;
@@ -111,7 +145,7 @@ static int tr_tids_req_handler (TIDS_INSTANCE *tids,
     goto cleanup;
   }
   /* Check that the rp_realm is a member of the community in the request */
-  if (NULL == (tr_find_comm_rp(cfg_comm, orig_req->rp_realm))) {
+  if (NULL == (tr_comm_find_rp(cfg_mgr->active->ctable, cfg_comm, orig_req->rp_realm))) {
     tr_notice("tr_tids_req_handler: RP Realm (%s) not member of community (%s).", orig_req->rp_realm->buf, orig_req->comm->buf);
     tids_send_err_response(tids, orig_req, "RP COI membership error");
     retval=-1;
@@ -120,6 +154,13 @@ static int tr_tids_req_handler (TIDS_INSTANCE *tids,
 
   /* Map the comm in the request from a COI to an APC, if needed */
   if (TR_COMM_COI == cfg_comm->type) {
+    if (orig_req->orig_coi!=NULL) {
+      tr_notice("tr_tids_req_handler: community %s is COI but COI to APC mapping already occurred. Dropping request.",
+               orig_req->comm->buf);
+      tids_send_err_response(tids, orig_req, "Second COI to APC mapping would result, permitted only once.");
+      retval=-1;
+      goto cleanup;
+    }
     tr_debug("tr_tids_req_handler: Community was a COI, switching.");
     /* TBD -- In theory there can be more than one?  How would that work? */
     if ((!cfg_comm->apcs) || (!cfg_comm->apcs->id)) {
@@ -131,7 +172,7 @@ static int tr_tids_req_handler (TIDS_INSTANCE *tids,
     apc = tr_dup_name(cfg_comm->apcs->id);
 
     /* Check that the APC is configured */
-    if (NULL == (cfg_apc = tr_comm_lookup(cfg_mgr->active->comms, apc))) {
+    if (NULL == (cfg_apc = tr_comm_table_find_comm(cfg_mgr->active->ctable, apc))) {
       tr_notice("tr_tids_req_hander: Request for unknown comm: %s.", apc->buf);
       tids_send_err_response(tids, orig_req, "Unknown APC");
       retval=-1;
@@ -142,7 +183,7 @@ static int tr_tids_req_handler (TIDS_INSTANCE *tids,
     fwd_req->orig_coi = orig_req->comm;
 
     /* Check that rp_realm is a  member of this APC */
-    if (NULL == (tr_find_comm_rp(cfg_apc, orig_req->rp_realm))) {
+    if (NULL == (tr_comm_find_rp(cfg_mgr->active->ctable, cfg_apc, orig_req->rp_realm))) {
       tr_notice("tr_tids_req_hander: RP Realm (%s) not member of community (%s).", orig_req->rp_realm->buf, orig_req->comm->buf);
       tids_send_err_response(tids, orig_req, "RP APC membership error");
       retval=-1;
@@ -162,8 +203,8 @@ static int tr_tids_req_handler (TIDS_INSTANCE *tids,
   }
   tr_debug("tr_tids_req_handler: found route.");
   if (trp_route_is_local(route)) {
-  tr_debug("tr_tids_req_handler: route is local.");
-    aaa_servers = tr_idp_aaa_server_lookup(cfg_mgr->active->idp_realms, 
+    tr_debug("tr_tids_req_handler: route is local.");
+    aaa_servers = tr_idp_aaa_server_lookup(cfg_mgr->active->ctable->idp_realms, 
                                            orig_req->realm, 
                                            orig_req->comm);
   } else {
@@ -183,13 +224,13 @@ static int tr_tids_req_handler (TIDS_INSTANCE *tids,
     }
   } else {
     /* if we aren't defaulting, check idp coi and apc membership */
-    if (NULL == (tr_find_comm_idp(cfg_comm, fwd_req->realm))) {
+    if (NULL == (tr_comm_find_idp(cfg_mgr->active->ctable, cfg_comm, fwd_req->realm))) {
       tr_notice("tr_tids_req_handler: IDP Realm (%s) not member of community (%s).", orig_req->realm->buf, orig_req->comm->buf);
       tids_send_err_response(tids, orig_req, "IDP community membership error");
       retval=-1;
       goto cleanup;
     }
-    if ( cfg_apc && (NULL == (tr_find_comm_idp(cfg_apc, fwd_req->realm)))) {
+    if ( cfg_apc && (NULL == (tr_comm_find_idp(cfg_mgr->active->ctable, cfg_apc, fwd_req->realm)))) {
       tr_notice("tr_tids_req_handler: IDP Realm (%s) not member of APC (%s).", orig_req->realm->buf, orig_req->comm->buf);
       tids_send_err_response(tids, orig_req, "IDP APC membership error");
       retval=-1;