};
/*
- * Yucky hacks.
- */
-extern int max_proxies;
-
-static int generate_realms(const char *filename);
-static int generate_clients(const char *filename);
-static CONF_SECTION *conf_read(const char *fromfile, int fromline,
- const char *conffile, CONF_SECTION *parent);
-
-#ifndef RADIUS_CONFIG
-#define RADIUS_CONFIG "radiusd.conf"
-#endif
-
-/*
* Isolate the scary casts in these tiny provably-safe functions
*/
CONF_PAIR *cf_itemtopair(CONF_ITEM *ci)
/*
* Read the config file.
*/
-static CONF_SECTION *conf_read(const char *fromfile, int fromline,
- const char *conffile, CONF_SECTION *parent)
+CONF_SECTION *conf_read(const char *fromfile, int fromline,
+ const char *conffile, CONF_SECTION *parent)
{
FILE *fp;
int lineno = 0;
return cs;
}
-/*
- * Xlat for %{config:section.subsection.attribute}
- */
-static int xlat_config(void *instance, REQUEST *request,
- char *fmt, char *out, int outlen,
- RADIUS_ESCAPE_STRING func)
-{
- CONF_SECTION *cs;
- CONF_PAIR *cp;
- char buffer[1024];
- char *p;
- const char *start = fmt;
-
- cp = NULL;
- cs = NULL;
-
- while (cp == NULL) {
- /*
- * Find the next section.
- */
- for (p = buffer; (*fmt != 0) && (*fmt != '.'); p++, fmt++) {
- *p = *fmt;
- }
- *p = '\0';
-
- /*
- * The character is a '.', find a section (as the user
- * has given us a subsection to find)
- */
- if (*fmt == '.') {
- CONF_SECTION *next;
-
- fmt++; /* skip the period */
-
- if (cs == NULL) {
- next = cf_section_find(buffer);
- } else {
- next = cf_subsection_find_next(cs, NULL, buffer);
- }
- if (next == NULL) {
- radlog(L_ERR, "config: No such section %s in format string %s", buffer, start);
- return 0;
- }
- cs = next;
-
- } else { /* no period, must be a conf-part */
- cp = cf_pair_find(cs, buffer);
-
- if (cp == NULL) {
- radlog(L_ERR, "config: No such section %s in format string %s", buffer, start);
- return 0;
- }
- }
- } /* until cp is non-NULL */
-
- /*
- * Ensure that we only copy what's necessary.
- *
- * If 'outlen' is too small, then the output is chopped to fit.
- */
- if (outlen > strlen(cp->value)) {
- outlen = strlen(cp->value) + 1;
- }
-
- return func(out, outlen, cp->value);
-}
-
-/*
- * These are not used anywhere else..
- */
-static const char *localstatedir = NULL;
-static const char *prefix = NULL;
-
-static CONF_PARSER directory_config[] = {
- /*
- * FIXME: 'prefix' is the ONLY one which should be configured
- * at compile time. Hard-coding it here is bad. It will be cleaned
- * up once we clean up the hard-coded defines for the locations of
- * the various files.
- */
- { "prefix", PW_TYPE_STRING_PTR, 0, &prefix, "/usr/local"},
- { "localstatedir", PW_TYPE_STRING_PTR, 0, &localstatedir, "${prefix}/var"},
- { "logdir", PW_TYPE_STRING_PTR, 0, &radlog_dir, "${localstatedir}/log"},
- { "libdir", PW_TYPE_STRING_PTR, 0, &radlib_dir, "${prefix}/lib"},
- { "radacctdir", PW_TYPE_STRING_PTR, 0, &radacct_dir, "${logdir}/radacct" },
- { "hostname_lookups", PW_TYPE_BOOLEAN, 0, &librad_dodns, "no" },
-
- /*
- * We don't allow re-defining this, as doing so will cause
- * all sorts of confusion.
- */
-#if 0
- { "confdir", PW_TYPE_STRING_PTR, 0, &radius_dir, RADIUS_DIR },
-#endif
- { NULL, -1, 0, NULL, NULL }
-};
-
-int read_radius_conf_file(void)
-{
- char buffer[256];
- CONF_SECTION *cs;
-
- /* Lets go look for the new configuration files */
- snprintf(buffer, sizeof(buffer), "%.200s/%.50s", radius_dir, RADIUS_CONFIG);
- if ((cs = conf_read(NULL, 0, buffer, NULL)) == NULL) {
- return -1;
- }
-
- /*
- * Free the old configuration data, and replace it
- * with the new one.
- */
- cf_section_free(&mainconfig.config);
- mainconfig.config = cs;
-
- /*
- * And parse the directory configuration values.
- */
- cs = cf_section_find(NULL);
- if (cs == NULL)
- return -1;
-
- /*
- * This allows us to figure out where, relative to
- * radiusd.conf, the other configuration files exist.
- */
- cf_section_parse(cs, NULL, directory_config);
-
- /* Initialize the dictionary */
- DEBUG2("read_config_files: reading dictionary");
- if (dict_init(radius_dir, RADIUS_DICTIONARY) != 0) {
- radlog(L_ERR|L_CONS, "Errors reading dictionary: %s",
- librad_errstr);
- return -1;
- }
-
- /* old-style naslist file */
- snprintf(buffer, sizeof(buffer), "%.200s/%.50s", radius_dir, RADIUS_NASLIST);
- DEBUG2("read_config_files: reading naslist");
- if (read_naslist_file(buffer) < 0) {
- radlog(L_ERR|L_CONS, "Errors reading naslist");
- return -1;
- }
-
- /* old-style clients file */
- snprintf(buffer, sizeof(buffer), "%.200s/%.50s", radius_dir, RADIUS_CLIENTS);
- DEBUG2("read_config_files: reading clients");
- if (read_clients_file(buffer) < 0) {
- radlog(L_ERR|L_CONS, "Errors reading clients");
- return -1;
- }
-
- /*
- * Add to that, the *new* list of clients.
- */
- snprintf(buffer, sizeof(buffer), "%.200s/%.50s", radius_dir, RADIUS_CONFIG);
- if (generate_clients(buffer) < 0) {
- return -1;
- }
-
- /* old-style realms file */
- snprintf(buffer, sizeof(buffer), "%.200s/%.50s", radius_dir, RADIUS_REALMS);
- DEBUG2("read_config_files: reading realms");
- if (read_realms_file(buffer) < 0) {
- radlog(L_ERR|L_CONS, "Errors reading realms");
- return -1;
- }
-
- /*
- * If there isn't any realms it isn't fatal..
- */
- snprintf(buffer, sizeof(buffer), "%.200s/%.50s", radius_dir, RADIUS_CONFIG);
- if (generate_realms(buffer) < 0) {
- return -1;
- }
-
- /*
- * Register the %{config:section.subsection} xlat function.
- */
- xlat_register("config", xlat_config, NULL);
-
- return 0;
-}
-
-/* JLN
- * Create the linked list of realms from the new configuration type
- * This way we don't have to change to much in the other source-files
- */
-
-static int generate_realms(const char *filename)
-{
- CONF_SECTION *cs;
- REALM *my_realms = NULL;
- REALM *c, **tail;
- char *s, *t, *authhost, *accthost;
-
- tail = &my_realms;
- for (cs = cf_subsection_find_next(mainconfig.config, NULL, "realm"); cs != NULL;
- cs = cf_subsection_find_next(mainconfig.config, cs, "realm")) {
- if (!cs->name2) {
- radlog(L_CONS|L_ERR, "%s[%d]: Missing realm name", filename, cs->item.lineno);
- return -1;
- }
- /*
- * We've found a realm, allocate space for it
- */
- c = rad_malloc(sizeof(REALM));
- memset(c, 0, sizeof(REALM));
-
- c->secret[0] = '\0';
-
- /*
- * No authhost means LOCAL.
- */
- if ((authhost = cf_section_value_find(cs, "authhost")) == NULL) {
- c->ipaddr = htonl(INADDR_NONE);
- c->auth_port = auth_port;
- } else {
- if ((s = strchr(authhost, ':')) != NULL) {
- *s++ = 0;
- c->auth_port = atoi(s);
- } else {
- c->auth_port = auth_port;
- }
- if (strcmp(authhost, "LOCAL") == 0) {
- /*
- * Local realms don't have an IP address,
- * secret, or port.
- */
- c->ipaddr = htonl(INADDR_NONE);
- c->auth_port = auth_port;
- } else {
- c->ipaddr = ip_getaddr(authhost);
- }
- }
-
- /*
- * No accthost means LOCAL
- */
- if ((accthost = cf_section_value_find(cs, "accthost")) == NULL) {
- c->acct_ipaddr = htonl(INADDR_NONE);
- c->acct_port = acct_port;
- } else {
- if ((s = strchr(accthost, ':')) != NULL) {
- *s++ = 0;
- c->acct_port = atoi(s);
- } else {
- c->acct_port = acct_port;
- }
- if (strcmp(accthost, "LOCAL") == 0) {
- /*
- * Local realms don't have an IP address,
- * secret, or port.
- */
- c->acct_ipaddr = htonl(INADDR_NONE);
- c->acct_port = acct_port;
- } else {
- c->acct_ipaddr = ip_getaddr(accthost);
- }
- }
-
- /*
- * Double check length, just to be sure!
- */
- if (strlen(authhost) >= sizeof(c->server)) {
- radlog(L_ERR, "%s[%d]: Server name of length %d is greater that allowed: %d",
- filename, cs->item.lineno,
- strlen(authhost), sizeof(c->server) - 1);
- return -1;
- }
- if (strlen(cs->name2) >= sizeof(c->realm)) {
- radlog(L_ERR, "%s[%d]: Realm name of length %d is greater than allowed %d",
- filename, cs->item.lineno,
- strlen(cs->name2), sizeof(c->server) - 1);
- return -1;
- }
-
- strcpy(c->realm, cs->name2);
- strcpy(c->server, authhost);
-
- /*
- * If one or the other of authentication/accounting
- * servers is set to LOCALHOST, then don't require
- * a shared secret.
- */
- if ((c->ipaddr != htonl(INADDR_NONE)) ||
- (c->acct_ipaddr != htonl(INADDR_NONE))) {
- if ((s = cf_section_value_find(cs, "secret")) == NULL ) {
- radlog(L_ERR, "%s[%d]: No shared secret supplied for realm: %s",
- filename, cs->item.lineno, cs->name2);
- return -1;
- }
-
- if (strlen(s) >= sizeof(c->secret)) {
- radlog(L_ERR, "%s[%d]: Secret of length %d is greater than the allowed maximum of %d.",
- filename, cs->item.lineno,
- strlen(s), sizeof(c->secret) - 1);
- return -1;
- }
- strNcpy((char *)c->secret, s, sizeof(c->secret));
- }
-
- c->striprealm = 1;
-
- if ((cf_section_value_find(cs, "nostrip")) != NULL)
- c->striprealm = 0;
- if ((cf_section_value_find(cs, "noacct")) != NULL)
- c->acct_port = 0;
- if ((cf_section_value_find(cs, "trusted")) != NULL)
- c->trusted = 1;
- if ((cf_section_value_find(cs, "notrealm")) != NULL)
- c->notrealm = 1;
- if ((cf_section_value_find(cs, "notsuffix")) != NULL)
- c->notrealm = 1;
- if ((t = cf_section_value_find(cs,"ldflag")) != NULL) {
- if ((strcmp(t,"1") == 0) ||
- (strcasecmp(t,"round_robin") == 0)) {
- c->ldflag = 1;
- }
- else if ((strcmp(t,"0") == 0) ||
- (strcasecmp(t,"fail_over") == 0)) {
- c->ldflag = 0;
- }
- else {
- /* set to invalid value
- * to be caught later
- */
- c->ldflag = -1;
- }
- }
- else {
- c->ldflag = 0;
- }
- c->active = TRUE;
- c->acct_active = TRUE;
-
- c->next = NULL;
- *tail = c;
- tail = &c->next;
- }
-
- /*
- * And make these realms preferred over the ones
- * in the 'realms' file.
- */
- *tail = mainconfig.realms;
- mainconfig.realms = my_realms;
-
- return 0;
-}
-
-/* JLN
- * Create the linked list of realms from the new configuration type
- * This way we don't have to change to much in the other source-files
- */
-static int generate_clients(const char *filename)
-{
- CONF_SECTION *cs;
- RADCLIENT *c;
- char *hostnm, *secret, *shortnm, *netmask;
- char *nastype, *login, *password;
-
- for (cs = cf_subsection_find_next(mainconfig.config, NULL, "client"); cs != NULL;
- cs = cf_subsection_find_next(mainconfig.config, cs, "client")) {
- if (!cs->name2) {
- radlog(L_CONS|L_ERR, "%s[%d]: Missing client name", filename, cs->item.lineno);
- return -1;
- }
- /*
- * Check the lengths, we don't want any core dumps
- */
- hostnm = cs->name2;
-
- if((secret = cf_section_value_find(cs, "secret")) == NULL) {
- radlog(L_ERR, "%s[%d]: Missing secret for client: %s",
- filename, cs->item.lineno, cs->name2);
- return -1;
- }
-
- if((shortnm = cf_section_value_find(cs, "shortname")) == NULL) {
- radlog(L_ERR, "%s[%d]: Missing shortname for client: %s",
- filename, cs->item.lineno, cs->name2);
- return -1;
- }
-
- netmask = strchr(hostnm, '/');
-
- if (strlen(secret) >= sizeof(c->secret)) {
- radlog(L_ERR, "%s[%d]: Secret of length %d is greater than the allowed maximum of %d.",
- filename, cs->item.lineno,
- strlen(secret), sizeof(c->secret) - 1);
- return -1;
- }
- if (strlen(shortnm) > sizeof(c->shortname)) {
- radlog(L_ERR, "%s[%d]: Client short name of length %d is greater than the allowed maximum of %d.",
- filename, cs->item.lineno,
- strlen(shortnm), sizeof(c->shortname) - 1);
- return -1;
- }
-
- if((nastype = cf_section_value_find(cs, "nastype")) != NULL) {
- if(strlen(nastype) >= sizeof(c->nastype)) {
- radlog(L_ERR, "%s[%d]: nastype of length %d longer than the allowed maximum of %d",
- filename, cs->item.lineno,
- strlen(nastype), sizeof(c->nastype) - 1);
- return -1;
- }
- }
-
- if((login = cf_section_value_find(cs, "login")) != NULL) {
- if(strlen(login) >= sizeof(c->login)) {
- radlog(L_ERR, "%s[%d]: login of length %d longer than the allowed maximum of %d",
- filename, cs->item.lineno,
- strlen(login), sizeof(c->login) - 1);
- return -1;
- }
- }
-
- if((password = cf_section_value_find(cs, "password")) != NULL) {
- if(strlen(password) >= sizeof(c->password)) {
- radlog(L_ERR, "%s[%d]: password of length %d longer than the allowed maximum of %d",
- filename, cs->item.lineno,
- strlen(password), sizeof(c->password) - 1);
- return -1;
- }
- }
-
- /*
- * The size is fine.. Let's create the buffer
- */
- c = rad_malloc(sizeof(RADCLIENT));
- memset(c, 0, sizeof(RADCLIENT));
-
- /*
- * Look for netmasks.
- */
- c->netmask = ~0;
- if (netmask) {
- int i, mask_length;
-
- mask_length = atoi(netmask + 1);
- if ((mask_length <= 0) || (mask_length > 32)) {
- radlog(L_ERR, "%s[%d]: Invalid value '%s' for IP network mask.",
- filename, cs->item.lineno, netmask + 1);
- return -1;
- }
-
- c->netmask = (1 << 31);
- for (i = 1; i < mask_length; i++) {
- c->netmask |= (c->netmask >> 1);
- }
-
- *netmask = '\0';
- c->netmask = htonl(c->netmask);
- }
-
- c->ipaddr = ip_getaddr(hostnm);
- if (c->ipaddr == INADDR_NONE) {
- radlog(L_CONS|L_ERR, "%s[%d]: Failed to look up hostname %s",
- filename, cs->item.lineno, hostnm);
- return -1;
- }
-
- /*
- * Update the client name again...
- */
- if (netmask) {
- *netmask = '/';
- c->ipaddr &= c->netmask;
- strcpy(c->longname, hostnm);
- } else {
- ip_hostname(c->longname, sizeof(c->longname),
- c->ipaddr);
- }
-
- strcpy((char *)c->secret, secret);
- strcpy(c->shortname, shortnm);
- if(nastype != NULL)
- strcpy(c->nastype, nastype);
- if(login != NULL)
- strcpy(c->login, login);
- if(password != NULL)
- strcpy(c->password, password);
-
- c->next =mainconfig. clients;
- mainconfig.clients = c;
- }
-
- return 0;
-}
/*
* Return a CONF_PAIR within a CONF_SECTION.
*/
-
CONF_PAIR *cf_pair_find(CONF_SECTION *section, const char *name)
{
CONF_ITEM *ci;