Merge branch 'tr-integ' into kevin-chbind
[freeradius.git] / src / main / realms.c
index b8f5401..0dd0164 100644 (file)
@@ -370,8 +370,6 @@ static CONF_PARSER home_server_config[] = {
          offsetof(home_server,response_window), NULL,   "30" },
        { "max_outstanding", PW_TYPE_INTEGER,
          offsetof(home_server,max_outstanding), NULL,   "65536" },
-       { "require_message_authenticator",  PW_TYPE_BOOLEAN,
-         offsetof(home_server, message_authenticator), 0, NULL },
 
        { "zombie_period", PW_TYPE_INTEGER,
          offsetof(home_server,zombie_period), NULL,   "40" },
@@ -415,6 +413,179 @@ static void null_free(UNUSED void *data)
 {
 }
 
+
+int realms_home_server_add(home_server *home, CONF_SECTION *cs, int dual)
+{
+        CONF_SECTION *parent = NULL;
+       const char * name2 = home->name;
+       
+       /*
+        *      Make sure that this is set.
+        */
+       if (home->src_ipaddr.af == AF_UNSPEC) {
+               home->src_ipaddr.af = home->ipaddr.af;
+       }
+
+       hs_srcipaddr = NULL;
+
+       if (rbtree_finddata(home_servers_byname, home) != NULL) {
+               cf_log_err(cf_sectiontoitem(cs),
+                          "Duplicate home server name %s.", name2);
+               goto error;
+       }
+
+       if (!home->server &&
+           (rbtree_finddata(home_servers_byaddr, home) != NULL)) {
+               cf_log_err(cf_sectiontoitem(cs),
+                          "Duplicate home server IP %s.", name2);
+               goto error;
+       }
+
+       if (!rbtree_insert(home_servers_byname, home)) {
+               cf_log_err(cf_sectiontoitem(cs),
+                          "Internal error %d adding home server %s.",
+                          __LINE__, name2);
+               goto error;
+       }
+
+       if (!home->server &&
+           !rbtree_insert(home_servers_byaddr, home)) {
+               rbtree_deletebydata(home_servers_byname, home);
+               cf_log_err(cf_sectiontoitem(cs),
+                          "Internal error %d adding home server %s.",
+                          __LINE__, name2);
+               goto error;
+       }
+
+#ifdef WITH_STATS
+       home->number = home_server_max_number++;
+       if (!rbtree_insert(home_servers_bynumber, home)) {
+               rbtree_deletebydata(home_servers_byname, home);
+               if (home->ipaddr.af != AF_UNSPEC) {
+                       rbtree_deletebydata(home_servers_byname, home);
+               }
+               cf_log_err(cf_sectiontoitem(cs),
+                          "Internal error %d adding home server %s.",
+                          __LINE__, name2);
+               goto error;
+       }
+#endif
+
+       if (home->max_outstanding < 8) home->max_outstanding = 8;
+       if (home->max_outstanding > 65536*16) home->max_outstanding = 65536*16;
+
+       if (home->ping_interval < 6) home->ping_interval = 6;
+       if (home->ping_interval > 120) home->ping_interval = 120;
+
+       if (home->response_window < 1) home->response_window = 1;
+       if (home->response_window > 60) home->response_window = 60;
+       if (home->response_window > mainconfig.max_request_time) home->response_window = mainconfig.max_request_time;
+
+       if (home->zombie_period < 1) home->zombie_period = 1;
+       if (home->zombie_period > 120) home->zombie_period = 120;
+
+       if (home->zombie_period < home->response_window) {
+               home->zombie_period = home->response_window;
+       }
+
+       if (home->num_pings_to_alive < 3) home->num_pings_to_alive = 3;
+       if (home->num_pings_to_alive > 10) home->num_pings_to_alive = 10;
+
+       if (home->ping_timeout < 3) home->ping_timeout = 3;
+       if (home->ping_timeout > 10) home->ping_timeout = 10;
+
+       if (home->revive_interval < 60) home->revive_interval = 60;
+       if (home->revive_interval > 3600) home->revive_interval = 3600;
+
+#ifdef WITH_COA
+       if (home->coa_irt < 1) home->coa_irt = 1;
+       if (home->coa_irt > 5) home->coa_irt = 5;
+
+       if (home->coa_mrc < 0) home->coa_mrc = 0;
+       if (home->coa_mrc > 20 ) home->coa_mrc = 20;
+
+       if (home->coa_mrt < 0) home->coa_mrt = 0;
+       if (home->coa_mrt > 30 ) home->coa_mrt = 30;
+
+       if (home->coa_mrd < 5) home->coa_mrd = 5;
+       if (home->coa_mrd > 60 ) home->coa_mrd = 60;
+#endif
+
+       if (home->limit.max_connections > 1024) home->limit.max_connections = 1024;
+
+#ifdef WITH_TCP
+       /*
+        *      UDP sockets can't be connection limited.
+        */
+       if (home->proto != IPPROTO_TCP) home->limit.max_connections = 0;
+#endif
+
+       if ((home->limit.idle_timeout > 0) && (home->limit.idle_timeout < 5))
+               home->limit.idle_timeout = 5;
+       if ((home->limit.lifetime > 0) && (home->limit.lifetime < 5))
+               home->limit.lifetime = 5;
+       if ((home->limit.lifetime > 0) && (home->limit.idle_timeout > home->limit.lifetime))
+               home->limit.idle_timeout = 0;
+
+       
+       if (cs) {
+               parent = cf_item_parent(cf_sectiontoitem(cs));
+               if (strcmp(cf_section_name1(parent), "server") == 0) {
+                       home->parent_server = cf_section_name2(parent);
+               }
+       }
+       
+       if (dual) {
+               home_server *home2 = rad_malloc(sizeof(*home2));
+
+               memcpy(home2, home, sizeof(*home2));
+
+               home2->type = HOME_TYPE_ACCT;
+               home2->port++;
+               home2->ping_user_password = NULL;
+               home2->cs = cs;
+               home2->parent_server = home->parent_server;
+
+               if (!rbtree_insert(home_servers_byname, home2)) {
+                       cf_log_err(cf_sectiontoitem(cs),
+                                  "Internal error %d adding home server %s.",
+                                  __LINE__, name2);
+                       free(home2);
+                       return 0;
+               }
+               
+               if (!home->server &&
+                   !rbtree_insert(home_servers_byaddr, home2)) {
+                       rbtree_deletebydata(home_servers_byname, home2);
+                       cf_log_err(cf_sectiontoitem(cs),
+                                  "Internal error %d adding home server %s.",
+                                  __LINE__, name2);
+                       free(home2);
+                       return 0;
+               }
+
+#ifdef WITH_STATS
+               home2->number = home_server_max_number++;
+               if (!rbtree_insert(home_servers_bynumber, home2)) {
+                       rbtree_deletebydata(home_servers_byname, home2);
+                       if (!home2->server) {
+                               rbtree_deletebydata(home_servers_byname, home2);
+                       }
+                       cf_log_err(cf_sectiontoitem(cs),
+                                  "Internal error %d adding home server %s.",
+                                  __LINE__, name2);
+                       free(home2);
+                       return 0;
+               }
+#endif
+       }
+
+       return 1;
+ error:
+       return 0;
+}
+
+
 static int home_server_add(realm_config_t *rc, CONF_SECTION *cs)
 {
        const char *name2;
@@ -423,7 +594,6 @@ static int home_server_add(realm_config_t *rc, CONF_SECTION *cs)
        CONF_PAIR *cp;
        CONF_SECTION *tls;
 
-       free(hs_virtual_server); /* used only for printing during parsing */
        hs_virtual_server = NULL;
 
        name2 = cf_section_name2(cs);
@@ -490,15 +660,11 @@ static int home_server_add(realm_config_t *rc, CONF_SECTION *cs)
                           "No ipaddr, ipv6addr, or virtual_server defined for home server \"%s\".",
                           name2);
        error:
