diff options
author | sobomax <sobomax@FreeBSD.org> | 2003-11-12 17:47:23 +0000 |
---|---|---|
committer | sobomax <sobomax@FreeBSD.org> | 2003-11-12 17:47:23 +0000 |
commit | c33bd8de4149ea8ab805371a6221a72533b3fa40 (patch) | |
tree | 617f0801bb8b9b4e9c5e317badad6e3be37e8d6f /lib | |
parent | 58594e4f865859b55305336030f06daf5d44930d (diff) | |
download | FreeBSD-src-c33bd8de4149ea8ab805371a6221a72533b3fa40.zip FreeBSD-src-c33bd8de4149ea8ab805371a6221a72533b3fa40.tar.gz |
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
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libpam/modules/pam_radius/pam_radius.8 | 4 | ||||
-rw-r--r-- | lib/libpam/modules/pam_radius/pam_radius.c | 51 |
2 files changed, 47 insertions, 8 deletions
diff --git a/lib/libpam/modules/pam_radius/pam_radius.8 b/lib/libpam/modules/pam_radius/pam_radius.8 index ea311dd4..519f07e 100644 --- a/lib/libpam/modules/pam_radius/pam_radius.8 +++ b/lib/libpam/modules/pam_radius/pam_radius.8 @@ -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 diff --git a/lib/libpam/modules/pam_radius/pam_radius.c b/lib/libpam/modules/pam_radius/pam_radius.c index 229e29a..5bb65ec 100644 --- a/lib/libpam/modules/pam_radius/pam_radius.c +++ b/lib/libpam/modules/pam_radius/pam_radius.c @@ -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); } |