Add a new configuration variable - nas_ipaddr, which if set allows to
set NAS-IP-Address attribute in requests generated by the pam_radius module. This attribute is mandatory for some Radius servers out there. Reviewed by: des MFC after: 2 weeks
This commit is contained in:
parent
d55a273392
commit
f142677b46
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=122571
@ -100,6 +100,10 @@ If this option is omitted, and there is no username
|
||||
in the system databases equal to the supplied one (as determined by call to
|
||||
.Xr getpwnam 3 ) ,
|
||||
the authentication will fail.
|
||||
.It Cm nas_ipaddr Ns Op No = Ns Ar address
|
||||
specifies a NAS IP address to be sent.
|
||||
If option is present, but there is no value provided then IP address
|
||||
corresponding to the current hostname will be used.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/radius.conf -compact
|
||||
|
@ -38,6 +38,9 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <pwd.h>
|
||||
#include <radlib.h>
|
||||
#include <stdlib.h>
|
||||
@ -54,12 +57,14 @@ __FBSDID("$FreeBSD$");
|
||||
#define PAM_OPT_CONF "conf"
|
||||
#define PAM_OPT_TEMPLATE_USER "template_user"
|
||||
#define PAM_OPT_NAS_ID "nas_id"
|
||||
#define PAM_OPT_NAS_IPADDR "nas_ipaddr"
|
||||
|
||||
#define MAX_CHALLENGE_MSGS 10
|
||||
#define PASSWORD_PROMPT "RADIUS Password:"
|
||||
|
||||
static int build_access_request(struct rad_handle *, const char *,
|
||||
const char *, const char *, const void *, size_t);
|
||||
const char *, const char *, const char *, const void *,
|
||||
size_t);
|
||||
static int do_accept(pam_handle_t *, struct rad_handle *);
|
||||
static int do_challenge(pam_handle_t *, struct rad_handle *,
|
||||
const char *);
|
||||
@ -70,16 +75,28 @@ static int do_challenge(pam_handle_t *, struct rad_handle *,
|
||||
*/
|
||||
static int
|
||||
build_access_request(struct rad_handle *radh, const char *user,
|
||||
const char *pass, const char *nas_id, const void *state, size_t state_len)
|
||||
const char *pass, const char *nas_id, const char *nas_ipaddr,
|
||||
const void *state, size_t state_len)
|
||||
{
|
||||
char host[MAXHOSTNAMELEN];
|
||||
int error;
|
||||
char host[MAXHOSTNAMELEN];
|
||||
struct sockaddr_in *haddr;
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *res;
|
||||
|
||||
if (rad_create_request(radh, RAD_ACCESS_REQUEST) == -1) {
|
||||
syslog(LOG_CRIT, "rad_create_request: %s", rad_strerror(radh));
|
||||
return (-1);
|
||||
}
|
||||
if (nas_id == NULL && gethostname(host, sizeof host) != -1)
|
||||
nas_id = host;
|
||||
if (nas_id == NULL ||
|
||||
(nas_ipaddr != NULL && strlen(nas_ipaddr) == 0)) {
|
||||
if (gethostname(host, sizeof host) != -1) {
|
||||
if (nas_id == NULL)
|
||||
nas_id = host;
|
||||
if (nas_ipaddr != NULL && strlen(nas_ipaddr) == 0)
|
||||
nas_ipaddr = host;
|
||||
}
|
||||
}
|
||||
if ((user != NULL &&
|
||||
rad_put_string(radh, RAD_USER_NAME, user) == -1) ||
|
||||
(pass != NULL &&
|
||||
@ -89,6 +106,22 @@ build_access_request(struct rad_handle *radh, const char *user,
|
||||
syslog(LOG_CRIT, "rad_put_string: %s", rad_strerror(radh));
|
||||
return (-1);
|
||||
}
|
||||
if (nas_ipaddr != NULL) {
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = PF_INET;
|
||||
if (getaddrinfo(nas_ipaddr, NULL, &hints, &res) == 0 &&
|
||||
res != NULL) {
|
||||
haddr = (struct sockaddr_in *)res->ai_addr;
|
||||
error = rad_put_addr(radh, RAD_NAS_IP_ADDRESS,
|
||||
haddr->sin_addr);
|
||||
freeaddrinfo(res);
|
||||
if (error == -1) {
|
||||
syslog(LOG_CRIT, "rad_put_addr: %s",
|
||||
rad_strerror(radh));
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (state != NULL && rad_put_attr(radh, RAD_STATE, state,
|
||||
state_len) == -1) {
|
||||
syslog(LOG_CRIT, "rad_put_attr: %s", rad_strerror(radh));
|
||||
@ -197,7 +230,7 @@ do_challenge(pam_handle_t *pamh, struct rad_handle *radh, const char *user)
|
||||
conv->appdata_ptr)) != PAM_SUCCESS)
|
||||
return (retval);
|
||||
if (build_access_request(radh, user, resp[num_msgs-1].resp, NULL,
|
||||
state, statelen) == -1)
|
||||
NULL, state, statelen) == -1)
|
||||
return (PAM_SERVICE_ERR);
|
||||
memset(resp[num_msgs-1].resp, 0, strlen(resp[num_msgs-1].resp));
|
||||
free(resp[num_msgs-1].resp);
|
||||
@ -213,13 +246,14 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags __unused,
|
||||
{
|
||||
struct rad_handle *radh;
|
||||
const char *user, *tmpuser, *pass;
|
||||
const char *conf_file, *template_user, *nas_id;
|
||||
const char *conf_file, *template_user, *nas_id, *nas_ipaddr;
|
||||
int retval;
|
||||
int e;
|
||||
|
||||
conf_file = openpam_get_option(pamh, PAM_OPT_CONF);
|
||||
template_user = openpam_get_option(pamh, PAM_OPT_TEMPLATE_USER);
|
||||
nas_id = openpam_get_option(pamh, PAM_OPT_NAS_ID);
|
||||
nas_ipaddr = openpam_get_option(pamh, PAM_OPT_NAS_IPADDR);
|
||||
|
||||
retval = pam_get_user(pamh, &user, NULL);
|
||||
if (retval != PAM_SUCCESS)
|
||||
@ -249,7 +283,8 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags __unused,
|
||||
|
||||
PAM_LOG("Radius config file read");
|
||||
|
||||
if (build_access_request(radh, user, pass, nas_id, NULL, 0) == -1) {
|
||||
if (build_access_request(radh, user, pass, nas_id, nas_ipaddr, NULL,
|
||||
0) == -1) {
|
||||
rad_close(radh);
|
||||
return (PAM_SERVICE_ERR);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user