-               free(home);
-               free(hs_type);
+               talloc_free(hs_type);
                hs_type = NULL;
-               free(hs_check);
                hs_check = NULL;
-               free(hs_srcipaddr);
                hs_srcipaddr = NULL;
 #ifdef WITH_TCP
-               free(hs_proto);
                hs_proto = NULL;
 #endif
                return 0;
@@ -529,7 +695,7 @@ static int home_server_add(realm_config_t *rc, CONF_SECTION *cs)
         *      Use a reasonable default.
         */
  skip_port:
-       if (!hs_type) hs_type = strdup("auth+acct");
+       if (!hs_type) hs_type = talloc_strdup(cs, "auth+acct");
 
        if (strcasecmp(hs_type, "auth") == 0) {
                home->type = HOME_TYPE_AUTH;
@@ -559,7 +725,7 @@ static int home_server_add(realm_config_t *rc, CONF_SECTION *cs)
                           hs_type, name2);
                goto error;
        }
-       free(hs_type);
+       if (hs_type) talloc_free(hs_type);
        hs_type = NULL;
 
        if (!hs_check || (strcasecmp(hs_check, "none") == 0)) {
@@ -590,7 +756,6 @@ static int home_server_add(realm_config_t *rc, CONF_SECTION *cs)
                           hs_check, name2);
                goto error;
        }
