PATCH: expiration -> support for schacExpiryDate format
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@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@domena.si" Session-Timeout = 9461962 Thu May 15 13:40:37 2008 : Debug: TTLS: Got tunneled Access-Accept -- Best regards, Rok Papež.
participants (1)
-
Rok Papež