int rc_find_server (rc_handle *rh, const char *server_name, uint32_t *ip_addr, char *secret) { int i; size_t len; int result = 0; FILE *clientfd; char *h; char *s; char buffer[128]; char hostnm[AUTH_ID_LEN + 1]; char *buffer_save; char *hostnm_save; SERVER *authservers; SERVER *acctservers; /* Lookup the IP address of the radius server */ if ((*ip_addr = rc_get_ipaddr (server_name)) == (uint32_t) 0) return -1; /* Check to see if the server secret is defined in the rh config */ if( (authservers = rc_conf_srv(rh, "authserver")) != NULL ) { for( i = 0; i < authservers->max; i++ ) { if( (strncmp(server_name, authservers->name[i], strlen(server_name)) == 0) && (authservers->secret[i] != NULL) ) { memset (secret, '\0', MAX_SECRET_LENGTH); len = strlen (authservers->secret[i]); if (len > MAX_SECRET_LENGTH) { len = MAX_SECRET_LENGTH; } strncpy (secret, authservers->secret[i], (size_t) len); secret[MAX_SECRET_LENGTH] = '\0'; return 0; } } } if( (acctservers = rc_conf_srv(rh, "acctserver")) != NULL ) { for( i = 0; i < acctservers->max; i++ ) { if( (strncmp(server_name, acctservers->name[i], strlen(server_name)) == 0) && (acctservers->secret[i] != NULL) ) { memset (secret, '\0', MAX_SECRET_LENGTH); len = strlen (acctservers->secret[i]); if (len > MAX_SECRET_LENGTH) { len = MAX_SECRET_LENGTH; } strncpy (secret, acctservers->secret[i], (size_t) len); secret[MAX_SECRET_LENGTH] = '\0'; return 0; } } } /* We didn't find it in the rh_config or the servername is too long so look for a * servers file to define the secret(s) */ if ((clientfd = fopen (rc_conf_str(rh, "servers"), "r")) == NULL) { rc_log(LOG_ERR, "rc_find_server: couldn't open file: %s: %s", strerror(errno), rc_conf_str(rh, "servers")); return -1; } while (fgets (buffer, sizeof (buffer), clientfd) != NULL) { if (*buffer == '#') continue; if ((h = strtok_r(buffer, " \t\n", &buffer_save)) == NULL) /* first hostname */ continue; memset (hostnm, '\0', AUTH_ID_LEN); len = strlen (h); if (len > AUTH_ID_LEN) { len = AUTH_ID_LEN; } strncpy (hostnm, h, (size_t) len); hostnm[AUTH_ID_LEN] = '\0'; if ((s = strtok_r (NULL, " \t\n", &buffer_save)) == NULL) /* and secret field */ continue; memset (secret, '\0', MAX_SECRET_LENGTH); len = strlen (s); if (len > MAX_SECRET_LENGTH) { len = MAX_SECRET_LENGTH; } strncpy (secret, s, (size_t) len); secret[MAX_SECRET_LENGTH] = '\0'; if (!strchr (hostnm, '/')) /* If single name form */ { if (find_match (ip_addr, hostnm) == 0) { result++; break; } } else /* <name1>/<name2> "paired" form */ { strtok_r(hostnm, "/", &hostnm_save); if (rc_is_myname(hostnm) == 0) { /* If we're the 1st name, target is 2nd */ if (find_match (ip_addr, hostnm_save) == 0) { result++; break; } } else /* If we were 2nd name, target is 1st name */ { if (find_match (ip_addr, hostnm) == 0) { result++; break; } } } } fclose (clientfd); if (result == 0) { memset (buffer, '\0', sizeof (buffer)); memset (secret, '\0', sizeof (secret)); rc_log(LOG_ERR, "rc_find_server: couldn't find RADIUS server %s in %s", server_name, rc_conf_str(rh, "servers")); return -1; } return 0; }
/** Locate a server in the rh config or if not found, check for a servers file * * @param rh a handle to parsed configuration. * @param server_name the name of the server. * @param info: will hold a pointer to addrinfo * @param secret will hold the server's secret (of %MAX_SECRET_LENGTH). * @param flags %AUTH or %ACCT * @return 0 on success, -1 on failure. */ int rc_find_server_addr (rc_handle const *rh, char const *server_name, struct addrinfo** info, char *secret, unsigned flags) { int i; int result = 0; FILE *clientfd; char *h; char *s; char buffer[128]; char hostnm[AUTH_ID_LEN + 1]; char *buffer_save; char *hostnm_save; SERVER *authservers; SERVER *acctservers; struct addrinfo *tmpinfo = NULL; /* Lookup the IP address of the radius server */ if ((*info = rc_getaddrinfo (server_name, flags==AUTH?PW_AI_AUTH:PW_AI_ACCT)) == NULL) return -1; if (flags == AUTH) { /* Check to see if the server secret is defined in the rh config */ if( (authservers = rc_conf_srv(rh, "authserver")) != NULL ) { for( i = 0; i < authservers->max; i++ ) { if( (strncmp(server_name, authservers->name[i], strlen(server_name)) == 0) && (authservers->secret[i] != NULL) ) { memset (secret, '\0', MAX_SECRET_LENGTH); strlcpy (secret, authservers->secret[i], MAX_SECRET_LENGTH); return 0; } } } } else if (flags == ACCT) { if( (acctservers = rc_conf_srv(rh, "acctserver")) != NULL ) { for( i = 0; i < acctservers->max; i++ ) { if( (strncmp(server_name, acctservers->name[i], strlen(server_name)) == 0) && (acctservers->secret[i] != NULL) ) { memset (secret, '\0', MAX_SECRET_LENGTH); strlcpy (secret, acctservers->secret[i], MAX_SECRET_LENGTH); return 0; } } } } /* We didn't find it in the rh_config or the servername is too long so look for a * servers file to define the secret(s) */ if ((clientfd = fopen (rc_conf_str(rh, "servers"), "r")) == NULL) { rc_log(LOG_ERR, "rc_find_server: couldn't open file: %s: %s", strerror(errno), rc_conf_str(rh, "servers")); goto fail; } while (fgets (buffer, sizeof (buffer), clientfd) != NULL) { if (*buffer == '#') continue; if ((h = strtok_r(buffer, " \t\n", &buffer_save)) == NULL) /* first hostname */ continue; strlcpy (hostnm, h, AUTH_ID_LEN); if ((s = strtok_r (NULL, " \t\n", &buffer_save)) == NULL) /* and secret field */ continue; strlcpy (secret, s, MAX_SECRET_LENGTH); if (!strchr (hostnm, '/')) /* If single name form */ { tmpinfo = rc_getaddrinfo(hostnm, 0); if (tmpinfo) { result = find_match (*info, tmpinfo); if (result == 0) { result++; break; } freeaddrinfo(tmpinfo); tmpinfo = NULL; } } else /* <name1>/<name2> "paired" form */ { strtok_r(hostnm, "/", &hostnm_save); tmpinfo = rc_getaddrinfo(hostnm, 0); if (tmpinfo) { if (rc_is_myname(tmpinfo) == 0) { /* If we're the 1st name, target is 2nd */ if (find_match (*info, tmpinfo) == 0) { result++; break; } } else /* If we were 2nd name, target is 1st name */ { if (find_match (*info, tmpinfo) == 0) { result++; break; } } freeaddrinfo(tmpinfo); tmpinfo = NULL; } } } fclose (clientfd); if (result == 0) { memset (buffer, '\0', sizeof (buffer)); memset (secret, '\0', MAX_SECRET_LENGTH); rc_log(LOG_ERR, "rc_find_server: couldn't find RADIUS server %s in %s", server_name, rc_conf_str(rh, "servers")); goto fail; } result = 0; goto cleanup; fail: freeaddrinfo(*info); result = -1; cleanup: if (tmpinfo) freeaddrinfo(tmpinfo); return result; }