summaryrefslogtreecommitdiffstats
path: root/lib/libpam
diff options
context:
space:
mode:
authorsobomax <sobomax@FreeBSD.org>2003-11-12 17:47:23 +0000
committersobomax <sobomax@FreeBSD.org>2003-11-12 17:47:23 +0000
commitc33bd8de4149ea8ab805371a6221a72533b3fa40 (patch)
tree617f0801bb8b9b4e9c5e317badad6e3be37e8d6f /lib/libpam
parent58594e4f865859b55305336030f06daf5d44930d (diff)
downloadFreeBSD-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/libpam')
-rw-r--r--lib/libpam/modules/pam_radius/pam_radius.84
-rw-r--r--lib/libpam/modules/pam_radius/pam_radius.c51
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);
}
OpenPOWER on IntegriCloud