📄 realms.c
字号:
home_server **phome){ home_server myhome, *home; CONF_SECTION *server_cs; if (!name) { cf_log_err(cf_pairtoitem(cp), "No value given for home_server."); return 0; } myhome.name = name; myhome.type = server_type; home = rbtree_finddata(home_servers_byname, &myhome); if (home) { *phome = home; return 1; } server_cs = cf_section_sub_find_name2(rc->cs, "home_server", name); if (!server_cs) { cf_log_err(cf_pairtoitem(cp), "Unknown home_server \"%s\".", name); return 0; } if (!home_server_add(rc, server_cs, server_type)) { return 0; } home = rbtree_finddata(home_servers_byname, &myhome); if (!home) { radlog(L_ERR, "Internal sanity check failed %d", __LINE__); return 0; } *phome = home; return 1;}static int server_pool_add(realm_config_t *rc, CONF_SECTION *cs, int server_type, int do_print){ const char *name2; home_pool_t *pool = NULL; const char *value; CONF_PAIR *cp; int num_home_servers; home_server *home; name2 = cf_section_name1(cs); if (!name2 || ((strcasecmp(name2, "server_pool") != 0) && (strcasecmp(name2, "home_server_pool") != 0))) { cf_log_err(cf_sectiontoitem(cs), "Section is not a home_server_pool."); return 0; } name2 = cf_section_name2(cs); if (!name2) { cf_log_err(cf_sectiontoitem(cs), "Server pool section is missing a name."); return 0; } /* * Count the home servers and initalize them. */ num_home_servers = 0; for (cp = cf_pair_find(cs, "home_server"); cp != NULL; cp = cf_pair_find_next(cs, cp, "home_server")) { num_home_servers++; if (!pool_check_home_server(rc, cp, cf_pair_value(cp), server_type, &home)) { return 0; } } if (num_home_servers == 0) { cf_log_err(cf_sectiontoitem(cs), "No home servers defined in pool %s", name2); goto error; } pool = server_pool_alloc(name2, HOME_POOL_FAIL_OVER, server_type, num_home_servers); pool->cs = cs; cp = cf_pair_find(cs, "fallback"); if (cp) { if (!pool_check_home_server(rc, cp, cf_pair_value(cp), server_type, &pool->fallback)) { goto error; } } if (do_print) cf_log_info(cs, " home_server_pool %s {", name2); cp = cf_pair_find(cs, "type"); if (cp) { static FR_NAME_NUMBER pool_types[] = { { "load-balance", HOME_POOL_LOAD_BALANCE }, { "fail-over", HOME_POOL_FAIL_OVER }, { "round_robin", HOME_POOL_LOAD_BALANCE }, { "fail_over", HOME_POOL_FAIL_OVER }, { "client-balance", HOME_POOL_CLIENT_BALANCE }, { "client-port-balance", HOME_POOL_CLIENT_PORT_BALANCE }, { "keyed-balance", HOME_POOL_KEYED_BALANCE }, { NULL, 0 } }; value = cf_pair_value(cp); if (!value) { cf_log_err(cf_pairtoitem(cp), "No value given for type."); goto error; } pool->type = fr_str2int(pool_types, value, 0); if (!pool->type) { cf_log_err(cf_pairtoitem(cp), "Unknown type \"%s\".", value); goto error; } if (do_print) cf_log_info(cs, "\ttype = %s", value); } cp = cf_pair_find(cs, "virtual_server"); if (cp) { pool->virtual_server = cf_pair_value(cp); if (do_print && pool->virtual_server) { cf_log_info(cs, "\tvirtual_server = %s", pool->virtual_server); } if (!cf_section_sub_find_name2(rc->cs, "server", pool->virtual_server)) { cf_log_err(cf_pairtoitem(cp), "No such server %s", pool->virtual_server); goto error; } } num_home_servers = 0; for (cp = cf_pair_find(cs, "home_server"); cp != NULL; cp = cf_pair_find_next(cs, cp, "home_server")) { home_server myhome; value = cf_pair_value(cp); memset(&myhome, 0, sizeof(&myhome)); myhome.name = value; myhome.type = server_type; home = rbtree_finddata(home_servers_byname, &myhome); if (!home) { DEBUG2("Internal sanity check failed"); goto error; } if (0) { DEBUG2("Warning: Duplicate home server %s in server pool %s", home->name, pool->name); continue; } if (do_print) cf_log_info(cs, "\thome_server = %s", home->name); pool->servers[num_home_servers++] = home; } /* loop over home_server's */ if (pool->fallback && do_print) { cf_log_info(cs, "\tfallback = %s", pool->fallback->name); } if (!rbtree_insert(home_pools_byname, pool)) { rad_assert("Internal sanity check failed"); goto error; } if (do_print) cf_log_info(cs, " }"); rad_assert(pool->server_type != 0); return 1; error: if (do_print) cf_log_info(cs, " }"); free(pool); return 0;}static int old_server_add(realm_config_t *rc, CONF_SECTION *cs, const char *realm, const char *name, const char *secret, home_pool_type_t ldflag, home_pool_t **pool_p, int type, const char *server){ int i, insert_point, num_home_servers; home_server myhome, *home; home_pool_t mypool, *pool; CONF_SECTION *subcs; /* * LOCAL realms get sanity checked, and nothing else happens. */ if (strcmp(name, "LOCAL") == 0) { if (*pool_p) { cf_log_err(cf_sectiontoitem(cs), "Realm \"%s\" cannot be both LOCAL and remote", name); return 0; } return 1; } mypool.name = realm; mypool.server_type = type; pool = rbtree_finddata(home_pools_byname, &mypool); if (pool) { if (pool->type != ldflag) { cf_log_err(cf_sectiontoitem(cs), "Inconsistent ldflag for server pool \"%s\"", name); return 0; } if (pool->server_type != type) { cf_log_err(cf_sectiontoitem(cs), "Inconsistent home server type for server pool \"%s\"", name); return 0; } } myhome.name = name; myhome.type = type; home = rbtree_finddata(home_servers_byname, &myhome); if (home) { if (strcmp(home->secret, secret) != 0) { cf_log_err(cf_sectiontoitem(cs), "Inconsistent shared secret for home server \"%s\"", name); return 0; } if (home->type != type) { cf_log_err(cf_sectiontoitem(cs), "Inconsistent type for home server \"%s\"", name); return 0; } /* * See if the home server is already listed * in the pool. If so, do nothing else. */ if (pool) for (i = 0; i < pool->num_home_servers; i++) { if (pool->servers[i] == home) { return 1; } } } /* * If we do have a pool, check that there is room to * insert the home server we've found, or the one that we * create here. * * Note that we insert it into the LAST available * position, in order to maintain the same order as in * the configuration files. */ insert_point = -1; if (pool) { for (i = pool->num_home_servers - 1; i >= 0; i--) { if (pool->servers[i]) break; if (!pool->servers[i]) { insert_point = i; } } if (insert_point < 0) { cf_log_err(cf_sectiontoitem(cs), "No room in pool to add home server \"%s\". Please update the realm configuration to use the new-style home servers and server pools.", name); return 0; } } /* * No home server, allocate one. */ if (!home) { const char *p; char *q; home = rad_malloc(sizeof(*home)); memset(home, 0, sizeof(*home)); home->name = name; home->hostname = name; home->type = type; home->secret = secret; home->cs = cs; p = strchr(name, ':'); if (!p) { if (type == HOME_TYPE_AUTH) { home->port = PW_AUTH_UDP_PORT; } else { home->port = PW_ACCT_UDP_PORT; } p = name; q = NULL; } else if (p == name) { cf_log_err(cf_sectiontoitem(cs), "Invalid hostname %s.", name); free(home); return 0; } else { home->port = atoi(p + 1); if ((home->port == 0) || (home->port > 65535)) { cf_log_err(cf_sectiontoitem(cs), "Invalid port %s.", p + 1); free(home); return 0; } q = rad_malloc((p - name) + 1); memcpy(q, name, (p - name)); q[p - name] = '\0'; p = q; } if (!server) { if (ip_hton(p, AF_UNSPEC, &home->ipaddr) < 0) { cf_log_err(cf_sectiontoitem(cs), "Failed looking up hostname %s.", p); free(home); free(q); return 0; } } else { home->ipaddr.af = AF_UNSPEC; home->server = server; } free(q); /* * Use the old-style configuration. */ home->max_outstanding = 65535*16; home->zombie_period = rc->retry_delay * rc->retry_count; if (home->zombie_period == 0) home->zombie_period =30; home->response_window = home->zombie_period - 1; home->ping_check = HOME_PING_CHECK_NONE; home->revive_interval = rc->dead_time; if (rbtree_finddata(home_servers_byaddr, home)) { cf_log_err(cf_sectiontoitem(cs), "Home server %s has the same IP address and/or port as another home server.", name); free(home); return 0; } if (!rbtree_insert(home_servers_byname, home)) { cf_log_err(cf_sectiontoitem(cs), "Internal error adding home server %s.", name); free(home); return 0; } if (!rbtree_insert(home_servers_byaddr, home)) { rbtree_deletebydata(home_servers_byname, home); cf_log_err(cf_sectiontoitem(cs), "Internal error adding home server %s.", name); free(home); return 0; } } /* * We now have a home server, see if we can insert it * into pre-existing pool. */ if (insert_point >= 0) { rad_assert(pool != NULL); pool->servers[insert_point] = home; return 1; } rad_assert(pool == NULL); rad_assert(home != NULL); /* * Count the old-style realms of this name. */ num_home_servers = 0; for (subcs = cf_section_find_next(cs, NULL, "realm"); subcs != NULL; subcs = cf_section_find_next(cs, subcs, "realm")) { const char *this = cf_section_name2(subcs); if (!this || (strcmp(this, realm) != 0)) continue; num_home_servers++; } if (num_home_servers == 0) { cf_log_err(cf_sectiontoitem(cs), "Internal error counting pools for home server %s.", name); free(home); return 0; } pool = server_pool_alloc(realm, ldflag, type, num_home_servers); pool->cs = cs; pool->servers[0] = home; if (!rbtree_insert(home_pools_byname, pool)) { rad_assert("Internal sanity check failed"); return 0; } *pool_p = pool; return 1;}static int old_realm_config(realm_config_t *rc, CONF_SECTION *cs, REALM *r){ const char *host; const char *secret = NULL; home_pool_type_t ldflag; CONF_PAIR *cp; cp = cf_pair_find(cs, "ldflag"); ldflag = HOME_POOL_FAIL_OVER; if (cp) { host = cf_pair_value(cp); if (!host) { cf_log_err(cf_pairtoitem(cp), "No value specified for ldflag"); return 0; } if (strcasecmp(host, "fail_over") == 0) { cf_log_info(cs, "\tldflag = fail_over"); } else if (strcasecmp(host, "round_robin") == 0) { ldflag = HOME_POOL_LOAD_BALANCE; cf_log_info(cs, "\tldflag = round_robin"); } else { cf_log_err(cf_sectiontoitem(cs), "Unknown value \"%s\" for ldflag", host); return 0; } } /* else don't print it. */ /* * Allow old-style if it doesn't exist, or if it exists and * it's LOCAL. */ cp = cf_pair_find(cs, "authhost"); if (cp) { host = cf_pair_value(cp); if (!host) { cf_log_err(cf_pairtoitem(cp), "No value specified for authhost"); return 0; } if (strcmp(host, "LOCAL") != 0) { cp = cf_pair_find(cs, "secret"); if (!cp) { cf_log_err(cf_sectiontoitem(cs), "No shared secret supplied for realm: %s", r->name); return 0; } secret = cf_pair_value(cp); if (!secret) { cf_log_err(cf_pairtoitem(cp), "No value specified for secret"); return 0; } } cf_log_info(cs, "\tauthhost = %s", host); if (!old_server_add(rc, cs, r->name, host, secret, ldflag, &r->auth_pool, HOME_TYPE_AUTH, NULL)) { return 0; } } cp = cf_pair_find(cs, "accthost"); if (cp) { host = cf_pair_value(cp); if (!host) { cf_log_err(cf_pairtoitem(cp), "No value specified for accthost"); return 0; } /* * Don't look for a secret again if it was found * above. */ if ((strcmp(host, "LOCAL") != 0) && !secret) { cp = cf_pair_find(cs, "secret"); if (!cp) { cf_log_err(cf_sectiontoitem(cs), "No shared secret supplied for realm: %s", r->name); return 0; } secret = cf_pair_value(cp); if (!secret) { cf_log_err(cf_pairtoitem(cp), "No value specified for secret"); return 0; } } cf_log_info(cs, "\taccthost = %s", host); if (!old_server_add(rc, cs, r->name, host, secret, ldflag, &r->acct_pool, HOME_TYPE_ACCT, NULL)) { return 0; } } cp = cf_pair_find(cs, "virtual_server"); if (cp) { host = cf_pair_value(cp); if (!host) { cf_log_err(cf_pairtoitem(cp), "No value specified for virtual_server"); return 0; } cf_log_info(cs, "\tvirtual_server = %s", host); if (!old_server_add(rc, cs, r->name, host, "", ldflag, &r->auth_pool, HOME_TYPE_AUTH, host)) { return 0; } if (!old_server_add(rc, cs, r->name, host, "", ldflag, &r->acct_pool, HOME_TYPE_ACCT, host)) { return 0; } } if (secret) cf_log_info(cs, "\tsecret = %s", secret); return 1;}static int add_pool_to_realm(realm_config_t *rc, CONF_SECTION *cs, const char *name, home_pool_t **dest, int server_type, int do_print){ home_pool_t mypool, *pool; mypool.name = name; mypool.server_type = server_type; pool = rbtree_finddata(home_pools_byname, &mypool); if (!pool) { CONF_SECTION *pool_cs; pool_cs = cf_section_sub_find_name2(rc->cs, "home_server_pool", name); if (!pool_cs) { pool_cs = cf_section_sub_find_name2(rc->cs, "server_pool", name); } if (!pool_cs) { cf_log_err(cf_sectiontoitem(cs), "Failed to find home_server_pool \"%s\"", name); return 0; } if (!server_pool_add(rc, pool_cs, server_type, do_print)) { return 0; } pool = rbtree_finddata(home_pools_byname, &mypool); if (!pool) { radlog(L_ERR, "Internal sanity check failed in add_pool_to_realm"); return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -