--- mod_auth_radius-2.0.c	2003-03-25 23:05:00.000000000 +0100
+++ mod_auth_radius-2.0-nas-2.0.c	2006-02-23 11:33:33.000000000 +0100
@@ -1,6 +1,10 @@
 /* ====================================================================
  * Copyright (c) 1997-2002 The Apache Group.  All rights reserved.
  *
+ *
+ * Changed 2005-2006 by Folke Ashberg <folke@ashberg.de>
+ *   Added per-directory parameter nasname
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -290,6 +294,9 @@
 #include <netdb.h>
 #include <openssl/md5.h>
 #include <sys/stat.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <string.h>
 
 #include "httpd.h"
 #include "http_config.h"
@@ -438,6 +445,7 @@
   int active;                   /* Are we doing RADIUS in this dir? */
   int authoritative;		/* is RADIUS authentication authoritative? */
   int timeout;			/* cookie time valid */
+  char *nasname;		/* nasname sent to radius */
 } radius_dir_config_rec;
 
 /* Per-dir configuration create */
@@ -452,6 +460,7 @@
   rec->active = 1;              /* active by default */  
   rec->authoritative = 1;	/* authoritative by default */
   rec->timeout = 0;		/* let the server config decide timeouts */
+  rec->nasname = NULL;		/* set nasname to NULL */
 
   return rec;
 }
@@ -564,6 +573,11 @@
   AP_INIT_FLAG("AuthRadiusActive", ap_set_flag_slot,
     (void*)APR_OFFSETOF(radius_dir_config_rec, active), OR_AUTHCFG,
     "per-directory toggle the use of RADIUS authentication."),
+  
+  AP_INIT_TAKE1("AuthRadiusNasName", ap_set_string_slot,
+    (void*)APR_OFFSETOF(radius_dir_config_rec, nasname), OR_AUTHCFG,
+    "per-directory nas name sent to radius server." ),
+
   { NULL }
 };
 
@@ -623,7 +637,7 @@
 #define COOKIE_SIZE 1024
 /* make a cookie based on secret + public information */
 static char *
-make_cookie(request_rec *r, time_t expires, const char *passwd, const char *string)
+make_cookie(request_rec *r, time_t expires, const char *passwd, const char *string, const char *nasname)
 {
   char one[COOKIE_SIZE], two[COOKIE_SIZE];
   char *cookie = apr_pcalloc(r->pool, COOKIE_SIZE);
@@ -676,8 +690,8 @@
    * Also, RFC 2104.  I don't know if the HMAC gives any additional
    * benefit here.
    */  
-  apr_snprintf(one, COOKIE_SIZE, "%s%s%s%s%s%08x", scr->secret,
-	      r->user, passwd, c->remote_ip, hostname, expires);
+  apr_snprintf(one, COOKIE_SIZE, "%s%s%s%s%s%s%08x", scr->secret,
+	      r->user, passwd, c->remote_ip, hostname, nasname, (unsigned int)expires);
 
   /* if you're REALLY worried about what's going on */
 
@@ -694,15 +708,15 @@
   apr_snprintf(two, COOKIE_SIZE, "%s%s", scr->secret, ap_md5(r->pool, one));
   if (string == NULL) {
     apr_snprintf(cookie, COOKIE_SIZE, "%s%08x",
-		ap_md5(r->pool, two), expires);
+		ap_md5(r->pool, two), (unsigned int)expires);
   } else {
     apr_snprintf(cookie, COOKIE_SIZE, "%s%08x%s",
-		ap_md5(r->pool, two), expires, string);
+		ap_md5(r->pool, two), (unsigned int)expires, string);
   }
   return cookie;
 }
 static int
-valid_cookie(request_rec *r, const char *cookie, const char *passwd)
+valid_cookie(request_rec *r, const char *cookie, const char *passwd, const char *nasname)
 {
   time_t expires, now;
 
@@ -718,7 +732,7 @@
   }
 
   /* Is the returned cookie identical to one made from our secret? */
-  if (strcmp(cookie, make_cookie(r, expires, passwd, NULL)) == 0)
+  if (strcmp(cookie, make_cookie(r, expires, passwd, NULL, nasname)) == 0)
     return TRUE;
   
   return FALSE;			/* cookie doesn't match: re-validate */
@@ -776,7 +790,8 @@
 
 /* There's a lot of parameters to this function, but it does a lot of work */
 static int
