PATCH: expiration -> support for schacExpiryDate format

Rok Papež rok.papez at arnes.si
Thu May 15 13:55:28 CEST 2008


Hello!

First of all I must admit that Freeradius 2.0 looks fantastic. The proxying configuration is excellent:
failover/balancers, regexps, pools.... Not to mention other numerous improvements. Congratulations
to developers for the excellent work :))).

Back to the topic:
Some of the customers in eduroam.si federation are using the schacExpiryDate
LDAP field to set account expiration date. Since this date format isn't support I've
added support for it. I would appreciate any comments about the patch.

Details follow:
==========================================================
Data specification from European SCHAC - SChema Harmonisation Committee:
http://www.terena.org/activities/tf-emc2/schacreleases.html
Short description of format:
Values MUST be expressed Greenwich Mean Time (Zulu) and MUST include seconds
(i.e., times are YYYYMMDDhhmmssZ)

==========================================================
Patch for version 2.0.4 follows here:
###############################
--- freeradius-server-2.0.4/src/lib/valuepair.c.schac	2008-05-15 12:56:05.000000000 +0200
+++ freeradius-server-2.0.4/src/lib/valuepair.c	2008-05-15 12:56:14.000000000 +0200
@@ -658,12 +658,33 @@
 }
 
 /*
+ *	We need mktime that can handle UTC time. 
+ *	See "man timegm" for details.
+ */
+static time_t mkgmtime(struct tm *tm) {
+	time_t ret;
+	char *tz;
+
+	tz = getenv("TZ");
+	setenv("TZ","",1);
+	tzset();
+	ret = mktime(tm);
+	if (tz)	{
+		setenv("TZ",tz,1);
+	} else {
+		unsetenv("TZ");
+	}
+	tzset();
+	return ret;
+}
+
+/*
  *	Turn printable string into time_t
  *	Returns -1 on error, 0 on OK.
  */
 static int gettime(const char *valstr, time_t *date)
 {
-	int		i;
+	int		i,len;
 	time_t		t;
 	struct tm	*tm, s_tm;
 	char		buf[64];
@@ -678,11 +699,37 @@
 	if (*tail == '\0') {
 		return 0;
 	}
-
+	
 	tm = &s_tm;
 	memset(tm, 0, sizeof(*tm));
 	tm->tm_isdst = -1;	/* don't know, and don't care about DST */
 
+	/*
+	 * Test for SCHAC date: RFC3339 Par 5.6 'full-date' with no dashes
+	 */
+	len = strlen(valstr);
+	if (sizeof("YYYYMMDDhhmmssZ") == len+1) {
+		i = sscanf(valstr, "%4d%2d%2d%2d%2d%2d%*1[zZ]",
+			&s_tm.tm_year, &s_tm.tm_mon, &s_tm.tm_mday,
+			&s_tm.tm_hour, &s_tm.tm_min, &s_tm.tm_sec);
+		if (6 == i) { /* all 6 elements returned or no cigar */
+			/* fix to mt interpretation */
+			s_tm.tm_mon  -= 1;
+			s_tm.tm_year -= 1900;
+			t = mkgmtime(tm);
+			if (t == (time_t) -1) return -1;
+			*date = t;
+			DEBUG("Expiry date set to local time: %s", ctime(date));
+			return 0;
+		}
+	}
+
+	/*
+	 * Let's try to parse it as a string:
+	 * Month must be a string, year must be a 4 digit value,
+	 * day/year/hour position is auto-detected
+	 */
+
 	strlcpy(buf, valstr, sizeof(buf));
 
 	p = buf;
###############################


I've added to the configuration file /etc/raddb/ldap.attrmap the following:
checkItem	Expiration	schacExpiryDate
Also the rlm_expiration is being used in authorize section right after the ldap query.

==========================================================
Logfile before patch:

Wed May 14 15:16:01 2008 : Debug: rlm_ldap: - authorize
Wed May 14 15:16:01 2008 : Debug: rlm_ldap: performing user authorization for uporabnik1
[... user found ...]
Wed May 14 15:16:01 2008 : Debug: rlm_ldap: looking for check items in directory...
Wed May 14 15:16:01 2008 : Error: rlm_ldap: Failed to create the pair: failed to parse time string "20080501235959Z"
Wed May 14 15:16:01 2008 : Debug: rlm_ldap: looking for reply items in directory...
Wed May 14 15:16:01 2008 : Debug: rlm_ldap: user uporabnik1 authorized to use remote access
Wed May 14 15:16:01 2008 : Debug: rlm_ldap: ldap_release_conn: Release Id: 0

==========================================================
1. Logfile with patch (user acc expired):
Thu May 15 13:40:03 2008 : Debug: rlm_ldap: looking for check items in directory...
Expiry date set to local time: Fri May  2 01:59:59 2008
Thu May 15 13:40:03 2008 : Debug: rlm_ldap: LDAP attribute schacExpiryDate as RADIUS attribute Expiration == "May  2 2008 01:59:59 CEST"
Thu May 15 13:40:03 2008 : Debug: rlm_ldap: looking for reply items in directory...
[...]
Thu May 15 13:40:03 2008 : Debug:   modsingle[authorize]: calling expiration (rlm_expiration) for request 5
Thu May 15 13:40:03 2008 : Debug: rlm_expiration: Checking Expiration time: '20080501235959Z'
Thu May 15 13:40:03 2008 : Debug: rlm_expiration: Account has expired
Thu May 15 13:40:03 2008 : Debug:       expand: Authorization failed: Account Has Expired   -> Authorization failed: Account Has Expired  
Thu May 15 13:40:03 2008 : Debug:   modsingle[authorize]: returned from expiration (rlm_expiration) for request 5
Thu May 15 13:40:03 2008 : Debug: ++[expiration] returns userlock
Thu May 15 13:40:03 2008 : Auth: Invalid user (Account has expired [Expiration 20080501235959Z]): [uporabnik1 at domena.si/geslo1]

==========================================================
2. Logfile with patch (user acc is valid):

Thu May 15 13:40:37 2008 : Debug: rlm_ldap: looking for check items in directory...
Expiry date set to local time: Tue Sep  2 01:59:59 2008
Thu May 15 13:40:37 2008 : Debug: rlm_ldap: LDAP attribute schacExpiryDate as RADIUS attribute Expiration == "Sep  2 2008 01:59:59 CEST"
Thu May 15 13:40:37 2008 : Debug: rlm_ldap: looking for reply items in directory...
Thu May 15 13:40:37 2008 : Debug: rlm_ldap: user uporabnik1 authorized to use remote access
Thu May 15 13:40:37 2008 : Debug: rlm_ldap: ldap_release_conn: Release Id: 0
[...]
Thu May 15 13:40:37 2008 : Debug:   modsingle[authorize]: calling expiration (rlm_expiration) for request 10
Thu May 15 13:40:37 2008 : Debug: rlm_expiration: Checking Expiration time: '20080901235959Z'
Thu May 15 13:40:37 2008 : Debug:   modsingle[authorize]: returned from expiration (rlm_expiration) for request 10
Thu May 15 13:40:37 2008 : Debug: ++[expiration] returns ok
[...]
Thu May 15 13:40:37 2008 : Debug:   modsingle[post-auth]: returned from exec (rlm_exec) for request 10
Thu May 15 13:40:37 2008 : Debug: ++[exec] returns noop
} # server (null)
  TTLS: Got tunneled reply RADIUS code 2
        User-Name = "uporabnik1 at domena.si"
        Session-Timeout = 9461962
Thu May 15 13:40:37 2008 : Debug:   TTLS: Got tunneled Access-Accept

-- 
Best regards,
Rok Papež.




More information about the Freeradius-Devel mailing list