-       free(hs_check);
        hs_check = NULL;
 
        if ((home->ping_check != HOME_PING_CHECK_NONE) &&
@@ -611,11 +776,9 @@ static int home_server_add(realm_config_t *rc, CONF_SECTION *cs)
 #ifdef WITH_TCP
        if (hs_proto) {
                if (strcmp(hs_proto, "udp") == 0) {
-                       free(hs_proto);
                        hs_proto = NULL;
                        
                } else if (strcmp(hs_proto, "tcp") == 0) {
-                       free(hs_proto);
                        hs_proto = NULL;
                        home->proto = IPPROTO_TCP;
                        
@@ -697,164 +860,8 @@ static int home_server_add(realm_config_t *rc, CONF_SECTION *cs)
                goto error;
        }
 
-       /*
-        *      Make sure that this is set.
-        */
-       if (home->src_ipaddr.af == AF_UNSPEC) {
-               home->src_ipaddr.af = home->ipaddr.af;
-       }
-
-       free(hs_srcipaddr);
-       hs_srcipaddr = NULL;
-
-       if (rbtree_finddata(home_servers_byname, home) != NULL) {
-               cf_log_err(cf_sectiontoitem(cs),
-                          "Duplicate home server name %s.", name2);
-               goto error;
-       }
-
-       if (!home->server &&
-           (rbtree_finddata(home_servers_byaddr, home) != NULL)) {
-               cf_log_err(cf_sectiontoitem(cs),
-                          "Duplicate home server IP %s.", name2);
-               goto error;
-       }
-
-       if (!rbtree_insert(home_servers_byname, home)) {
-               cf_log_err(cf_sectiontoitem(cs),
-                          "Internal error %d adding home server %s.",
-                          __LINE__, name2);
-               goto error;
-       }
-
-       if (!home->server &&
-           !rbtree_insert(home_servers_byaddr, home)) {
-               rbtree_deletebydata(home_servers_byname, home);
-               cf_log_err(cf_sectiontoitem(cs),
-                          "Internal error %d adding home server %s.",
-                          __LINE__, name2);
+       if ( !realms_home_server_add( home, cs, dual))
                goto error;
-       }
-
-#ifdef WITH_STATS
-       home->number = home_server_max_number++;
-       if (!rbtree_insert(home_servers_bynumber, home)) {
-               rbtree_deletebydata(home_servers_byname, home);
-               if (home->ipaddr.af != AF_UNSPEC) {
-                       rbtree_deletebydata(home_servers_byname, home);
-               }
-               cf_log_err(cf_sectiontoitem(cs),
-                          "Internal error %d adding home server %s.",
-                          __LINE__, name2);
-               goto error;
-       }
-#endif
-
-       if (home->max_outstanding < 8) home->max_outstanding = 8;
-       if (home->max_outstanding > 65536*16) home->max_outstanding = 65536*16;
-
-       if (home->ping_interval < 6) home->ping_interval = 6;
-       if (home->ping_interval > 120) home->ping_interval = 120;
-
-       if (home->response_window < 1) home->response_window = 1;
-       if (home->response_window > 60) home->response_window = 60;
-       if (home->response_window > mainconfig.max_request_time) home->response_window = mainconfig.max_request_time;
-
-       if (home->zombie_period < 1) home->zombie_period = 1;
-       if (home->zombie_period > 120) home->zombie_period = 120;
-
-       if (home->zombie_period < home->response_window) {
-               home->zombie_period = home->response_window;
-       }
-
-       if (home->num_pings_to_alive < 3) home->num_pings_to_alive = 3;
-       if (home->num_pings_to_alive > 10) home->num_pings_to_alive = 10;
-
-       if (home->ping_timeout < 3) home->ping_timeout = 3;
-       if (home->ping_timeout > 10) home->ping_timeout = 10;
-
-       if (home->revive_interval < 60) home->revive_interval = 60;
-       if (home->revive_interval > 3600) home->revive_interval = 3600;
-
-#ifdef WITH_COA
-       if (home->coa_irt < 1) home->coa_irt = 1;
-       if (home->coa_irt > 5) home->coa_irt = 5;
-
-       if (home->coa_mrc < 0) home->coa_mrc = 0;
-       if (home->coa_mrc > 20 ) home->coa_mrc = 20;
-
-       if (home->coa_mrt < 0) home->coa_mrt = 0;
-       if (home->coa_mrt > 30 ) home->coa_mrt = 30;
-
-       if (home->coa_mrd < 5) home->coa_mrd = 5;
-       if (home->coa_mrd > 60 ) home->coa_mrd = 60;
-#endif
-
-       if (home->limit.max_connections > 1024) home->limit.max_connections = 1024;
-
-#ifdef WITH_TCP
-       /*
-        *      UDP sockets can't be connection limited.
-        */
-       if (home->proto != IPPROTO_TCP) home->limit.max_connections = 0;
-#endif
-
-       if ((home->limit.idle_timeout > 0) && (home->limit.idle_timeout < 5))
-               home->limit.idle_timeout = 5;
-       if ((home->limit.lifetime > 0) && (home->limit.lifetime < 5))
-               home->limit.lifetime = 5;
-       if ((home->limit.lifetime > 0) && (home->limit.idle_timeout > home->limit.lifetime))
-               home->limit.idle_timeout = 0;
-
-       tls = cf_item_parent(cf_sectiontoitem(cs));
-       if (strcmp(cf_section_name1(tls), "server") == 0) {
-               home->parent_server = cf_section_name2(tls);
-       }
-
-       if (dual) {
-               home_server *home2 = rad_malloc(sizeof(*home2));
-
-               memcpy(home2, home, sizeof(*home2));
-
-               home2->type = HOME_TYPE_ACCT;
-               home2->port++;
-               home2->ping_user_password = NULL;
-               home2->cs = cs;
-               home2->parent_server = home->parent_server;
-
-               if (!rbtree_insert(home_servers_byname, home2)) {
-                       cf_log_err(cf_sectiontoitem(cs),
-                                  "Internal error %d adding home server %s.",
-                                  __LINE__, name2);
-                       free(home2);
-                       return 0;
-               }
-               
-               if (!home->server &&
-                   !rbtree_insert(home_servers_byaddr, home2)) {
-                       rbtree_deletebydata(home_servers_byname, home2);
-                       cf_log_err(cf_sectiontoitem(cs),
-                                  "Internal error %d adding home server %s.",
-                                  __LINE__, name2);
-                       free(home2);
-                       return 0;
-               }
-
-#ifdef WITH_STATS
-               home2->number = home_server_max_number++;
-               if (!rbtree_insert(home_servers_bynumber, home2)) {
-                       rbtree_deletebydata(home_servers_byname, home2);
-                       if (!home2->server) {
-                               rbtree_deletebydata(home_servers_byname, home2);
-                       }
-                       cf_log_err(cf_sectiontoitem(cs),
-                                  "Internal error %d adding home server %s.",
-                                  __LINE__, name2);
-                       free(home2);
-                       return 0;
-               }
-#endif
-       }
 
        /*
         *      Mark it as already processed
@@ -926,6 +933,16 @@ static int pool_check_home_server(realm_config_t *rc, CONF_PAIR *cp,
 }
 
 
+int realms_pool_add( home_pool_t *pool, UNUSED CONF_SECTION *cs)
+{
+               if (!rbtree_insert(home_pools_byname, pool)) {
+               rad_assert("Internal sanity check failed");
+               return 0;
+       }
+               return 1;
+}
+
+
 static int server_pool_add(realm_config_t *rc,
                           CONF_SECTION *cs, int server_type, int do_print)
 {
@@ -1088,8 +1105,7 @@ static int server_pool_add(realm_config_t *rc,
                cf_log_info(cs, "\tfallback = %s", pool->fallback->name);
        }
 
-       if (!rbtree_insert(home_pools_byname, pool)) {
-               rad_assert("Internal sanity check failed");
+       if (! realms_pool_add(pool, cs)) {
                goto error;
        }
 
@@ -1544,6 +1560,38 @@ static int add_pool_to_realm(realm_config_t *rc, CONF_SECTION *cs,
 #endif
 
 
+int realms_realm_add (REALM *r, CONF_SECTION *cs)
+{
+       #ifdef HAVE_REGEX_H
+       /*
+        *      It's a regex.  Add it to a separate list.
+        */
+       if (r->name[0] == '~') {
+               realm_regex_t *rr, **last;
+
+               rr = rad_malloc(sizeof(*rr));
+               
+               last = &realms_regex;
+               while (*last) last = &((*last)->next);  /* O(N^2)... sue me. */
+
+               rr->realm = r;
+               rr->next = NULL;
+
+               *last = rr;
+
+               return 1;
+       }
+#endif
+
+       if (!rbtree_insert(realms_byname, r)) {
+               rad_assert("Internal sanity check failed");
+               return 0;
+       }
+
+       return 1;
+}
+
+
 static int realm_add(realm_config_t *rc, CONF_SECTION *cs)
 {
        const char *name2;
@@ -1737,7 +1785,7 @@ static int realm_add(realm_config_t *rc, CONF_SECTION *cs)
                    ((cp = cf_pair_find(cs, "accthost")) != NULL) ||
                    ((cp = cf_pair_find(cs, "secret")) != NULL) ||
                    ((cp = cf_pair_find(cs, "ldflag")) != NULL)) {
-                       DEBUG2("WARNING: Ignoring old-style configuration entry \"%s\" in realm \"%s\"", cf_pair_attr(cp), r->name);
+                       DEBUG2W("Ignoring old-style configuration entry \"%s\" in realm \"%s\"", cf_pair_attr(cp), r->name);
                }
 
 
@@ -1750,38 +1798,12 @@ static int realm_add(realm_config_t *rc, CONF_SECTION *cs)
                goto error;
        }
 