-radius_authenticate(request_rec *r, radius_server_config_rec *scr, 
+radius_authenticate(request_rec *r, radius_server_config_rec *scr,
+		    radius_dir_config_rec *rec,
 		    int sockfd, int code, char *recv_buffer,
 		    const char *user, const char *passwd_in, const char *state, 
 		    unsigned char *vector, char *errstr)
@@ -787,7 +802,7 @@
   fd_set set;
   int retries = scr->retries;
   struct timeval tv;
-  int rcode;
+  int rcode = -1;
   struct in_addr *ip_addr;
   
   unsigned char misc[RADIUS_RANDOM_VECTOR_LEN];
@@ -854,8 +869,8 @@
   
   /* ************************************************************ */
   /* Tell the RADIUS server which virtual server we're coming from */
-  add_attribute(packet, RADIUS_NAS_IDENTIFIER, r->server->server_hostname,
-		strlen(r->server->server_hostname));
+  add_attribute(packet, RADIUS_NAS_IDENTIFIER, rec->nasname,
+		strlen(rec->nasname));
 
   /* ************************************************************ */
   /* Tell the RADIUS server which IP address we're coming from */
@@ -983,7 +998,7 @@
 
 /* authentication module utility functions */
 static int
-check_pw(request_rec *r, radius_server_config_rec *scr, const char *user, const char *passwd_in, const char *state, char *message, char *errstr)
+check_pw(request_rec *r, radius_server_config_rec *scr, radius_dir_config_rec *rec, const char *user, const char *passwd_in, const char *state, char *message, char *errstr)
 {
   struct sockaddr_in *sin;
   struct sockaddr salocal;
@@ -1020,7 +1035,7 @@
     return FALSE;
   }
 
-  rcode = radius_authenticate(r, scr, sockfd, RADIUS_ACCESS_REQUEST, recv_buffer, user, passwd_in, state, vector, errstr);
+  rcode = radius_authenticate(r, scr, rec, sockfd, RADIUS_ACCESS_REQUEST, recv_buffer, user, passwd_in, state, vector, errstr);
 
   close(sockfd);		/* we're done with it */
 
@@ -1080,7 +1095,7 @@
 	  }
 	  
 	  /* set the magic cookie */
-	  add_cookie(r, r->err_headers_out,make_cookie(r, expires, "", server_state), expires);
+	  add_cookie(r, r->err_headers_out,make_cookie(r, expires, "", server_state, rec->nasname), expires);
 
 	  /* log the challenge, as it IS an error returned to the user */
 	  ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r->server, "RADIUS server requested challenge for user %s", user);
@@ -1130,7 +1145,6 @@
   server_rec *s = r->server; 
   radius_server_config_rec *scr = (radius_server_config_rec *)
     ap_get_module_config (s->module_config, &radius_auth_module);
-  conn_rec *c = r->connection;
   const char *sent_pw;
   char errstr[MAX_STRING_LEN];
   int res, min;
@@ -1142,7 +1156,10 @@
   
   if (!rec->active || !scr->radius_ip)	/*  not active here, or no radius */
     return DECLINED;                    /*  server declared, decline      */
-  
+  if (!rec->nasname){
+      ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r->server,  "AuthRadiusNasName not set!");
+      return HTTP_INTERNAL_SERVER_ERROR;
+  }
   if ((res = ap_get_basic_auth_pw(r, &sent_pw)))
     return res;
 
@@ -1171,7 +1188,7 @@
       state += sizeof(APACHE_RADIUS_MAGIC_STATE) -1; /* skip state string */
 
       /* valid username, passwd, and expiry date: don't do RADIUS */
-    } else if (valid_cookie(r, cookie, sent_pw)) {
+    } else if (valid_cookie(r, cookie, sent_pw, rec->nasname)) {
       ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r->server,"still valid.  Serving page.\n");
       return OK;
     } else {			/* the cookie has probably expired */
@@ -1195,7 +1212,7 @@
   }
 
   /* Check the password, and fill in the error string if an error happens */
-  if (!(check_pw(r, scr, r->user, sent_pw, state, message, errstr))) {
+  if (!(check_pw(r, scr, rec, r->user, sent_pw, state, message, errstr))) {
     ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r->server, "RADIUS authentication for user=%s password=%s failed\n",
 	    r->user, sent_pw);
     if (!(rec->authoritative)) {
@@ -1218,7 +1235,7 @@
   }
 
   expires = time(NULL) + (min * 60);
-  cookie = make_cookie(r, expires, sent_pw, NULL);
+  cookie = make_cookie(r, expires, sent_pw, NULL, rec->nasname);
 
   ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_DEBUG, 0, r->server," RADIUS Authentication for user=%s password=%s OK.  Cookie expiry in %d minutes\n",
 	  r->user, sent_pw, min);