-#ifdef HAVE_REGEX_H
-       /*
-        *      It's a regex.  Add it to a separate list.
-        */
-       if (name2[0] == '~') {
-               realm_regex_t *rr, **last;
-
-               rr = rad_malloc(sizeof(*rr));
-               
-               last = &realms_regex;
-               while (*last) last = &((*last)->next);  /* O(N^2)... sue me. */
-
-               r->name = name2;
-               rr->realm = r;
-               rr->next = NULL;
-
-               *last = rr;
+       if ( !realms_realm_add(r, cs))
+               goto error;
 
                cf_log_info(cs, " }");
                return 1;
-       }
-#endif
-
-       if (!rbtree_insert(realms_byname, r)) {
-               rad_assert("Internal sanity check failed");
-               goto error;
-       }
-
-       cf_log_info(cs, " }");
-
-       return 1;
-
+               
  error:
        cf_log_info(cs, " } # realm %s", name2);
        free(r);
@@ -1895,7 +1917,13 @@ int realms_init(CONF_SECTION *config)
 #ifdef WITH_PROXY
        cs = cf_subsection_find_next(config, NULL, "proxy");
        if (cs) {
-               cf_section_parse(cs, rc, proxy_config);
+               if (cf_section_parse(cs, rc, proxy_config) < 0) {
+                       radlog(L_ERR, "Failed parsing proxy section");
+                       
+                       free(rc);
+                       realms_free();
+                       return 0;
+               }
        } else {
                rc->dead_time = DEAD_TIME;
                rc->retry_count = RETRY_COUNT;
@@ -2103,8 +2131,9 @@ void home_server_update_request(home_server *home, REQUEST *request)
         *      module, and encapsulated into an EAP packet.
         */
        if (!request->proxy) {
-               if ((request->proxy = rad_alloc(TRUE)) == NULL) {
-                       radlog(L_ERR|L_CONS, "no memory");
+               request->proxy = rad_alloc(request, TRUE);
+               if (!request->proxy) {
+                       radlog(L_ERR, "no memory");
                        exit(1);
                }
                
@@ -2131,11 +2160,10 @@ void home_server_update_request(home_server *home, REQUEST *request)
        request->home_server = home;
 
        /*
-        *      We're supposed to add a Message-Authenticator
-        *      if it doesn't exist, and it doesn't exist.
+        *      Access-Requests have a Message-Authenticator added,
+        *      unless one already exists.
         */
-       if (home->message_authenticator &&
-           (request->packet->code == PW_AUTHENTICATION_REQUEST) &&
+       if ((request->packet->code == PW_AUTHENTICATION_REQUEST) &&
            !pairfind(request->proxy->vps, PW_MESSAGE_AUTHENTICATOR, 0, TAG_ANY)) {
                radius_pairmake(request, &request->proxy->vps,
                                "Message-Authenticator", "0x00",
@@ -2363,7 +2391,7 @@ home_server *home_server_ldb(const char *realmname,
        if (!found && pool->fallback) {
                found = pool->fallback;
 
-               DEBUG("WARNING: Home server pool %s failing over to fallback %s",
+               DEBUGW("Home server pool %s failing over to fallback %s",
                      pool->name, found->server);
                if (pool->in_fallback) goto update_and_return;